From: Mathieu Baudier Date: Fri, 21 Oct 2022 05:21:05 +0000 (+0200) Subject: Move legacy code and icons to Argeo JCR X-Git-Tag: v2.3.10~6 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=64de5f2d37daf02d9c086d06e73f295e8470274d;p=gpl%2Fargeo-jcr.git Move legacy code and icons to Argeo JCR --- diff --git a/swt/org.argeo.cms.jcr.e4/.project b/swt/org.argeo.cms.jcr.e4/.project index 01f8dd2..290b0e6 100644 --- a/swt/org.argeo.cms.jcr.e4/.project +++ b/swt/org.argeo.cms.jcr.e4/.project @@ -20,6 +20,11 @@ + + org.eclipse.pde.ds.core.builder + + + org.eclipse.pde.PluginNature diff --git a/swt/org.argeo.cms.jcr.e4/OSGI-INF/cmsAdminRap.xml b/swt/org.argeo.cms.jcr.e4/OSGI-INF/cmsAdminRap.xml new file mode 100644 index 0000000..33dd78d --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/OSGI-INF/cmsAdminRap.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/swt/org.argeo.cms.jcr.e4/OSGI-INF/homeRepository.xml b/swt/org.argeo.cms.jcr.e4/OSGI-INF/homeRepository.xml new file mode 100644 index 0000000..2722aab --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/OSGI-INF/homeRepository.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/swt/org.argeo.cms.jcr.e4/OSGI-INF/userAdminWrapper.xml b/swt/org.argeo.cms.jcr.e4/OSGI-INF/userAdminWrapper.xml new file mode 100644 index 0000000..cc7087b --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/OSGI-INF/userAdminWrapper.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/swt/org.argeo.cms.jcr.e4/bnd.bnd b/swt/org.argeo.cms.jcr.e4/bnd.bnd index fde6c09..906f959 100644 --- a/swt/org.argeo.cms.jcr.e4/bnd.bnd +++ b/swt/org.argeo.cms.jcr.e4/bnd.bnd @@ -1,3 +1,5 @@ +Bundle-ActivationPolicy: lazy + Import-Package: \ org.eclipse.swt,\ org.eclipse.swt.widgets;version="0.0.0",\ @@ -9,4 +11,8 @@ javax.jcr.nodetype,\ org.apache.jackrabbit.*;version="[2,3)",\ org.argeo.cms,\ org.argeo.jcr,\ -* \ No newline at end of file +* + +Service-Component: OSGI-INF/homeRepository.xml,\ +OSGI-INF/userAdminWrapper.xml,\ +OSGI-INF/cmsAdminRap.xml,\ diff --git a/swt/org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi b/swt/org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi new file mode 100644 index 0000000..a3d955a --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi @@ -0,0 +1,129 @@ + + + + + shellMaximized + auth.cn=admin,ou=roles,ou=node + + + auth.cn=admin,ou=roles,ou=node + + + + + + + + + + + + + usersEditorArea + + + + + + + + + + + + + + + + + + + + + + + + + ViewMenu + + + + + + + + + + dataExplorer + + + + + + + + + + + + + + + + + + + + + + + + + auth.cn=admin,ou=roles,ou=node + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java new file mode 100644 index 0000000..aabfbf5 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java @@ -0,0 +1,47 @@ +package org.argeo.cms.e4.files; + +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.spi.FileSystemProvider; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; + +import org.argeo.eclipse.ui.fs.SimpleFsBrowser; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; + +/** Browse the node file system. */ +public class NodeFsBrowserView { + // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + + // ".nodeFsBrowserView"; + + @Inject + FileSystemProvider nodeFileSystemProvider; + + @PostConstruct + public void createPartControl(Composite parent) { + try { + // URI uri = new URI("node://root:demo@localhost:7070/"); + URI uri = new URI("node:///"); + FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri); + if (fileSystem == null) + fileSystem = nodeFileSystemProvider.newFileSystem(uri, null); + Path nodePath = fileSystem.getPath("/"); + + Path localPath = Paths.get(System.getProperty("user.home")); + + SimpleFsBrowser browser = new SimpleFsBrowser(parent, SWT.NO_FOCUS); + browser.setInput(nodePath, localPath); +// AdvancedFsBrowser browser = new AdvancedFsBrowser(); +// browser.createUi(parent, localPath); + } catch (Exception e) { + throw new RuntimeException("Cannot open file system browser", e); + } + } + + public void setFocus() { + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/package-info.java new file mode 100644 index 0000000..b481dd4 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/files/package-info.java @@ -0,0 +1,2 @@ +/** Files browser perspective. */ +package org.argeo.cms.e4.files; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundleNode.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundleNode.java new file mode 100644 index 0000000..e953683 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundleNode.java @@ -0,0 +1,46 @@ +package org.argeo.cms.e4.monitoring; + +import org.argeo.cms.ux.widgets.TreeParent; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +/** A tree element representing a {@link Bundle} */ +class BundleNode extends TreeParent { + private final Bundle bundle; + + public BundleNode(Bundle bundle) { + this(bundle, false); + } + + @SuppressWarnings("rawtypes") + public BundleNode(Bundle bundle, boolean hasChildren) { + super(bundle.getSymbolicName()); + this.bundle = bundle; + + if (hasChildren) { + // REFERENCES + ServiceReference[] usedServices = bundle.getServicesInUse(); + if (usedServices != null) { + for (ServiceReference sr : usedServices) { + if (sr != null) + addChild(new ServiceReferenceNode(sr, false)); + } + } + + // SERVICES + ServiceReference[] registeredServices = bundle + .getRegisteredServices(); + if (registeredServices != null) { + for (ServiceReference sr : registeredServices) { + if (sr != null) + addChild(new ServiceReferenceNode(sr, true)); + } + } + } + + } + + Bundle getBundle() { + return bundle; + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundlesView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundlesView.java new file mode 100644 index 0000000..c639255 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/BundlesView.java @@ -0,0 +1,114 @@ +//package org.argeo.eclipse.ui.workbench.osgi; +//public class BundlesView {} + +package org.argeo.cms.e4.monitoring; + +import javax.annotation.PostConstruct; + +import org.argeo.eclipse.ui.ColumnViewerComparator; +import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +/** + * Overview of the bundles as a table. Equivalent to Equinox 'ss' console + * command. + */ +public class BundlesView { + private final static BundleContext bc = FrameworkUtil.getBundle(BundlesView.class).getBundleContext(); + private TableViewer viewer; + + @PostConstruct + public void createPartControl(Composite parent) { + viewer = new TableViewer(parent); + viewer.setContentProvider(new BundleContentProvider()); + viewer.getTable().setHeaderVisible(true); + + EclipseUiSpecificUtils.enableToolTipSupport(viewer); + + // ID + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(30); + column.getColumn().setText("ID"); + column.getColumn().setAlignment(SWT.RIGHT); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -3122136344359358605L; + + public String getText(Object element) { + return Long.toString(((Bundle) element).getBundleId()); + } + }); + new ColumnViewerComparator(column); + + // State + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(18); + column.getColumn().setText("State"); + column.setLabelProvider(new StateLabelProvider()); + new ColumnViewerComparator(column); + + // Symbolic name + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(250); + column.getColumn().setText("Symbolic Name"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -4280840684440451080L; + + public String getText(Object element) { + return ((Bundle) element).getSymbolicName(); + } + }); + new ColumnViewerComparator(column); + + // Version + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(250); + column.getColumn().setText("Version"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = 6871926308708629989L; + + public String getText(Object element) { + Bundle bundle = (org.osgi.framework.Bundle) element; + return bundle.getVersion().toString(); + } + }); + new ColumnViewerComparator(column); + + viewer.setInput(bc); + + } + + @Focus + public void setFocus() { + if (viewer != null) + viewer.getControl().setFocus(); + } + + /** Content provider managing the array of bundles */ + private static class BundleContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -8533792785725875977L; + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof BundleContext) { + BundleContext bc = (BundleContext) inputElement; + return bc.getBundles(); + } + return null; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/CmsSessionsView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/CmsSessionsView.java new file mode 100644 index 0000000..95b1eb2 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/CmsSessionsView.java @@ -0,0 +1,173 @@ +//package org.argeo.eclipse.ui.workbench.osgi; +//public class BundlesView {} + +package org.argeo.cms.e4.monitoring; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.argeo.api.cms.CmsSession; +import org.argeo.cms.auth.RoleNameUtils; +import org.argeo.eclipse.ui.ColumnViewerComparator; +import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; +import org.argeo.util.LangUtils; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +/** + * Overview of the active CMS sessions. + */ +public class CmsSessionsView { + private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionsView.class).getBundleContext(); + + private TableViewer viewer; + + @PostConstruct + public void createPartControl(Composite parent) { + viewer = new TableViewer(parent); + viewer.setContentProvider(new CmsSessionContentProvider()); + viewer.getTable().setHeaderVisible(true); + + EclipseUiSpecificUtils.enableToolTipSupport(viewer); + + int longColWidth = 150; + int smallColWidth = 100; + + // Display name + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(longColWidth); + column.getColumn().setText("User"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return ((CmsSession) element).getDisplayName(); + } + + public String getToolTipText(Object element) { + return ((CmsSession) element).getUserDn().toString(); + } + }); + new ColumnViewerComparator(column); + + // Creation time + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("Since"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return LangUtils.since(((CmsSession) element).getCreationTime()); + } + + public String getToolTipText(Object element) { + return ((CmsSession) element).getCreationTime().toString(); + } + }); + new ColumnViewerComparator(column); + + // Username + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("Username"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + String userDn = ((CmsSession) element).getUserDn(); + return RoleNameUtils.getLastRdnValue(userDn); + } + + public String getToolTipText(Object element) { + return ((CmsSession) element).getUserDn().toString(); + } + }); + new ColumnViewerComparator(column); + + // UUID + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("UUID"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return ((CmsSession) element).getUuid().toString(); + } + + public String getToolTipText(Object element) { + return getText(element); + } + }); + new ColumnViewerComparator(column); + + // Local ID + column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setWidth(smallColWidth); + column.getColumn().setText("Local ID"); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = -5234573509093747505L; + + public String getText(Object element) { + return ((CmsSession) element).getLocalId(); + } + + public String getToolTipText(Object element) { + return getText(element); + } + }); + new ColumnViewerComparator(column); + + viewer.setInput(bc); + + } + + @Focus + public void setFocus() { + if (viewer != null) + viewer.getControl().setFocus(); + } + + /** Content provider managing the array of bundles */ + private static class CmsSessionContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = -8533792785725875977L; + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof BundleContext) { + BundleContext bc = (BundleContext) inputElement; + Collection> srs; + try { + srs = bc.getServiceReferences(CmsSession.class, null); + } catch (InvalidSyntaxException e) { + throw new IllegalArgumentException("Cannot retrieve CMS sessions", e); + } + List res = new ArrayList<>(); + for (ServiceReference sr : srs) { + res.add(bc.getService(sr)); + } + return res.toArray(); + } + return null; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ModulesView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ModulesView.java new file mode 100644 index 0000000..6317882 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ModulesView.java @@ -0,0 +1,91 @@ +package org.argeo.cms.e4.monitoring; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.argeo.cms.ux.widgets.TreeParent; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +/** The OSGi runtime from a module perspective. */ +public class ModulesView { + private final static BundleContext bc = FrameworkUtil.getBundle(ModulesView.class).getBundleContext(); + private TreeViewer viewer; + + @PostConstruct + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(new ModulesContentProvider()); + viewer.setLabelProvider(new ModulesLabelProvider()); + viewer.setInput(bc); + } + + @Focus + public void setFocus() { + viewer.getTree().setFocus(); + } + + private class ModulesContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = 3819934804640641721L; + + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof BundleContext) { + BundleContext bundleContext = (BundleContext) parentElement; + Bundle[] bundles = bundleContext.getBundles(); + + List modules = new ArrayList(); + for (Bundle bundle : bundles) { + if (bundle.getState() == Bundle.ACTIVE) + modules.add(new BundleNode(bundle, true)); + } + return modules.toArray(); + } else if (parentElement instanceof TreeParent) { + return ((TreeParent) parentElement).getChildren(); + } else { + return null; + } + } + + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof TreeParent) { + return ((TreeParent) element).hasChildren(); + } + return false; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + private class ModulesLabelProvider extends StateLabelProvider { + private static final long serialVersionUID = 5290046145534824722L; + + @Override + public String getText(Object element) { + if (element instanceof BundleNode) + return element.toString() + " [" + ((BundleNode) element).getBundle().getBundleId() + "]"; + return element.toString(); + } + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiConfigurationsView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiConfigurationsView.java new file mode 100644 index 0000000..5db8bd1 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiConfigurationsView.java @@ -0,0 +1,163 @@ +package org.argeo.cms.e4.monitoring; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Dictionary; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.argeo.cms.swt.CmsException; +import org.argeo.util.LangUtils; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +public class OsgiConfigurationsView { + private final static BundleContext bc = FrameworkUtil.getBundle(OsgiConfigurationsView.class).getBundleContext(); + + @PostConstruct + public void createPartControl(Composite parent) { + ConfigurationAdmin configurationAdmin = bc.getService(bc.getServiceReference(ConfigurationAdmin.class)); + + TreeViewer viewer = new TreeViewer(parent); + // viewer.getTree().setHeaderVisible(true); + + TreeViewerColumn tvc = new TreeViewerColumn(viewer, SWT.NONE); + tvc.getColumn().setWidth(400); + tvc.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = 835407996597566763L; + + @Override + public String getText(Object element) { + if (element instanceof Configuration) { + return ((Configuration) element).getPid(); + } else if (element instanceof Prop) { + return ((Prop) element).key; + } + return super.getText(element); + } + + @Override + public Image getImage(Object element) { + if (element instanceof Configuration) + return OsgiExplorerImages.CONFIGURATION; + return null; + } + + }); + + tvc = new TreeViewerColumn(viewer, SWT.NONE); + tvc.getColumn().setWidth(400); + tvc.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = 6999659261190014687L; + + @Override + public String getText(Object element) { + if (element instanceof Configuration) { + // return ((Configuration) element).getFactoryPid(); + return null; + } else if (element instanceof Prop) { + return ((Prop) element).value.toString(); + } + return super.getText(element); + } + }); + + viewer.setContentProvider(new ConfigurationsContentProvider()); + viewer.setInput(configurationAdmin); + } + + static class ConfigurationsContentProvider implements ITreeContentProvider { + private static final long serialVersionUID = -4892768279440981042L; + private ConfigurationComparator configurationComparator = new ConfigurationComparator(); + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + ConfigurationAdmin configurationAdmin = (ConfigurationAdmin) inputElement; + try { + Configuration[] configurations = configurationAdmin.listConfigurations(null); + Arrays.sort(configurations, configurationComparator); + return configurations; + } catch (IOException | InvalidSyntaxException e) { + throw new CmsException("Cannot list configurations", e); + } + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof Configuration) { + List res = new ArrayList<>(); + Configuration configuration = (Configuration) parentElement; + Dictionary props = configuration.getProperties(); + keys: for (String key : LangUtils.keys(props)) { + if (Constants.SERVICE_PID.equals(key)) + continue keys; + if (ConfigurationAdmin.SERVICE_FACTORYPID.equals(key)) + continue keys; + res.add(new Prop(configuration, key, props.get(key))); + } + return res.toArray(new Prop[res.size()]); + } + return null; + } + + @Override + public Object getParent(Object element) { + if (element instanceof Prop) + return ((Prop) element).configuration; + return null; + } + + @Override + public boolean hasChildren(Object element) { + if (element instanceof Configuration) + return true; + return false; + } + + } + + static class Prop { + final Configuration configuration; + final String key; + final Object value; + + public Prop(Configuration configuration, String key, Object value) { + this.configuration = configuration; + this.key = key; + this.value = value; + } + + } + + static class ConfigurationComparator implements Comparator { + + @Override + public int compare(Configuration o1, Configuration o2) { + return o1.getPid().compareTo(o2.getPid()); + } + + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiExplorerImages.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiExplorerImages.java new file mode 100644 index 0000000..7217fe6 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/OsgiExplorerImages.java @@ -0,0 +1,15 @@ +package org.argeo.cms.e4.monitoring; + +import org.argeo.cms.ui.theme.CmsImages; +import org.eclipse.swt.graphics.Image; + +/** Shared icons. */ +public class OsgiExplorerImages extends CmsImages { + public final static Image INSTALLED = createIcon("installed.gif"); + public final static Image RESOLVED = createIcon("resolved.gif"); + public final static Image STARTING = createIcon("starting.gif"); + public final static Image ACTIVE = createIcon("active.gif"); + public final static Image SERVICE_PUBLISHED = createIcon("service_published.gif"); + public final static Image SERVICE_REFERENCED = createIcon("service_referenced.gif"); + public final static Image CONFIGURATION = createIcon("node.gif"); +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ServiceReferenceNode.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ServiceReferenceNode.java new file mode 100644 index 0000000..1c60811 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/ServiceReferenceNode.java @@ -0,0 +1,46 @@ +package org.argeo.cms.e4.monitoring; + +import org.argeo.cms.ux.widgets.TreeParent; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +/** A tree element representing a {@link ServiceReference} */ +@SuppressWarnings({ "rawtypes" }) +class ServiceReferenceNode extends TreeParent { + private final ServiceReference serviceReference; + private final boolean published; + + public ServiceReferenceNode(ServiceReference serviceReference, + boolean published) { + super(serviceReference.toString()); + this.serviceReference = serviceReference; + this.published = published; + + if (isPublished()) { + Bundle[] usedBundles = serviceReference.getUsingBundles(); + if (usedBundles != null) { + for (Bundle b : usedBundles) { + if (b != null) + addChild(new BundleNode(b)); + } + } + } else { + Bundle provider = serviceReference.getBundle(); + addChild(new BundleNode(provider)); + } + + for (String key : serviceReference.getPropertyKeys()) { + addChild(new TreeParent(key + "=" + + serviceReference.getProperty(key))); + } + + } + + public ServiceReference getServiceReference() { + return serviceReference; + } + + public boolean isPublished() { + return published; + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/StateLabelProvider.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/StateLabelProvider.java new file mode 100644 index 0000000..5cb5b65 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/StateLabelProvider.java @@ -0,0 +1,82 @@ +package org.argeo.cms.e4.monitoring; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.graphics.Image; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; + +/** Label provider showing the sate of bundles */ +class StateLabelProvider extends ColumnLabelProvider { + private static final long serialVersionUID = -7885583135316000733L; + + @Override + public Image getImage(Object element) { + int state; + if (element instanceof Bundle) + state = ((Bundle) element).getState(); + else if (element instanceof BundleNode) + state = ((BundleNode) element).getBundle().getState(); + else if (element instanceof ServiceReferenceNode) + if (((ServiceReferenceNode) element).isPublished()) + return OsgiExplorerImages.SERVICE_PUBLISHED; + else + return OsgiExplorerImages.SERVICE_REFERENCED; + else + return null; + + switch (state) { + case Bundle.UNINSTALLED: + return OsgiExplorerImages.INSTALLED; + case Bundle.INSTALLED: + return OsgiExplorerImages.INSTALLED; + case Bundle.RESOLVED: + return OsgiExplorerImages.RESOLVED; + case Bundle.STARTING: + return OsgiExplorerImages.STARTING; + case Bundle.STOPPING: + return OsgiExplorerImages.STARTING; + case Bundle.ACTIVE: + return OsgiExplorerImages.ACTIVE; + default: + return null; + } + } + + @Override + public String getText(Object element) { + return null; + } + + @Override + public String getToolTipText(Object element) { + Bundle bundle = (Bundle) element; + Integer state = bundle.getState(); + switch (state) { + case Bundle.UNINSTALLED: + return "UNINSTALLED"; + case Bundle.INSTALLED: + return "INSTALLED"; + case Bundle.RESOLVED: + return "RESOLVED"; + case Bundle.STARTING: + String activationPolicy = bundle.getHeaders() + .get(Constants.BUNDLE_ACTIVATIONPOLICY).toString(); + + // .get("Bundle-ActivationPolicy").toString(); + // FIXME constant triggers the compilation failure + if (activationPolicy != null + && activationPolicy.equals(Constants.ACTIVATION_LAZY)) + // && activationPolicy.equals("lazy")) + // FIXME constant triggers the compilation failure + // && activationPolicy.equals(Constants.ACTIVATION_LAZY)) + return "<>"; + return "STARTING"; + case Bundle.STOPPING: + return "STOPPING"; + case Bundle.ACTIVE: + return "ACTIVE"; + default: + return null; + } + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/package-info.java new file mode 100644 index 0000000..873bf31 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/monitoring/package-info.java @@ -0,0 +1,2 @@ +/** Monitoring perspective. */ +package org.argeo.cms.e4.monitoring; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/parts/EgoDashboard.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/parts/EgoDashboard.java new file mode 100644 index 0000000..f2a73f2 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/parts/EgoDashboard.java @@ -0,0 +1,41 @@ +package org.argeo.cms.e4.parts; + +import java.time.ZonedDateTime; + +import javax.annotation.PostConstruct; + +import org.argeo.api.cms.CmsSession; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.swt.CmsSwtUtils; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +/** A canonical view of the logged in user. */ +public class EgoDashboard { +// private BundleContext bc = FrameworkUtil.getBundle(EgoDashboard.class).getBundleContext(); + + @PostConstruct + public void createPartControl(Composite p) { + p.setLayout(new GridLayout()); + String username = CurrentUser.getUsername(); + + CmsSwtUtils.lbl(p, "" + CurrentUser.getDisplayName() + ""); + CmsSwtUtils.txt(p, username); + CmsSwtUtils.lbl(p, "Roles:"); + roles: for (String role : CurrentUser.roles()) { + if (username.equals(role)) + continue roles; + CmsSwtUtils.txt(p, role); + } + +// Subject subject = Subject.getSubject(AccessController.getContext()); +// if (subject != null) { + CmsSession cmsSession = CurrentUser.getCmsSession(); + ZonedDateTime loggedIndSince = cmsSession.getCreationTime(); + CmsSwtUtils.lbl(p, "Session:"); + CmsSwtUtils.txt(p, cmsSession.getUuid().toString()); + CmsSwtUtils.lbl(p, "Logged in since:"); + CmsSwtUtils.txt(p, loggedIndSince.toString()); +// } + } +} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupEditor.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupEditor.java index d54f8bc..80c5998 100644 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupEditor.java +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupEditor.java @@ -25,11 +25,11 @@ import org.argeo.cms.e4.users.providers.RoleIconLP; import org.argeo.cms.e4.users.providers.UserFilter; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.swt.useradmin.LdifUsersTable; import org.argeo.cms.ui.eclipse.forms.AbstractFormPart; import org.argeo.cms.ui.eclipse.forms.IManagedForm; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; import org.argeo.util.naming.LdapAttrs; diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupsView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupsView.java index 73e4f5d..84a279e 100644 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupsView.java +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupsView.java @@ -15,6 +15,7 @@ import org.argeo.cms.e4.users.providers.DomainNameLP; import org.argeo.cms.e4.users.providers.RoleIconLP; import org.argeo.cms.e4.users.providers.UserDragListener; import org.argeo.cms.swt.CmsException; +import org.argeo.cms.swt.useradmin.LdifUsersTable; //import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; //import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener; //import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; @@ -25,7 +26,6 @@ import org.argeo.cms.swt.CmsException; //import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.util.naming.LdapAttrs; import org.argeo.util.naming.LdapObjs; import org.eclipse.e4.ui.di.Focus; diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java index 4fc59d3..6f075f1 100644 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java @@ -14,9 +14,9 @@ import org.argeo.cms.e4.users.providers.DomainNameLP; import org.argeo.cms.e4.users.providers.MailLP; import org.argeo.cms.e4.users.providers.UserNameLP; import org.argeo.cms.swt.CmsException; +import org.argeo.cms.swt.useradmin.LdifUsersTable; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.util.naming.LdapAttrs; import org.argeo.util.naming.LdapObjs; import org.argeo.util.transaction.WorkTransaction; diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserEditor.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserEditor.java index 66f4420..fb443e3 100644 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserEditor.java +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserEditor.java @@ -21,12 +21,12 @@ import org.argeo.cms.e4.users.providers.DomainNameLP; import org.argeo.cms.e4.users.providers.RoleIconLP; import org.argeo.cms.e4.users.providers.UserFilter; import org.argeo.cms.swt.CmsSwtUtils; +import org.argeo.cms.swt.useradmin.LdifUsersTable; import org.argeo.cms.ui.eclipse.forms.AbstractFormPart; //import org.argeo.cms.ui.eclipse.forms.FormToolkit; import org.argeo.cms.ui.eclipse.forms.IManagedForm; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.util.naming.LdapAttrs; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.jface.action.Action; diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UsersView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UsersView.java index 720945c..1d7c873 100644 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UsersView.java +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UsersView.java @@ -15,9 +15,9 @@ import org.argeo.cms.e4.users.providers.MailLP; import org.argeo.cms.e4.users.providers.UserDragListener; import org.argeo.cms.e4.users.providers.UserNameLP; import org.argeo.cms.swt.CmsException; +import org.argeo.cms.swt.useradmin.LdifUsersTable; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.util.naming.LdapAttrs; import org.argeo.util.naming.LdapObjs; import org.eclipse.e4.ui.di.Focus; diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/jcr/e4/rap/CmsE4AdminApp.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/jcr/e4/rap/CmsE4AdminApp.java new file mode 100644 index 0000000..de497b4 --- /dev/null +++ b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/jcr/e4/rap/CmsE4AdminApp.java @@ -0,0 +1,17 @@ +package org.argeo.cms.jcr.e4.rap; + +import org.argeo.cms.e4.rap.AbstractRapE4App; +import org.eclipse.rap.rwt.application.Application; + +/** + * Access to canonical views of the core CMS concepts, useful for devleopers and + * operators. + */ +public class CmsE4AdminApp extends AbstractRapE4App { + @Override + protected void addEntryPoints(Application application) { + addE4EntryPoint(application, "/devops", "org.argeo.cms.jcr.e4/e4xmi/cms-devops.e4xmi", + customise("Argeo CMS DevOps")); + } + +} diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/add.png b/swt/org.argeo.cms.jcr.ui/icons/actions/add.png new file mode 100644 index 0000000..5c06bf0 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/add.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/close-all.png b/swt/org.argeo.cms.jcr.ui/icons/actions/close-all.png new file mode 100644 index 0000000..81bfc95 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/close-all.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/delete.png b/swt/org.argeo.cms.jcr.ui/icons/actions/delete.png new file mode 100644 index 0000000..9712723 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/delete.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/edit.png b/swt/org.argeo.cms.jcr.ui/icons/actions/edit.png new file mode 100644 index 0000000..ad3db9f Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/edit.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/save-all.png b/swt/org.argeo.cms.jcr.ui/icons/actions/save-all.png new file mode 100644 index 0000000..f48ed32 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/save-all.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/actions/save.png b/swt/org.argeo.cms.jcr.ui/icons/actions/save.png new file mode 100644 index 0000000..1c58ada Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/actions/save.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/active.gif b/swt/org.argeo.cms.jcr.ui/icons/active.gif new file mode 100644 index 0000000..7d24707 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/active.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/add.gif b/swt/org.argeo.cms.jcr.ui/icons/add.gif new file mode 100644 index 0000000..252d7eb Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/add.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/add.png b/swt/org.argeo.cms.jcr.ui/icons/add.png new file mode 100644 index 0000000..c7edfec Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/add.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/addFolder.gif b/swt/org.argeo.cms.jcr.ui/icons/addFolder.gif new file mode 100644 index 0000000..d3f43d9 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addFolder.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/addPrivileges.gif b/swt/org.argeo.cms.jcr.ui/icons/addPrivileges.gif new file mode 100644 index 0000000..a6b251f Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addPrivileges.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/addRepo.gif b/swt/org.argeo.cms.jcr.ui/icons/addRepo.gif new file mode 100644 index 0000000..26d81c0 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addRepo.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/addWorkspace.png b/swt/org.argeo.cms.jcr.ui/icons/addWorkspace.png new file mode 100644 index 0000000..bbee775 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/addWorkspace.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/adminLog.gif b/swt/org.argeo.cms.jcr.ui/icons/adminLog.gif new file mode 100644 index 0000000..6ef3bca Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/adminLog.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/batch.gif b/swt/org.argeo.cms.jcr.ui/icons/batch.gif new file mode 100644 index 0000000..b8ca14a Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/batch.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/begin.gif b/swt/org.argeo.cms.jcr.ui/icons/begin.gif new file mode 100755 index 0000000..feb8e94 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/begin.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/binary.png b/swt/org.argeo.cms.jcr.ui/icons/binary.png new file mode 100644 index 0000000..fdf4f82 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/binary.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/browser.gif b/swt/org.argeo.cms.jcr.ui/icons/browser.gif new file mode 100644 index 0000000..6c7320c Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/browser.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/bundles.gif b/swt/org.argeo.cms.jcr.ui/icons/bundles.gif new file mode 100644 index 0000000..e9a6bd9 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/bundles.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/changePassword.gif b/swt/org.argeo.cms.jcr.ui/icons/changePassword.gif new file mode 100644 index 0000000..274a850 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/changePassword.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/clear.gif b/swt/org.argeo.cms.jcr.ui/icons/clear.gif new file mode 100644 index 0000000..6bc10f9 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/clear.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/close-all.png b/swt/org.argeo.cms.jcr.ui/icons/close-all.png new file mode 100644 index 0000000..85d4d42 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/close-all.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/commit.gif b/swt/org.argeo.cms.jcr.ui/icons/commit.gif new file mode 100755 index 0000000..876f3eb Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/commit.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/delete.png b/swt/org.argeo.cms.jcr.ui/icons/delete.png new file mode 100644 index 0000000..676a39d Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/delete.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/dumpNode.gif b/swt/org.argeo.cms.jcr.ui/icons/dumpNode.gif new file mode 100644 index 0000000..14eb1be Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/dumpNode.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/file.gif b/swt/org.argeo.cms.jcr.ui/icons/file.gif new file mode 100644 index 0000000..ef30288 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/file.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/folder.gif b/swt/org.argeo.cms.jcr.ui/icons/folder.gif new file mode 100644 index 0000000..42e027c Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/folder.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/getSize.gif b/swt/org.argeo.cms.jcr.ui/icons/getSize.gif new file mode 100644 index 0000000..b05bf3e Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/getSize.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/group.png b/swt/org.argeo.cms.jcr.ui/icons/group.png new file mode 100644 index 0000000..cc6683a Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/group.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/home.gif b/swt/org.argeo.cms.jcr.ui/icons/home.gif new file mode 100644 index 0000000..fd0c669 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/home.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/home.png b/swt/org.argeo.cms.jcr.ui/icons/home.png new file mode 100644 index 0000000..5eb0967 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/home.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/import_fs.png b/swt/org.argeo.cms.jcr.ui/icons/import_fs.png new file mode 100644 index 0000000..d7c890c Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/import_fs.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/installed.gif b/swt/org.argeo.cms.jcr.ui/icons/installed.gif new file mode 100644 index 0000000..2988716 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/installed.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/loading.gif b/swt/org.argeo.cms.jcr.ui/icons/loading.gif deleted file mode 100644 index 3288d10..0000000 Binary files a/swt/org.argeo.cms.jcr.ui/icons/loading.gif and /dev/null differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/log.gif b/swt/org.argeo.cms.jcr.ui/icons/log.gif new file mode 100644 index 0000000..e3ecc55 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/log.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/logout.png b/swt/org.argeo.cms.jcr.ui/icons/logout.png new file mode 100644 index 0000000..f2952fa Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/logout.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/maintenance.gif b/swt/org.argeo.cms.jcr.ui/icons/maintenance.gif new file mode 100644 index 0000000..e5690ec Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/maintenance.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png b/swt/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png deleted file mode 100644 index 0396506..0000000 Binary files a/swt/org.argeo.cms.jcr.ui/icons/noPic-goldenRatio-640px.png and /dev/null differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png b/swt/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png deleted file mode 100644 index 8e3abb5..0000000 Binary files a/swt/org.argeo.cms.jcr.ui/icons/noPic-square-640px.png and /dev/null differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/node.gif b/swt/org.argeo.cms.jcr.ui/icons/node.gif new file mode 100644 index 0000000..364c0e7 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/node.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/nodes.gif b/swt/org.argeo.cms.jcr.ui/icons/nodes.gif new file mode 100644 index 0000000..bba3dbc Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/nodes.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/osgi_explorer.gif b/swt/org.argeo.cms.jcr.ui/icons/osgi_explorer.gif new file mode 100644 index 0000000..e9a6bd9 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/osgi_explorer.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/password.gif b/swt/org.argeo.cms.jcr.ui/icons/password.gif new file mode 100644 index 0000000..a6b251f Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/password.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/person-logged-in.png b/swt/org.argeo.cms.jcr.ui/icons/person-logged-in.png new file mode 100644 index 0000000..87acc14 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/person-logged-in.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/person.png b/swt/org.argeo.cms.jcr.ui/icons/person.png new file mode 100644 index 0000000..7d979a5 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/person.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/query.png b/swt/org.argeo.cms.jcr.ui/icons/query.png new file mode 100644 index 0000000..54c089d Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/query.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/refresh.png b/swt/org.argeo.cms.jcr.ui/icons/refresh.png new file mode 100644 index 0000000..71b3481 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/refresh.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/remote_connected.gif b/swt/org.argeo.cms.jcr.ui/icons/remote_connected.gif new file mode 100644 index 0000000..1492b4e Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/remote_connected.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/remote_disconnected.gif b/swt/org.argeo.cms.jcr.ui/icons/remote_disconnected.gif new file mode 100644 index 0000000..6c54da9 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/remote_disconnected.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/remove.gif b/swt/org.argeo.cms.jcr.ui/icons/remove.gif new file mode 100644 index 0000000..0ae6dec Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/remove.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/removePrivileges.gif b/swt/org.argeo.cms.jcr.ui/icons/removePrivileges.gif new file mode 100644 index 0000000..aa78fd2 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/removePrivileges.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/rename.gif b/swt/org.argeo.cms.jcr.ui/icons/rename.gif new file mode 100644 index 0000000..8048405 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/rename.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/repositories.gif b/swt/org.argeo.cms.jcr.ui/icons/repositories.gif new file mode 100644 index 0000000..c13bea1 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/repositories.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/repository_connected.gif b/swt/org.argeo.cms.jcr.ui/icons/repository_connected.gif new file mode 100644 index 0000000..a15fa55 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/repository_connected.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/repository_disconnected.gif b/swt/org.argeo.cms.jcr.ui/icons/repository_disconnected.gif new file mode 100644 index 0000000..4576dc5 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/repository_disconnected.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/resolved.gif b/swt/org.argeo.cms.jcr.ui/icons/resolved.gif new file mode 100644 index 0000000..f4a1ea1 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/resolved.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/role.gif b/swt/org.argeo.cms.jcr.ui/icons/role.gif new file mode 100644 index 0000000..274a850 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/role.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/rollback.gif b/swt/org.argeo.cms.jcr.ui/icons/rollback.gif new file mode 100755 index 0000000..c753995 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/rollback.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/save-all.png b/swt/org.argeo.cms.jcr.ui/icons/save-all.png new file mode 100644 index 0000000..b68a29b Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save-all.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/save.gif b/swt/org.argeo.cms.jcr.ui/icons/save.gif new file mode 100644 index 0000000..654ad7b Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/save.png b/swt/org.argeo.cms.jcr.ui/icons/save.png new file mode 100644 index 0000000..f27ef2d Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/save_security.png b/swt/org.argeo.cms.jcr.ui/icons/save_security.png new file mode 100644 index 0000000..ca41dc9 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save_security.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/save_security_disabled.png b/swt/org.argeo.cms.jcr.ui/icons/save_security_disabled.png new file mode 100644 index 0000000..fb7d08d Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/save_security_disabled.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/security.gif b/swt/org.argeo.cms.jcr.ui/icons/security.gif new file mode 100644 index 0000000..57fb95e Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/security.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/service_published.gif b/swt/org.argeo.cms.jcr.ui/icons/service_published.gif new file mode 100644 index 0000000..17f771a Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/service_published.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/service_referenced.gif b/swt/org.argeo.cms.jcr.ui/icons/service_referenced.gif new file mode 100644 index 0000000..c24a95f Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/service_referenced.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/sort.gif b/swt/org.argeo.cms.jcr.ui/icons/sort.gif new file mode 100644 index 0000000..23c5d0b Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/sort.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/starting.gif b/swt/org.argeo.cms.jcr.ui/icons/starting.gif new file mode 100644 index 0000000..563743d Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/starting.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/sync.gif b/swt/org.argeo.cms.jcr.ui/icons/sync.gif new file mode 100644 index 0000000..b4fa052 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/sync.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/user.gif b/swt/org.argeo.cms.jcr.ui/icons/user.gif new file mode 100644 index 0000000..90a0014 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/user.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/users.gif b/swt/org.argeo.cms.jcr.ui/icons/users.gif new file mode 100644 index 0000000..2de7edd Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/users.gif differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/workgroup.png b/swt/org.argeo.cms.jcr.ui/icons/workgroup.png new file mode 100644 index 0000000..7fef996 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workgroup.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/workgroup.xcf b/swt/org.argeo.cms.jcr.ui/icons/workgroup.xcf new file mode 100644 index 0000000..f517c82 Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workgroup.xcf differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/workspace_connected.png b/swt/org.argeo.cms.jcr.ui/icons/workspace_connected.png new file mode 100644 index 0000000..0430baa Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workspace_connected.png differ diff --git a/swt/org.argeo.cms.jcr.ui/icons/workspace_disconnected.png b/swt/org.argeo.cms.jcr.ui/icons/workspace_disconnected.png new file mode 100644 index 0000000..fddcb8c Binary files /dev/null and b/swt/org.argeo.cms.jcr.ui/icons/workspace_disconnected.png differ diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/LdifUsersTable.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/LdifUsersTable.java new file mode 100644 index 0000000..a30d2f7 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/LdifUsersTable.java @@ -0,0 +1,401 @@ +package org.argeo.cms.swt.useradmin; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.User; + +/** + * Generic composite that display a filter and a table viewer to display users + * (can also be groups) + * + * Warning: this class does not extends TableViewer. Use the + * getTableViewer method to access it. + * + */ +public abstract class LdifUsersTable extends Composite { + private static final long serialVersionUID = -7385959046279360420L; + + // Context + // private UserAdmin userAdmin; + + // Configuration + private List columnDefs = new ArrayList(); + private boolean hasFilter; + private boolean preventTableLayout = false; + private boolean hasSelectionColumn; + private int tableStyle; + + // Local UI Objects + private TableViewer usersViewer; + private Text filterTxt; + + /* EXPOSED METHODS */ + + /** + * @param parent + * @param style + */ + public LdifUsersTable(Composite parent, int style) { + super(parent, SWT.NO_FOCUS); + this.tableStyle = style; + } + + // TODO workaround the bug of the table layout in the Form + public LdifUsersTable(Composite parent, int style, boolean preventTableLayout) { + super(parent, SWT.NO_FOCUS); + this.tableStyle = style; + this.preventTableLayout = preventTableLayout; + } + + /** This must be called before the call to populate method */ + public void setColumnDefinitions(List columnDefinitions) { + this.columnDefs = columnDefinitions; + } + + /** + * + * @param addFilter + * choose to add a field to filter results or not + * @param addSelection + * choose to add a column to select some of the displayed results or + * not + */ + public void populate(boolean addFilter, boolean addSelection) { + // initialization + Composite parent = this; + hasFilter = addFilter; + hasSelectionColumn = addSelection; + + // Main Layout + GridLayout layout = EclipseUiUtils.noSpaceGridLayout(); + layout.verticalSpacing = 5; + this.setLayout(layout); + if (hasFilter) + createFilterPart(parent); + + Composite tableComp = new Composite(parent, SWT.NO_FOCUS); + tableComp.setLayoutData(EclipseUiUtils.fillAll()); + usersViewer = createTableViewer(tableComp); + usersViewer.setContentProvider(new UsersContentProvider()); + } + + /** + * + * @param showMore + * display static filters on creation + * @param addSelection + * choose to add a column to select some of the displayed results or + * not + */ + public void populateWithStaticFilters(boolean showMore, boolean addSelection) { + // initialization + Composite parent = this; + hasFilter = true; + hasSelectionColumn = addSelection; + + // Main Layout + GridLayout layout = EclipseUiUtils.noSpaceGridLayout(); + layout.verticalSpacing = 5; + this.setLayout(layout); + createStaticFilterPart(parent, showMore); + + Composite tableComp = new Composite(parent, SWT.NO_FOCUS); + tableComp.setLayoutData(EclipseUiUtils.fillAll()); + usersViewer = createTableViewer(tableComp); + usersViewer.setContentProvider(new UsersContentProvider()); + } + + /** Enable access to the selected users or groups */ + public List getSelectedUsers() { + if (hasSelectionColumn) { + Object[] elements = ((CheckboxTableViewer) usersViewer).getCheckedElements(); + + List result = new ArrayList(); + for (Object obj : elements) { + result.add((User) obj); + } + return result; + } else + throw new EclipseUiException( + "Unvalid request: no selection column " + "has been created for the current table"); + } + + /** Returns the User table viewer, typically to add doubleclick listener */ + public TableViewer getTableViewer() { + return usersViewer; + } + + /** + * Force the refresh of the underlying table using the current filter string if + * relevant + */ + public void refresh() { + String filter = hasFilter ? filterTxt.getText().trim() : null; + if ("".equals(filter)) + filter = null; + refreshFilteredList(filter); + } + + /** Effective repository request: caller must implement this method */ + abstract protected List listFilteredElements(String filter); + + // protected List listFilteredElements(String filter) { + // List users = new ArrayList(); + // try { + // Role[] roles = userAdmin.getRoles(filter); + // // Display all users and groups + // for (Role role : roles) + // users.add((User) role); + // } catch (InvalidSyntaxException e) { + // throw new EclipseUiException("Unable to get roles with filter: " + // + filter, e); + // } + // return users; + // } + + /* GENERIC COMPOSITE METHODS */ + @Override + public boolean setFocus() { + if (hasFilter) + return filterTxt.setFocus(); + else + return usersViewer.getTable().setFocus(); + } + + @Override + public void dispose() { + super.dispose(); + } + + /* LOCAL CLASSES AND METHODS */ + // Will be usefull to rather use a virtual table viewer + private void refreshFilteredList(String filter) { + List users = listFilteredElements(filter); + usersViewer.setInput(users.toArray()); + } + + private class UsersContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = 1L; + + public Object[] getElements(Object inputElement) { + return (Object[]) inputElement; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + /* MANAGE FILTER */ + private void createFilterPart(Composite parent) { + // Text Area for the filter + filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL); + filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + filterTxt.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = 1L; + + public void modifyText(ModifyEvent event) { + refreshFilteredList(filterTxt.getText()); + } + }); + } + + private void createStaticFilterPart(Composite parent, boolean showMore) { + Composite filterComp = new Composite(parent, SWT.NO_FOCUS); + filterComp.setLayout(new GridLayout(2, false)); + filterComp.setLayoutData(EclipseUiUtils.fillWidth()); + // generic search + filterTxt = new Text(filterComp, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL); + filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + // filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | + // GridData.HORIZONTAL_ALIGN_FILL)); + filterTxt.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = 1L; + + public void modifyText(ModifyEvent event) { + refreshFilteredList(filterTxt.getText()); + } + }); + + // add static filter abilities + Link moreLk = new Link(filterComp, SWT.NONE); + Composite staticFilterCmp = new Composite(filterComp, SWT.NO_FOCUS); + staticFilterCmp.setLayoutData(EclipseUiUtils.fillWidth(2)); + populateStaticFilters(staticFilterCmp); + + MoreLinkListener listener = new MoreLinkListener(moreLk, staticFilterCmp, showMore); + // initialise the layout + listener.refresh(); + moreLk.addSelectionListener(listener); + } + + /** Overwrite to add static filters */ + protected void populateStaticFilters(Composite staticFilterCmp) { + } + + // private void addMoreSL(final Link more) { + // more.addSelectionListener( } + + private class MoreLinkListener extends SelectionAdapter { + private static final long serialVersionUID = -524987616510893463L; + private boolean isShown; + private final Composite staticFilterCmp; + private final Link moreLk; + + public MoreLinkListener(Link moreLk, Composite staticFilterCmp, boolean isShown) { + this.moreLk = moreLk; + this.staticFilterCmp = staticFilterCmp; + this.isShown = isShown; + } + + @Override + public void widgetSelected(SelectionEvent e) { + isShown = !isShown; + refresh(); + } + + public void refresh() { + GridData gd = (GridData) staticFilterCmp.getLayoutData(); + if (isShown) { + moreLk.setText(" Less... "); + gd.heightHint = SWT.DEFAULT; + } else { + moreLk.setText(" More... "); + gd.heightHint = 0; + } + forceLayout(); + } + } + + private void forceLayout() { + LdifUsersTable.this.getParent().layout(true, true); + } + + private TableViewer createTableViewer(final Composite parent) { + + int style = tableStyle | SWT.H_SCROLL | SWT.V_SCROLL; + if (hasSelectionColumn) + style = style | SWT.CHECK; + Table table = new Table(parent, style); + TableColumnLayout layout = new TableColumnLayout(); + + // TODO the table layout does not works with the scrolled form + + if (preventTableLayout) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + table.setLayoutData(EclipseUiUtils.fillAll()); + } else + parent.setLayout(layout); + + TableViewer viewer; + if (hasSelectionColumn) + viewer = new CheckboxTableViewer(table); + else + viewer = new TableViewer(table); + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableViewerColumn column; + // int offset = 0; + if (hasSelectionColumn) { + // offset = 1; + column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE, 25); + column.setLabelProvider(new ColumnLabelProvider() { + private static final long serialVersionUID = 1L; + + @Override + public String getText(Object element) { + return null; + } + }); + layout.setColumnData(column.getColumn(), new ColumnWeightData(25, 25, false)); + + SelectionAdapter selectionAdapter = new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + boolean allSelected = false; + + @Override + public void widgetSelected(SelectionEvent e) { + allSelected = !allSelected; + ((CheckboxTableViewer) usersViewer).setAllChecked(allSelected); + } + }; + column.getColumn().addSelectionListener(selectionAdapter); + } + + // NodeViewerComparator comparator = new NodeViewerComparator(); + // TODO enable the sort by click on the header + // int i = offset; + for (ColumnDefinition colDef : columnDefs) + createTableColumn(viewer, layout, colDef); + + // column = ViewerUtils.createTableViewerColumn(viewer, + // colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize()); + // column.setLabelProvider(new CLProvider(colDef.getPropertyName())); + // column.getColumn().addSelectionListener( + // JcrUiUtils.getNodeSelectionAdapter(i, + // colDef.getPropertyType(), colDef.getPropertyName(), + // comparator, viewer)); + // i++; + // } + + // IMPORTANT: initialize comparator before setting it + // JcrColumnDefinition firstCol = colDefs.get(0); + // comparator.setColumn(firstCol.getPropertyType(), + // firstCol.getPropertyName()); + // viewer.setComparator(comparator); + + return viewer; + } + + /** Default creation of a column for a user table */ + private TableViewerColumn createTableColumn(TableViewer tableViewer, TableColumnLayout layout, + ColumnDefinition columnDef) { + + boolean resizable = true; + TableViewerColumn tvc = new TableViewerColumn(tableViewer, SWT.NONE); + TableColumn column = tvc.getColumn(); + + column.setText(columnDef.getLabel()); + column.setWidth(columnDef.getMinWidth()); + column.setResizable(resizable); + + ColumnLabelProvider lp = columnDef.getLabelProvider(); + // add a reference to the display to enable font management + // if (lp instanceof UserAdminAbstractLP) + // ((UserAdminAbstractLP) lp).setDisplay(tableViewer.getTable() + // .getDisplay()); + tvc.setLabelProvider(lp); + + layout.setColumnData(column, new ColumnWeightData(columnDef.getWeight(), columnDef.getMinWidth(), resizable)); + + return tvc; + } +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java new file mode 100644 index 0000000..dbf6577 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java @@ -0,0 +1,245 @@ +package org.argeo.cms.swt.useradmin; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.api.cms.CmsConstants; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.LdapObjs; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Dialog with a user (or group) list to pick up one */ +public class PickUpUserDialog extends TrayDialog { + private static final long serialVersionUID = -1420106871173920369L; + + // Business objects + private final UserAdmin userAdmin; + private User selectedUser; + + // this page widgets and UI objects + private String title; + private LdifUsersTable userTableViewerCmp; + private TableViewer userViewer; + private List columnDefs = new ArrayList(); + + /** + * A dialog to pick up a group or a user, showing a table with default + * columns + */ + public PickUpUserDialog(Shell parentShell, String title, UserAdmin userAdmin) { + super(parentShell); + this.title = title; + this.userAdmin = userAdmin; + + columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_ICON), "", + 24, 24)); + columnDefs.add(new ColumnDefinition( + new UserLP(UserLP.COL_DISPLAY_NAME), "Common Name", 150, 100)); + columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DOMAIN), + "Domain", 100, 120)); + columnDefs.add(new ColumnDefinition(new UserLP(UserLP.COL_DN), + "Distinguished Name", 300, 100)); + } + + /** A dialog to pick up a group or a user */ + public PickUpUserDialog(Shell parentShell, String title, + UserAdmin userAdmin, List columnDefs) { + super(parentShell); + this.title = title; + this.userAdmin = userAdmin; + this.columnDefs = columnDefs; + } + + @Override + protected void okPressed() { + if (getSelected() == null) + MessageDialog.openError(getShell(), "No user chosen", + "Please, choose a user or press Cancel."); + else + super.okPressed(); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogArea = (Composite) super.createDialogArea(parent); + dialogArea.setLayout(new FillLayout()); + + Composite bodyCmp = new Composite(dialogArea, SWT.NO_FOCUS); + bodyCmp.setLayout(new GridLayout()); + + // Create and configure the table + userTableViewerCmp = new MyUserTableViewer(bodyCmp, SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL); + + userTableViewerCmp.setColumnDefinitions(columnDefs); + userTableViewerCmp.populateWithStaticFilters(false, false); + GridData gd = EclipseUiUtils.fillAll(); + gd.minimumHeight = 300; + userTableViewerCmp.setLayoutData(gd); + userTableViewerCmp.refresh(); + + // Controllers + userViewer = userTableViewerCmp.getTableViewer(); + userViewer.addDoubleClickListener(new MyDoubleClickListener()); + userViewer + .addSelectionChangedListener(new MySelectionChangedListener()); + + parent.pack(); + return dialogArea; + } + + public User getSelected() { + if (selectedUser == null) + return null; + else + return selectedUser; + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(title); + } + + class MyDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + if (evt.getSelection().isEmpty()) + return; + + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + if (obj instanceof User) { + selectedUser = (User) obj; + okPressed(); + } + } + } + + class MySelectionChangedListener implements ISelectionChangedListener { + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (event.getSelection().isEmpty()) { + selectedUser = null; + return; + } + Object obj = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + if (obj instanceof Group) { + selectedUser = (Group) obj; + } + } + } + + private class MyUserTableViewer extends LdifUsersTable { + private static final long serialVersionUID = 8467999509931900367L; + + private final String[] knownProps = { LdapAttrs.uid.name(), + LdapAttrs.cn.name(), LdapAttrs.DN }; + + private Button showSystemRoleBtn; + private Button showUserBtn; + + public MyUserTableViewer(Composite parent, int style) { + super(parent, style); + } + + protected void populateStaticFilters(Composite staticFilterCmp) { + staticFilterCmp.setLayout(new GridLayout()); + showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); + showSystemRoleBtn.setText("Show system roles "); + + showUserBtn = new Button(staticFilterCmp, SWT.CHECK); + showUserBtn.setText("Show users "); + + SelectionListener sl = new SelectionAdapter() { + private static final long serialVersionUID = -7033424592697691676L; + + @Override + public void widgetSelected(SelectionEvent e) { + refresh(); + } + }; + + showSystemRoleBtn.addSelectionListener(sl); + showUserBtn.addSelectionListener(sl); + } + + @Override + protected List listFilteredElements(String filter) { + Role[] roles; + try { + StringBuilder builder = new StringBuilder(); + + StringBuilder filterBuilder = new StringBuilder(); + if (notNull(filter)) + for (String prop : knownProps) { + filterBuilder.append("("); + filterBuilder.append(prop); + filterBuilder.append("=*"); + filterBuilder.append(filter); + filterBuilder.append("*)"); + } + + String typeStr = "(" + LdapAttrs.objectClass.name() + "=" + + LdapObjs.groupOfNames.name() + ")"; + if ((showUserBtn.getSelection())) + typeStr = "(|(" + LdapAttrs.objectClass.name() + "=" + + LdapObjs.inetOrgPerson.name() + ")" + typeStr + + ")"; + + if (!showSystemRoleBtn.getSelection()) + typeStr = "(& " + typeStr + "(!(" + LdapAttrs.DN + "=*" + + CmsConstants.SYSTEM_ROLES_BASEDN + ")))"; + + if (filterBuilder.length() > 1) { + builder.append("(&" + typeStr); + builder.append("(|"); + builder.append(filterBuilder.toString()); + builder.append("))"); + } else { + builder.append(typeStr); + } + roles = userAdmin.getRoles(builder.toString()); + } catch (InvalidSyntaxException e) { + throw new EclipseUiException( + "Unable to get roles with filter: " + filter, e); + } + List users = new ArrayList(); + for (Role role : roles) + if (!users.contains(role)) + users.add((User) role); + return users; + } + } + + private boolean notNull(String string) { + if (string == null) + return false; + else + return !"".equals(string.trim()); + } +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UserLP.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UserLP.java new file mode 100644 index 0000000..b3ab40e --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UserLP.java @@ -0,0 +1,76 @@ +package org.argeo.cms.swt.useradmin; + +import org.argeo.api.cms.CmsConstants; +import org.argeo.cms.auth.UserAdminUtils; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; + +/** Centralize label providers for the group table */ +class UserLP extends ColumnLabelProvider { + private static final long serialVersionUID = -4645930210988368571L; + + final static String COL_ICON = "colID.icon"; + final static String COL_DN = "colID.dn"; + final static String COL_DISPLAY_NAME = "colID.displayName"; + final static String COL_DOMAIN = "colID.domain"; + + final String currType; + + // private Font italic; + private Font bold; + + UserLP(String colId) { + this.currType = colId; + } + + @Override + public Font getFont(Object element) { + // Current user as bold + if (UserAdminUtils.isCurrentUser(((User) element))) { + if (bold == null) + bold = JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD) + .createFont(Display.getCurrent()); + return bold; + } + return null; + } + + @Override + public Image getImage(Object element) { + if (COL_ICON.equals(currType)) { + User user = (User) element; + String dn = user.getName(); + if (dn.endsWith(CmsConstants.SYSTEM_ROLES_BASEDN)) + return UsersImages.ICON_ROLE; + else if (user.getType() == Role.GROUP) + return UsersImages.ICON_GROUP; + else + return UsersImages.ICON_USER; + } else + return null; + } + + @Override + public String getText(Object element) { + User user = (User) element; + return getText(user); + + } + + public String getText(User user) { + if (COL_DN.equals(currType)) + return user.getName(); + else if (COL_DISPLAY_NAME.equals(currType)) + return UserAdminUtils.getCommonName(user); + else if (COL_DOMAIN.equals(currType)) + return UserAdminUtils.getDomainName(user); + else + return ""; + } +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UsersImages.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UsersImages.java new file mode 100644 index 0000000..21fc5af --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/UsersImages.java @@ -0,0 +1,14 @@ +package org.argeo.cms.swt.useradmin; + +import org.argeo.cms.ui.theme.CmsImages; +import org.eclipse.swt.graphics.Image; + +/** Specific users icons. */ +public class UsersImages { + private final static String PREFIX = "icons/"; + + public final static Image ICON_USER = CmsImages.createImg(PREFIX + "person.png"); + public final static Image ICON_GROUP = CmsImages.createImg(PREFIX + "group.png"); + public final static Image ICON_ROLE = CmsImages.createImg(PREFIX + "role.gif"); + public final static Image ICON_CHANGE_PASSWORD = CmsImages.createImg(PREFIX + "security.gif"); +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/ViewerUtils.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/ViewerUtils.java new file mode 100644 index 0000000..d186783 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/ViewerUtils.java @@ -0,0 +1,58 @@ +package org.argeo.cms.swt.useradmin; + +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TreeColumn; + +/** + * Centralise useful methods to manage JFace Table, Tree and TreeColumn viewers. + */ +public class ViewerUtils { + + /** + * Creates a basic column for the given table. For the time being, we do not + * support movable columns. + */ + public static TableColumn createColumn(Table parent, String name, int style, int width) { + TableColumn result = new TableColumn(parent, style); + result.setText(name); + result.setWidth(width); + result.setResizable(true); + return result; + } + + /** + * Creates a TableViewerColumn for the given viewer. For the time being, we do + * not support movable columns. + */ + public static TableViewerColumn createTableViewerColumn(TableViewer parent, String name, int style, int width) { + TableViewerColumn tvc = new TableViewerColumn(parent, style); + TableColumn column = tvc.getColumn(); + column.setText(name); + column.setWidth(width); + column.setResizable(true); + return tvc; + } + + // public static TableViewerColumn createTableViewerColumn(TableViewer parent, + // Localized name, int style, int width) { + // return createTableViewerColumn(parent, name.lead(), style, width); + // } + + /** + * Creates a TreeViewerColumn for the given viewer. For the time being, we do + * not support movable columns. + */ + public static TreeViewerColumn createTreeViewerColumn(TreeViewer parent, String name, int style, int width) { + TreeViewerColumn tvc = new TreeViewerColumn(parent, style); + TreeColumn column = tvc.getColumn(); + column.setText(name); + column.setWidth(width); + column.setResizable(true); + return tvc; + } +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/package-info.java new file mode 100644 index 0000000..3597bfc --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/swt/useradmin/package-info.java @@ -0,0 +1,2 @@ +/** SWT/JFace users management components. */ +package org.argeo.cms.swt.useradmin; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/CmsImages.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/CmsImages.java new file mode 100644 index 0000000..1c4d79e --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/CmsImages.java @@ -0,0 +1,49 @@ +package org.argeo.cms.ui.theme; + +import java.net.URL; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +public class CmsImages { + private static BundleContext themeBc = FrameworkUtil.getBundle(CmsImages.class).getBundleContext(); + + final public static String ICONS_BASE = "icons/"; + final public static String TYPES_BASE = ICONS_BASE + "types/"; + final public static String ACTIONS_BASE = ICONS_BASE + "actions/"; + + public static Image createIcon(String name) { + return createImg(CmsImages.ICONS_BASE + name); + } + + public static Image createAction(String name) { + return createImg(CmsImages.ACTIONS_BASE + name); + } + + public static Image createType(String name) { + return createImg(CmsImages.TYPES_BASE + name); + } + + public static Image createImg(String name) { + return CmsImages.createDesc(name).createImage(Display.getDefault()); + } + + public static ImageDescriptor createDesc(String name) { + return createDesc(themeBc, name); + } + + public static ImageDescriptor createDesc(BundleContext bc, String name) { + URL url = bc.getBundle().getResource(name); + if (url == null) + return ImageDescriptor.getMissingImageDescriptor(); + return ImageDescriptor.createFromURL(url); + } + + public static Image createImg(BundleContext bc, String name) { + return createDesc(bc, name).createImage(Display.getDefault()); + } + +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/package-info.java new file mode 100644 index 0000000..7d3a260 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/theme/package-info.java @@ -0,0 +1,2 @@ +/** Argeo CMS core theme images. */ +package org.argeo.cms.ui.theme; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java new file mode 100644 index 0000000..a388e74 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java @@ -0,0 +1,106 @@ +package org.argeo.eclipse.ui.dialogs; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.argeo.api.cms.CmsLog; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Generic error dialog to be used in try/catch blocks. + * + * @deprecated Use CMS dialogs instead. + */ +@Deprecated +public class ErrorFeedback extends TitleAreaDialog { + private static final long serialVersionUID = -8918084784628179044L; + + private final static CmsLog log = CmsLog.getLog(ErrorFeedback.class); + + private final String message; + private final Throwable exception; + + public static void show(String message, Throwable e) { + // rethrow ThreaDeath in order to make sure that RAP will properly clean + // up the UI thread + if (e instanceof ThreadDeath) + throw (ThreadDeath) e; + + new ErrorFeedback(newShell(), message, e).open(); + } + + public static void show(String message) { + new ErrorFeedback(newShell(), message, null).open(); + } + + private static Shell newShell() { + return new Shell(getDisplay(), SWT.NO_TRIM); + } + + /** Tries to find a display */ + private static Display getDisplay() { + try { + Display display = Display.getCurrent(); + if (display != null) + return display; + else + return Display.getDefault(); + } catch (Exception e) { + return Display.getCurrent(); + } + } + + public ErrorFeedback(Shell parentShell, String message, Throwable e) { + super(parentShell); + setShellStyle(SWT.NO_TRIM); + this.message = message; + this.exception = e; + log.error(message, e); + } + + protected Point getInitialSize() { + if (exception != null) + return new Point(800, 600); + else + return new Point(400, 300); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + Composite composite = new Composite(dialogarea, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + setMessage(message != null ? message + (exception != null ? ": " + exception.getMessage() : "") + : exception != null ? exception.getMessage() : "Unkown Error", IMessageProvider.ERROR); + + if (exception != null) { + Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + stack.setEditable(false); + stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + StringWriter sw = new StringWriter(); + exception.printStackTrace(new PrintWriter(sw)); + stack.setText(sw.toString()); + } + + parent.pack(); + return composite; + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText("Error"); + } +} \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java new file mode 100644 index 0000000..f2715bc --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java @@ -0,0 +1,141 @@ +package org.argeo.eclipse.ui.dialogs; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.argeo.api.cms.CmsLog; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Generic lightweight dialog, not based on JFace. + * + * @deprecated Use CMS dialogs instead. + */ +@Deprecated +public class FeedbackDialog extends LightweightDialog { + private final static CmsLog log = CmsLog.getLog(FeedbackDialog.class); + + private String message; + private Throwable exception; + +// private Shell parentShell; + private Shell shell; + + public static void show(String message, Throwable e) { + // rethrow ThreaDeath in order to make sure that RAP will properly clean + // up the UI thread + if (e instanceof ThreadDeath) + throw (ThreadDeath) e; + + new FeedbackDialog(getDisplay().getActiveShell(), message, e).open(); + } + + public static void show(String message) { + new FeedbackDialog(getDisplay().getActiveShell(), message, null).open(); + } + + /** Tries to find a display */ + private static Display getDisplay() { + try { + Display display = Display.getCurrent(); + if (display != null) + return display; + else + return Display.getDefault(); + } catch (Exception e) { + return Display.getCurrent(); + } + } + + public FeedbackDialog(Shell parentShell, String message, Throwable e) { + super(parentShell); + this.message = message; + this.exception = e; + log.error(message, e); + } + + public int open() { + if (shell != null) + throw new EclipseUiException("There is already a shell"); + shell = new Shell(getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP); + shell.setLayout(new GridLayout()); + // shell.setText("Error"); + shell.setSize(getInitialSize()); + createDialogArea(shell); + // shell.pack(); + // shell.layout(); + + Rectangle shellBounds = Display.getCurrent().getBounds();// RAP + Point dialogSize = shell.getSize(); + int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2; + int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2; + shell.setLocation(x, y); + + shell.addShellListener(new ShellAdapter() { + private static final long serialVersionUID = -2701270481953688763L; + + @Override + public void shellDeactivated(ShellEvent e) { + closeShell(); + } + }); + + shell.open(); + return OK; + } + + protected void closeShell() { + shell.close(); + shell.dispose(); + shell = null; + } + + protected Point getInitialSize() { + // if (exception != null) + // return new Point(800, 600); + // else + return new Point(400, 300); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = new Composite(parent, SWT.NONE); + dialogarea.setLayout(new GridLayout()); + // Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Label messageLbl = new Label(dialogarea, SWT.NONE); + if (message != null) + messageLbl.setText(message); + else if (exception != null) + messageLbl.setText(exception.getLocalizedMessage()); + + Composite composite = new Composite(dialogarea, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + if (exception != null) { + Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + stack.setEditable(false); + stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + StringWriter sw = new StringWriter(); + exception.printStackTrace(new PrintWriter(sw)); + stack.setText(sw.toString()); + } + + // parent.pack(); + return composite; + } +} \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java new file mode 100644 index 0000000..615e141 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java @@ -0,0 +1,256 @@ +package org.argeo.eclipse.ui.dialogs; + +import org.argeo.api.cms.CmsLog; +import org.argeo.eclipse.ui.EclipseUiException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** Generic lightweight dialog, not based on JFace. */ +@Deprecated +public class LightweightDialog { + private final static CmsLog log = CmsLog.getLog(LightweightDialog.class); + + // must be the same value as org.eclipse.jface.window.Window#OK + public final static int OK = 0; + // must be the same value as org.eclipse.jface.window.Window#CANCEL + public final static int CANCEL = 1; + + private Shell parentShell; + private Shell backgroundShell; + private Shell foregoundShell; + + private Integer returnCode = null; + private boolean block = true; + + private String title; + + /** Tries to find a display */ + private static Display getDisplay() { + try { + Display display = Display.getCurrent(); + if (display != null) + return display; + else + return Display.getDefault(); + } catch (Exception e) { + return Display.getCurrent(); + } + } + + public LightweightDialog(Shell parentShell) { + this.parentShell = parentShell; + } + + public int open() { + if (foregoundShell != null) + throw new EclipseUiException("There is already a shell"); + backgroundShell = new Shell(parentShell, SWT.ON_TOP); + backgroundShell.setFullScreen(true); + // if (parentShell != null) { + // backgroundShell.setBounds(parentShell.getBounds()); + // } else + // backgroundShell.setMaximized(true); + backgroundShell.setAlpha(128); + backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP); + if (title != null) + setTitle(title); + foregoundShell.setLayout(new GridLayout()); + foregoundShell.setSize(getInitialSize()); + createDialogArea(foregoundShell); + // shell.pack(); + // shell.layout(); + + Rectangle shellBounds = parentShell != null ? parentShell.getBounds() : Display.getCurrent().getBounds();// RAP + Point dialogSize = foregoundShell.getSize(); + int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2; + int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2; + foregoundShell.setLocation(x, y); + + foregoundShell.addShellListener(new ShellAdapter() { + private static final long serialVersionUID = -2701270481953688763L; + + @Override + public void shellDeactivated(ShellEvent e) { + if (hasChildShells()) + return; + if (returnCode == null)// not yet closed + closeShell(CANCEL); + } + + @Override + public void shellClosed(ShellEvent e) { + notifyClose(); + } + + }); + + backgroundShell.open(); + foregoundShell.open(); + // after the foreground shell has been opened + backgroundShell.addFocusListener(new FocusListener() { + private static final long serialVersionUID = 3137408447474661070L; + + @Override + public void focusLost(FocusEvent event) { + } + + @Override + public void focusGained(FocusEvent event) { + if (hasChildShells()) + return; + if (returnCode == null)// not yet closed + closeShell(CANCEL); + } + }); + + if (block) { + block(); + } + if (returnCode == null) + returnCode = OK; + return returnCode; + } + + public void block() { + try { + runEventLoop(foregoundShell); + } catch (ThreadDeath t) { + returnCode = CANCEL; + if (log.isTraceEnabled()) + log.error("Thread death, canceling dialog", t); + } catch (Throwable t) { + returnCode = CANCEL; + log.error("Cannot open blocking lightweight dialog", t); + } + } + + private boolean hasChildShells() { + if (foregoundShell == null) + return false; + return foregoundShell.getShells().length != 0; + } + + // public synchronized int openAndWait() { + // open(); + // while (returnCode == null) + // try { + // wait(100); + // } catch (InterruptedException e) { + // // silent + // } + // return returnCode; + // } + + private synchronized void notifyClose() { + if (returnCode == null) + returnCode = CANCEL; + notifyAll(); + } + + protected void closeShell(int returnCode) { + this.returnCode = returnCode; + if (CANCEL == returnCode) + onCancel(); + if (foregoundShell != null && !foregoundShell.isDisposed()) { + foregoundShell.close(); + foregoundShell.dispose(); + foregoundShell = null; + } + + if (backgroundShell != null && !backgroundShell.isDisposed()) { + backgroundShell.close(); + backgroundShell.dispose(); + } + } + + protected Point getInitialSize() { + // if (exception != null) + // return new Point(800, 600); + // else + return new Point(600, 400); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = new Composite(parent, SWT.NONE); + dialogarea.setLayout(new GridLayout()); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return dialogarea; + } + + protected Shell getBackgroundShell() { + return backgroundShell; + } + + protected Shell getForegoundShell() { + return foregoundShell; + } + + public void setBlockOnOpen(boolean shouldBlock) { + block = shouldBlock; + } + + public void pack() { + foregoundShell.pack(); + } + + private void runEventLoop(Shell loopShell) { + Display display; + if (foregoundShell == null) { + display = Display.getCurrent(); + } else { + display = loopShell.getDisplay(); + } + + while (loopShell != null && !loopShell.isDisposed()) { + try { + if (!display.readAndDispatch()) { + display.sleep(); + } + } catch (UnsupportedOperationException e) { + throw e; + } catch (Throwable e) { + handleException(e); + } + } + if (!display.isDisposed()) + display.update(); + } + + protected void handleException(Throwable t) { + if (t instanceof ThreadDeath) { + // Don't catch ThreadDeath as this is a normal occurrence when + // the thread dies + throw (ThreadDeath) t; + } + // Try to keep running. + t.printStackTrace(); + } + + /** @return false, if the dialog should not be closed. */ + protected boolean onCancel() { + return true; + } + + public void setTitle(String title) { + this.title = title; + if (title != null && getForegoundShell() != null) + getForegoundShell().setText(title); + } + + public Integer getReturnCode() { + return returnCode; + } + +} \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/SingleValue.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/SingleValue.java new file mode 100644 index 0000000..8ce9b44 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/SingleValue.java @@ -0,0 +1,130 @@ +package org.argeo.eclipse.ui.dialogs; + +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Dialog to retrieve a single value. + * + * @deprecated Use CMS dialogs instead. + */ +@Deprecated +public class SingleValue extends TitleAreaDialog { + private static final long serialVersionUID = 2843538207460082349L; + + private Text valueT; + private String value; + private final String title, message, label; + private final Boolean multiline; + + public static String ask(String label, String message) { + SingleValue svd = new SingleValue(label, message); + if (svd.open() == Window.OK) + return svd.getString(); + else + return null; + } + + public static Long askLong(String label, String message) { + SingleValue svd = new SingleValue(label, message); + if (svd.open() == Window.OK) + return svd.getLong(); + else + return null; + } + + public static Double askDouble(String label, String message) { + SingleValue svd = new SingleValue(label, message); + if (svd.open() == Window.OK) + return svd.getDouble(); + else + return null; + } + + public SingleValue(String label, String message) { + this(Display.getDefault().getActiveShell(), label, message, label, false); + } + + public SingleValue(Shell parentShell, String title, String message, String label, Boolean multiline) { + super(parentShell); + this.title = title; + this.message = message; + this.label = label; + this.multiline = multiline; + } + + protected Point getInitialSize() { + if (multiline) + return new Point(450, 350); + + else + return new Point(400, 270); + } + + protected Control createDialogArea(Composite parent) { + Composite dialogarea = (Composite) super.createDialogArea(parent); + dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + Composite composite = new Composite(dialogarea, SWT.NONE); + composite.setLayoutData(EclipseUiUtils.fillAll()); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = layout.marginHeight = 20; + composite.setLayout(layout); + + valueT = createLT(composite, label); + + setMessage(message, IMessageProvider.NONE); + + parent.pack(); + valueT.setFocus(); + return composite; + } + + @Override + protected void okPressed() { + value = valueT.getText(); + super.okPressed(); + } + + /** Creates label and text. */ + protected Text createLT(Composite parent, String label) { + new Label(parent, SWT.NONE).setText(label); + Text text; + if (multiline) { + text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.MULTI); + text.setLayoutData(EclipseUiUtils.fillAll()); + } else { + text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.SINGLE); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + } + return text; + } + + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(title); + } + + public String getString() { + return value; + } + + public Long getLong() { + return Long.valueOf(getString()); + } + + public Double getDouble() { + return Double.valueOf(getString()); + } +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/package-info.java new file mode 100644 index 0000000..d6ab148 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/eclipse/ui/dialogs/package-info.java @@ -0,0 +1,2 @@ +/** Generic SWT/JFace dialogs. */ +package org.argeo.eclipse.ui.dialogs; \ No newline at end of file