From: Mathieu Date: Tue, 6 Dec 2022 05:11:42 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/unstable' into testing X-Git-Tag: v2.1.1~3 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=40e89f491fb2aad2e1219b28106588ea365198a0;hp=33e698c7bcfe801cca9866d0e9e302c1e8e9a412;p=gpl%2Fargeo-jcr.git Merge remote-tracking branch 'origin/unstable' into testing --- diff --git a/Makefile b/Makefile index df27ce8..f1ad813 100644 --- a/Makefile +++ b/Makefile @@ -7,17 +7,14 @@ A2_CATEGORY = org.argeo.cms.jcr BUNDLES = \ org.argeo.cms.jcr \ swt/org.argeo.cms.jcr.ui \ -swt/org.argeo.cms.jcr.e4 \ DEP_CATEGORIES = \ org.argeo.tp \ -org.argeo.tp.apache \ -org.argeo.tp.jetty \ +org.argeo.tp.jcr \ osgi/api/org.argeo.tp.osgi \ osgi/equinox/org.argeo.tp.eclipse \ swt/rap/org.argeo.tp.swt \ swt/rap/org.argeo.tp.swt.workbench \ -org.argeo.tp.jcr \ org.argeo.cms \ swt/org.argeo.cms \ swt/rap/org.argeo.cms \ diff --git a/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml b/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml index 033ddbd..a39a4dc 100644 --- a/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml +++ b/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml @@ -1,4 +1,5 @@ + diff --git a/org.argeo.cms.jcr/bnd.bnd b/org.argeo.cms.jcr/bnd.bnd index 01446c1..8cda76f 100644 --- a/org.argeo.cms.jcr/bnd.bnd +++ b/org.argeo.cms.jcr/bnd.bnd @@ -11,7 +11,6 @@ org.argeo.cms.servlet,\ javax.jcr.security,\ org.h2;resolution:=optional;version="[1,3)",\ org.postgresql;version="[42,43)";resolution:=optional,\ -org.apache.commons.httpclient.cookie;resolution:=optional,\ org.osgi.framework.namespace;version=0.0.0,\ org.osgi.*;version=0.0.0,\ org.osgi.service.http.whiteboard,\ diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java index 7fde177..1b94623 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java @@ -18,8 +18,8 @@ import javax.security.auth.login.LoginException; import org.argeo.api.cms.CmsAuth; import org.argeo.api.cms.CmsConstants; +import org.argeo.cms.util.CurrentSubject; import org.argeo.jcr.JcrUtils; -import org.argeo.util.CurrentSubject; /** Utilities related to Argeo model in JCR */ public class CmsJcrUtils { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java index a4af35b..3059064 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java @@ -257,12 +257,20 @@ public class JcrContent extends AbstractContent { public A adapt(Class clss) { if (Source.class.isAssignableFrom(clss)) { // try { - PipedInputStream in = new PipedInputStream(); + PipedOutputStream out = new PipedOutputStream(); + PipedInputStream in; + try { + in = new PipedInputStream(out); + } catch (IOException e) { + throw new RuntimeException("Cannot export " + jcrPath + " in workspace " + jcrWorkspace, e); + } ForkJoinPool.commonPool().execute(() -> { - try (PipedOutputStream out = new PipedOutputStream(in)) { +// try (PipedOutputStream out = new PipedOutputStream(in)) { + try { provider.getJcrSession(getSession(), jcrWorkspace).exportDocumentView(jcrPath, out, true, false); out.flush(); + out.close(); } catch (IOException | RepositoryException e) { throw new RuntimeException("Cannot export " + jcrPath + " in workspace " + jcrWorkspace, e); } diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentNamespace.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentNamespace.java new file mode 100644 index 0000000..8b721f7 --- /dev/null +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentNamespace.java @@ -0,0 +1,75 @@ +package org.argeo.cms.jcr.acr; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Objects; + +import org.argeo.api.acr.spi.ContentNamespace; + +/** JCR-specific content namespaces. */ +public enum JcrContentNamespace implements ContentNamespace { + // + // ARGEO + // + JCRX("jcrx", "http://www.argeo.org/ns/jcrx", null, null), + // + // EXTERNAL + // + JCR("jcr", "http://www.jcp.org/jcr/1.0", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + JCR_MIX("mix", "http://www.jcp.org/jcr/mix/1.0", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + JCR_NT("nt", "http://www.jcp.org/jcr/nt/1.0", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + JACKRABBIT("rep", "internal", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + ; + + private final static String RESOURCE_BASE = "/org/argeo/cms/jcr/acr/schemas/"; + + private String defaultPrefix; + private String namespace; + private URL resource; + private URL publicUrl; + + JcrContentNamespace(String defaultPrefix, String namespace, String resourceFileName, String publicUrl) { + Objects.requireNonNull(namespace); + this.defaultPrefix = defaultPrefix; + Objects.requireNonNull(namespace); + this.namespace = namespace; + if (resourceFileName != null) { + resource = getClass().getResource(RESOURCE_BASE + resourceFileName); + Objects.requireNonNull(resource); + } + if (publicUrl != null) + try { + this.publicUrl = new URL(publicUrl); + } catch (MalformedURLException e) { + throw new IllegalArgumentException("Cannot interpret public URL", e); + } + } + + @Override + public String getDefaultPrefix() { + return defaultPrefix; + } + + @Override + public String getNamespaceURI() { + return namespace; + } + + @Override + public URL getSchemaResource() { + return resource; + } + + public URL getPublicUrl() { + return publicUrl; + } + +} diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java index eaa27b7..38bcd56 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Objects; +import java.util.function.Function; import javax.jcr.Repository; import javax.jcr.RepositoryException; @@ -89,11 +90,24 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { return mountPath; } + public synchronized T doInAdminSession(Function toDo) { + try { + return toDo.apply(adminSession); + } finally { + try { + if (adminSession.hasPendingChanges()) + adminSession.save(); + } catch (RepositoryException e) { + throw new JcrException("Cannot save admin session", e); + } + } + } + /* * NAMESPACE CONTEXT */ @Override - public String getNamespaceURI(String prefix) { + public synchronized String getNamespaceURI(String prefix) { try { return adminSession.getNamespaceURI(prefix); } catch (RepositoryException e) { @@ -102,7 +116,7 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { } @Override - public String getPrefix(String namespaceURI) { + public synchronized String getPrefix(String namespaceURI) { try { return adminSession.getNamespacePrefix(namespaceURI); } catch (RepositoryException e) { @@ -111,7 +125,7 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { } @Override - public Iterator getPrefixes(String namespaceURI) { + public synchronized Iterator getPrefixes(String namespaceURI) { try { return Arrays.asList(adminSession.getNamespacePrefix(namespaceURI)).iterator(); } catch (RepositoryException e) { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java index 35800f8..a871355 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java @@ -26,10 +26,12 @@ import javax.servlet.Servlet; import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.core.RepositoryContext; import org.apache.jackrabbit.core.RepositoryImpl; +import org.argeo.api.acr.spi.ProvidedRepository; import org.argeo.api.cms.CmsConstants; import org.argeo.api.cms.CmsLog; import org.argeo.cms.ArgeoNames; import org.argeo.cms.jcr.CmsJcrUtils; +import org.argeo.cms.jcr.acr.JcrContentNamespace; import org.argeo.cms.jcr.internal.servlet.CmsRemotingServlet; import org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet; import org.argeo.cms.jcr.internal.servlet.JcrHttpUtils; @@ -62,17 +64,21 @@ public class CmsJcrDeployment { // Readiness private boolean nodeAvailable = false; + private ProvidedRepository contentRepository; + // CmsDeployment cmsDeployment; public void start() { dataModels = new DataModels(bc); + contentRepository.registerTypes(JcrContentNamespace.values()); + ServiceTracker repoContextSt = new RepositoryContextStc(); repoContextSt.open(); // KernelUtils.asyncOpen(repoContextSt); // nodeDeployment = CmsJcrActivator.getService(NodeDeployment.class); - //JcrInitUtils.addToDeployment(cmsDeployment); + // JcrInitUtils.addToDeployment(cmsDeployment); // contentRepository.registerTypes(NamespaceRegistry.PREFIX_JCR, NamespaceRegistry.NAMESPACE_JCR, null); // contentRepository.registerTypes(NamespaceRegistry.PREFIX_MIX, NamespaceRegistry.NAMESPACE_MIX, null); @@ -88,7 +94,6 @@ public class CmsJcrDeployment { // if (nodeHttp != null) // nodeHttp.destroy(); - try { for (ServiceReference sr : bc .getServiceReferences(JackrabbitLocalRepository.class, null)) { @@ -351,7 +356,8 @@ public class CmsJcrDeployment { boolean isStandalone(String dataModelName) { return true; - //return cmsDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null; + // return cmsDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, + // dataModelName) != null; } private void publishLocalRepo(String dataModelName, Repository repository) { @@ -432,6 +438,10 @@ public class CmsJcrDeployment { bc.registerService(Servlet.class, remotingServlet, ip); } + public void setContentRepository(ProvidedRepository contentRepository) { + this.contentRepository = contentRepository; + } + private class RepositoryContextStc extends ServiceTracker { public RepositoryContextStc() { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrFsProvider.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrFsProvider.java index 0099b3b..4eb693b 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrFsProvider.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrFsProvider.java @@ -19,7 +19,7 @@ import javax.jcr.Session; import javax.jcr.nodetype.NodeType; import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.CurrentUser; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider; import org.argeo.jcr.fs.JcrFileSystem; diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java index 17625f5..ff117e3 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java @@ -28,11 +28,11 @@ import javax.jcr.query.Query; import org.apache.commons.io.IOUtils; import org.argeo.api.cms.CmsConstants; import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.keyring.PBEKeySpecCallback; +import org.argeo.cms.AbstractKeyring; import org.argeo.cms.ArgeoNames; import org.argeo.cms.ArgeoTypes; import org.argeo.cms.jcr.CmsJcrUtils; -import org.argeo.cms.security.AbstractKeyring; -import org.argeo.cms.security.PBEKeySpecCallback; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java index f3a099b..791b8a2 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java @@ -20,7 +20,7 @@ import org.argeo.cms.CmsDeployProperty; import org.argeo.cms.internal.jcr.RepoConf; import org.argeo.cms.internal.jcr.RepositoryBuilder; import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator; -import org.argeo.util.LangUtils; +import org.argeo.cms.util.LangUtils; import org.osgi.service.cm.ManagedServiceFactory; /** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */ diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java index ccd543f..821212e 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java @@ -2,8 +2,8 @@ package org.argeo.cms.jcr.tabular; import java.io.OutputStream; -import org.argeo.cms.tabular.TabularWriter; -import org.argeo.util.CsvWriter; +import org.argeo.api.acr.tabular.TabularWriter; +import org.argeo.cms.util.CsvWriter; /** Write tabular content in a stream as CSV. Wraps a {@link CsvWriter}. */ public class CsvTabularWriter implements TabularWriter { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java index d1d9b58..0d589b1 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java @@ -13,13 +13,13 @@ import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import org.apache.commons.io.IOUtils; +import org.argeo.api.acr.tabular.ArrayTabularRow; +import org.argeo.api.acr.tabular.TabularColumn; +import org.argeo.api.acr.tabular.TabularRow; +import org.argeo.api.acr.tabular.TabularRowIterator; import org.argeo.cms.ArgeoTypes; -import org.argeo.cms.tabular.ArrayTabularRow; -import org.argeo.cms.tabular.TabularColumn; -import org.argeo.cms.tabular.TabularRow; -import org.argeo.cms.tabular.TabularRowIterator; +import org.argeo.cms.util.CsvParser; import org.argeo.jcr.JcrException; -import org.argeo.util.CsvParser; /** Iterates over the rows of a {@link ArgeoTypes#ARGEO_TABLE} node. */ public class JcrTabularRowIterator implements TabularRowIterator { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java index cc3e0d7..b4ba65b 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java @@ -12,12 +12,12 @@ import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import org.apache.commons.io.IOUtils; +import org.argeo.api.acr.tabular.TabularColumn; +import org.argeo.api.acr.tabular.TabularWriter; import org.argeo.cms.ArgeoTypes; -import org.argeo.cms.tabular.TabularColumn; -import org.argeo.cms.tabular.TabularWriter; +import org.argeo.cms.util.CsvWriter; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; -import org.argeo.util.CsvWriter; /** Write / reference tabular content in a JCR repository. */ public class JcrTabularWriter implements TabularWriter { diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/Jcr.java b/org.argeo.cms.jcr/src/org/argeo/jcr/Jcr.java index 49b008d..88f5345 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/Jcr.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/Jcr.java @@ -49,11 +49,15 @@ public class Jcr { /** * The name of a node which will be serialized as XML text, as per section 7.3.1 * of the JCR 2.0 specifications. + * + * @see Workspace#NAME_JCR_XMLTEXT */ public final static String JCR_XMLTEXT = "jcr:xmltext"; /** * The name of a property which will be serialized as XML text, as per section * 7.3.1 of the JCR 2.0 specifications. + * + * @see Workspace#NAME_JCR_XMLCHARACTERS */ public final static String JCR_XMLCHARACTERS = "jcr:xmlcharacters"; /** @@ -609,6 +613,23 @@ public class Jcr { } } + /** + * Retrieve a {@link PropertyType#DATE} property as an {@link Instant}. + * + * @return the property value, or null if not found. + */ + public static Instant getAsInstant(Node node, String property) { + try { + if (!node.hasProperty(property)) + return null; + Calendar calendar = node.getProperty(property).getDate(); + return calendar.getTime().toInstant(); + } catch (RepositoryException e) { + throw new JcrException("Cannot get property " + property + " of " + node + " as an instant.", e); + } + + } + /** * Get a multiple property as a list, doing a best effort to cast it as the * target list. diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUtils.java b/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUtils.java index 1f1fa11..7f157cd 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/JcrUtils.java @@ -1151,7 +1151,7 @@ public class JcrUtils { // } catch (InterruptedException e1) { // // ignore // } - + workspaceSession = repository.login(credentials, workspaceName); } return workspaceSession; @@ -1382,7 +1382,7 @@ public class JcrUtils { /** * Convenience method for adding a single privilege to a principal (user or - * role), typically jcr:all + * role), typically jcr:all. Session is saved. */ public synchronized static void addPrivilege(Session session, String path, String principal, String privilege) throws RepositoryException { diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxApi.java b/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxApi.java index 666b259..ff61a62 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxApi.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/JcrxApi.java @@ -67,7 +67,7 @@ public class JcrxApi { try { if (node.hasNode(name)) { Node child = node.getNode(name); - setXmlValue(node, child, value); + setXmlValue(child, value); } else node.addNode(name, JcrxType.JCRX_XMLVALUE).addNode(Jcr.JCR_XMLTEXT, JcrxType.JCRX_XMLTEXT) .setProperty(Jcr.JCR_XMLCHARACTERS, value); @@ -76,7 +76,8 @@ public class JcrxApi { } } - public static void setXmlValue(Node node, Node child, String value) { + /** Set the value as XML characters. */ + public static void setXmlValue(Node child, String value) { try { if (!child.hasNode(Jcr.JCR_XMLTEXT)) child.addNode(Jcr.JCR_XMLTEXT, JcrxType.JCRX_XMLTEXT); diff --git a/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java b/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java index 977adac..3eef961 100644 --- a/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java +++ b/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java @@ -10,13 +10,13 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; +import org.argeo.api.acr.ldap.Distinguished; import org.argeo.api.acr.spi.ProvidedRepository; import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.transaction.WorkTransaction; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrUtils; -import org.argeo.util.naming.Distinguished; -import org.argeo.util.transaction.WorkTransaction; import org.osgi.service.useradmin.Group; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.UserAdmin; diff --git a/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java b/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java index e65e46a..df2618c 100644 --- a/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java +++ b/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java @@ -8,7 +8,7 @@ import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; import org.argeo.api.cms.CmsLog; -import org.argeo.util.transaction.WorkTransaction; +import org.argeo.api.cms.transaction.WorkTransaction; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.UserAdmin; diff --git a/sdk/argeo-build b/sdk/argeo-build index 639ffc6..5bf3887 160000 --- a/sdk/argeo-build +++ b/sdk/argeo-build @@ -1 +1 @@ -Subproject commit 639ffc61c03f6aebf9cfe5e0f79dd0c4c6aa632a +Subproject commit 5bf388711048a659992c292c4b9bdcbc595e066b diff --git a/sdk/branches/unstable.bnd b/sdk/branches/unstable.bnd index 4146cb0..b8e5aef 100644 --- a/sdk/branches/unstable.bnd +++ b/sdk/branches/unstable.bnd @@ -1,4 +1,4 @@ major=2 minor=3 -micro=9 +micro=12 qualifier=.next \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/.classpath b/swt/org.argeo.cms.jcr.e4/.classpath deleted file mode 100644 index 81fe078..0000000 --- a/swt/org.argeo.cms.jcr.e4/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/swt/org.argeo.cms.jcr.e4/.project b/swt/org.argeo.cms.jcr.e4/.project deleted file mode 100644 index 01f8dd2..0000000 --- a/swt/org.argeo.cms.jcr.e4/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.argeo.cms.jcr.e4 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/swt/org.argeo.cms.jcr.e4/bnd.bnd b/swt/org.argeo.cms.jcr.e4/bnd.bnd deleted file mode 100644 index fde6c09..0000000 --- a/swt/org.argeo.cms.jcr.e4/bnd.bnd +++ /dev/null @@ -1,12 +0,0 @@ -Import-Package: \ -org.eclipse.swt,\ -org.eclipse.swt.widgets;version="0.0.0",\ -org.eclipse.jface.window,\ -org.eclipse.core.commands.common,\ -org.eclipse.e4.ui.model.application.ui,\ -org.eclipse.e4.ui.model.application,\ -javax.jcr.nodetype,\ -org.apache.jackrabbit.*;version="[2,3)",\ -org.argeo.cms,\ -org.argeo.jcr,\ -* \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/build.properties b/swt/org.argeo.cms.jcr.e4/build.properties deleted file mode 100644 index 34d2e4d..0000000 --- a/swt/org.argeo.cms.jcr.e4/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/EclipseJcrMonitor.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/EclipseJcrMonitor.java deleted file mode 100644 index e10738e..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/EclipseJcrMonitor.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.argeo.cms.e4.jcr; - -import org.argeo.jcr.JcrMonitor; -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * Wraps an Eclipse {@link IProgressMonitor} so that it can be passed to - * framework agnostic Argeo routines. - */ -public class EclipseJcrMonitor implements JcrMonitor { - private final IProgressMonitor progressMonitor; - - public EclipseJcrMonitor(IProgressMonitor progressMonitor) { - this.progressMonitor = progressMonitor; - } - - public void beginTask(String name, int totalWork) { - progressMonitor.beginTask(name, totalWork); - } - - public void done() { - progressMonitor.done(); - } - - public boolean isCanceled() { - return progressMonitor.isCanceled(); - } - - public void setCanceled(boolean value) { - progressMonitor.setCanceled(value); - } - - public void setTaskName(String name) { - progressMonitor.setTaskName(name); - } - - public void subTask(String name) { - progressMonitor.subTask(name); - } - - public void worked(int work) { - progressMonitor.worked(work); - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/GenericPropertyPage.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/GenericPropertyPage.java deleted file mode 100644 index e17f17b..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/GenericPropertyPage.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.argeo.cms.e4.jcr; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.RepositoryException; - -import org.argeo.cms.ui.jcr.PropertyLabelProvider; -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.jface.layout.TreeColumnLayout; -import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.jface.viewers.IBaseLabelProvider; -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.custom.ScrolledComposite; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; - -/** - * Generic editor property page. Lists all properties of current node as a - * complex tree. TODO: enable editing - */ -public class GenericPropertyPage { - - // Main business Objects - private Node currentNode; - - public GenericPropertyPage(Node currentNode) { - this.currentNode = currentNode; - } - - protected void createFormContent(Composite parent) { - Composite innerBox = new Composite(parent, SWT.NONE); - // Composite innerBox = new Composite(body, SWT.NO_FOCUS); - FillLayout layout = new FillLayout(); - layout.marginHeight = 5; - layout.marginWidth = 5; - innerBox.setLayout(layout); - createComplexTree(innerBox); - // TODO TreeColumnLayout triggers a scroll issue with the form: - // The inside body is always to big and a scroll bar is shown - // Composite tableCmp = new Composite(body, SWT.NO_FOCUS); - // createComplexTree(tableCmp); - } - - private TreeViewer createComplexTree(Composite parent) { - int style = SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION; - Tree tree = new Tree(parent, style); - TreeColumnLayout tableColumnLayout = new TreeColumnLayout(); - - createColumn(tree, tableColumnLayout, "Property", SWT.LEFT, 200, 30); - createColumn(tree, tableColumnLayout, "Value(s)", SWT.LEFT, 300, 60); - createColumn(tree, tableColumnLayout, "Type", SWT.LEFT, 75, 10); - createColumn(tree, tableColumnLayout, "Attributes", SWT.LEFT, 75, 0); - // Do not apply the treeColumnLayout it does not work yet - // parent.setLayout(tableColumnLayout); - - tree.setLinesVisible(true); - tree.setHeaderVisible(true); - - TreeViewer treeViewer = new TreeViewer(tree); - treeViewer.setContentProvider(new TreeContentProvider()); - treeViewer.setLabelProvider((IBaseLabelProvider) new PropertyLabelProvider()); - treeViewer.setInput(currentNode); - treeViewer.expandAll(); - return treeViewer; - } - - private static TreeColumn createColumn(Tree parent, TreeColumnLayout tableColumnLayout, String name, int style, - int width, int weight) { - TreeColumn column = new TreeColumn(parent, style); - column.setText(name); - column.setWidth(width); - column.setMoveable(true); - column.setResizable(true); - tableColumnLayout.setColumnData(column, new ColumnWeightData(weight, width, true)); - return column; - } - - private class TreeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = -6162736530019406214L; - - public Object[] getElements(Object parent) { - Object[] props = null; - try { - - if (parent instanceof Node) { - Node node = (Node) parent; - PropertyIterator pi; - pi = node.getProperties(); - List propList = new ArrayList(); - while (pi.hasNext()) { - propList.add(pi.nextProperty()); - } - props = propList.toArray(); - } - } catch (RepositoryException e) { - throw new EclipseUiException("Unexpected exception while listing node properties", e); - } - return props; - } - - public Object getParent(Object child) { - return null; - } - - public Object[] getChildren(Object parent) { - if (parent instanceof Property) { - Property prop = (Property) parent; - try { - if (prop.isMultiple()) - return prop.getValues(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot get multi-prop values on " + prop, e); - } - } - return null; - } - - public boolean hasChildren(Object parent) { - try { - return (parent instanceof Property && ((Property) parent).isMultiple()); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot check if property is multiple for " + parent, e); - } - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public void dispose() { - } - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java deleted file mode 100644 index 0b77c07..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java +++ /dev/null @@ -1,349 +0,0 @@ -package org.argeo.cms.e4.jcr; - -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.Value; -import javax.jcr.observation.Event; -import javax.jcr.observation.EventListener; -import javax.jcr.observation.ObservationManager; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.security.CryptoKeyring; -import org.argeo.cms.security.Keyring; -import org.argeo.cms.swt.CmsException; -import org.argeo.cms.swt.CmsSwtUtils; -import org.argeo.cms.ui.jcr.JcrBrowserUtils; -import org.argeo.cms.ui.jcr.NodeContentProvider; -import org.argeo.cms.ui.jcr.NodeLabelProvider; -import org.argeo.cms.ui.jcr.OsgiRepositoryRegister; -import org.argeo.cms.ui.jcr.PropertiesContentProvider; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.jcr.AsyncUiEventListener; -import org.argeo.eclipse.ui.jcr.util.NodeViewerComparer; -import org.argeo.jcr.JcrUtils; -import org.eclipse.e4.core.contexts.IEclipseContext; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.services.EMenuService; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; - -/** - * Basic View to display a sash form to browse a JCR compliant multiple - * repository environment - */ -public class JcrBrowserView { - final static String ID = "org.argeo.cms.e4.jcrbrowser"; - final static String NODE_VIEWER_POPUP_MENU_ID = "org.argeo.cms.e4.popupmenu.nodeViewer"; - - private boolean sortChildNodes = true; - - /* DEPENDENCY INJECTION */ - @Inject - @Optional - private Keyring keyring; - @Inject - private RepositoryFactory repositoryFactory; - @Inject - private Repository nodeRepository; - - // Current user session on the home repository default workspace - private Session userSession; - - private OsgiRepositoryRegister repositoryRegister = new OsgiRepositoryRegister(); - - // This page widgets - private TreeViewer nodesViewer; - private NodeContentProvider nodeContentProvider; - private TableViewer propertiesViewer; - private EventListener resultsObserver; - - @PostConstruct - public void createPartControl(Composite parent, IEclipseContext context, EPartService partService, - ESelectionService selectionService, EMenuService menuService) { - repositoryRegister.init(); - - parent.setLayout(new FillLayout()); - SashForm sashForm = new SashForm(parent, SWT.VERTICAL); - // sashForm.setSashWidth(4); - // sashForm.setLayout(new FillLayout()); - - // Create the tree on top of the view - Composite top = new Composite(sashForm, SWT.NONE); - // GridLayout gl = new GridLayout(1, false); - top.setLayout(CmsSwtUtils.noSpaceGridLayout()); - - try { - this.userSession = this.nodeRepository.login(CmsConstants.HOME_WORKSPACE); - } catch (RepositoryException e) { - throw new CmsException("Cannot open user session", e); - } - - nodeContentProvider = new NodeContentProvider(userSession, keyring, repositoryRegister, repositoryFactory, - sortChildNodes); - - // nodes viewer - nodesViewer = createNodeViewer(top, nodeContentProvider); - - // context menu : it is completely defined in the plugin.xml file. - // MenuManager menuManager = new MenuManager(); - // Menu menu = menuManager.createContextMenu(nodesViewer.getTree()); - - // nodesViewer.getTree().setMenu(menu); - - nodesViewer.setInput(""); - - // Create the property viewer on the bottom - Composite bottom = new Composite(sashForm, SWT.NONE); - bottom.setLayout(CmsSwtUtils.noSpaceGridLayout()); - propertiesViewer = createPropertiesViewer(bottom); - - sashForm.setWeights(getWeights()); - nodesViewer.setComparer(new NodeViewerComparer()); - nodesViewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - selectionService.setSelection(selection.toList()); - } - }); - nodesViewer.addDoubleClickListener(new JcrE4DClickListener(nodesViewer, partService)); - menuService.registerContextMenu(nodesViewer.getControl(), NODE_VIEWER_POPUP_MENU_ID); - // getSite().registerContextMenu(menuManager, nodesViewer); - // getSite().setSelectionProvider(nodesViewer); - } - - @PreDestroy - public void dispose() { - JcrUtils.logoutQuietly(userSession); - repositoryRegister.destroy(); - } - - public void refresh(Object obj) { - // Enable full refresh from a command when no element of the tree is - // selected - if (obj == null) { - Object[] elements = nodeContentProvider.getElements(null); - for (Object el : elements) { - if (el instanceof TreeParent) - JcrBrowserUtils.forceRefreshIfNeeded((TreeParent) el); - getNodeViewer().refresh(el); - } - } else - getNodeViewer().refresh(obj); - } - - /** - * To be overridden to adapt size of form and result frames. - */ - protected int[] getWeights() { - return new int[] { 70, 30 }; - } - - protected TreeViewer createNodeViewer(Composite parent, final ITreeContentProvider nodeContentProvider) { - - final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI); - - tmpNodeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - tmpNodeViewer.setContentProvider(nodeContentProvider); - tmpNodeViewer.setLabelProvider((IBaseLabelProvider) new NodeLabelProvider()); - tmpNodeViewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - if (!event.getSelection().isEmpty()) { - IStructuredSelection sel = (IStructuredSelection) event.getSelection(); - Object firstItem = sel.getFirstElement(); - if (firstItem instanceof SingleJcrNodeElem) - propertiesViewer.setInput(((SingleJcrNodeElem) firstItem).getNode()); - } else { - propertiesViewer.setInput(""); - } - } - }); - - resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay()); - if (keyring != null) - try { - ObservationManager observationManager = userSession.getWorkspace().getObservationManager(); - observationManager.addEventListener(resultsObserver, Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/", - true, null, null, false); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot register listeners", e); - } - - // tmpNodeViewer.addDoubleClickListener(new JcrDClickListener(tmpNodeViewer)); - return tmpNodeViewer; - } - - protected TableViewer createPropertiesViewer(Composite parent) { - propertiesViewer = new TableViewer(parent, SWT.NONE); - propertiesViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - propertiesViewer.getTable().setHeaderVisible(true); - propertiesViewer.setContentProvider(new PropertiesContentProvider()); - TableViewerColumn col = new TableViewerColumn(propertiesViewer, SWT.NONE); - col.getColumn().setText("Name"); - col.getColumn().setWidth(200); - col.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -6684361063107478595L; - - public String getText(Object element) { - try { - return ((Property) element).getName(); - } catch (RepositoryException e) { - throw new EclipseUiException("Unexpected exception in label provider", e); - } - } - }); - col = new TableViewerColumn(propertiesViewer, SWT.NONE); - col.getColumn().setText("Value"); - col.getColumn().setWidth(400); - col.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -8201994187693336657L; - - public String getText(Object element) { - try { - Property property = (Property) element; - if (property.getType() == PropertyType.BINARY) - return ""; - else if (property.isMultiple()) { - StringBuffer buf = new StringBuffer("["); - Value[] values = property.getValues(); - for (int i = 0; i < values.length; i++) { - if (i != 0) - buf.append(", "); - buf.append(values[i].getString()); - } - buf.append(']'); - return buf.toString(); - } else - return property.getValue().getString(); - } catch (RepositoryException e) { - throw new EclipseUiException("Unexpected exception in label provider", e); - } - } - }); - col = new TableViewerColumn(propertiesViewer, SWT.NONE); - col.getColumn().setText("Type"); - col.getColumn().setWidth(200); - col.setLabelProvider(new ColumnLabelProvider() { - private static final long serialVersionUID = -6009599998150286070L; - - public String getText(Object element) { - return JcrBrowserUtils.getPropertyTypeAsString((Property) element); - } - }); - propertiesViewer.setInput(""); - return propertiesViewer; - } - - protected TreeViewer getNodeViewer() { - return nodesViewer; - } - - /** - * Resets the tree content provider - * - * @param sortChildNodes if true the content provider will use a comparer to - * sort nodes that might slow down the display - */ - public void setSortChildNodes(boolean sortChildNodes) { - this.sortChildNodes = sortChildNodes; - ((NodeContentProvider) nodesViewer.getContentProvider()).setSortChildren(sortChildNodes); - nodesViewer.setInput(""); - } - - /** Notifies the current view that a node has been added */ - public void nodeAdded(TreeParent parentNode) { - // insure that Ui objects have been correctly created: - JcrBrowserUtils.forceRefreshIfNeeded(parentNode); - getNodeViewer().refresh(parentNode); - getNodeViewer().expandToLevel(parentNode, 1); - } - - /** Notifies the current view that a node has been removed */ - public void nodeRemoved(TreeParent parentNode) { - IStructuredSelection newSel = new StructuredSelection(parentNode); - getNodeViewer().setSelection(newSel, true); - // Force refresh - IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer().getSelection(); - getNodeViewer().refresh(tmpSel.getFirstElement()); - } - - class TreeObserver extends AsyncUiEventListener { - - public TreeObserver(Display display) { - super(display); - } - - @Override - protected Boolean willProcessInUiThread(List events) throws RepositoryException { - for (Event event : events) { - if (getLog().isTraceEnabled()) - getLog().debug("Received event " + event); - String path = event.getPath(); - int index = path.lastIndexOf('/'); - String propertyName = path.substring(index + 1); - if (getLog().isTraceEnabled()) - getLog().debug("Concerned property " + propertyName); - } - return false; - } - - protected void onEventInUiThread(List events) throws RepositoryException { - if (getLog().isTraceEnabled()) - getLog().trace("Refresh result list"); - nodesViewer.refresh(); - } - - } - - public boolean getSortChildNodes() { - return sortChildNodes; - } - - public void setFocus() { - getNodeViewer().getTree().setFocus(); - } - - /* DEPENDENCY INJECTION */ - // public void setRepositoryRegister(RepositoryRegister repositoryRegister) { - // this.repositoryRegister = repositoryRegister; - // } - - public void setKeyring(CryptoKeyring keyring) { - this.keyring = keyring; - } - - public void setRepositoryFactory(RepositoryFactory repositoryFactory) { - this.repositoryFactory = repositoryFactory; - } - - public void setNodeRepository(Repository nodeRepository) { - this.nodeRepository = nodeRepository; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrE4DClickListener.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrE4DClickListener.java deleted file mode 100644 index f4ee2e8..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrE4DClickListener.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.argeo.cms.e4.jcr; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.swt.CmsException; -import org.argeo.cms.ui.jcr.JcrDClickListener; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; -import org.eclipse.jface.viewers.TreeViewer; - -public class JcrE4DClickListener extends JcrDClickListener { - EPartService partService; - - public JcrE4DClickListener(TreeViewer nodeViewer, EPartService partService) { - super(nodeViewer); - this.partService = partService; - } - - @Override - protected void openNode(Node node) { - MPart part = partService.createPart(JcrNodeEditor.DESCRIPTOR_ID); - try { - part.setLabel(node.getName()); - part.getPersistedState().put("nodeWorkspace", node.getSession().getWorkspace().getName()); - part.getPersistedState().put("nodePath", node.getPath()); - } catch (RepositoryException e) { - throw new CmsException("Cannot open " + node, e); - } - - // the provided part is be shown - partService.showPart(part, PartState.ACTIVATE); - } - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrNodeEditor.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrNodeEditor.java deleted file mode 100644 index ae2b325..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrNodeEditor.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.argeo.cms.e4.jcr; - -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.jcr.Node; - -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; - -public class JcrNodeEditor { - final static String DESCRIPTOR_ID = "org.argeo.cms.e4.partdescriptor.nodeEditor"; - - @PostConstruct - public void createUi(Composite parent, MPart part, ESelectionService selectionService) { - parent.setLayout(new FillLayout()); - List selection = (List) selectionService.getSelection(); - Node node = ((SingleJcrNodeElem) selection.get(0)).getNode(); - GenericPropertyPage propertyPage = new GenericPropertyPage(node); - propertyPage.createFormContent(parent); - } - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/SimplePart.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/SimplePart.java deleted file mode 100644 index 17d8d2a..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/SimplePart.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.argeo.cms.e4.jcr; - -import javax.annotation.PostConstruct; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; - -public class SimplePart { - - @PostConstruct - void init(Composite parent) { - parent.setLayout(new GridLayout()); - Label label = new Label(parent, SWT.NONE); - label.setText("Hello e4 World"); - } - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/AddFolderNode.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/AddFolderNode.java deleted file mode 100644 index 09fa760..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/AddFolderNode.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.argeo.cms.e4.jcr.handlers; - -import java.util.List; - -import javax.inject.Named; -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; - -import org.argeo.cms.e4.jcr.JcrBrowserView; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.cms.ui.jcr.model.WorkspaceElem; -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.eclipse.ui.dialogs.SingleValue; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; - -/** - * Adds a node of type nt:folder, only on {@link SingleJcrNodeElem} and - * {@link WorkspaceElem} TreeObject types. - * - * This handler assumes that a selection provider is available and picks only - * first selected item. It is UI's job to enable the command only when the - * selection contains one and only one element. Thus no parameter is passed - * through the command. - */ -public class AddFolderNode { - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) { - List selection = (List) selectionService.getSelection(); - JcrBrowserView view = (JcrBrowserView) part.getObject(); - - if (selection != null && selection.size() == 1) { - TreeParent treeParentNode = null; - Node jcrParentNode = null; - Object obj = selection.get(0); - - if (obj instanceof SingleJcrNodeElem) { - treeParentNode = (TreeParent) obj; - jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode(); - } else if (obj instanceof WorkspaceElem) { - treeParentNode = (TreeParent) obj; - jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode(); - } else - return; - - String folderName = SingleValue.ask("Folder name", "Enter folder name"); - if (folderName != null) { - try { - jcrParentNode.addNode(folderName, NodeType.NT_FOLDER); - jcrParentNode.getSession().save(); - view.nodeAdded(treeParentNode); - } catch (RepositoryException e) { - ErrorFeedback.show("Cannot create folder " + folderName + " under " + treeParentNode, e); - } - } - } else { - // ErrorFeedback.show(WorkbenchUiPlugin - // .getMessage("errorUnvalidNtFolderNodeType")); - ErrorFeedback.show("Invalid NT folder node type"); - } - } - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java deleted file mode 100644 index dc47f6e..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java +++ /dev/null @@ -1,210 +0,0 @@ -package org.argeo.cms.e4.jcr.handlers; - -import java.net.URI; -import java.util.Hashtable; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.SimpleCredentials; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.ArgeoNames; -import org.argeo.cms.ArgeoTypes; -import org.argeo.cms.e4.jcr.JcrBrowserView; -import org.argeo.cms.jcr.CmsJcrUtils; -import org.argeo.cms.security.Keyring; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.jcr.JcrUtils; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.core.di.annotations.Optional; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Point; -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.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * Connect to a remote repository and, if successful publish it as an OSGi - * service. - */ -public class AddRemoteRepository { - - @Inject - private RepositoryFactory repositoryFactory; - @Inject - private Repository nodeRepository; - @Inject - @Optional - private Keyring keyring; - - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part) { - JcrBrowserView view = (JcrBrowserView) part.getObject(); - RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(Display.getDefault().getActiveShell()); - if (dlg.open() == Dialog.OK) { - view.refresh(null); - } - } - - // public void setRepositoryFactory(RepositoryFactory repositoryFactory) { - // this.repositoryFactory = repositoryFactory; - // } - // - // public void setKeyring(Keyring keyring) { - // this.keyring = keyring; - // } - // - // public void setNodeRepository(Repository nodeRepository) { - // this.nodeRepository = nodeRepository; - // } - - class RemoteRepositoryLoginDialog extends TitleAreaDialog { - private static final long serialVersionUID = 2234006887750103399L; - private Text name; - private Text uri; - private Text username; - private Text password; - private Button saveInKeyring; - - public RemoteRepositoryLoginDialog(Shell parentShell) { - super(parentShell); - } - - protected Point getInitialSize() { - return new Point(600, 400); - } - - 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, false)); - setMessage("Login to remote repository", IMessageProvider.NONE); - name = createLT(composite, "Name", "remoteRepository"); - uri = createLT(composite, "URI", "http://localhost:7070/jcr/node"); - username = createLT(composite, "User", ""); - password = createLP(composite, "Password"); - - saveInKeyring = createLC(composite, "Remember password", false); - parent.pack(); - return composite; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - super.createButtonsForButtonBar(parent); - Button test = createButton(parent, 2, "Test", false); - test.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -1829962269440419560L; - - public void widgetSelected(SelectionEvent arg0) { - testConnection(); - } - }); - } - - void testConnection() { - Session session = null; - try { - URI checkedUri = new URI(uri.getText()); - String checkedUriStr = checkedUri.toString(); - - Hashtable params = new Hashtable(); - params.put(CmsConstants.LABELED_URI, checkedUriStr); - Repository repository = repositoryFactory.getRepository(params); - if (username.getText().trim().equals("")) {// anonymous - // FIXME make it more generic - session = repository.login(CmsConstants.SYS_WORKSPACE); - } else { - // FIXME use getTextChars() when upgrading to 3.7 - // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412 - char[] pwd = password.getText().toCharArray(); - SimpleCredentials sc = new SimpleCredentials(username.getText(), pwd); - session = repository.login(sc, "main"); - MessageDialog.openInformation(getParentShell(), "Success", - "Connection to '" + uri.getText() + "' successful"); - } - } catch (Exception e) { - ErrorFeedback.show("Connection test failed for " + uri.getText(), e); - } finally { - JcrUtils.logoutQuietly(session); - } - } - - @Override - protected void okPressed() { - Session nodeSession = null; - try { - nodeSession = nodeRepository.login(); - Node home = CmsJcrUtils.getUserHome(nodeSession); - - Node remote = home.hasNode(ArgeoNames.ARGEO_REMOTE) ? home.getNode(ArgeoNames.ARGEO_REMOTE) - : home.addNode(ArgeoNames.ARGEO_REMOTE); - if (remote.hasNode(name.getText())) - throw new EclipseUiException("There is already a remote repository named " + name.getText()); - Node remoteRepository = remote.addNode(name.getText(), ArgeoTypes.ARGEO_REMOTE_REPOSITORY); - remoteRepository.setProperty(ArgeoNames.ARGEO_URI, uri.getText()); - remoteRepository.setProperty(ArgeoNames.ARGEO_USER_ID, username.getText()); - nodeSession.save(); - if (saveInKeyring.getSelection()) { - String pwdPath = remoteRepository.getPath() + '/' + ArgeoNames.ARGEO_PASSWORD; - keyring.set(pwdPath, password.getText().toCharArray()); - } - nodeSession.save(); - MessageDialog.openInformation(getParentShell(), "Repository Added", - "Remote repository '" + username.getText() + "@" + uri.getText() + "' added"); - - super.okPressed(); - } catch (Exception e) { - ErrorFeedback.show("Cannot add remote repository", e); - } finally { - JcrUtils.logoutQuietly(nodeSession); - } - } - - /** Creates label and text. */ - protected Text createLT(Composite parent, String label, String initial) { - new Label(parent, SWT.NONE).setText(label); - Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - text.setText(initial); - return text; - } - - /** Creates label and check. */ - protected Button createLC(Composite parent, String label, Boolean initial) { - new Label(parent, SWT.NONE).setText(label); - Button check = new Button(parent, SWT.CHECK); - check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - check.setSelection(initial); - return check; - } - - protected Text createLP(Composite parent, String label) { - new Label(parent, SWT.NONE).setText(label); - Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER | SWT.PASSWORD); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - return text; - } - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/DeleteNodes.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/DeleteNodes.java deleted file mode 100644 index b8de06b..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/DeleteNodes.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.argeo.cms.e4.jcr.handlers; - -import java.util.List; - -import javax.inject.Named; -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.e4.jcr.JcrBrowserView; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.cms.ui.jcr.model.WorkspaceElem; -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.widgets.Display; - -/** - * Delete the selected nodes: both in the JCR repository and in the UI view. - * Warning no check is done, except implementation dependent native checks, - * handle with care. - * - * This handler is still 'hard linked' to a GenericJcrBrowser view to enable - * correct tree refresh when a node is added. This must be corrected in future - * versions. - */ -public class DeleteNodes { - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) { - List selection = (List) selectionService.getSelection(); - if (selection == null) - return; - - JcrBrowserView view = (JcrBrowserView) part.getObject(); - - // confirmation - StringBuffer buf = new StringBuffer(""); - for (Object o : selection) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) o; - buf.append(sjn.getName()).append(' '); - } - Boolean doRemove = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Confirm deletion", - "Do you want to delete " + buf + "?"); - - // operation - if (doRemove) { - SingleJcrNodeElem ancestor = null; - WorkspaceElem rootAncestor = null; - try { - for (Object obj : selection) { - if (obj instanceof SingleJcrNodeElem) { - // Cache objects - SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj; - TreeParent tp = (TreeParent) sjn.getParent(); - Node node = sjn.getNode(); - - // Jcr Remove - node.remove(); - node.getSession().save(); - // UI remove - tp.removeChild(sjn); - - // Check if the parent is the root node - if (tp instanceof WorkspaceElem) - rootAncestor = (WorkspaceElem) tp; - else - ancestor = getOlder(ancestor, (SingleJcrNodeElem) tp); - } - } - if (rootAncestor != null) - view.nodeRemoved(rootAncestor); - else if (ancestor != null) - view.nodeRemoved(ancestor); - } catch (Exception e) { - ErrorFeedback.show("Cannot delete selected node ", e); - } - } - } - - private SingleJcrNodeElem getOlder(SingleJcrNodeElem A, SingleJcrNodeElem B) { - try { - if (A == null) - return B == null ? null : B; - // Todo enhanced this method - else - return A.getNode().getDepth() <= B.getNode().getDepth() ? A : B; - } catch (RepositoryException re) { - throw new EclipseUiException("Cannot find ancestor", re); - } - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/Refresh.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/Refresh.java deleted file mode 100644 index 036e70a..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/Refresh.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.argeo.cms.e4.jcr.handlers; - -import java.util.List; - -import javax.inject.Named; - -import org.argeo.cms.e4.jcr.JcrBrowserView; -import org.argeo.cms.ui.jcr.JcrBrowserUtils; -import org.argeo.cms.ux.widgets.TreeParent; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; - -/** - * Force the selected objects of the active view to be refreshed doing the - * following: - *
    - *
  1. The model objects are recomputed
  2. - *
  3. the view is refreshed
  4. - *
- */ -public class Refresh { - - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, EPartService partService, - ESelectionService selectionService) { - - JcrBrowserView view = (JcrBrowserView) part.getObject(); - List selection = (List) selectionService.getSelection(); - - if (selection != null && !selection.isEmpty()) { - for (Object obj : selection) - if (obj instanceof TreeParent) { - TreeParent tp = (TreeParent) obj; - JcrBrowserUtils.forceRefreshIfNeeded(tp); - view.refresh(obj); - } - } else if (view instanceof JcrBrowserView) - view.refresh(null); // force full refresh - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/RenameNode.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/RenameNode.java deleted file mode 100644 index 97674ab..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/RenameNode.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.argeo.cms.e4.jcr.handlers; - -import java.util.List; - -import javax.inject.Named; -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.cms.e4.jcr.JcrBrowserView; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.dialogs.SingleValue; -import org.argeo.jcr.JcrUtils; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; - -/** - * Canonically call JCR Session#move(String, String) on the first element - * returned by HandlerUtil#getActiveWorkbenchWindow() - * (...getActivePage().getSelection()), if it is a {@link SingleJcrNodeElem}. - * The user must then fill a new name in and confirm - */ -public class RenameNode { - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, EPartService partService, - ESelectionService selectionService) { - List selection = (List) selectionService.getSelection(); - if (selection == null || selection.size() != 1) - return; - JcrBrowserView view = (JcrBrowserView) part.getObject(); - - Object element = selection.get(0); - if (element instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; - Node node = sjn.getNode(); - Session session = null; - String newName = null; - String oldPath = null; - try { - newName = SingleValue.ask("New node name", "Please provide a new name for [" + node.getName() + "]"); - // TODO sanity check and user feedback - newName = JcrUtils.replaceInvalidChars(newName); - oldPath = node.getPath(); - session = node.getSession(); - session.move(oldPath, JcrUtils.parentPath(oldPath) + "/" + newName); - session.save(); - - // Manually refresh the browser view. Must be enhanced - view.refresh(sjn); - } catch (RepositoryException e) { - throw new EclipseUiException("Unable to rename " + node + " to " + newName, e); - } - } - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/package-info.java deleted file mode 100644 index 4e075e2..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/handlers/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** JCR browser handlers. */ -package org.argeo.cms.e4.jcr.handlers; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/package-info.java deleted file mode 100644 index 3e92fb0..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** JCR browser perspective. */ -package org.argeo.cms.e4.jcr; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java deleted file mode 100644 index 137f762..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java +++ /dev/null @@ -1,287 +0,0 @@ -package org.argeo.cms.e4.users; - -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; - -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.ui.eclipse.forms.AbstractFormPart; -import org.argeo.cms.ui.eclipse.forms.IManagedForm; -import org.argeo.cms.ui.eclipse.forms.ManagedForm; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.util.naming.LdapAttrs; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.e4.ui.di.Persist; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -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.Text; -import org.osgi.service.useradmin.Authorization; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Editor for a user, might be a user or a group. */ -public abstract class AbstractRoleEditor { - - // public final static String USER_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID + - // ".userEditor"; - // public final static String GROUP_EDITOR_ID = WorkbenchUiPlugin.PLUGIN_ID + - // ".groupEditor"; - - /* DEPENDENCY INJECTION */ - @Inject - protected UserAdminWrapper userAdminWrapper; - - @Inject - private MPart mPart; - - // @Inject - // Composite parent; - - private UserAdmin userAdmin; - - // Context - private User user; - private String username; - - private NameChangeListener listener; - - private ManagedForm managedForm; - - // public void init(IEditorSite site, IEditorInput input) throws - // PartInitException { - @PostConstruct - public void init(Composite parent) { - this.userAdmin = userAdminWrapper.getUserAdmin(); - username = mPart.getPersistedState().get(LdapAttrs.uid.name()); - user = (User) userAdmin.getRole(username); - - listener = new NameChangeListener(Display.getCurrent()); - userAdminWrapper.addListener(listener); - updateEditorTitle(null); - - managedForm = new ManagedForm(parent) { - - @Override - public void staleStateChanged() { - refresh(); - } - }; - ScrolledComposite scrolled = managedForm.getForm(); - Composite body = new Composite(scrolled, SWT.NONE); - scrolled.setContent(body); - createUi(body); - managedForm.refresh(); - } - - abstract void createUi(Composite parent); - - /** - * returns the list of all authorizations for the given user or of the current - * displayed user if parameter is null - */ - protected List getFlatGroups(User aUser) { - Authorization currAuth; - if (aUser == null) - currAuth = userAdmin.getAuthorization(this.user); - else - currAuth = userAdmin.getAuthorization(aUser); - - String[] roles = currAuth.getRoles(); - - List groups = new ArrayList(); - for (String roleStr : roles) { - User currRole = (User) userAdmin.getRole(roleStr); - if (currRole != null && !groups.contains(currRole)) - groups.add(currRole); - } - return groups; - } - - protected IManagedForm getManagedForm() { - return managedForm; - } - - /** Exposes the user (or group) that is displayed by the current editor */ - protected User getDisplayedUser() { - return user; - } - - private void setDisplayedUser(User user) { - this.user = user; - } - - void updateEditorTitle(String title) { - if (title == null) { - String commonName = UserAdminUtils.getProperty(user, LdapAttrs.cn.name()); - title = "".equals(commonName) ? user.getName() : commonName; - } - setPartName(title); - } - - protected void setPartName(String name) { - mPart.setLabel(name); - } - - // protected void addPages() { - // try { - // if (user.getType() == Role.GROUP) - // addPage(new GroupMainPage(this, userAdminWrapper, repository, nodeInstance)); - // else - // addPage(new UserMainPage(this, userAdminWrapper)); - // } catch (Exception e) { - // throw new CmsException("Cannot add pages", e); - // } - // } - - @Persist - public void doSave(IProgressMonitor monitor) { - userAdminWrapper.beginTransactionIfNeeded(); - commitPages(true); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - // firePropertyChange(PROP_DIRTY); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, user)); - } - - protected void commitPages(boolean b) { - managedForm.commit(b); - } - - @PreDestroy - public void dispose() { - userAdminWrapper.removeListener(listener); - managedForm.dispose(); - } - - // CONTROLERS FOR THIS EDITOR AND ITS PAGES - - class NameChangeListener extends UiUserAdminListener { - public NameChangeListener(Display display) { - super(display); - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - Role changedRole = event.getRole(); - if (changedRole == null || changedRole.equals(user)) { - updateEditorTitle(null); - User reloadedUser = (User) userAdminWrapper.getUserAdmin().getRole(user.getName()); - setDisplayedUser(reloadedUser); - } - } - } - - class MainInfoListener extends UiUserAdminListener { - private final AbstractFormPart part; - - public MainInfoListener(Display display, AbstractFormPart part) { - super(display); - this.part = part; - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - // Rollback - if (event.getRole() == null) - part.markStale(); - } - } - - class GroupChangeListener extends UiUserAdminListener { - private final AbstractFormPart part; - - public GroupChangeListener(Display display, AbstractFormPart part) { - super(display); - this.part = part; - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - // always mark as stale - part.markStale(); - } - } - - /** Registers a listener that will notify this part */ - class FormPartML implements ModifyListener { - private static final long serialVersionUID = 6299808129505381333L; - private AbstractFormPart formPart; - - public FormPartML(AbstractFormPart generalPart) { - this.formPart = generalPart; - } - - public void modifyText(ModifyEvent e) { - // Discard event when the control does not have the focus, typically - // to avoid all editors being marked as dirty during a Rollback - if (((Control) e.widget).isFocusControl()) - formPart.markDirty(); - } - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } - - /** Creates label and multiline text. */ - Text createLMT(Composite parent, String label, String value) { - Label lbl = new Label(parent, SWT.NONE); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); - Text text = new Text(parent, SWT.NONE); - text.setText(value); - text.setLayoutData(new GridData(SWT.LEAD, SWT.FILL, true, true)); - return text; - } - - /** Creates label and password. */ - Text createLP(Composite parent, String label, String value) { - Label lbl = new Label(parent, SWT.NONE); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); - Text text = new Text(parent, SWT.PASSWORD | SWT.BORDER); - text.setText(value); - text.setLayoutData(new GridData(SWT.LEAD, SWT.FILL, true, false)); - return text; - } - - /** Creates label and text. */ - Text createLT(Composite parent, String label, String value) { - Label lbl = new Label(parent, SWT.NONE); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); - lbl.setFont(EclipseUiUtils.getBoldFont(parent)); - Text text = new Text(parent, SWT.BORDER); - text.setText(value); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT); - return text; - } - - Text createReadOnlyLT(Composite parent, String label, String value) { - Label lbl = new Label(parent, SWT.NONE); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); - lbl.setFont(EclipseUiUtils.getBoldFont(parent)); - Text text = new Text(parent, SWT.NONE); - text.setText(value); - text.setLayoutData(new GridData(SWT.LEAD, SWT.FILL, true, false)); - text.setEditable(false); - // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT); - return text; - } - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/CmsWorkbenchStyles.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/CmsWorkbenchStyles.java deleted file mode 100644 index 07df312..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/CmsWorkbenchStyles.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.argeo.cms.e4.users; - -/** Centralize the declaration of Workbench specific CSS Styles */ -interface CmsWorkbenchStyles { - - // Specific People layouting - String WORKBENCH_FORM_TEXT = "workbench_form_text"; -} 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 deleted file mode 100644 index d54f8bc..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupEditor.java +++ /dev/null @@ -1,566 +0,0 @@ -package org.argeo.cms.e4.users; - -import static org.argeo.api.cms.CmsContext.WORKGROUP; -import static org.argeo.cms.auth.UserAdminUtils.setProperty; -import static org.argeo.util.naming.LdapAttrs.businessCategory; -import static org.argeo.util.naming.LdapAttrs.description; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.annotation.PreDestroy; -import javax.inject.Inject; -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.api.cms.CmsContext; -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.e4.users.providers.CommonNameLP; -import org.argeo.cms.e4.users.providers.MailLP; -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.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; -import org.argeo.util.transaction.WorkTransaction; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.ViewerDropAdapter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.dnd.TransferData; -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.Label; -import org.eclipse.swt.widgets.Link; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -//import org.eclipse.ui.forms.AbstractFormPart; -//import org.eclipse.ui.forms.IManagedForm; -//import org.eclipse.ui.forms.SectionPart; -//import org.eclipse.ui.forms.editor.FormEditor; -//import org.eclipse.ui.forms.editor.FormPage; -//import org.eclipse.ui.forms.widgets.FormToolkit; -//import org.eclipse.ui.forms.widgets.ScrolledForm; -//import org.eclipse.ui.forms.widgets.Section; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Display/edit main properties of a given group */ -public class GroupEditor extends AbstractRoleEditor { - // final static String ID = "GroupEditor.mainPage"; - - @Inject - private EPartService partService; - - // private final UserEditor editor; - @Inject - private Repository repository; - @Inject - private CmsContext nodeInstance; - // private final UserAdminWrapper userAdminWrapper; - private Session groupsSession; - - // public GroupMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper, - // Repository repository, - // NodeInstance nodeInstance) { - // super(editor, ID, "Main"); - // try { - // session = repository.login(); - // } catch (RepositoryException e) { - // throw new CmsException("Cannot retrieve session of in MainGroupPage - // constructor", e); - // } - // this.editor = (UserEditor) editor; - // this.userAdminWrapper = userAdminWrapper; - // this.nodeInstance = nodeInstance; - // } - - // protected void createFormContent(final IManagedForm mf) { - // ScrolledForm form = mf.getForm(); - // Composite body = form.getBody(); - // GridLayout mainLayout = new GridLayout(); - // body.setLayout(mainLayout); - // Group group = (Group) editor.getDisplayedUser(); - // appendOverviewPart(body, group); - // appendMembersPart(body, group); - // } - - @Override - protected void createUi(Composite parent) { - try { - groupsSession = repository.login(CmsConstants.SRV_WORKSPACE); - } catch (RepositoryException e) { - throw new JcrException("Cannot retrieve session", e); - } - // ScrolledForm form = mf.getForm(); - // Composite body = form.getBody(); - // Composite body = new Composite(parent, SWT.NONE); - Composite body = parent; - GridLayout mainLayout = new GridLayout(); - body.setLayout(mainLayout); - Group group = (Group) getDisplayedUser(); - appendOverviewPart(body, group); - appendMembersPart(body, group); - } - - @PreDestroy - public void dispose() { - JcrUtils.logoutQuietly(groupsSession); - super.dispose(); - } - - /** Creates the general section */ - protected void appendOverviewPart(final Composite parent, final Group group) { - Composite body = new Composite(parent, SWT.NONE); - // GridLayout layout = new GridLayout(5, false); - GridLayout layout = new GridLayout(2, false); - body.setLayout(layout); - body.setLayoutData(CmsSwtUtils.fillWidth()); - - String cn = UserAdminUtils.getProperty(group, LdapAttrs.cn.name()); - createReadOnlyLT(body, "Name", cn); - createReadOnlyLT(body, "DN", group.getName()); - createReadOnlyLT(body, "Domain", UserAdminUtils.getDomainName(group)); - - // Description - Label descLbl = new Label(body, SWT.LEAD); - descLbl.setFont(EclipseUiUtils.getBoldFont(body)); - descLbl.setText("Description"); - descLbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, true, false, 2, 1)); - final Text descTxt = new Text(body, SWT.LEAD | SWT.MULTI | SWT.WRAP | SWT.BORDER); - GridData gd = EclipseUiUtils.fillWidth(); - gd.heightHint = 50; - gd.horizontalSpan = 2; - descTxt.setLayoutData(gd); - - // Mark as workgroup - Link markAsWorkgroupLk = new Link(body, SWT.NONE); - markAsWorkgroupLk.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); - - // create form part (controller) - final AbstractFormPart part = new AbstractFormPart() { - - private MainInfoListener listener; - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = new MainInfoListener(parent.getDisplay(), this); - userAdminWrapper.addListener(listener); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - public void commit(boolean onSave) { - // group.getProperties().put(LdapAttrs.description.name(), descTxt.getText()); - setProperty(group, description, descTxt.getText()); - super.commit(onSave); - } - - @Override - public void refresh() { - // dnTxt.setText(group.getName()); - // cnTxt.setText(UserAdminUtils.getProperty(group, LdapAttrs.cn.name())); - descTxt.setText(UserAdminUtils.getProperty(group, LdapAttrs.description.name())); - Node workgroupHome = CmsJcrUtils.getGroupHome(groupsSession, cn); - if (workgroupHome == null) - markAsWorkgroupLk.setText("
Mark as workgroup"); - else - markAsWorkgroupLk.setText("Configured as workgroup"); - parent.layout(true, true); - super.refresh(); - } - }; - - markAsWorkgroupLk.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -6439340898096365078L; - - @Override - public void widgetSelected(SelectionEvent e) { - - boolean confirmed = MessageDialog.openConfirm(parent.getShell(), "Mark as workgroup", - "Are you sure you want to mark " + cn + " as being a workgroup? "); - if (confirmed) { - Node workgroupHome = CmsJcrUtils.getGroupHome(groupsSession, cn); - if (workgroupHome != null) - return; // already marked as workgroup, do nothing - else { - // improve transaction management - userAdminWrapper.beginTransactionIfNeeded(); - nodeInstance.createWorkgroup(group.getName()); - setProperty(group, businessCategory, WORKGROUP); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group)); - part.refresh(); - } - } - } - }); - - ModifyListener defaultListener = new FormPartML(part); - descTxt.addModifyListener(defaultListener); - getManagedForm().addPart(part); - } - - /** Filtered table with members. Has drag and drop ability */ - protected void appendMembersPart(Composite parent, Group group) { - // Section section = tk.createSection(parent, Section.TITLE_BAR); - // section.setText("Members"); - // section.setLayoutData(EclipseUiUtils.fillAll()); - - Composite body = new Composite(parent, SWT.BORDER); - body.setLayout(new GridLayout()); - // section.setClient(body); - body.setLayoutData(EclipseUiUtils.fillAll()); - - // Define the displayed columns - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "Mail", 150)); - // columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", - // 240)); - - // Create and configure the table - LdifUsersTable userViewerCmp = new MyUserTableViewer(body, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, - userAdminWrapper.getUserAdmin()); - - userViewerCmp.setColumnDefinitions(columnDefs); - userViewerCmp.populate(true, false); - userViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); - - // Controllers - TableViewer userViewer = userViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService)); - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - userViewer.addDropSupport(operations, tt, - new GroupDropListener(userAdminWrapper, userViewerCmp, (Group) getDisplayedUser())); - - AbstractFormPart part = new GroupMembersPart(userViewerCmp); - getManagedForm().addPart(part); - - // remove button - // addRemoveAbility(toolBarManager, userViewerCmp.getTableViewer(), group); - Action action = new RemoveMembershipAction(userViewer, group, "Remove selected items from this group", - SecurityAdminImages.ICON_REMOVE_DESC); - - ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); - ToolBar toolBar = toolBarManager.createControl(body); - toolBar.setLayoutData(CmsSwtUtils.fillWidth()); - - toolBarManager.add(action); - toolBarManager.update(true); - - } - - // private LdifUsersTable createMemberPart(Composite parent, Group group) { - // - // // Define the displayed columns - // List columnDefs = new ArrayList(); - // columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); - // columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150)); - // columnDefs.add(new ColumnDefinition(new MailLP(), "Mail", 150)); - // // columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished - // Name", - // // 240)); - // - // // Create and configure the table - // LdifUsersTable userViewerCmp = new MyUserTableViewer(parent, SWT.MULTI | - // SWT.H_SCROLL | SWT.V_SCROLL, - // userAdminWrapper.getUserAdmin()); - // - // userViewerCmp.setColumnDefinitions(columnDefs); - // userViewerCmp.populate(true, false); - // userViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); - // - // // Controllers - // TableViewer userViewer = userViewerCmp.getTableViewer(); - // userViewer.addDoubleClickListener(new - // UserTableDefaultDClickListener(partService)); - // int operations = DND.DROP_COPY | DND.DROP_MOVE; - // Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - // userViewer.addDropSupport(operations, tt, - // new GroupDropListener(userAdminWrapper, userViewerCmp, (Group) - // getDisplayedUser())); - // - // // userViewerCmp.refresh(); - // return userViewerCmp; - // } - - // Local viewers - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 8467999509931900367L; - - private final UserFilter userFilter; - - public MyUserTableViewer(Composite parent, int style, UserAdmin userAdmin) { - super(parent, style, true); - userFilter = new UserFilter(); - - } - - @Override - protected List listFilteredElements(String filter) { - // reload user and set it in the editor - Group group = (Group) getDisplayedUser(); - Role[] roles = group.getMembers(); - List users = new ArrayList(); - userFilter.setSearchText(filter); - // userFilter.setShowSystemRole(true); - for (Role role : roles) - // if (role.getType() == Role.GROUP) - if (userFilter.select(null, null, role)) - users.add((User) role); - return users; - } - } - - // private void addRemoveAbility(ToolBarManager toolBarManager, TableViewer - // userViewer, Group group) { - // // Section section = sectionPart.getSection(); - // // ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); - // // ToolBar toolbar = toolBarManager.createControl(parent); - // // ToolBar toolbar = toolBarManager.getControl(); - // // final Cursor handCursor = new Cursor(toolbar.getDisplay(), - // SWT.CURSOR_HAND); - // // toolbar.setCursor(handCursor); - // // toolbar.addDisposeListener(new DisposeListener() { - // // private static final long serialVersionUID = 3882131405820522925L; - // // - // // public void widgetDisposed(DisposeEvent e) { - // // if ((handCursor != null) && (handCursor.isDisposed() == false)) { - // // handCursor.dispose(); - // // } - // // } - // // }); - // - // Action action = new RemoveMembershipAction(userViewer, group, "Remove - // selected items from this group", - // SecurityAdminImages.ICON_REMOVE_DESC); - // toolBarManager.add(action); - // toolBarManager.update(true); - // // section.setTextClient(toolbar); - // } - - private class RemoveMembershipAction extends Action { - private static final long serialVersionUID = -1337713097184522588L; - - private final TableViewer userViewer; - private final Group group; - - RemoveMembershipAction(TableViewer userViewer, Group group, String name, ImageDescriptor img) { - super(name, img); - this.userViewer = userViewer; - this.group = group; - } - - @Override - public void run() { - ISelection selection = userViewer.getSelection(); - if (selection.isEmpty()) - return; - - @SuppressWarnings("unchecked") - Iterator it = ((IStructuredSelection) selection).iterator(); - List users = new ArrayList(); - while (it.hasNext()) { - User currUser = it.next(); - users.add(currUser); - } - - userAdminWrapper.beginTransactionIfNeeded(); - for (User user : users) { - group.removeMember(user); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group)); - } - } - - // LOCAL CONTROLLERS - private class GroupMembersPart extends AbstractFormPart { - private final LdifUsersTable userViewer; - // private final Group group; - - private GroupChangeListener listener; - - public GroupMembersPart(LdifUsersTable userViewer) { - // super(section); - this.userViewer = userViewer; - // this.group = group; - } - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = new GroupChangeListener(userViewer.getDisplay(), GroupMembersPart.this); - userAdminWrapper.addListener(listener); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @Override - public void refresh() { - userViewer.refresh(); - super.refresh(); - } - } - - /** - * Defines this table as being a potential target to add group membership - * (roles) to this group - */ - private class GroupDropListener extends ViewerDropAdapter { - private static final long serialVersionUID = 2893468717831451621L; - - private final UserAdminWrapper userAdminWrapper; - // private final LdifUsersTable myUserViewerCmp; - private final Group myGroup; - - public GroupDropListener(UserAdminWrapper userAdminWrapper, LdifUsersTable userTableViewerCmp, Group group) { - super(userTableViewerCmp.getTableViewer()); - this.userAdminWrapper = userAdminWrapper; - this.myGroup = group; - // this.myUserViewerCmp = userTableViewerCmp; - } - - @Override - public boolean validateDrop(Object target, int operation, TransferData transferType) { - // Target is always OK in a list only view - // TODO check if not a string - boolean validDrop = true; - return validDrop; - } - - @Override - public void drop(DropTargetEvent event) { - // TODO Is there an opportunity to perform the check before? - String newUserName = (String) event.data; - UserAdmin myUserAdmin = userAdminWrapper.getUserAdmin(); - Role role = myUserAdmin.getRole(newUserName); - if (role.getType() == Role.GROUP) { - Group newGroup = (Group) role; - Shell shell = getViewer().getControl().getShell(); - // Sanity checks - if (myGroup == newGroup) { // Equality - MessageDialog.openError(shell, "Forbidden addition ", "A group cannot be a member of itself."); - return; - } - - // Cycle - String myName = myGroup.getName(); - List myMemberships = getFlatGroups(myGroup); - if (myMemberships.contains(newGroup)) { - MessageDialog.openError(shell, "Forbidden addition: cycle", - "Cannot add " + newUserName + " to group " + myName + ". This would create a cycle"); - return; - } - - // Already member - List newGroupMemberships = getFlatGroups(newGroup); - if (newGroupMemberships.contains(myGroup)) { - MessageDialog.openError(shell, "Forbidden addition", - "Cannot add " + newUserName + " to group " + myName + ", this membership already exists"); - return; - } - userAdminWrapper.beginTransactionIfNeeded(); - myGroup.addMember(newGroup); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, myGroup)); - } else if (role.getType() == Role.USER) { - // TODO check if the group is already member of this group - WorkTransaction transaction = userAdminWrapper.beginTransactionIfNeeded(); - User user = (User) role; - myGroup.addMember(user); - if (UserAdminWrapper.COMMIT_ON_SAVE) - try { - transaction.commit(); - } catch (Exception e) { - throw new IllegalStateException( - "Cannot commit transaction " + "after user group membership update", e); - } - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, myGroup)); - } - super.drop(event); - } - - @Override - public boolean performDrop(Object data) { - // myUserViewerCmp.refresh(); - return true; - } - } - - // LOCAL HELPERS - // private Composite addSection(FormToolkit tk, Composite parent) { - // Section section = tk.createSection(parent, SWT.NO_FOCUS); - // section.setLayoutData(EclipseUiUtils.fillWidth()); - // Composite body = tk.createComposite(section, SWT.WRAP); - // body.setLayoutData(EclipseUiUtils.fillAll()); - // section.setClient(body); - // return body; - // } - - /** Creates label and text. */ - // private Text createLT(Composite parent, String label, String value) { - // FormToolkit toolkit = getManagedForm().getToolkit(); - // Label lbl = toolkit.createLabel(parent, label); - // lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); - // lbl.setFont(EclipseUiUtils.getBoldFont(parent)); - // Text text = toolkit.createText(parent, value, SWT.BORDER); - // text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT); - // return text; - // } - // - // Text createReadOnlyLT(Composite parent, String label, String value) { - // FormToolkit toolkit = getManagedForm().getToolkit(); - // Label lbl = toolkit.createLabel(parent, label); - // lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); - // lbl.setFont(EclipseUiUtils.getBoldFont(parent)); - // Text text = toolkit.createText(parent, value, SWT.NONE); - // text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - // text.setEditable(false); - // CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT); - // return text; - // } - -} 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 deleted file mode 100644 index 73e4f5d..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/GroupsView.java +++ /dev/null @@ -1,251 +0,0 @@ -package org.argeo.cms.e4.users; - -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.api.cms.CmsLog; -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.e4.users.providers.CommonNameLP; -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.ui.workbench.WorkbenchUiPlugin; -//import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener; -//import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper; -//import org.argeo.cms.ui.workbench.internal.useradmin.providers.CommonNameLP; -//import org.argeo.cms.ui.workbench.internal.useradmin.providers.DomainNameLP; -//import org.argeo.cms.ui.workbench.internal.useradmin.providers.RoleIconLP; -//import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserDragListener; -//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; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -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.dnd.DND; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -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.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -//import org.eclipse.ui.part.ViewPart; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** List all groups with filter */ -public class GroupsView { - private final static CmsLog log = CmsLog.getLog(GroupsView.class); - // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".groupsView"; - - @Inject - private EPartService partService; - @Inject - private UserAdminWrapper userAdminWrapper; - - // UI Objects - private LdifUsersTable groupTableViewerCmp; - private TableViewer userViewer; - private List columnDefs = new ArrayList(); - - private UserAdminListener listener; - - @PostConstruct - public void createPartControl(Composite parent, ESelectionService selectionService) { - parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - // boolean isAdmin = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); - - // Define the displayed columns - columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 19)); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 100)); - // Only show technical DN to admin - // if (isAdmin) - // columnDefs.add(new ColumnDefinition(new UserNameLP(), - // "Distinguished Name", 300)); - - // Create and configure the table - groupTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - - groupTableViewerCmp.setColumnDefinitions(columnDefs); - // if (isAdmin) - // groupTableViewerCmp.populateWithStaticFilters(false, false); - // else - groupTableViewerCmp.populate(true, false); - - groupTableViewerCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - // Links - userViewer = groupTableViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService)); - // getViewSite().setSelectionProvider(userViewer); - userViewer.addSelectionChangedListener(new ISelectionChangedListener() { - - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - selectionService.setSelection(selection.toList()); - } - }); - - // Really? - groupTableViewerCmp.refresh(); - - // Drag and drop - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - userViewer.addDragSupport(operations, tt, new UserDragListener(userViewer)); - - // // Register a useradmin listener - // listener = new UserAdminListener() { - // @Override - // public void roleChanged(UserAdminEvent event) { - // if (userViewer != null && !userViewer.getTable().isDisposed()) - // refresh(); - // } - // }; - // userAdminWrapper.addListener(listener); - // } - - // Register a useradmin listener - listener = new MyUiUAListener(parent.getDisplay()); - userAdminWrapper.addListener(listener); - } - - private class MyUiUAListener extends UiUserAdminListener { - public MyUiUAListener(Display display) { - super(display); - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - if (userViewer != null && !userViewer.getTable().isDisposed()) - refresh(); - } - } - - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 8467999509931900367L; - - private boolean showSystemRoles = true; - - private final String[] knownProps = { LdapAttrs.uid.name(), LdapAttrs.cn.name(), LdapAttrs.DN }; - - public MyUserTableViewer(Composite parent, int style) { - super(parent, style); - showSystemRoles = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN); - } - - protected void populateStaticFilters(Composite staticFilterCmp) { - staticFilterCmp.setLayout(new GridLayout()); - final Button showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); - showSystemRoleBtn.setText("Show system roles"); - showSystemRoles = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN); - showSystemRoleBtn.setSelection(showSystemRoles); - - showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -7033424592697691676L; - - @Override - public void widgetSelected(SelectionEvent e) { - showSystemRoles = showSystemRoleBtn.getSelection(); - refresh(); - } - - }); - } - - @Override - protected List listFilteredElements(String filter) { - Role[] roles; - try { - StringBuilder builder = new StringBuilder(); - StringBuilder tmpBuilder = new StringBuilder(); - if (EclipseUiUtils.notEmpty(filter)) - for (String prop : knownProps) { - tmpBuilder.append("("); - tmpBuilder.append(prop); - tmpBuilder.append("=*"); - tmpBuilder.append(filter); - tmpBuilder.append("*)"); - } - if (tmpBuilder.length() > 1) { - builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") - .append(LdapObjs.groupOfNames.name()).append(")"); - // hide tokens - builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.TOKENS_BASEDN) - .append("))"); - - if (!showSystemRoles) - builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.SYSTEM_ROLES_BASEDN) - .append("))"); - builder.append("(|"); - builder.append(tmpBuilder.toString()); - builder.append("))"); - } else { - if (!showSystemRoles) - builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") - .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*") - .append(CmsConstants.SYSTEM_ROLES_BASEDN).append("))(!(").append(LdapAttrs.DN).append("=*") - .append(CmsConstants.TOKENS_BASEDN).append(")))"); - else - builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") - .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*") - .append(CmsConstants.TOKENS_BASEDN).append(")))"); - - } - roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString()); - } catch (InvalidSyntaxException e) { - throw new CmsException("Unable to get roles with filter: " + filter, e); - } - List users = new ArrayList(); - for (Role role : roles) - if (!users.contains(role)) - users.add((User) role); - else - log.warn("Duplicated role: " + role); - - return users; - } - } - - public void refresh() { - groupTableViewerCmp.refresh(); - } - - @PreDestroy - public void dispose() { - userAdminWrapper.removeListener(listener); - } - - @Focus - public void setFocus() { - groupTableViewerCmp.setFocus(); - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/SecurityAdminImages.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/SecurityAdminImages.java deleted file mode 100644 index 7bbe3c7..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/SecurityAdminImages.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.argeo.cms.e4.users; - -import org.argeo.cms.ui.theme.CmsImages; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; - -/** Shared icons that must be declared programmatically . */ -public class SecurityAdminImages extends CmsImages { - private final static String PREFIX = "icons/"; - - public final static ImageDescriptor ICON_REMOVE_DESC = createDesc(PREFIX + "delete.png"); - public final static ImageDescriptor ICON_USER_DESC = createDesc(PREFIX + "person.png"); - - public final static Image ICON_USER = ICON_USER_DESC.createImage(); - public final static Image ICON_GROUP = createImg(PREFIX + "group.png"); - public final static Image ICON_WORKGROUP = createImg(PREFIX + "workgroup.png"); - public final static Image ICON_ROLE = createImg(PREFIX + "role.gif"); - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UiAdminUtils.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UiAdminUtils.java deleted file mode 100644 index fb48a47..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UiAdminUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.argeo.cms.e4.users; - -import org.argeo.util.transaction.WorkTransaction; - -/** First effort to centralize back end methods used by the user admin UI */ -public class UiAdminUtils { - /* - * INTERNAL METHODS: Below methods are meant to stay here and are not part - * of a potential generic backend to manage the useradmin - */ - /** Easily notify the ActiveWindow that the transaction had a state change */ - public final static void notifyTransactionStateChange( - WorkTransaction userTransaction) { -// try { -// IWorkbenchWindow aww = PlatformUI.getWorkbench() -// .getActiveWorkbenchWindow(); -// ISourceProviderService sourceProviderService = (ISourceProviderService) aww -// .getService(ISourceProviderService.class); -// UserTransactionProvider esp = (UserTransactionProvider) sourceProviderService -// .getSourceProvider(UserTransactionProvider.TRANSACTION_STATE); -// esp.fireTransactionStateChange(); -// } catch (Exception e) { -// throw new CmsException("Unable to begin transaction", e); -// } - } - - /** - * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}. - * Thanks to this tip. - */ - public final static String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UiUserAdminListener.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UiUserAdminListener.java deleted file mode 100644 index eb64aba..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UiUserAdminListener.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.argeo.cms.e4.users; - -import org.eclipse.swt.widgets.Display; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** Convenience class to insure the call to refresh is done in the UI thread */ -public abstract class UiUserAdminListener implements UserAdminListener { - - private final Display display; - - public UiUserAdminListener(Display display) { - this.display = display; - } - - @Override - public void roleChanged(final UserAdminEvent event) { - display.asyncExec(new Runnable() { - @Override - public void run() { - roleChangedToUiThread(event); - } - }); - } - - public abstract void roleChangedToUiThread(UserAdminEvent event); -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java deleted file mode 100644 index dbb629c..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java +++ /dev/null @@ -1,153 +0,0 @@ -package org.argeo.cms.e4.users; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.swt.CmsException; -import org.argeo.osgi.useradmin.UserDirectory; -import org.argeo.util.directory.DirectoryConf; -import org.argeo.util.transaction.WorkTransaction; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** Centralise interaction with the UserAdmin in this bundle */ -public class UserAdminWrapper { - - private UserAdmin userAdmin; - // private ServiceReference userAdminServiceReference; -// private Set uris; - private Map> userDirectories = Collections - .synchronizedMap(new LinkedHashMap<>()); - private WorkTransaction userTransaction; - - // First effort to simplify UX while managing users and groups - public final static boolean COMMIT_ON_SAVE = true; - - // Registered listeners - List listeners = new ArrayList(); - - /** - * Starts a transaction if necessary. Should always been called together with - * {@link UserAdminWrapper#commitOrNotifyTransactionStateChange()} once the - * security model changes have been performed. - */ - public WorkTransaction beginTransactionIfNeeded() { - try { - // UserTransaction userTransaction = getUserTransaction(); - if (userTransaction.isNoTransactionStatus()) { - userTransaction.begin(); - // UiAdminUtils.notifyTransactionStateChange(userTransaction); - } - return userTransaction; - } catch (Exception e) { - throw new CmsException("Unable to begin transaction", e); - } - } - - /** - * Depending on the current application configuration, it will either commit the - * current transaction or throw a notification that the transaction state has - * changed (In the later case, it must be called from the UI thread). - */ - public void commitOrNotifyTransactionStateChange() { - try { - // UserTransaction userTransaction = getUserTransaction(); - if (userTransaction.isNoTransactionStatus()) - return; - - if (UserAdminWrapper.COMMIT_ON_SAVE) - userTransaction.commit(); - else - UiAdminUtils.notifyTransactionStateChange(userTransaction); - } catch (Exception e) { - throw new CmsException("Unable to clean transaction", e); - } - } - - // TODO implement safer mechanism - public void addListener(UserAdminListener userAdminListener) { - if (!listeners.contains(userAdminListener)) - listeners.add(userAdminListener); - } - - public void removeListener(UserAdminListener userAdminListener) { - if (listeners.contains(userAdminListener)) - listeners.remove(userAdminListener); - } - - public void notifyListeners(UserAdminEvent event) { - for (UserAdminListener listener : listeners) - listener.roleChanged(event); - } - - public Map getKnownBaseDns(boolean onlyWritable) { - Map dns = new HashMap(); - for (UserDirectory userDirectory : userDirectories.keySet()) { - Boolean readOnly = userDirectory.isReadOnly(); - String baseDn = userDirectory.getBase(); - - if (onlyWritable && readOnly) - continue; - if (baseDn.equalsIgnoreCase(CmsConstants.SYSTEM_ROLES_BASEDN)) - continue; - if (baseDn.equalsIgnoreCase(CmsConstants.TOKENS_BASEDN)) - continue; - dns.put(baseDn, DirectoryConf.propertiesAsUri(userDirectories.get(userDirectory)).toString()); - - } -// for (String uri : uris) { -// if (!uri.startsWith("/")) -// continue; -// Dictionary props = UserAdminConf.uriAsProperties(uri); -// String readOnly = UserAdminConf.readOnly.getValue(props); -// String baseDn = UserAdminConf.baseDn.getValue(props); -// -// if (onlyWritable && "true".equals(readOnly)) -// continue; -// if (baseDn.equalsIgnoreCase(NodeConstants.ROLES_BASEDN)) -// continue; -// if (baseDn.equalsIgnoreCase(NodeConstants.TOKENS_BASEDN)) -// continue; -// dns.put(baseDn, uri); -// } - return dns; - } - - public UserAdmin getUserAdmin() { - return userAdmin; - } - - public WorkTransaction getUserTransaction() { - return userTransaction; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdmin(UserAdmin userAdmin, Map properties) { - this.userAdmin = userAdmin; -// this.uris = Collections.unmodifiableSortedSet(new TreeSet<>(properties.keySet())); - } - - public void setUserTransaction(WorkTransaction userTransaction) { - this.userTransaction = userTransaction; - } - - public void addUserDirectory(UserDirectory userDirectory, Map properties) { - userDirectories.put(userDirectory, new Hashtable<>(properties)); - } - - public void removeUserDirectory(UserDirectory userDirectory, Map properties) { - userDirectories.remove(userDirectory); - } - - // public void setUserAdminServiceReference( - // ServiceReference userAdminServiceReference) { - // this.userAdminServiceReference = userAdminServiceReference; - // } -} 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 deleted file mode 100644 index 4fc59d3..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java +++ /dev/null @@ -1,606 +0,0 @@ -package org.argeo.cms.e4.users; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.api.cms.CmsLog; -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.e4.users.providers.CommonNameLP; -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.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; -import org.eclipse.jface.dialogs.IPageChangeProvider; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.PageChangedEvent; -import org.eclipse.jface.wizard.IWizardContainer; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardPage; -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.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Wizard to update users */ -public class UserBatchUpdateWizard extends Wizard { - - private final static CmsLog log = CmsLog.getLog(UserBatchUpdateWizard.class); - private UserAdminWrapper userAdminWrapper; - - // pages - private ChooseCommandWizardPage chooseCommandPage; - private ChooseUsersWizardPage userListPage; - private ValidateAndLaunchWizardPage validatePage; - - // Various implemented commands keys - private final static String CMD_UPDATE_PASSWORD = "resetPassword"; - private final static String CMD_UPDATE_EMAIL = "resetEmail"; - private final static String CMD_GROUP_MEMBERSHIP = "groupMembership"; - - private final Map commands = new HashMap() { - private static final long serialVersionUID = 1L; - { - put("Reset password(s)", CMD_UPDATE_PASSWORD); - put("Reset email(s)", CMD_UPDATE_EMAIL); - // TODO implement role / group management - // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP); - } - }; - - public UserBatchUpdateWizard(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } - - @Override - public void addPages() { - chooseCommandPage = new ChooseCommandWizardPage(); - addPage(chooseCommandPage); - userListPage = new ChooseUsersWizardPage(); - addPage(userListPage); - validatePage = new ValidateAndLaunchWizardPage(); - addPage(validatePage); - } - - @Override - public boolean performFinish() { - if (!canFinish()) - return false; - WorkTransaction ut = userAdminWrapper.getUserTransaction(); - if (!ut.isNoTransactionStatus() && !MessageDialog.openConfirm(getShell(), "Existing Transaction", - "A user transaction is already existing, " + "are you sure you want to proceed ?")) - return false; - - // We cannot use jobs, user modifications are still meant to be done in - // the UIThread - // UpdateJob job = null; - // if (job != null) - // job.schedule(); - - if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) { - char[] newValue = chooseCommandPage.getPwdValue(); - if (newValue == null) - throw new CmsException("Password cannot be null or an empty string"); - ResetPassword job = new ResetPassword(userAdminWrapper, userListPage.getSelectedUsers(), newValue); - job.doUpdate(); - } else if (CMD_UPDATE_EMAIL.equals(chooseCommandPage.getCommand())) { - String newValue = chooseCommandPage.getEmailValue(); - if (newValue == null) - throw new CmsException("Password cannot be null or an empty string"); - ResetEmail job = new ResetEmail(userAdminWrapper, userListPage.getSelectedUsers(), newValue); - job.doUpdate(); - } - return true; - } - - public boolean canFinish() { - if (this.getContainer().getCurrentPage() == validatePage) - return true; - return false; - } - - private class ResetPassword { - private char[] newPwd; - private UserAdminWrapper userAdminWrapper; - private List usersToUpdate; - - public ResetPassword(UserAdminWrapper userAdminWrapper, List usersToUpdate, char[] newPwd) { - this.newPwd = newPwd; - this.usersToUpdate = usersToUpdate; - this.userAdminWrapper = userAdminWrapper; - } - - @SuppressWarnings("unchecked") - protected void doUpdate() { - userAdminWrapper.beginTransactionIfNeeded(); - try { - for (User user : usersToUpdate) { - // the char array is emptied after being used. - user.getCredentials().put(null, newPwd.clone()); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - } catch (Exception e) { - throw new CmsException("Cannot perform batch update on users", e); - } finally { - WorkTransaction ut = userAdminWrapper.getUserTransaction(); - if (!ut.isNoTransactionStatus()) - ut.rollback(); - } - } - } - - private class ResetEmail { - private String newEmail; - private UserAdminWrapper userAdminWrapper; - private List usersToUpdate; - - public ResetEmail(UserAdminWrapper userAdminWrapper, List usersToUpdate, String newEmail) { - this.newEmail = newEmail; - this.usersToUpdate = usersToUpdate; - this.userAdminWrapper = userAdminWrapper; - } - - @SuppressWarnings("unchecked") - protected void doUpdate() { - userAdminWrapper.beginTransactionIfNeeded(); - try { - for (User user : usersToUpdate) { - // the char array is emptied after being used. - user.getProperties().put(LdapAttrs.mail.name(), newEmail); - } - - userAdminWrapper.commitOrNotifyTransactionStateChange(); - if (!usersToUpdate.isEmpty()) - userAdminWrapper.notifyListeners( - new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, usersToUpdate.get(0))); - } catch (Exception e) { - throw new CmsException("Cannot perform batch update on users", e); - } finally { - WorkTransaction ut = userAdminWrapper.getUserTransaction(); - if (!ut.isNoTransactionStatus()) - ut.rollback(); - } - } - } - - // @SuppressWarnings("unused") - // private class AddToGroup extends UpdateJob { - // private String groupID; - // private Session session; - // - // public AddToGroup(Session session, List nodesToUpdate, - // String groupID) { - // super(session, nodesToUpdate); - // this.session = session; - // this.groupID = groupID; - // } - // - // protected void doUpdate(Node node) { - // log.info("Add/Remove to group actions are not yet implemented"); - // // TODO implement this - // // try { - // // throw new CmsException("Not yet implemented"); - // // } catch (RepositoryException re) { - // // throw new CmsException( - // // "Unable to update boolean value for node " + node, re); - // // } - // } - // } - - // /** - // * Base privileged job that will be run asynchronously to perform the - // batch - // * update - // */ - // private abstract class UpdateJob extends PrivilegedJob { - // - // private final UserAdminWrapper userAdminWrapper; - // private final List usersToUpdate; - // - // protected abstract void doUpdate(User user); - // - // public UpdateJob(UserAdminWrapper userAdminWrapper, - // List usersToUpdate) { - // super("Perform update"); - // this.usersToUpdate = usersToUpdate; - // this.userAdminWrapper = userAdminWrapper; - // } - // - // @Override - // protected IStatus doRun(IProgressMonitor progressMonitor) { - // try { - // JcrMonitor monitor = new EclipseJcrMonitor(progressMonitor); - // int total = usersToUpdate.size(); - // monitor.beginTask("Performing change", total); - // userAdminWrapper.beginTransactionIfNeeded(); - // for (User user : usersToUpdate) { - // doUpdate(user); - // monitor.worked(1); - // } - // userAdminWrapper.getUserTransaction().commit(); - // } catch (Exception e) { - // throw new CmsException( - // "Cannot perform batch update on users", e); - // } finally { - // UserTransaction ut = userAdminWrapper.getUserTransaction(); - // try { - // if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION) - // ut.rollback(); - // } catch (IllegalStateException | SecurityException - // | SystemException e) { - // log.error("Unable to rollback session in 'finally', " - // + "the system might be in a dirty state"); - // e.printStackTrace(); - // } - // } - // return Status.OK_STATUS; - // } - // } - - // PAGES - /** - * Displays a combo box that enables user to choose which action to perform - */ - private class ChooseCommandWizardPage extends WizardPage { - private static final long serialVersionUID = -8069434295293996633L; - private Combo chooseCommandCmb; - private Button trueChk; - private Text valueTxt; - private Text pwdTxt; - private Text pwd2Txt; - - public ChooseCommandWizardPage() { - super("Choose a command to run."); - setTitle("Choose a command to run."); - } - - @Override - public void createControl(Composite parent) { - GridLayout gl = new GridLayout(); - Composite container = new Composite(parent, SWT.NO_FOCUS); - container.setLayout(gl); - - chooseCommandCmb = new Combo(container, SWT.READ_ONLY); - chooseCommandCmb.setLayoutData(EclipseUiUtils.fillWidth()); - String[] values = commands.keySet().toArray(new String[0]); - chooseCommandCmb.setItems(values); - - final Composite bottomPart = new Composite(container, SWT.NO_FOCUS); - bottomPart.setLayoutData(EclipseUiUtils.fillAll()); - bottomPart.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - chooseCommandCmb.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = 1L; - - @Override - public void widgetSelected(SelectionEvent e) { - if (getCommand().equals(CMD_UPDATE_PASSWORD)) - populatePasswordCmp(bottomPart); - else if (getCommand().equals(CMD_UPDATE_EMAIL)) - populateEmailCmp(bottomPart); - else if (getCommand().equals(CMD_GROUP_MEMBERSHIP)) - populateGroupCmp(bottomPart); - else - populateBooleanFlagCmp(bottomPart); - checkPageComplete(); - bottomPart.layout(true, true); - } - }); - setControl(container); - } - - private void populateBooleanFlagCmp(Composite parent) { - EclipseUiUtils.clear(parent); - trueChk = new Button(parent, SWT.CHECK); - trueChk.setText("Do it. (It will to the contrary if unchecked)"); - trueChk.setSelection(true); - trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); - } - - private void populatePasswordCmp(Composite parent) { - EclipseUiUtils.clear(parent); - Composite body = new Composite(parent, SWT.NO_FOCUS); - - ModifyListener ml = new ModifyListener() { - private static final long serialVersionUID = -1558726363536729634L; - - @Override - public void modifyText(ModifyEvent event) { - checkPageComplete(); - } - }; - - body.setLayout(new GridLayout(2, false)); - body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - pwdTxt = EclipseUiUtils.createGridLP(body, "New password", ml); - pwd2Txt = EclipseUiUtils.createGridLP(body, "Repeat password", ml); - } - - private void populateEmailCmp(Composite parent) { - EclipseUiUtils.clear(parent); - Composite body = new Composite(parent, SWT.NO_FOCUS); - - ModifyListener ml = new ModifyListener() { - private static final long serialVersionUID = 2147704227294268317L; - - @Override - public void modifyText(ModifyEvent event) { - checkPageComplete(); - } - }; - - body.setLayout(new GridLayout(2, false)); - body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - valueTxt = EclipseUiUtils.createGridLT(body, "New e-mail", ml); - } - - private void checkPageComplete() { - String errorMsg = null; - if (chooseCommandCmb.getSelectionIndex() < 0) - errorMsg = "Please select an action"; - else if (CMD_UPDATE_EMAIL.equals(getCommand())) { - if (!valueTxt.getText().matches(UiAdminUtils.EMAIL_PATTERN)) - errorMsg = "Not a valid e-mail address"; - } else if (CMD_UPDATE_PASSWORD.equals(getCommand())) { - if (EclipseUiUtils.isEmpty(pwdTxt.getText()) || pwdTxt.getText().length() < 4) - errorMsg = "Please enter a password that is at least 4 character long"; - else if (!pwdTxt.getText().equals(pwd2Txt.getText())) - errorMsg = "Passwords are different"; - } - if (EclipseUiUtils.notEmpty(errorMsg)) { - setMessage(errorMsg, WizardPage.ERROR); - setPageComplete(false); - } else { - setMessage("Page complete, you can proceed to user choice", WizardPage.INFORMATION); - setPageComplete(true); - } - - getContainer().updateButtons(); - } - - private void populateGroupCmp(Composite parent) { - EclipseUiUtils.clear(parent); - trueChk = new Button(parent, SWT.CHECK); - trueChk.setText("Add to group. (It will remove user(s) from the " + "corresponding group if unchecked)"); - trueChk.setSelection(true); - trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); - } - - protected String getCommand() { - return commands.get(chooseCommandCmb.getItem(chooseCommandCmb.getSelectionIndex())); - } - - protected String getCommandLbl() { - return chooseCommandCmb.getItem(chooseCommandCmb.getSelectionIndex()); - } - - @SuppressWarnings("unused") - protected boolean getBoleanValue() { - // FIXME this is not consistent and will lead to errors. - if ("argeo:enabled".equals(getCommand())) - return trueChk.getSelection(); - else - return !trueChk.getSelection(); - } - - @SuppressWarnings("unused") - protected String getStringValue() { - String value = null; - if (valueTxt != null) { - value = valueTxt.getText(); - if ("".equals(value.trim())) - value = null; - } - return value; - } - - protected char[] getPwdValue() { - // We do not directly reset the password text fields: There is no - // need to over secure this process: setting a pwd to multi users - // at the same time is anyhow a bad practice and should be used only - // in test environment or for temporary access - if (pwdTxt == null || pwdTxt.isDisposed()) - return null; - else - return pwdTxt.getText().toCharArray(); - } - - protected String getEmailValue() { - // We do not directly reset the password text fields: There is no - // need to over secure this process: setting a pwd to multi users - // at the same time is anyhow a bad practice and should be used only - // in test environment or for temporary access - if (valueTxt == null || valueTxt.isDisposed()) - return null; - else - return valueTxt.getText(); - } - } - - /** - * Displays a list of users with a check box to be able to choose some of them - */ - private class ChooseUsersWizardPage extends WizardPage implements IPageChangedListener { - private static final long serialVersionUID = 7651807402211214274L; - private ChooseUserTableViewer userTableCmp; - - public ChooseUsersWizardPage() { - super("Choose Users"); - setTitle("Select users who will be impacted"); - } - - @Override - public void createControl(Composite parent) { - Composite pageCmp = new Composite(parent, SWT.NONE); - pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - // Define the displayed columns - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); - - // Only show technical DN to admin - if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN)) - columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300)); - - userTableCmp = new ChooseUserTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - userTableCmp.setLayoutData(EclipseUiUtils.fillAll()); - userTableCmp.setColumnDefinitions(columnDefs); - userTableCmp.populate(true, true); - userTableCmp.refresh(); - - setControl(pageCmp); - - // Add listener to update message when shown - final IWizardContainer wContainer = this.getContainer(); - if (wContainer instanceof IPageChangeProvider) { - ((IPageChangeProvider) wContainer).addPageChangedListener(this); - } - - } - - @Override - public void pageChanged(PageChangedEvent event) { - if (event.getSelectedPage() == this) { - String msg = "Chosen batch action: " + chooseCommandPage.getCommandLbl(); - ((WizardPage) event.getSelectedPage()).setMessage(msg); - } - } - - protected List getSelectedUsers() { - return userTableCmp.getSelectedUsers(); - } - - private class ChooseUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 5080437561015853124L; - private final String[] knownProps = { LdapAttrs.uid.name(), LdapAttrs.DN, LdapAttrs.cn.name(), - LdapAttrs.givenName.name(), LdapAttrs.sn.name(), LdapAttrs.mail.name() }; - - public ChooseUserTableViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - protected List listFilteredElements(String filter) { - Role[] roles; - - try { - StringBuilder builder = new StringBuilder(); - - StringBuilder tmpBuilder = new StringBuilder(); - if (EclipseUiUtils.notEmpty(filter)) - for (String prop : knownProps) { - tmpBuilder.append("("); - tmpBuilder.append(prop); - tmpBuilder.append("=*"); - tmpBuilder.append(filter); - tmpBuilder.append("*)"); - } - if (tmpBuilder.length() > 1) { - builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") - .append(LdapObjs.inetOrgPerson.name()).append(")(|"); - builder.append(tmpBuilder.toString()); - builder.append("))"); - } else - builder.append("(").append(LdapAttrs.objectClass.name()).append("=") - .append(LdapObjs.inetOrgPerson.name()).append(")"); - roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString()); - } catch (InvalidSyntaxException e) { - throw new CmsException("Unable to get roles with filter: " + filter, e); - } - List users = new ArrayList(); - for (Role role : roles) - // Prevent current logged in user to perform batch on - // himself - if (!UserAdminUtils.isCurrentUser((User) role)) - users.add((User) role); - return users; - } - } - } - - /** Summary of input data before launching the process */ - private class ValidateAndLaunchWizardPage extends WizardPage implements IPageChangedListener { - private static final long serialVersionUID = 7098918351451743853L; - private ChosenUsersTableViewer userTableCmp; - - public ValidateAndLaunchWizardPage() { - super("Validate and launch"); - setTitle("Validate and launch"); - } - - @Override - public void createControl(Composite parent) { - Composite pageCmp = new Composite(parent, SWT.NO_FOCUS); - pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); - // Only show technical DN to admin - if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN)) - columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300)); - userTableCmp = new ChosenUsersTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - userTableCmp.setLayoutData(EclipseUiUtils.fillAll()); - userTableCmp.setColumnDefinitions(columnDefs); - userTableCmp.populate(false, false); - userTableCmp.refresh(); - setControl(pageCmp); - // Add listener to update message when shown - final IWizardContainer wContainer = this.getContainer(); - if (wContainer instanceof IPageChangeProvider) { - ((IPageChangeProvider) wContainer).addPageChangedListener(this); - } - } - - @Override - public void pageChanged(PageChangedEvent event) { - if (event.getSelectedPage() == this) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - Object[] values = ((ArrayList) userListPage.getSelectedUsers()) - .toArray(new Object[userListPage.getSelectedUsers().size()]); - userTableCmp.getTableViewer().setInput(values); - String msg = "Following batch action: [" + chooseCommandPage.getCommandLbl() - + "] will be perfomed on the users listed below.\n"; - // + "Are you sure you want to proceed?"; - setMessage(msg); - } - } - - private class ChosenUsersTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 7814764735794270541L; - - public ChosenUsersTableViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - protected List listFilteredElements(String filter) { - return userListPage.getSelectedUsers(); - } - } - } -} 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 deleted file mode 100644 index 66f4420..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserEditor.java +++ /dev/null @@ -1,535 +0,0 @@ -package org.argeo.cms.e4.users; - -import static org.argeo.cms.auth.UserAdminUtils.getProperty; -import static org.argeo.util.naming.LdapAttrs.cn; -import static org.argeo.util.naming.LdapAttrs.givenName; -import static org.argeo.util.naming.LdapAttrs.mail; -import static org.argeo.util.naming.LdapAttrs.sn; -import static org.argeo.util.naming.LdapAttrs.uid; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.inject.Inject; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.e4.users.providers.CommonNameLP; -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.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; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.TrayDialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerDropAdapter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.dnd.TransferData; -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.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Link; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Display/edit the properties of a given user */ -public class UserEditor extends AbstractRoleEditor { - // final static String ID = "UserEditor.mainPage"; - - @Inject - private EPartService partService; - - // private final UserEditor editor; - // private UserAdminWrapper userAdminWrapper; - - // Local configuration - // private final int PRE_TITLE_INDENT = 10; - - // public UserMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) { - // super(editor, ID, "Main"); - // this.editor = (UserEditor) editor; - // this.userAdminWrapper = userAdminWrapper; - // } - - // protected void createFormContent(final IManagedForm mf) { - // ScrolledForm form = mf.getForm(); - // Composite body = form.getBody(); - // GridLayout mainLayout = new GridLayout(); - // // mainLayout.marginRight = 10; - // body.setLayout(mainLayout); - // User user = editor.getDisplayedUser(); - // appendOverviewPart(body, user); - // // Remove to ability to force the password for his own user. The user - // // must then use the change pwd feature - // appendMemberOfPart(body, user); - // } - - @Override - protected void createUi(Composite body) { - // Composite body = new Composite(parent, SWT.BORDER); - GridLayout mainLayout = new GridLayout(); - // mainLayout.marginRight = 10; - body.setLayout(mainLayout); - // body.getParent().setLayout(new GridLayout()); - // body.setLayoutData(CmsUiUtils.fillAll()); - User user = getDisplayedUser(); - appendOverviewPart(body, user); - // Remove to ability to force the password for his own user. The user - // must then use the change pwd feature - appendMemberOfPart(body, user); - } - - /** Creates the general section */ - private void appendOverviewPart(final Composite parent, final User user) { - // FormToolkit tk = getManagedForm().getToolkit(); - - // Section section = tk.createSection(parent, SWT.NO_FOCUS); - // GridData gd = EclipseUiUtils.fillWidth(); - // // gd.verticalAlignment = PRE_TITLE_INDENT; - // section.setLayoutData(gd); - Composite body = new Composite(parent, SWT.NONE); - body.setLayoutData(EclipseUiUtils.fillWidth()); - // section.setClient(body); - // body.setLayout(new GridLayout(6, false)); - body.setLayout(new GridLayout(2, false)); - - Text commonName = createReadOnlyLT(body, "Name", getProperty(user, cn)); - Text distinguishedName = createReadOnlyLT(body, "Login", getProperty(user, uid)); - Text firstName = createLT(body, "First name", getProperty(user, givenName)); - Text lastName = createLT(body, "Last name", getProperty(user, sn)); - Text email = createLT(body, "Email", getProperty(user, mail)); - - Link resetPwdLk = new Link(body, SWT.NONE); - if (!UserAdminUtils.isCurrentUser(user)) { - resetPwdLk.setText("Reset password"); - } - resetPwdLk.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); - - // create form part (controller) - AbstractFormPart part = new AbstractFormPart() { - private MainInfoListener listener; - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = new MainInfoListener(parent.getDisplay(), this); - userAdminWrapper.addListener(listener); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @SuppressWarnings("unchecked") - public void commit(boolean onSave) { - // TODO Sanity checks (mail validity...) - user.getProperties().put(LdapAttrs.givenName.name(), firstName.getText()); - user.getProperties().put(LdapAttrs.sn.name(), lastName.getText()); - user.getProperties().put(LdapAttrs.cn.name(), commonName.getText()); - user.getProperties().put(LdapAttrs.mail.name(), email.getText()); - super.commit(onSave); - } - - @Override - public void refresh() { - distinguishedName.setText(UserAdminUtils.getProperty(user, LdapAttrs.uid.name())); - commonName.setText(UserAdminUtils.getProperty(user, LdapAttrs.cn.name())); - firstName.setText(UserAdminUtils.getProperty(user, LdapAttrs.givenName.name())); - lastName.setText(UserAdminUtils.getProperty(user, LdapAttrs.sn.name())); - email.setText(UserAdminUtils.getProperty(user, LdapAttrs.mail.name())); - refreshFormTitle(user); - super.refresh(); - } - }; - - // Improve this: automatically generate CN when first or last name - // changes - ModifyListener cnML = new ModifyListener() { - private static final long serialVersionUID = 4298649222869835486L; - - @Override - public void modifyText(ModifyEvent event) { - String first = firstName.getText(); - String last = lastName.getText(); - String cn = first.trim() + " " + last.trim() + " "; - cn = cn.trim(); - commonName.setText(cn); - // getManagedForm().getForm().setText(cn); - updateEditorTitle(cn); - } - }; - firstName.addModifyListener(cnML); - lastName.addModifyListener(cnML); - - ModifyListener defaultListener = new FormPartML(part); - firstName.addModifyListener(defaultListener); - lastName.addModifyListener(defaultListener); - email.addModifyListener(defaultListener); - - if (!UserAdminUtils.isCurrentUser(user)) - resetPwdLk.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = 5881800534589073787L; - - @Override - public void widgetSelected(SelectionEvent e) { - new ChangePasswordDialog(user, "Reset password").open(); - } - }); - - getManagedForm().addPart(part); - } - - private class ChangePasswordDialog extends TrayDialog { - private static final long serialVersionUID = 2843538207460082349L; - - private User user; - private Text password1; - private Text password2; - private String title; - // private FormToolkit tk; - - public ChangePasswordDialog(User user, String title) { - super(Display.getDefault().getActiveShell()); - // this.tk = tk; - this.user = user; - this.title = title; - } - - protected Control createDialogArea(Composite parent) { - Composite dialogarea = (Composite) super.createDialogArea(parent); - dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - Composite body = new Composite(dialogarea, SWT.NO_FOCUS); - body.setLayoutData(EclipseUiUtils.fillAll()); - GridLayout layout = new GridLayout(2, false); - body.setLayout(layout); - - password1 = createLP(body, "New password", ""); - password2 = createLP(body, "Repeat password", ""); - parent.pack(); - return body; - } - - @SuppressWarnings("unchecked") - @Override - protected void okPressed() { - String msg = null; - - if (password1.getText().equals("")) - msg = "Password cannot be empty"; - else if (password1.getText().equals(password2.getText())) { - char[] newPassword = password1.getText().toCharArray(); - // userAdminWrapper.beginTransactionIfNeeded(); - userAdminWrapper.beginTransactionIfNeeded(); - user.getCredentials().put(null, newPassword); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - super.okPressed(); - } else { - msg = "Passwords are not equals"; - } - - if (EclipseUiUtils.notEmpty(msg)) - MessageDialog.openError(getParentShell(), "Cannot reset pasword", msg); - } - - protected void configureShell(Shell shell) { - super.configureShell(shell); - shell.setText(title); - } - } - - private LdifUsersTable appendMemberOfPart(final Composite parent, User user) { - // Section section = addSection(tk, parent, "Roles"); - // Composite body = (Composite) section.getClient(); - // Composite body= parent; - Composite body = new Composite(parent, SWT.BORDER); - body.setLayout(new GridLayout()); - body.setLayoutData(CmsSwtUtils.fillAll()); - - // boolean isAdmin = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); - - // Displayed columns - List columnDefs = new ArrayList(); - columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24)); - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Name", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 100)); - // Only show technical DN to administrators - // if (isAdmin) - // columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", - // 300)); - - // Create and configure the table - final LdifUsersTable userViewerCmp = new MyUserTableViewer(body, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, user); - - userViewerCmp.setColumnDefinitions(columnDefs); - // if (isAdmin) - // userViewerCmp.populateWithStaticFilters(false, false); - // else - userViewerCmp.populate(true, false); - GridData gd = EclipseUiUtils.fillAll(); - gd.heightHint = 500; - userViewerCmp.setLayoutData(gd); - - // Controllers - TableViewer userViewer = userViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService)); - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - GroupDropListener dropL = new GroupDropListener(userAdminWrapper, userViewer, user); - userViewer.addDropSupport(operations, tt, dropL); - - AbstractFormPart part = new AbstractFormPart() { - - private GroupChangeListener listener; - - @Override - public void initialize(IManagedForm form) { - super.initialize(form); - listener = new GroupChangeListener(parent.getDisplay(), this); - userAdminWrapper.addListener(listener); - } - - public void commit(boolean onSave) { - super.commit(onSave); - } - - @Override - public void dispose() { - userAdminWrapper.removeListener(listener); - super.dispose(); - } - - @Override - public void refresh() { - userViewerCmp.refresh(); - super.refresh(); - } - }; - getManagedForm().addPart(part); - // addRemoveAbitily(body, userViewer, user); - // userViewerCmp.refresh(); - String tooltip = "Remove " + UserAdminUtils.getUserLocalId(user.getName()) + " from the below selected groups"; - Action action = new RemoveMembershipAction(userViewer, user, tooltip, SecurityAdminImages.ICON_REMOVE_DESC); - ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); - ToolBar toolBar = toolBarManager.createControl(body); - toolBar.setLayoutData(CmsSwtUtils.fillWidth()); - toolBarManager.add(action); - toolBarManager.update(true); - return userViewerCmp; - } - - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 2653790051461237329L; - - private Button showSystemRoleBtn; - - private final User user; - private final UserFilter userFilter; - - public MyUserTableViewer(Composite parent, int style, User user) { - super(parent, style, true); - this.user = user; - userFilter = new UserFilter(); - } - - protected void populateStaticFilters(Composite staticFilterCmp) { - staticFilterCmp.setLayout(new GridLayout()); - showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); - showSystemRoleBtn.setText("Show system roles"); - boolean showSysRole = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN); - showSystemRoleBtn.setSelection(showSysRole); - userFilter.setShowSystemRole(showSysRole); - showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -7033424592697691676L; - - @Override - public void widgetSelected(SelectionEvent e) { - userFilter.setShowSystemRole(showSystemRoleBtn.getSelection()); - refresh(); - } - }); - } - - @Override - protected List listFilteredElements(String filter) { - List users = (List) getFlatGroups(null); - List filteredUsers = new ArrayList(); - if (users.contains(user)) - users.remove(user); - userFilter.setSearchText(filter); - for (User user : users) - if (userFilter.select(null, null, user)) - filteredUsers.add(user); - return filteredUsers; - } - } - - // private void addRemoveAbility(Composite parent, TableViewer userViewer, User - // user) { - // // Section section = sectionPart.getSection(); - // ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); - // ToolBar toolbar = toolBarManager.createControl(parent); - // final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND); - // toolbar.setCursor(handCursor); - // toolbar.addDisposeListener(new DisposeListener() { - // private static final long serialVersionUID = 3882131405820522925L; - // - // public void widgetDisposed(DisposeEvent e) { - // if ((handCursor != null) && (handCursor.isDisposed() == false)) { - // handCursor.dispose(); - // } - // } - // }); - // - // String tooltip = "Remove " + UserAdminUtils.getUserLocalId(user.getName()) + - // " from the below selected groups"; - // Action action = new RemoveMembershipAction(userViewer, user, tooltip, - // SecurityAdminImages.ICON_REMOVE_DESC); - // toolBarManager.add(action); - // toolBarManager.update(true); - // // section.setTextClient(toolbar); - // } - - private class RemoveMembershipAction extends Action { - private static final long serialVersionUID = -1337713097184522588L; - - private final TableViewer userViewer; - private final User user; - - RemoveMembershipAction(TableViewer userViewer, User user, String name, ImageDescriptor img) { - super(name, img); - this.userViewer = userViewer; - this.user = user; - } - - @Override - public void run() { - ISelection selection = userViewer.getSelection(); - if (selection.isEmpty()) - return; - - @SuppressWarnings("unchecked") - Iterator it = ((IStructuredSelection) selection).iterator(); - List groups = new ArrayList(); - while (it.hasNext()) { - Group currGroup = it.next(); - groups.add(currGroup); - } - - userAdminWrapper.beginTransactionIfNeeded(); - for (Group group : groups) { - group.removeMember(user); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - for (Group group : groups) { - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group)); - } - } - } - - /** - * Defines the table as being a potential target to add group memberships - * (roles) to this user - */ - private class GroupDropListener extends ViewerDropAdapter { - private static final long serialVersionUID = 2893468717831451621L; - - private final UserAdminWrapper myUserAdminWrapper; - private final User myUser; - - public GroupDropListener(UserAdminWrapper userAdminWrapper, Viewer userViewer, User user) { - super(userViewer); - this.myUserAdminWrapper = userAdminWrapper; - this.myUser = user; - } - - @Override - public boolean validateDrop(Object target, int operation, TransferData transferType) { - // Target is always OK in a list only view - // TODO check if not a string - boolean validDrop = true; - return validDrop; - } - - @Override - public void drop(DropTargetEvent event) { - String name = (String) event.data; - UserAdmin myUserAdmin = myUserAdminWrapper.getUserAdmin(); - Role role = myUserAdmin.getRole(name); - // TODO this check should be done before. - if (role.getType() == Role.GROUP) { - // TODO check if the user is already member of this group - - myUserAdminWrapper.beginTransactionIfNeeded(); - Group group = (Group) role; - group.addMember(myUser); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - myUserAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, group)); - } - super.drop(event); - } - - @Override - public boolean performDrop(Object data) { - // userTableViewerCmp.refresh(); - return true; - } - } - - // LOCAL HELPERS - private void refreshFormTitle(User group) { - // getManagedForm().getForm().setText(UserAdminUtils.getProperty(group, - // LdapAttrs.cn.name())); - } - - /** Appends a section with a title */ - // private Section addSection(FormToolkit tk, Composite parent, String title) { - // Section section = tk.createSection(parent, Section.TITLE_BAR); - // GridData gd = EclipseUiUtils.fillWidth(); - // gd.verticalAlignment = PRE_TITLE_INDENT; - // section.setLayoutData(gd); - // section.setText(title); - // // section.getMenu().setVisible(true); - // - // Composite body = tk.createComposite(section, SWT.WRAP); - // body.setLayoutData(EclipseUiUtils.fillAll()); - // section.setClient(body); - // - // return section; - // } - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java deleted file mode 100644 index c6d024e..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.argeo.cms.e4.users; - -import org.argeo.cms.e4.CmsE4Utils; -import org.argeo.util.naming.LdapAttrs; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.User; - -/** - * Default double click listener for the various user tables, will open the - * clicked item in the editor - */ -public class UserTableDefaultDClickListener implements IDoubleClickListener { - private final EPartService partService; - - public UserTableDefaultDClickListener(EPartService partService) { - this.partService = partService; - } - - public void doubleClick(DoubleClickEvent evt) { - if (evt.getSelection().isEmpty()) - return; - Object obj = ((IStructuredSelection) evt.getSelection()).getFirstElement(); - User user = (User) obj; - - String editorId = getEditorId(user); - CmsE4Utils.openEditor(partService, editorId, LdapAttrs.uid.name(), user.getName()); - } - - protected String getEditorId(User user) { - if (user instanceof Group) - return "org.argeo.cms.e4.partdescriptor.groupEditor"; - else - return "org.argeo.cms.e4.partdescriptor.userEditor"; - } -} 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 deleted file mode 100644 index 720945c..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/UsersView.java +++ /dev/null @@ -1,182 +0,0 @@ -package org.argeo.cms.e4.users; - -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.e4.users.providers.CommonNameLP; -import org.argeo.cms.e4.users.providers.DomainNameLP; -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.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; -import org.eclipse.e4.ui.workbench.modeling.EPartService; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -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.dnd.DND; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdminEvent; -import org.osgi.service.useradmin.UserAdminListener; - -/** List all users with filter - based on Ldif userAdmin */ -public class UsersView { - // private final static Log log = LogFactory.getLog(UsersView.class); - - // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".usersView"; - - @Inject - private UserAdminWrapper userAdminWrapper; - @Inject - private EPartService partService; - - // UI Objects - private LdifUsersTable userTableViewerCmp; - private TableViewer userViewer; - private List columnDefs = new ArrayList(); - - private UserAdminListener listener; - - @PostConstruct - public void createPartControl(Composite parent, ESelectionService selectionService) { - - parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); - // Define the displayed columns - columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150)); - columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); - columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); - // Only show technical DN to admin - if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN)) - columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300)); - - // Create and configure the table - userTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - userTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll()); - userTableViewerCmp.setColumnDefinitions(columnDefs); - userTableViewerCmp.populate(true, false); - - // Links - userViewer = userTableViewerCmp.getTableViewer(); - userViewer.addDoubleClickListener(new UserTableDefaultDClickListener(partService)); - userViewer.addSelectionChangedListener(new ISelectionChangedListener() { - - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - selectionService.setSelection(selection.toList()); - } - }); - // getViewSite().setSelectionProvider(userViewer); - - // Really? - userTableViewerCmp.refresh(); - - // Drag and drop - int operations = DND.DROP_COPY | DND.DROP_MOVE; - Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - userViewer.addDragSupport(operations, tt, new UserDragListener(userViewer)); - - // Register a useradmin listener - listener = new MyUiUAListener(parent.getDisplay()); - userAdminWrapper.addListener(listener); - } - - private class MyUiUAListener extends UiUserAdminListener { - public MyUiUAListener(Display display) { - super(display); - } - - @Override - public void roleChangedToUiThread(UserAdminEvent event) { - if (userViewer != null && !userViewer.getTable().isDisposed()) - refresh(); - } - } - - private class MyUserTableViewer extends LdifUsersTable { - private static final long serialVersionUID = 8467999509931900367L; - - private final String[] knownProps = { LdapAttrs.DN, LdapAttrs.uid.name(), LdapAttrs.cn.name(), - LdapAttrs.givenName.name(), LdapAttrs.sn.name(), LdapAttrs.mail.name() }; - - public MyUserTableViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - protected List listFilteredElements(String filter) { - Role[] roles; - - try { - StringBuilder builder = new StringBuilder(); - - StringBuilder tmpBuilder = new StringBuilder(); - if (EclipseUiUtils.notEmpty(filter)) - for (String prop : knownProps) { - tmpBuilder.append("("); - tmpBuilder.append(prop); - tmpBuilder.append("=*"); - tmpBuilder.append(filter); - tmpBuilder.append("*)"); - } - if (tmpBuilder.length() > 1) { - builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") - .append(LdapObjs.inetOrgPerson.name()).append(")(|"); - builder.append(tmpBuilder.toString()); - builder.append("))"); - } else - builder.append("(").append(LdapAttrs.objectClass.name()).append("=") - .append(LdapObjs.inetOrgPerson.name()).append(")"); - roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString()); - } catch (InvalidSyntaxException e) { - throw new CmsException("Unable to get roles with filter: " + filter, e); - } - List users = new ArrayList(); - for (Role role : roles) - // if (role.getType() == Role.USER && role.getType() != - // Role.GROUP) - users.add((User) role); - return users; - } - } - - public void refresh() { - userTableViewerCmp.refresh(); - } - - // Override generic view methods - @PreDestroy - public void dispose() { - userAdminWrapper.removeListener(listener); - } - - @Focus - public void setFocus() { - userTableViewerCmp.setFocus(); - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/DeleteGroups.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/DeleteGroups.java deleted file mode 100644 index 742bc3f..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/DeleteGroups.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.argeo.cms.e4.users.handlers; - -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.e4.users.GroupsView; -import org.argeo.cms.e4.users.UserAdminWrapper; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.widgets.Display; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Delete the selected groups */ -public class DeleteGroups { - // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + - // ".deleteGroups"; - - /* DEPENDENCY INJECTION */ - @Inject - private UserAdminWrapper userAdminWrapper; - - @Inject - ESelectionService selectionService; - - @SuppressWarnings("unchecked") - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) { - // ISelection selection = null;// HandlerUtil.getCurrentSelection(event); - // if (selection.isEmpty()) - // return null; - // - // List groups = new ArrayList(); - // Iterator it = ((IStructuredSelection) selection).iterator(); - - List selection = (List) selectionService.getSelection(); - if (selection == null) - return; - - StringBuilder builder = new StringBuilder(); - for (Group group : selection) { - Group currGroup = group; - String groupName = UserAdminUtils.getUserLocalId(currGroup.getName()); - // TODO add checks - builder.append(groupName).append("; "); - // groups.add(currGroup); - } - - if (!MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "Delete Groups", "Are you sure that you " - + "want to delete these groups?\n" + builder.substring(0, builder.length() - 2))) - return; - - userAdminWrapper.beginTransactionIfNeeded(); - UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); - // IWorkbenchPage iwp = - // HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); - for (Group group : selection) { - String groupName = group.getName(); - // TODO find a way to close the editor cleanly if opened. Cannot be - // done through the UserAdminListeners, it causes a - // java.util.ConcurrentModificationException because disposing the - // editor unregisters and disposes the listener - // IEditorPart part = iwp.findEditor(new UserEditorInput(groupName)); - // if (part != null) - // iwp.closeEditor(part, false); - userAdmin.removeRole(groupName); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - - // Update the view - for (Group group : selection) { - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, group)); - } - - // return null; - } - - @CanExecute - public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) { - return part.getObject() instanceof GroupsView && selectionService.getSelection() != null; - } - - /* DEPENDENCY INJECTION */ - // public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - // this.userAdminWrapper = userAdminWrapper; - // } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/DeleteUsers.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/DeleteUsers.java deleted file mode 100644 index d1afd22..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/DeleteUsers.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.argeo.cms.e4.users.handlers; - -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.e4.users.UserAdminWrapper; -import org.argeo.cms.e4.users.UsersView; -import org.eclipse.e4.core.di.annotations.CanExecute; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.e4.ui.workbench.modeling.ESelectionService; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.widgets.Display; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Delete the selected users */ -public class DeleteUsers { - // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".deleteUsers"; - - /* DEPENDENCY INJECTION */ - @Inject - private UserAdminWrapper userAdminWrapper; - - @SuppressWarnings("unchecked") - @Execute - public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) { - // ISelection selection = null;// HandlerUtil.getCurrentSelection(event); - // if (selection.isEmpty()) - // return null; - List selection = (List) selectionService.getSelection(); - if (selection == null) - return; - -// Iterator it = ((IStructuredSelection) selection).iterator(); -// List users = new ArrayList(); - StringBuilder builder = new StringBuilder(); - - for(User user:selection) { - User currUser = user; -// User currUser = it.next(); - String userName = UserAdminUtils.getUserLocalId(currUser.getName()); - if (UserAdminUtils.isCurrentUser(currUser)) { - MessageDialog.openError(Display.getCurrent().getActiveShell(), "Deletion forbidden", - "You cannot delete your own user this way."); - return; - } - builder.append(userName).append("; "); -// users.add(currUser); - } - - if (!MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "Delete Users", - "Are you sure that you want to delete these users?\n" + builder.substring(0, builder.length() - 2))) - return; - - userAdminWrapper.beginTransactionIfNeeded(); - UserAdmin userAdmin = userAdminWrapper.getUserAdmin(); - // IWorkbenchPage iwp = - // HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); - - for (User user : selection) { - String userName = user.getName(); - // TODO find a way to close the editor cleanly if opened. Cannot be - // done through the UserAdminListeners, it causes a - // java.util.ConcurrentModificationException because disposing the - // editor unregisters and disposes the listener - // IEditorPart part = iwp.findEditor(new UserEditorInput(userName)); - // if (part != null) - // iwp.closeEditor(part, false); - userAdmin.removeRole(userName); - } - userAdminWrapper.commitOrNotifyTransactionStateChange(); - - for (User user : selection) { - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_REMOVED, user)); - } - } - - @CanExecute - public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart part, ESelectionService selectionService) { - return part.getObject() instanceof UsersView && selectionService.getSelection() != null; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java deleted file mode 100644 index 41e14e0..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java +++ /dev/null @@ -1,212 +0,0 @@ -package org.argeo.cms.e4.users.handlers; - -import java.util.Dictionary; -import java.util.Map; - -import javax.inject.Inject; - -import org.argeo.cms.e4.users.UserAdminWrapper; -import org.argeo.cms.swt.CmsException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.util.directory.DirectoryConf; -import org.argeo.util.naming.LdapAttrs; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Create a new group */ -public class NewGroup { - // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newGroup"; - - /* DEPENDENCY INJECTION */ - @Inject - private UserAdminWrapper userAdminWrapper; - - @Execute - public Object execute() { - NewGroupWizard newGroupWizard = new NewGroupWizard(); - newGroupWizard.setWindowTitle("Group creation"); - WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), newGroupWizard); - dialog.open(); - return null; - } - - private class NewGroupWizard extends Wizard { - - // Pages - private MainGroupInfoWizardPage mainGroupInfo; - - // UI fields - private Text dNameTxt, commonNameTxt, descriptionTxt; - private Combo baseDnCmb; - - public NewGroupWizard() { - } - - @Override - public void addPages() { - mainGroupInfo = new MainGroupInfoWizardPage(); - addPage(mainGroupInfo); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public boolean performFinish() { - if (!canFinish()) - return false; - String commonName = commonNameTxt.getText(); - try { - userAdminWrapper.beginTransactionIfNeeded(); - String dn = getDn(commonName); - Group group = (Group) userAdminWrapper.getUserAdmin().createRole(dn, Role.GROUP); - Dictionary props = group.getProperties(); - String descStr = descriptionTxt.getText(); - if (EclipseUiUtils.notEmpty(descStr)) - props.put(LdapAttrs.description.name(), descStr); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CREATED, group)); - return true; - } catch (Exception e) { - ErrorFeedback.show("Cannot create new group " + commonName, e); - return false; - } - } - - private class MainGroupInfoWizardPage extends WizardPage implements FocusListener { - private static final long serialVersionUID = -3150193365151601807L; - - public MainGroupInfoWizardPage() { - super("Main"); - setTitle("General information"); - setMessage("Please choose a domain, provide a common name " + "and a free description"); - } - - @Override - public void createControl(Composite parent) { - Composite bodyCmp = new Composite(parent, SWT.NONE); - setControl(bodyCmp); - bodyCmp.setLayout(new GridLayout(2, false)); - - dNameTxt = EclipseUiUtils.createGridLT(bodyCmp, "Distinguished name"); - dNameTxt.setEnabled(false); - - baseDnCmb = createGridLC(bodyCmp, "Base DN"); - // Initialise before adding the listener to avoid NPE - initialiseDnCmb(baseDnCmb); - baseDnCmb.addFocusListener(this); - - commonNameTxt = EclipseUiUtils.createGridLT(bodyCmp, "Common name"); - commonNameTxt.addFocusListener(this); - - Label descLbl = new Label(bodyCmp, SWT.LEAD); - descLbl.setText("Description"); - descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); - descriptionTxt = new Text(bodyCmp, SWT.LEAD | SWT.MULTI | SWT.WRAP | SWT.BORDER); - descriptionTxt.setLayoutData(EclipseUiUtils.fillAll()); - descriptionTxt.addFocusListener(this); - - // Initialize buttons - setPageComplete(false); - getContainer().updateButtons(); - } - - @Override - public void focusLost(FocusEvent event) { - String name = commonNameTxt.getText(); - if (EclipseUiUtils.isEmpty(name)) - dNameTxt.setText(""); - else - dNameTxt.setText(getDn(name)); - - String message = checkComplete(); - if (message != null) { - setMessage(message, WizardPage.ERROR); - setPageComplete(false); - } else { - setMessage("Complete", WizardPage.INFORMATION); - setPageComplete(true); - } - getContainer().updateButtons(); - } - - @Override - public void focusGained(FocusEvent event) { - } - - /** @return the error message or null if complete */ - protected String checkComplete() { - String name = commonNameTxt.getText(); - - if (name.trim().equals("")) - return "Common name must not be empty"; - Role role = userAdminWrapper.getUserAdmin().getRole(getDn(name)); - if (role != null) - return "Group " + name + " already exists"; - return null; - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) - if (baseDnCmb.getSelectionIndex() == -1) - baseDnCmb.setFocus(); - else - commonNameTxt.setFocus(); - } - } - - private Map getDns() { - return userAdminWrapper.getKnownBaseDns(true); - } - - private String getDn(String cn) { - Map dns = getDns(); - String bdn = baseDnCmb.getText(); - if (EclipseUiUtils.notEmpty(bdn)) { - Dictionary props = DirectoryConf.uriAsProperties(dns.get(bdn)); - String dn = LdapAttrs.cn.name() + "=" + cn + "," + DirectoryConf.groupBase.getValue(props) + "," + bdn; - return dn; - } - return null; - } - - private void initialiseDnCmb(Combo combo) { - Map dns = userAdminWrapper.getKnownBaseDns(true); - if (dns.isEmpty()) - throw new CmsException("No writable base dn found. Cannot create group"); - combo.setItems(dns.keySet().toArray(new String[0])); - if (dns.size() == 1) - combo.select(0); - } - } - - private Combo createGridLC(Composite parent, String label) { - Label lbl = new Label(parent, SWT.LEAD); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY); - combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return combo; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java deleted file mode 100644 index 40a4460..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java +++ /dev/null @@ -1,287 +0,0 @@ -package org.argeo.cms.e4.users.handlers; - -import java.util.Dictionary; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.e4.users.UiAdminUtils; -import org.argeo.cms.e4.users.UserAdminWrapper; -import org.argeo.cms.swt.CmsException; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.util.directory.DirectoryConf; -import org.argeo.util.naming.LdapAttrs; -import org.eclipse.e4.core.di.annotations.Execute; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; -import org.osgi.service.useradmin.UserAdminEvent; - -/** Open a wizard that enables creation of a new user. */ -public class NewUser { - // private final static Log log = LogFactory.getLog(NewUser.class); - // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newUser"; - - /* DEPENDENCY INJECTION */ - @Inject - private UserAdminWrapper userAdminWrapper; - - @Execute - public Object execute() { - NewUserWizard newUserWizard = new NewUserWizard(); - newUserWizard.setWindowTitle("User creation"); - WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), newUserWizard); - dialog.open(); - return null; - } - - private class NewUserWizard extends Wizard { - - // pages - private MainUserInfoWizardPage mainUserInfo; - - // End user fields - private Text dNameTxt, usernameTxt, firstNameTxt, lastNameTxt, primaryMailTxt, pwd1Txt, pwd2Txt; - private Combo baseDnCmb; - - public NewUserWizard() { - - } - - @Override - public void addPages() { - mainUserInfo = new MainUserInfoWizardPage(); - addPage(mainUserInfo); - String message = "Default wizard that also eases user creation tests:\n " - + "Mail and last name are automatically " - + "generated form the uid. Password are defauted to 'demo'."; - mainUserInfo.setMessage(message, WizardPage.WARNING); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public boolean performFinish() { - if (!canFinish()) - return false; - String username = mainUserInfo.getUsername(); - userAdminWrapper.beginTransactionIfNeeded(); - try { - User user = (User) userAdminWrapper.getUserAdmin().createRole(getDn(username), Role.USER); - - Dictionary props = user.getProperties(); - - String lastNameStr = lastNameTxt.getText(); - if (EclipseUiUtils.notEmpty(lastNameStr)) - props.put(LdapAttrs.sn.name(), lastNameStr); - - String firstNameStr = firstNameTxt.getText(); - if (EclipseUiUtils.notEmpty(firstNameStr)) - props.put(LdapAttrs.givenName.name(), firstNameStr); - - String cn = UserAdminUtils.buildDefaultCn(firstNameStr, lastNameStr); - if (EclipseUiUtils.notEmpty(cn)) - props.put(LdapAttrs.cn.name(), cn); - - String mailStr = primaryMailTxt.getText(); - if (EclipseUiUtils.notEmpty(mailStr)) - props.put(LdapAttrs.mail.name(), mailStr); - - char[] password = mainUserInfo.getPassword(); - user.getCredentials().put(null, password); - userAdminWrapper.commitOrNotifyTransactionStateChange(); - userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CREATED, user)); - return true; - } catch (Exception e) { - ErrorFeedback.show("Cannot create new user " + username, e); - return false; - } - } - - private class MainUserInfoWizardPage extends WizardPage implements ModifyListener { - private static final long serialVersionUID = -3150193365151601807L; - - public MainUserInfoWizardPage() { - super("Main"); - setTitle("Required Information"); - } - - @Override - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); - dNameTxt = EclipseUiUtils.createGridLT(composite, "Distinguished name", this); - dNameTxt.setEnabled(false); - - baseDnCmb = createGridLC(composite, "Base DN"); - initialiseDnCmb(baseDnCmb); - baseDnCmb.addModifyListener(this); - baseDnCmb.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = -1435351236582736843L; - - @Override - public void modifyText(ModifyEvent event) { - String name = usernameTxt.getText(); - dNameTxt.setText(getDn(name)); - } - }); - - usernameTxt = EclipseUiUtils.createGridLT(composite, "Local ID", this); - usernameTxt.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = -1435351236582736843L; - - @Override - public void modifyText(ModifyEvent event) { - String name = usernameTxt.getText(); - if (name.trim().equals("")) { - dNameTxt.setText(""); - lastNameTxt.setText(""); - primaryMailTxt.setText(""); - pwd1Txt.setText(""); - pwd2Txt.setText(""); - } else { - dNameTxt.setText(getDn(name)); - lastNameTxt.setText(name.toUpperCase()); - primaryMailTxt.setText(getMail(name)); - pwd1Txt.setText("demo"); - pwd2Txt.setText("demo"); - } - } - }); - - primaryMailTxt = EclipseUiUtils.createGridLT(composite, "Email", this); - firstNameTxt = EclipseUiUtils.createGridLT(composite, "First name", this); - lastNameTxt = EclipseUiUtils.createGridLT(composite, "Last name", this); - pwd1Txt = EclipseUiUtils.createGridLP(composite, "Password", this); - pwd2Txt = EclipseUiUtils.createGridLP(composite, "Repeat password", this); - setControl(composite); - - // Initialize buttons - setPageComplete(false); - getContainer().updateButtons(); - } - - @Override - public void modifyText(ModifyEvent event) { - String message = checkComplete(); - if (message != null) { - setMessage(message, WizardPage.ERROR); - setPageComplete(false); - } else { - setMessage("Complete", WizardPage.INFORMATION); - setPageComplete(true); - } - getContainer().updateButtons(); - } - - /** @return error message or null if complete */ - protected String checkComplete() { - String name = usernameTxt.getText(); - - if (name.trim().equals("")) - return "User name must not be empty"; - Role role = userAdminWrapper.getUserAdmin().getRole(getDn(name)); - if (role != null) - return "User " + name + " already exists"; - if (!primaryMailTxt.getText().matches(UiAdminUtils.EMAIL_PATTERN)) - return "Not a valid email address"; - if (lastNameTxt.getText().trim().equals("")) - return "Specify a last name"; - if (pwd1Txt.getText().trim().equals("")) - return "Specify a password"; - if (pwd2Txt.getText().trim().equals("")) - return "Repeat the password"; - if (!pwd2Txt.getText().equals(pwd1Txt.getText())) - return "Passwords are different"; - return null; - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) - if (baseDnCmb.getSelectionIndex() == -1) - baseDnCmb.setFocus(); - else - usernameTxt.setFocus(); - } - - public String getUsername() { - return usernameTxt.getText(); - } - - public char[] getPassword() { - return pwd1Txt.getTextChars(); - } - - } - - private Map getDns() { - return userAdminWrapper.getKnownBaseDns(true); - } - - private String getDn(String uid) { - Map dns = getDns(); - String bdn = baseDnCmb.getText(); - if (EclipseUiUtils.notEmpty(bdn)) { - Dictionary props = DirectoryConf.uriAsProperties(dns.get(bdn)); - String dn = LdapAttrs.uid.name() + "=" + uid + "," + DirectoryConf.userBase.getValue(props) + "," + bdn; - return dn; - } - return null; - } - - private void initialiseDnCmb(Combo combo) { - Map dns = userAdminWrapper.getKnownBaseDns(true); - if (dns.isEmpty()) - throw new CmsException("No writable base dn found. Cannot create user"); - combo.setItems(dns.keySet().toArray(new String[0])); - if (dns.size() == 1) - combo.select(0); - } - - private String getMail(String username) { - if (baseDnCmb.getSelectionIndex() == -1) - return null; - String baseDn = baseDnCmb.getText(); - try { - LdapName name = new LdapName(baseDn); - List rdns = name.getRdns(); - return username + "@" + (String) rdns.get(1).getValue() + '.' + (String) rdns.get(0).getValue(); - } catch (InvalidNameException e) { - throw new CmsException("Unable to generate mail for " + username + " with base dn " + baseDn, e); - } - } - } - - private Combo createGridLC(Composite parent, String label) { - Label lbl = new Label(parent, SWT.LEAD); - lbl.setText(label); - lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); - Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY); - combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - return combo; - } - - /* DEPENDENCY INJECTION */ - public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) { - this.userAdminWrapper = userAdminWrapper; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/package-info.java deleted file mode 100644 index cf3db1d..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/handlers/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Users management handlers. */ -package org.argeo.cms.e4.users.handlers; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/package-info.java deleted file mode 100644 index c6f14b0..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Users management perspective. */ -package org.argeo.cms.e4.users; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java deleted file mode 100644 index 2d8db67..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.util.naming.LdapAttrs; -import org.osgi.service.useradmin.User; - -/** Simply declare a label provider that returns the common name of a user */ -public class CommonNameLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 5256703081044911941L; - - @Override - public String getText(User user) { - return UserAdminUtils.getProperty(user, LdapAttrs.cn.name()); - } - - @Override - public String getToolTipText(Object element) { - return UserAdminUtils.getProperty((User) element, LdapAttrs.DN); - } - -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/DomainNameLP.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/DomainNameLP.java deleted file mode 100644 index e23729d..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/DomainNameLP.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import org.argeo.cms.auth.UserAdminUtils; -import org.osgi.service.useradmin.User; - -/** The human friendly domain name for the corresponding user. */ -public class DomainNameLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 5256703081044911941L; - - @Override - public String getText(User user) { - return UserAdminUtils.getDomainName(user); - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/MailLP.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/MailLP.java deleted file mode 100644 index 52d3b85..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/MailLP.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.util.naming.LdapAttrs; -import org.osgi.service.useradmin.User; - -/** Simply declare a label provider that returns the Primary Mail of a user */ -public class MailLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 8329764452141982707L; - - @Override - public String getText(User user) { - return UserAdminUtils.getProperty(user, LdapAttrs.mail.name()); - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java deleted file mode 100644 index 8e12eed..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import org.argeo.api.cms.CmsContext; -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.e4.users.SecurityAdminImages; -import org.argeo.util.naming.LdapAttrs; -import org.eclipse.swt.graphics.Image; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.User; - -/** Provide a bundle specific image depending on the current user type */ -public class RoleIconLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 6550449442061090388L; - - @Override - public String getText(User user) { - return ""; - } - - @Override - public Image getImage(Object element) { - User user = (User) element; - String dn = user.getName(); - if (dn.endsWith(CmsConstants.SYSTEM_ROLES_BASEDN)) - return SecurityAdminImages.ICON_ROLE; - else if (user.getType() == Role.GROUP) { - String businessCategory = UserAdminUtils.getProperty(user, LdapAttrs.businessCategory); - if (businessCategory != null && businessCategory.equals(CmsContext.WORKGROUP)) - return SecurityAdminImages.ICON_WORKGROUP; - return SecurityAdminImages.ICON_GROUP; - } else - return SecurityAdminImages.ICON_USER; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserAdminAbstractLP.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserAdminAbstractLP.java deleted file mode 100644 index 29873db..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserAdminAbstractLP.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; - -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.cms.swt.CmsException; -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.widgets.Display; -import org.osgi.service.useradmin.User; - -/** - * Utility class that add font modifications to a column label provider - * depending on the given user properties - */ -public abstract class UserAdminAbstractLP extends ColumnLabelProvider { - private static final long serialVersionUID = 137336765024922368L; - - // private Font italic; - private Font bold; - - @Override - public Font getFont(Object element) { - // Self as bold - try { - LdapName selfUserName = UserAdminUtils.getCurrentUserLdapName(); - String userName = ((User) element).getName(); - LdapName userLdapName = new LdapName(userName); - if (userLdapName.equals(selfUserName)) { - if (bold == null) - bold = JFaceResources.getFontRegistry() - .defaultFontDescriptor().setStyle(SWT.BOLD) - .createFont(Display.getCurrent()); - return bold; - } - } catch (InvalidNameException e) { - throw new CmsException("cannot parse dn for " + element, e); - } - - // Disabled as Italic - // Node userProfile = (Node) elem; - // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) - // return italic; - - return null; - // return super.getFont(element); - } - - @Override - public String getText(Object element) { - User user = (User) element; - return getText(user); - } - - public void setDisplay(Display display) { - // italic = JFaceResources.getFontRegistry().defaultFontDescriptor() - // .setStyle(SWT.ITALIC).createFont(display); - bold = JFaceResources.getFontRegistry().defaultFontDescriptor() - .setStyle(SWT.BOLD).createFont(Display.getCurrent()); - } - - public abstract String getText(User user); -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserDragListener.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserDragListener.java deleted file mode 100644 index 56a2624..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserDragListener.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.dnd.DragSourceEvent; -import org.eclipse.swt.dnd.DragSourceListener; -import org.osgi.service.useradmin.User; - -/** Default drag listener to modify group and users via the UI */ -public class UserDragListener implements DragSourceListener { - private static final long serialVersionUID = -2074337775033781454L; - private final Viewer viewer; - - public UserDragListener(Viewer viewer) { - this.viewer = viewer; - } - - public void dragStart(DragSourceEvent event) { - // TODO implement finer checks - IStructuredSelection selection = (IStructuredSelection) viewer - .getSelection(); - if (selection.isEmpty() || selection.size() > 1) - event.doit = false; - else - event.doit = true; - } - - public void dragSetData(DragSourceEvent event) { - // TODO Support multiple selection - Object obj = ((IStructuredSelection) viewer.getSelection()) - .getFirstElement(); - if (obj != null) { - User user = (User) obj; - event.data = user.getName(); - } - } - - public void dragFinished(DragSourceEvent event) { - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java deleted file mode 100644 index 7a7bfbf..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.util.naming.LdapAttrs; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.osgi.service.useradmin.User; - -/** - * Filter user list using JFace mechanism on the client (yet on the server) side - * rather than having the UserAdmin to process the search - */ -public class UserFilter extends ViewerFilter { - private static final long serialVersionUID = 5082509381672880568L; - - private String searchString; - private boolean showSystemRole = true; - - private final String[] knownProps = { LdapAttrs.DN, LdapAttrs.cn.name(), LdapAttrs.givenName.name(), - LdapAttrs.sn.name(), LdapAttrs.uid.name(), LdapAttrs.description.name(), LdapAttrs.mail.name() }; - - public void setSearchText(String s) { - // ensure that the value can be used for matching - if (notEmpty(s)) - searchString = ".*" + s.toLowerCase() + ".*"; - else - searchString = ".*"; - } - - public void setShowSystemRole(boolean showSystemRole) { - this.showSystemRole = showSystemRole; - } - - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - User user = (User) element; - if (!showSystemRole && user.getName().matches(".*(" + CmsConstants.SYSTEM_ROLES_BASEDN + ")")) - // UserAdminUtils.getProperty(user, LdifName.dn.name()) - // .toLowerCase().endsWith(AuthConstants.ROLES_BASEDN)) - return false; - - if (searchString == null || searchString.length() == 0) - return true; - - if (user.getName().matches(searchString)) - return true; - - for (String key : knownProps) { - String currVal = UserAdminUtils.getProperty(user, key); - if (notEmpty(currVal) && currVal.toLowerCase().matches(searchString)) - return true; - } - return false; - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserNameLP.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserNameLP.java deleted file mode 100644 index 3cd00eb..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/UserNameLP.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.argeo.cms.e4.users.providers; - -import org.osgi.service.useradmin.User; - -/** Simply declare a label provider that returns the username of a user */ -public class UserNameLP extends UserAdminAbstractLP { - private static final long serialVersionUID = 6550449442061090388L; - - @Override - public String getText(User user) { - return user.getName(); - } -} diff --git a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/package-info.java b/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/package-info.java deleted file mode 100644 index 33bef8d..0000000 --- a/swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/users/providers/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Users management content providers. */ -package org.argeo.cms.e4.users.providers; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/bnd.bnd b/swt/org.argeo.cms.jcr.ui/bnd.bnd index c3c609c..60d23b1 100644 --- a/swt/org.argeo.cms.jcr.ui/bnd.bnd +++ b/swt/org.argeo.cms.jcr.ui/bnd.bnd @@ -1,4 +1,3 @@ -Bundle-Activator: org.argeo.cms.ui.internal.Activator Bundle-ActivationPolicy: lazy Import-Package: org.eclipse.swt,\ 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/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/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java deleted file mode 100644 index 4fd1d68..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import java.util.Collection; - -import org.argeo.api.cms.CmsLog; -import org.argeo.cms.swt.CmsSwtUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -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; - -abstract class AbstractOsgiComposite extends Composite { - private static final long serialVersionUID = -4097415973477517137L; - protected final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); - protected final CmsLog log = CmsLog.getLog(getClass()); - - public AbstractOsgiComposite(Composite parent, int style) { - super(parent, style); - parent.setLayout(CmsSwtUtils.noSpaceGridLayout()); - setLayout(CmsSwtUtils.noSpaceGridLayout()); - setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); - initUi(style); - } - - protected abstract void initUi(int style); - - protected T getService(Class clazz) { - return bc.getService(bc.getServiceReference(clazz)); - } - - protected Collection> getServiceReferences(Class clazz, String filter) { - try { - return bc.getServiceReferences(clazz, filter); - } catch (InvalidSyntaxException e) { - throw new IllegalArgumentException("Filter " + filter + " is invalid", e); - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/Browse.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/Browse.java deleted file mode 100644 index a536da0..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/Browse.java +++ /dev/null @@ -1,576 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import static org.eclipse.swt.SWT.RIGHT; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.LinkedHashMap; - -import javax.jcr.ItemNotFoundException; -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; -import javax.jcr.Value; - -import org.argeo.api.cms.ux.Cms2DSize; -import org.argeo.cms.swt.CmsException; -import org.argeo.cms.swt.CmsSwtUtils; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.util.CmsLink; -import org.argeo.cms.ui.widgets.EditableImage; -import org.argeo.cms.ui.widgets.Img; -import org.argeo.jcr.JcrUtils; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ILazyContentProvider; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -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.custom.ScrolledComposite; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -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.Label; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Text; - -public class Browse implements CmsUiProvider { - - // Some local constants to experiment. should be cleaned - private final static String BROWSE_PREFIX = "browse#"; - private final static int THUMBNAIL_WIDTH = 400; - private final static int COLUMN_WIDTH = 160; - private DateFormat timeFormatter = new SimpleDateFormat("dd-MM-yyyy', 'HH:mm"); - - // keep a cache of the opened nodes - // Key is the path - private LinkedHashMap browserCols = new LinkedHashMap(); - private Composite nodeDisplayParent; - private Composite colViewer; - private ScrolledComposite scrolledCmp; - private Text parentPathTxt; - private Text filterTxt; - private Node currEdited; - - private String initialPath; - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - if (context == null) - // return null; - throw new CmsException("Context cannot be null"); - GridLayout layout = CmsSwtUtils.noSpaceGridLayout(); - layout.numColumns = 2; - parent.setLayout(layout); - - // Left - Composite leftCmp = new Composite(parent, SWT.NO_FOCUS); - leftCmp.setLayoutData(CmsSwtUtils.fillAll()); - createBrowserPart(leftCmp, context); - - // Right - nodeDisplayParent = new Composite(parent, SWT.NO_FOCUS | SWT.BORDER); - GridData gd = new GridData(SWT.RIGHT, SWT.FILL, false, true); - gd.widthHint = THUMBNAIL_WIDTH; - nodeDisplayParent.setLayoutData(gd); - createNodeView(nodeDisplayParent, context); - - // INIT - setEdited(context); - initialPath = context.getPath(); - - // Workaround we don't yet manage the delete to display parent of the - // initial context node - - return null; - } - - private void createBrowserPart(Composite parent, Node context) throws RepositoryException { - GridLayout layout = CmsSwtUtils.noSpaceGridLayout(); - parent.setLayout(layout); - Composite filterCmp = new Composite(parent, SWT.NO_FOCUS); - filterCmp.setLayoutData(CmsSwtUtils.fillWidth()); - - // top filter - addFilterPanel(filterCmp); - - // scrolled composite - scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER | SWT.NO_FOCUS); - scrolledCmp.setLayoutData(CmsSwtUtils.fillAll()); - scrolledCmp.setExpandVertical(true); - scrolledCmp.setExpandHorizontal(true); - scrolledCmp.setShowFocusedControl(true); - - colViewer = new Composite(scrolledCmp, SWT.NO_FOCUS); - scrolledCmp.setContent(colViewer); - scrolledCmp.addControlListener(new ControlAdapter() { - private static final long serialVersionUID = 6589392045145698201L; - - @Override - public void controlResized(ControlEvent e) { - Rectangle r = scrolledCmp.getClientArea(); - scrolledCmp.setMinSize(colViewer.computeSize(SWT.DEFAULT, r.height)); - } - }); - initExplorer(colViewer, context); - } - - private Control initExplorer(Composite parent, Node context) throws RepositoryException { - parent.setLayout(CmsSwtUtils.noSpaceGridLayout()); - createBrowserColumn(parent, context); - return null; - } - - private Control createBrowserColumn(Composite parent, Node context) throws RepositoryException { - // TODO style is not correctly managed. - FilterEntitiesVirtualTable table = new FilterEntitiesVirtualTable(parent, SWT.BORDER | SWT.NO_FOCUS, context); - // CmsUiUtils.style(table, ArgeoOrgStyle.browserColumn.style()); - table.filterList("*"); - table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true)); - browserCols.put(context.getPath(), table); - return null; - } - - public void addFilterPanel(Composite parent) { - - parent.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false))); - - // Text Area for the filter - parentPathTxt = new Text(parent, SWT.NO_FOCUS); - parentPathTxt.setEditable(false); - filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL); - filterTxt.setMessage("Filter current list"); - filterTxt.setLayoutData(CmsSwtUtils.fillWidth()); - filterTxt.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = 7709303319740056286L; - - public void modifyText(ModifyEvent event) { - modifyFilter(false); - } - }); - - filterTxt.addKeyListener(new KeyListener() { - private static final long serialVersionUID = -4523394262771183968L; - - @Override - public void keyReleased(KeyEvent e) { - } - - @Override - public void keyPressed(KeyEvent e) { - boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0; - // boolean altPressed = (e.stateMask & SWT.ALT) != 0; - FilterEntitiesVirtualTable currTable = null; - if (currEdited != null) { - FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited)); - if (table != null && !table.isDisposed()) - currTable = table; - } - - try { - if (e.keyCode == SWT.ARROW_DOWN) - currTable.setFocus(); - else if (e.keyCode == SWT.BS) { - if (filterTxt.getText().equals("") - && !(getPath(currEdited).equals("/") || getPath(currEdited).equals(initialPath))) { - setEdited(currEdited.getParent()); - e.doit = false; - filterTxt.setFocus(); - } - } else if (e.keyCode == SWT.TAB && !shiftPressed) { - if (currEdited.getNodes(filterTxt.getText() + "*").getSize() == 1) { - setEdited(currEdited.getNodes(filterTxt.getText() + "*").nextNode()); - } - filterTxt.setFocus(); - e.doit = false; - } - } catch (RepositoryException e1) { - throw new CmsException("Unexpected error in key management for " + currEdited + "with filter " - + filterTxt.getText(), e1); - } - - } - }); - } - - private void setEdited(Node node) { - try { - currEdited = node; - CmsSwtUtils.clear(nodeDisplayParent); - createNodeView(nodeDisplayParent, currEdited); - nodeDisplayParent.layout(); - refreshFilters(node); - refreshBrowser(node); - } catch (RepositoryException re) { - throw new CmsException("Unable to update browser for " + node, re); - } - } - - private void refreshFilters(Node node) throws RepositoryException { - String currNodePath = node.getPath(); - parentPathTxt.setText(currNodePath); - filterTxt.setText(""); - filterTxt.getParent().layout(); - } - - private void refreshBrowser(Node node) throws RepositoryException { - - // Retrieve - String currNodePath = node.getPath(); - String currParPath = ""; - if (!"/".equals(currNodePath)) - currParPath = JcrUtils.parentPath(currNodePath); - if ("".equals(currParPath)) - currParPath = "/"; - - Object[][] colMatrix = new Object[browserCols.size()][2]; - - int i = 0, j = -1, k = -1; - for (String path : browserCols.keySet()) { - colMatrix[i][0] = path; - colMatrix[i][1] = browserCols.get(path); - if (j >= 0 && k < 0 && !currNodePath.equals("/")) { - boolean leaveOpened = path.startsWith(currNodePath); - - // workaround for same name siblings - // fix me weird side effect when we go left or click on anb - // already selected, unfocused node - if (leaveOpened && (path.lastIndexOf("/") == 0 && currNodePath.lastIndexOf("/") == 0 - || JcrUtils.parentPath(path).equals(JcrUtils.parentPath(currNodePath)))) - leaveOpened = JcrUtils.lastPathElement(path).equals(JcrUtils.lastPathElement(currNodePath)); - - if (!leaveOpened) - k = i; - } - if (currParPath.equals(path)) - j = i; - i++; - } - - if (j >= 0 && k >= 0) - // remove useless cols - for (int l = i - 1; l >= k; l--) { - browserCols.remove(colMatrix[l][0]); - ((FilterEntitiesVirtualTable) colMatrix[l][1]).dispose(); - } - - // Remove disposed columns - // TODO investigate and fix the mechanism that leave them there after - // disposal - if (browserCols.containsKey(currNodePath)) { - FilterEntitiesVirtualTable currCol = browserCols.get(currNodePath); - if (currCol.isDisposed()) - browserCols.remove(currNodePath); - } - - if (!browserCols.containsKey(currNodePath)) - createBrowserColumn(colViewer, node); - - colViewer.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false))); - // colViewer.pack(); - colViewer.layout(); - // also resize the scrolled composite - scrolledCmp.layout(); - scrolledCmp.getShowFocusedControl(); - // colViewer.getParent().layout(); - // if (JcrUtils.parentPath(currNodePath).equals(currBrowserKey)) { - // } else { - // } - } - - private void modifyFilter(boolean fromOutside) { - if (!fromOutside) - if (currEdited != null) { - String filter = filterTxt.getText() + "*"; - FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited)); - if (table != null && !table.isDisposed()) - table.filterList(filter); - } - - } - - private String getPath(Node node) { - try { - return node.getPath(); - } catch (RepositoryException e) { - throw new CmsException("Unable to get path for node " + node, e); - } - } - - private Cms2DSize imageWidth = new Cms2DSize(250, 0); - - /** - * Recreates the content of the box that displays information about the current - * selected node. - */ - private Control createNodeView(Composite parent, Node context) throws RepositoryException { - - parent.setLayout(new GridLayout(2, false)); - - if (isImg(context)) { - EditableImage image = new Img(parent, RIGHT, context, imageWidth); - image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 2, 1)); - } - - // Name and primary type - Label contextL = new Label(parent, SWT.NONE); - CmsSwtUtils.markup(contextL); - contextL.setText("" + context.getName() + ""); - new Label(parent, SWT.NONE).setText(context.getPrimaryNodeType().getName()); - - // Children - for (NodeIterator nIt = context.getNodes(); nIt.hasNext();) { - Node child = nIt.nextNode(); - new CmsLink(child.getName(), BROWSE_PREFIX + child.getPath()).createUi(parent, context); - new Label(parent, SWT.NONE).setText(child.getPrimaryNodeType().getName()); - } - - // Properties - for (PropertyIterator pIt = context.getProperties(); pIt.hasNext();) { - Property property = pIt.nextProperty(); - Label label = new Label(parent, SWT.NONE); - label.setText(property.getName()); - label.setToolTipText(JcrUtils.getPropertyDefinitionAsString(property)); - new Label(parent, SWT.NONE).setText(getPropAsString(property)); - } - - return null; - } - - private boolean isImg(Node node) throws RepositoryException { - // TODO support images - return false; -// return node.hasNode(JCR_CONTENT) && node.isNodeType(CmsTypes.CMS_IMAGE); - } - - private String getPropAsString(Property property) throws RepositoryException { - String result = ""; - if (property.isMultiple()) { - result = getMultiAsString(property, ", "); - } else { - Value value = property.getValue(); - if (value.getType() == PropertyType.BINARY) - result = ""; - else if (value.getType() == PropertyType.DATE) - result = timeFormatter.format(value.getDate().getTime()); - else - result = value.getString(); - } - return result; - } - - private String getMultiAsString(Property property, String separator) throws RepositoryException { - if (separator == null) - separator = "; "; - Value[] values = property.getValues(); - StringBuilder builder = new StringBuilder(); - for (Value val : values) { - String currStr = val.getString(); - if (!"".equals(currStr.trim())) - builder.append(currStr).append(separator); - } - if (builder.lastIndexOf(separator) >= 0) - return builder.substring(0, builder.length() - separator.length()); - else - return builder.toString(); - } - - /** Almost canonical implementation of a table that display entities */ - private class FilterEntitiesVirtualTable extends Composite { - private static final long serialVersionUID = 8798147431706283824L; - - // Context - private Node context; - - // UI Objects - private TableViewer entityViewer; - - // enable management of multiple columns - Node getNode() { - return context; - } - - @Override - public boolean setFocus() { - if (entityViewer.getTable().isDisposed()) - return false; - if (entityViewer.getSelection().isEmpty()) { - Object first = entityViewer.getElementAt(0); - if (first != null) { - entityViewer.setSelection(new StructuredSelection(first), true); - } - } - return entityViewer.getTable().setFocus(); - } - - void filterList(String filter) { - try { - NodeIterator nit = context.getNodes(filter); - refreshFilteredList(nit); - } catch (RepositoryException e) { - throw new CmsException("Unable to filter " + getNode() + " children with filter " + filter, e); - } - - } - - public FilterEntitiesVirtualTable(Composite parent, int style, Node context) { - super(parent, SWT.NO_FOCUS); - this.context = context; - populate(); - } - - protected void populate() { - Composite parent = this; - GridLayout layout = CmsSwtUtils.noSpaceGridLayout(); - - this.setLayout(layout); - createTableViewer(parent); - } - - private void createTableViewer(final Composite parent) { - // the list - // We must limit the size of the table otherwise the full list is - // loaded - // before the layout happens - Composite listCmp = new Composite(parent, SWT.NO_FOCUS); - GridData gd = new GridData(SWT.LEFT, SWT.FILL, false, true); - gd.widthHint = COLUMN_WIDTH; - listCmp.setLayoutData(gd); - listCmp.setLayout(CmsSwtUtils.noSpaceGridLayout()); - - entityViewer = new TableViewer(listCmp, SWT.VIRTUAL | SWT.SINGLE); - Table table = entityViewer.getTable(); - - table.setLayoutData(CmsSwtUtils.fillAll()); - table.setLinesVisible(true); - table.setHeaderVisible(false); - CmsSwtUtils.markup(table); - - CmsSwtUtils.style(table, MaintenanceStyles.BROWSER_COLUMN); - - // first column - TableViewerColumn column = new TableViewerColumn(entityViewer, SWT.NONE); - TableColumn tcol = column.getColumn(); - tcol.setWidth(COLUMN_WIDTH); - tcol.setResizable(true); - column.setLabelProvider(new SimpleNameLP()); - - entityViewer.setContentProvider(new MyLazyCP(entityViewer)); - entityViewer.addSelectionChangedListener(new ISelectionChangedListener() { - - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection(); - if (selection.isEmpty()) - return; - else - setEdited((Node) selection.getFirstElement()); - - } - }); - - table.addKeyListener(new KeyListener() { - private static final long serialVersionUID = -330694313896036230L; - - @Override - public void keyReleased(KeyEvent e) { - } - - @Override - public void keyPressed(KeyEvent e) { - - IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection(); - Node selected = null; - if (!selection.isEmpty()) - selected = ((Node) selection.getFirstElement()); - try { - if (e.keyCode == SWT.ARROW_RIGHT) { - if (selected != null) { - setEdited(selected); - browserCols.get(selected.getPath()).setFocus(); - } - } else if (e.keyCode == SWT.ARROW_LEFT) { - try { - selected = getNode().getParent(); - String newPath = selected.getPath(); // getNode().getParent() - setEdited(selected); - if (browserCols.containsKey(newPath)) - browserCols.get(newPath).setFocus(); - } catch (ItemNotFoundException ie) { - // root silent - } - } - } catch (RepositoryException ie) { - throw new CmsException("Error while managing arrow " + "events in the browser for " + selected, - ie); - } - } - }); - } - - private class MyLazyCP implements ILazyContentProvider { - private static final long serialVersionUID = 1L; - private TableViewer viewer; - private Object[] elements; - - public MyLazyCP(TableViewer viewer) { - this.viewer = viewer; - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // IMPORTANT: don't forget this: an exception will be thrown if - // a selected object is not part of the results anymore. - viewer.setSelection(null); - this.elements = (Object[]) newInput; - } - - public void updateElement(int index) { - viewer.replace(elements[index], index); - } - } - - protected void refreshFilteredList(NodeIterator children) { - Object[] rows = JcrUtils.nodeIteratorToList(children).toArray(); - entityViewer.setInput(rows); - entityViewer.setItemCount(rows.length); - entityViewer.refresh(); - } - - public class SimpleNameLP extends ColumnLabelProvider { - private static final long serialVersionUID = 2465059387875338553L; - - @Override - public String getText(Object element) { - if (element instanceof Node) { - Node curr = ((Node) element); - try { - return curr.getName(); - } catch (RepositoryException e) { - throw new CmsException("Unable to get name for" + curr); - } - } - return super.getText(element); - } - } - } -} \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/ConnectivityDeploymentUi.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/ConnectivityDeploymentUi.java deleted file mode 100644 index 97f3e67..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/ConnectivityDeploymentUi.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import org.argeo.cms.swt.CmsSwtUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.osgi.framework.ServiceReference; -import org.osgi.service.http.HttpService; -import org.osgi.service.useradmin.UserAdmin; - -class ConnectivityDeploymentUi extends AbstractOsgiComposite { - private static final long serialVersionUID = 590221539553514693L; - - public ConnectivityDeploymentUi(Composite parent, int style) { - super(parent, style); - } - - @Override - protected void initUi(int style) { - StringBuffer text = new StringBuffer(); - text.append("Provided Servers
"); - - ServiceReference userAdminRef = bc.getServiceReference(HttpService.class); - if (userAdminRef != null) { - // FIXME use constants - Object httpPort = userAdminRef.getProperty("http.port"); - Object httpsPort = userAdminRef.getProperty("https.port"); - if (httpPort != null) - text.append("http ").append(httpPort).append("
"); - if (httpsPort != null) - text.append("https ").append(httpsPort).append("
"); - - } - - text.append("
"); - text.append("Referenced Servers
"); - - Label label = new Label(this, SWT.NONE); - label.setData(new GridData(SWT.FILL, SWT.FILL, false, false)); - CmsSwtUtils.markup(label); - label.setText(text.toString()); - } - - protected boolean isDeployed() { - return bc.getServiceReference(UserAdmin.class) != null; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java deleted file mode 100644 index ef95bde..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java +++ /dev/null @@ -1,139 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import java.io.File; -import java.io.IOException; -import java.nio.file.FileStore; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; - -import org.apache.jackrabbit.core.RepositoryContext; -import org.apache.jackrabbit.core.config.RepositoryConfig; -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.swt.CmsSwtUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.osgi.framework.ServiceReference; - -class DataDeploymentUi extends AbstractOsgiComposite { - private static final long serialVersionUID = 590221539553514693L; - - public DataDeploymentUi(Composite parent, int style) { - super(parent, style); - } - - @Override - protected void initUi(int style) { - if (isDeployed()) { - initCurrentUi(this); - } else { - initNewUi(this); - } - } - - private void initNewUi(Composite parent) { -// try { -// ConfigurationAdmin confAdmin = bc.getService(bc.getServiceReference(ConfigurationAdmin.class)); -// Configuration[] confs = confAdmin.listConfigurations( -// "(" + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + NodeConstants.NODE_REPOS_FACTORY_PID + ")"); -// if (confs == null || confs.length == 0) { -// Group buttonGroup = new Group(parent, SWT.NONE); -// buttonGroup.setText("Repository Type"); -// buttonGroup.setLayout(new GridLayout(2, true)); -// buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL)); -// -// SelectionListener selectionListener = new SelectionAdapter() { -// private static final long serialVersionUID = 6247064348421088092L; -// -// public void widgetSelected(SelectionEvent event) { -// Button radio = (Button) event.widget; -// if (!radio.getSelection()) -// return; -// log.debug(event); -// JackrabbitType nodeType = (JackrabbitType) radio.getData(); -// if (log.isDebugEnabled()) -// log.debug(" selected = " + nodeType.name()); -// }; -// }; -// -// for (JackrabbitType nodeType : JackrabbitType.values()) { -// Button radio = new Button(buttonGroup, SWT.RADIO); -// radio.setText(nodeType.name()); -// radio.setData(nodeType); -// if (nodeType.equals(JackrabbitType.localfs)) -// radio.setSelection(true); -// radio.addSelectionListener(selectionListener); -// } -// -// } else if (confs.length == 1) { -// -// } else { -// throw new CmsException("Multiple repos not yet supported"); -// } -// } catch (Exception e) { -// throw new CmsException("Cannot initialize UI", e); -// } - - } - - private void initCurrentUi(Composite parent) { - parent.setLayout(new GridLayout()); - Collection> contexts = getServiceReferences(RepositoryContext.class, - "(" + CmsConstants.CN + "=*)"); - StringBuffer text = new StringBuffer(); - text.append("Jackrabbit Repositories
"); - for (ServiceReference sr : contexts) { - RepositoryContext repositoryContext = bc.getService(sr); - String alias = sr.getProperty(CmsConstants.CN).toString(); - String rootNodeId = repositoryContext.getRootNodeId().toString(); - RepositoryConfig repositoryConfig = repositoryContext.getRepositoryConfig(); - Path repoHomePath = new File(repositoryConfig.getHomeDir()).toPath().toAbsolutePath(); - // TODO check data store - - text.append("" + alias + "
"); - text.append("rootNodeId: " + rootNodeId + "
"); - try { - FileStore fileStore = Files.getFileStore(repoHomePath); - text.append("partition: " + fileStore.toString() + "
"); - text.append( - percentUsed(fileStore) + " used (" + humanReadable(fileStore.getUsableSpace()) + " free)
"); - } catch (IOException e) { - log.error("Cannot check fileStore for " + repoHomePath, e); - } - } - Label label = new Label(parent, SWT.NONE); - label.setData(new GridData(SWT.FILL, SWT.FILL, false, false)); - CmsSwtUtils.markup(label); - label.setText("" + text.toString() + ""); - } - - private String humanReadable(long bytes) { - long mb = bytes / (1024 * 1024); - return mb >= 2048 ? Long.toString(mb / 1024) + " GB" : Long.toString(mb) + " MB"; - } - - private String percentUsed(FileStore fs) throws IOException { - long used = fs.getTotalSpace() - fs.getUnallocatedSpace(); - long percent = used * 100 / fs.getTotalSpace(); - if (log.isTraceEnabled()) { - // output identical to `df -B 1`) - log.trace(fs.getTotalSpace() + "," + used + "," + fs.getUsableSpace()); - } - String span; - if (percent < 80) - span = ""; - else if (percent < 95) - span = ""; - else - span = ""; - return span + percent + "%"; - } - - protected boolean isDeployed() { - return bc.getServiceReference(RepositoryContext.class) != null; - } - -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java deleted file mode 100644 index 0a28dc5..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import java.util.GregorianCalendar; -import java.util.TimeZone; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.api.cms.CmsContext; -import org.argeo.api.cms.CmsDeployment; -import org.argeo.api.cms.CmsState; -import org.argeo.cms.swt.CmsSwtUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; - -class DeploymentEntryPoint { - private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); - - protected void createContents(Composite parent) { - // FIXME manage authentication if needed - // if (!CurrentUser.roles().contains(AuthConstants.ROLE_ADMIN)) - // return; - - // parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - if (isDesktop()) { - parent.setLayout(new GridLayout(2, true)); - } else { - // TODO add scrolling - parent.setLayout(new GridLayout(1, true)); - } - - initHighLevelSummary(parent); - - Group securityGroup = createHighLevelGroup(parent, "Security"); - securityGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); - new SecurityDeploymentUi(securityGroup, SWT.NONE); - - Group dataGroup = createHighLevelGroup(parent, "Data"); - dataGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); - new DataDeploymentUi(dataGroup, SWT.NONE); - - Group logGroup = createHighLevelGroup(parent, "Notifications"); - logGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); - new LogDeploymentUi(logGroup, SWT.NONE); - - Group connectivityGroup = createHighLevelGroup(parent, "Connectivity"); - new ConnectivityDeploymentUi(connectivityGroup, SWT.NONE); - connectivityGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); - - } - - private void initHighLevelSummary(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); - if (isDesktop()) - gridData.horizontalSpan = 3; - composite.setLayoutData(gridData); - composite.setLayout(new FillLayout()); - - ServiceReference nodeStateRef = bc.getServiceReference(CmsState.class); - if (nodeStateRef == null) - throw new IllegalStateException("No CMS state available"); - CmsState nodeState = bc.getService(nodeStateRef); - ServiceReference nodeDeploymentRef = bc.getServiceReference(CmsContext.class); - Label label = new Label(composite, SWT.WRAP); - CmsSwtUtils.markup(label); - if (nodeDeploymentRef == null) { - label.setText("Not yet deployed on, please configure below."); - } else { - Object stateUuid = nodeStateRef.getProperty(CmsConstants.CN); - CmsContext nodeDeployment = bc.getService(nodeDeploymentRef); - GregorianCalendar calendar = new GregorianCalendar(); - calendar.setTimeInMillis(nodeDeployment.getAvailableSince()); - calendar.setTimeZone(TimeZone.getDefault()); - label.setText("Deployment state " + stateUuid + ", available since " + calendar.getTime() + ""); - } - } - - private static Group createHighLevelGroup(Composite parent, String text) { - Group group = new Group(parent, SWT.NONE); - group.setText(text); - CmsSwtUtils.markup(group); - return group; - } - - private boolean isDesktop() { - return true; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/LogDeploymentUi.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/LogDeploymentUi.java deleted file mode 100644 index fa5d3da..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/LogDeploymentUi.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Enumeration; -import java.util.GregorianCalendar; -import java.util.TimeZone; - -import org.argeo.cms.swt.CmsSwtUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Text; -import org.osgi.service.log.LogEntry; -import org.osgi.service.log.LogListener; -import org.osgi.service.log.LogReaderService; - -class LogDeploymentUi extends AbstractOsgiComposite implements LogListener { - private static final long serialVersionUID = 590221539553514693L; - - private DateFormat dateFormat = new SimpleDateFormat("MMdd HH:mm"); - - private Display display; - private Text logDisplay; - - public LogDeploymentUi(Composite parent, int style) { - super(parent, style); - } - - @Override - protected void initUi(int style) { - LogReaderService logReader = getService(LogReaderService.class); - // FIXME use server push - // logReader.addLogListener(this); - this.display = getDisplay(); - this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - logDisplay = new Text(this, SWT.WRAP | SWT.MULTI | SWT.READ_ONLY); - logDisplay.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - CmsSwtUtils.markup(logDisplay); - Enumeration logEntries = (Enumeration) logReader.getLog(); - while (logEntries.hasMoreElements()) - logDisplay.append(printEntry(logEntries.nextElement())); - } - - private String printEntry(LogEntry entry) { - StringBuilder sb = new StringBuilder(); - GregorianCalendar calendar = new GregorianCalendar(TimeZone.getDefault()); - calendar.setTimeInMillis(entry.getTime()); - sb.append(dateFormat.format(calendar.getTime())).append(' '); - sb.append(entry.getMessage()); - sb.append('\n'); - return sb.toString(); - } - - @Override - public void logged(LogEntry entry) { - if (display.isDisposed()) - return; - display.asyncExec(() -> { - if (logDisplay.isDisposed()) - return; - logDisplay.append(printEntry(entry)); - }); - display.wake(); - } - - // @Override - // public void dispose() { - // super.dispose(); - // getService(LogReaderService.class).removeLogListener(this); - // } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/MaintenanceStyles.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/MaintenanceStyles.java deleted file mode 100644 index df1be51..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/MaintenanceStyles.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -/** Specific styles used by the various maintenance pages . */ -public interface MaintenanceStyles { - // General - public final static String PREFIX = "maintenance_"; - - // Browser - public final static String BROWSER_COLUMN = "browser_column"; - } diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/NonAdminPage.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/NonAdminPage.java deleted file mode 100644 index cb38ce8..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/NonAdminPage.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.swt.CmsSwtUtils; -import org.argeo.cms.ui.CmsUiProvider; -import org.eclipse.swt.SWT; -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.Label; - -public class NonAdminPage implements CmsUiProvider{ - - @Override - public Control createUi(Composite parent, Node context) - throws RepositoryException { - Composite body = new Composite(parent, SWT.NO_FOCUS); - body.setLayoutData(CmsSwtUtils.fillAll()); - body.setLayout(new GridLayout()); - Label label = new Label(body, SWT.NONE); - label.setText("You should be an admin to perform maintenance operations. " - + "Are you sure you are logged in?"); - label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); - return null; - } - -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/SecurityDeploymentUi.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/SecurityDeploymentUi.java deleted file mode 100644 index 3492c54..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/SecurityDeploymentUi.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.argeo.cms.e4.maintenance; - -import java.net.URI; - -import org.argeo.cms.swt.CmsSwtUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.UserAdmin; - -class SecurityDeploymentUi extends AbstractOsgiComposite { - private static final long serialVersionUID = 590221539553514693L; - - public SecurityDeploymentUi(Composite parent, int style) { - super(parent, style); - } - - @Override - protected void initUi(int style) { - if (isDeployed()) { - initCurrentUi(this); - } else { - initNewUi(this); - } - } - - private void initNewUi(Composite parent) { - new Label(parent, SWT.NONE).setText("Security is not configured"); - } - - private void initCurrentUi(Composite parent) { - ServiceReference userAdminRef = bc.getServiceReference(UserAdmin.class); - UserAdmin userAdmin = bc.getService(userAdminRef); - StringBuffer text = new StringBuffer(); - text.append("Domains
"); - domains: for (String key : userAdminRef.getPropertyKeys()) { - if (!key.startsWith("/")) - continue domains; - URI uri; - try { - uri = new URI(key); - } catch (Exception e) { - // ignore non URI keys - continue domains; - } - - String rootDn = uri.getPath().substring(1, uri.getPath().length()); - // FIXME make reading query options more robust, using utils - boolean readOnly = uri.getQuery().equals("readOnly=true"); - if (readOnly) - text.append(""); - else - text.append(""); - - text.append(rootDn); - text.append("
"); - try { - Role[] roles = userAdmin.getRoles("(dn=*," + rootDn + ")"); - long userCount = 0; - long groupCount = 0; - for (Role role : roles) { - if (role.getType() == Role.USER) - userCount++; - else - groupCount++; - } - text.append(" " + userCount + " users, " + groupCount +" groups.
"); - } catch (InvalidSyntaxException e) { - log.error("Invalid syntax", e); - } - } - Label label = new Label(parent, SWT.NONE); - label.setData(new GridData(SWT.FILL, SWT.FILL, false, false)); - CmsSwtUtils.markup(label); - label.setText(text.toString()); - } - - protected boolean isDeployed() { - return bc.getServiceReference(UserAdmin.class) != null; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/package-info.java deleted file mode 100644 index e4d2ad4..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/e4/maintenance/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Maintenance perspective. */ -package org.argeo.cms.e4.maintenance; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/jcr/swt/JcrQueryTabularPart.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/jcr/swt/JcrQueryTabularPart.java new file mode 100644 index 0000000..2ee35a2 --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/jcr/swt/JcrQueryTabularPart.java @@ -0,0 +1,63 @@ +package org.argeo.cms.jcr.swt; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.query.Query; + +import org.argeo.cms.ux.widgets.AbstractTabularPart; +import org.argeo.jcr.JcrException; + +public class JcrQueryTabularPart extends AbstractTabularPart { + private int cursor = 0; + private NodeIterator nit = null; + + @Override + public int getItemCount() { + return (int) nit.getSize(); + } + + @Override + public Node getData(int row) { + // System.out.println("Row " + row); + Node res; + if (row == cursor) { + res = nit.nextNode(); + cursor++; + } else if (row > cursor) { + nit.skip(row - cursor); + cursor = row; + res = nit.nextNode(); + cursor++; + } else if (row < cursor) { + try { + nit = getInput().execute().getNodes(); + } catch (RepositoryException e) { + throw new JcrException("Cannot refresh query", e); + } + notifyItemCountChange(); + nit.skip(row); + cursor = row; + res = nit.nextNode(); + cursor++; + } else { + throw new IllegalStateException("Cursor is " + cursor + " and row is " + row); + } + return res; + } + + @Override + public void refresh() { + cursor = 0; + try { + nit = getInput().execute().getNodes(); + } catch (RepositoryException e) { + throw new JcrException("Cannot refresh query", e); + } + super.refresh(); + } + + public long getQuerySize() { + return nit.getSize(); + } +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/jcr/swt/PagedJcrQueryTabularPart.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/jcr/swt/PagedJcrQueryTabularPart.java new file mode 100644 index 0000000..a463aac --- /dev/null +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/jcr/swt/PagedJcrQueryTabularPart.java @@ -0,0 +1,58 @@ +package org.argeo.cms.jcr.swt; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.query.Query; + +import org.argeo.cms.ux.widgets.AbstractTabularPart; +import org.argeo.jcr.JcrException; + +public class PagedJcrQueryTabularPart extends AbstractTabularPart { + private int pageSize = 100; + private int cursor = 0; + private int nextUpperBound = pageSize; + private NodeIterator nit = null; + + @Override + public int getItemCount() { + return (nextUpperBound - pageSize) + (int) nit.getSize(); + } + + @Override + public Node getData(int row) { + // System.out.println("Row " + row); + if (row == cursor) { + cursor++; + Node res = nit.nextNode(); + if (cursor == nextUpperBound) { + getInput().setOffset(cursor); + nextUpperBound = cursor + pageSize; + try { + nit = getInput().execute().getNodes(); + } catch (RepositoryException e) { + throw new JcrException("Cannot refresh query", e); + } + notifyItemCountChange(); + } + return res; + } else { + return null; + } + } + + @Override + public void refresh() { + getInput().setOffset(0); + getInput().setLimit(pageSize); + cursor = 0; + nextUpperBound = pageSize; + try { + nit = getInput().execute().getNodes(); + } catch (RepositoryException e) { + throw new JcrException("Cannot refresh query", e); + } + super.refresh(); + } + +} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/AbstractFormPart.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/AbstractFormPart.java deleted file mode 100644 index 4ce4688..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/AbstractFormPart.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; -/** - * AbstractFormPart implements IFormPart interface and can be used as a - * convenient base class for concrete form parts. If a method contains - * code that must be called, look for instructions to call 'super' - * when overriding. - * - * @see org.eclipse.ui.forms.widgets.Section - * @since 1.0 - */ -public abstract class AbstractFormPart implements IFormPart { - private IManagedForm managedForm; - private boolean dirty = false; - private boolean stale = true; - /** - * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) - */ - public void initialize(IManagedForm form) { - this.managedForm = form; - } - /** - * Returns the form that manages this part. - * - * @return the managed form - */ - public IManagedForm getManagedForm() { - return managedForm; - } - /** - * Disposes the part. Subclasses should override to release any system - * resources. - */ - public void dispose() { - } - /** - * Commits the part. Subclasses should call 'super' when overriding. - * - * @param onSave - * true if the request to commit has arrived as a - * result of the 'save' action. - */ - public void commit(boolean onSave) { - dirty = false; - } - /** - * Sets the overall form input. Subclases may elect to override the method - * and adjust according to the form input. - * - * @param input - * the form input object - * @return false - */ - public boolean setFormInput(Object input) { - return false; - } - /** - * Instructs the part to grab keyboard focus. - */ - public void setFocus() { - } - /** - * Refreshes the section after becoming stale (falling behind data in the - * model). Subclasses must call 'super' when overriding this method. - */ - public void refresh() { - stale = false; - // since we have refreshed, any changes we had in the - // part are gone and we are not dirty - dirty = false; - } - /** - * Marks the part dirty. Subclasses should call this method as a result of - * user interaction with the widgets in the section. - */ - public void markDirty() { - dirty = true; - managedForm.dirtyStateChanged(); - } - /** - * Tests whether the part is dirty i.e. its widgets have state that is - * newer than the data in the model. - * - * @return true if the part is dirty, false - * otherwise. - */ - public boolean isDirty() { - return dirty; - } - /** - * Tests whether the part is stale i.e. its widgets have state that is - * older than the data in the model. - * - * @return true if the part is stale, false - * otherwise. - */ - public boolean isStale() { - return stale; - } - /** - * Marks the part stale. Subclasses should call this method as a result of - * model notification that indicates that the content of the section is no - * longer in sync with the model. - */ - public void markStale() { - stale = true; - managedForm.staleStateChanged(); - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormColors.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormColors.java deleted file mode 100644 index 32b031b..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormColors.java +++ /dev/null @@ -1,730 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; -//import org.eclipse.swt.internal.graphics.Graphics; -import org.eclipse.swt.widgets.Display; - -/** - * Manages colors that will be applied to forms and form widgets. The colors are - * chosen to make the widgets look correct in the editor area. If a different - * set of colors is needed, subclass this class and override 'initialize' and/or - * 'initializeColors'. - * - * @since 1.0 - */ -public class FormColors { - /** - * Key for the form title foreground color. - * - * @deprecated use IFormColors.TITLE. - */ - public static final String TITLE = IFormColors.TITLE; - - /** - * Key for the tree/table border color. - * - * @deprecated use IFormColors.BORDER - */ - public static final String BORDER = IFormColors.BORDER; - - /** - * Key for the section separator color. - * - * @deprecated use IFormColors.SEPARATOR. - */ - public static final String SEPARATOR = IFormColors.SEPARATOR; - - /** - * Key for the section title bar background. - * - * @deprecated use IFormColors.TB_BG - */ - public static final String TB_BG = IFormColors.TB_BG; - - /** - * Key for the section title bar foreground. - * - * @deprecated use IFormColors.TB_FG - */ - public static final String TB_FG = IFormColors.TB_FG; - - /** - * Key for the section title bar gradient. - * - * @deprecated use IFormColors.TB_GBG - */ - public static final String TB_GBG = IFormColors.TB_GBG; - - /** - * Key for the section title bar border. - * - * @deprecated use IFormColors.TB_BORDER. - */ - public static final String TB_BORDER = IFormColors.TB_BORDER; - - /** - * Key for the section toggle color. Since 3.1, this color is used for all - * section styles. - * - * @deprecated use IFormColors.TB_TOGGLE. - */ - public static final String TB_TOGGLE = IFormColors.TB_TOGGLE; - - /** - * Key for the section toggle hover color. - * - * @deprecated use IFormColors.TB_TOGGLE_HOVER. - */ - public static final String TB_TOGGLE_HOVER = IFormColors.TB_TOGGLE_HOVER; - - protected Map colorRegistry = new HashMap(10); - - private LocalResourceManager resources; - - protected Color background; - - protected Color foreground; - - private boolean shared; - - protected Display display; - - protected Color border; - - /** - * Creates form colors using the provided display. - * - * @param display - * the display to use - */ - public FormColors(Display display) { - this.display = display; - initialize(); - } - - /** - * Returns the display used to create colors. - * - * @return the display - */ - public Display getDisplay() { - return display; - } - - /** - * Initializes the colors. Subclasses can override this method to change the - * way colors are created. Alternatively, only the color table can be - * modified by overriding initializeColorTable(). - * - * @see #initializeColorTable - */ - protected void initialize() { - background = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND); - foreground = display.getSystemColor(SWT.COLOR_LIST_FOREGROUND); - initializeColorTable(); - updateBorderColor(); - } - - /** - * Allocates colors for the following keys: BORDER, SEPARATOR and - * TITLE. Subclasses can override to allocate these colors differently. - */ - protected void initializeColorTable() { - createTitleColor(); - createColor(IFormColors.SEPARATOR, getColor(IFormColors.TITLE).getRGB()); - RGB black = getSystemColor(SWT.COLOR_BLACK); - RGB borderRGB = getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT); - createColor(IFormColors.BORDER, blend(borderRGB, black, 80)); - } - - /** - * Allocates colors for the section tool bar (all the keys that start with - * TB). Since these colors are only needed when TITLE_BAR style is used with - * the Section widget, they are not needed all the time and are allocated on - * demand. Consequently, this method will do nothing if the colors have been - * already initialized. Call this method prior to using colors with the TB - * keys to ensure they are available. - */ - public void initializeSectionToolBarColors() { - if (colorRegistry.containsKey(IFormColors.TB_BG)) - return; - createTitleBarGradientColors(); - createTitleBarOutlineColors(); - createTwistieColors(); - } - - /** - * Allocates additional colors for the form header, namely background - * gradients, bottom separator keylines and DND highlights. Since these - * colors are only needed for clients that want to use these particular - * style of header rendering, they are not needed all the time and are - * allocated on demand. Consequently, this method will do nothing if the - * colors have been already initialized. Call this method prior to using - * color keys with the H_ prefix to ensure they are available. - */ - protected void initializeFormHeaderColors() { - if (colorRegistry.containsKey(IFormColors.H_BOTTOM_KEYLINE2)) - return; - createFormHeaderColors(); - } - - /** - * Returns the RGB value of the system color represented by the code - * argument, as defined in SWT class. - * - * @param code - * the system color constant as defined in SWT - * class. - * @return the RGB value of the system color - */ - public RGB getSystemColor(int code) { - return getDisplay().getSystemColor(code).getRGB(); - } - - /** - * Creates the color for the specified key using the provided RGB object. - * The color object will be returned and also put into the registry. When - * the class is disposed, the color will be disposed with it. - * - * @param key - * the unique color key - * @param rgb - * the RGB object - * @return the allocated color object - */ - public Color createColor(String key, RGB rgb) { - // RAP [rh] changes due to missing Color constructor -// Color c = getResourceManager().createColor(rgb); -// Color prevC = (Color) colorRegistry.get(key); -// if (prevC != null && !prevC.isDisposed()) -// getResourceManager().destroyColor(prevC.getRGB()); -// Color c = Graphics.getColor(rgb); - Color c = new Color(display, rgb); - colorRegistry.put(key, c); - return c; - } - - /** - * Creates a color that can be used for areas of the form that is inactive. - * These areas can contain images, links, controls and other content but are - * considered auxilliary to the main content area. - * - *

- * The color should not be disposed because it is managed by this class. - * - * @return the inactive form color - */ - public Color getInactiveBackground() { - String key = "__ncbg__"; //$NON-NLS-1$ - Color color = getColor(key); - if (color == null) { - RGB sel = getSystemColor(SWT.COLOR_LIST_SELECTION); - // a blend of 95% white and 5% list selection system color - RGB ncbg = blend(sel, getSystemColor(SWT.COLOR_WHITE), 5); - color = createColor(key, ncbg); - } - return color; - } - - /** - * Creates the color for the specified key using the provided RGB values. - * The color object will be returned and also put into the registry. If - * there is already another color object under the same key in the registry, - * the existing object will be disposed. When the class is disposed, the - * color will be disposed with it. - * - * @param key - * the unique color key - * @param r - * red value - * @param g - * green value - * @param b - * blue value - * @return the allocated color object - */ - public Color createColor(String key, int r, int g, int b) { - return createColor(key, new RGB(r,g,b)); - } - - /** - * Computes the border color relative to the background. Allocated border - * color is designed to work well with white. Otherwise, stanard widget - * background color will be used. - */ - protected void updateBorderColor() { - if (isWhiteBackground()) - border = getColor(IFormColors.BORDER); - else { - border = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - Color bg = getImpliedBackground(); - if (border.getRed() == bg.getRed() - && border.getGreen() == bg.getGreen() - && border.getBlue() == bg.getBlue()) - border = display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW); - } - } - - /** - * Sets the background color. All the toolkits that use this class will - * share the same background. - * - * @param bg - * background color - */ - public void setBackground(Color bg) { - this.background = bg; - updateBorderColor(); - updateFormHeaderColors(); - } - - /** - * Sets the foreground color. All the toolkits that use this class will - * share the same foreground. - * - * @param fg - * foreground color - */ - public void setForeground(Color fg) { - this.foreground = fg; - } - - /** - * Returns the current background color. - * - * @return the background color - */ - public Color getBackground() { - return background; - } - - /** - * Returns the current foreground color. - * - * @return the foreground color - */ - public Color getForeground() { - return foreground; - } - - /** - * Returns the computed border color. Border color depends on the background - * and is recomputed whenever the background changes. - * - * @return the current border color - */ - public Color getBorderColor() { - return border; - } - - /** - * Tests if the background is white. White background has RGB value - * 255,255,255. - * - * @return true if background is white, false - * otherwise. - */ - public boolean isWhiteBackground() { - Color bg = getImpliedBackground(); - return bg.getRed() == 255 && bg.getGreen() == 255 - && bg.getBlue() == 255; - } - - /** - * Returns the color object for the provided key or null if - * not in the registry. - * - * @param key - * the color key - * @return color object if found, or null if not. - */ - public Color getColor(String key) { - if (key.startsWith(IFormColors.TB_PREFIX)) - initializeSectionToolBarColors(); - else if (key.startsWith(IFormColors.H_PREFIX)) - initializeFormHeaderColors(); - return (Color) colorRegistry.get(key); - } - - /** - * Disposes all the colors in the registry. - */ - public void dispose() { - if (resources != null) - resources.dispose(); - resources = null; - colorRegistry = null; - } - - /** - * Marks the colors shared. This prevents toolkits that share this object - * from disposing it. - */ - public void markShared() { - this.shared = true; - } - - /** - * Tests if the colors are shared. - * - * @return true if shared, false otherwise. - */ - public boolean isShared() { - return shared; - } - - /** - * Blends c1 and c2 based in the provided ratio. - * - * @param c1 - * first color - * @param c2 - * second color - * @param ratio - * percentage of the first color in the blend (0-100) - * @return the RGB value of the blended color - */ - public static RGB blend(RGB c1, RGB c2, int ratio) { - int r = blend(c1.red, c2.red, ratio); - int g = blend(c1.green, c2.green, ratio); - int b = blend(c1.blue, c2.blue, ratio); - return new RGB(r, g, b); - } - - /** - * Tests the source RGB for range. - * - * @param rgb - * the tested RGB - * @param from - * range start (excluding the value itself) - * @param to - * range end (excluding the value itself) - * @return true if at least one of the primary colors in the - * source RGB are within the provided range, false - * otherwise. - */ - public static boolean testAnyPrimaryColor(RGB rgb, int from, int to) { - if (testPrimaryColor(rgb.red, from, to)) - return true; - if (testPrimaryColor(rgb.green, from, to)) - return true; - if (testPrimaryColor(rgb.blue, from, to)) - return true; - return false; - } - - /** - * Tests the source RGB for range. - * - * @param rgb - * the tested RGB - * @param from - * range start (excluding the value itself) - * @param to - * tange end (excluding the value itself) - * @return true if at least two of the primary colors in the - * source RGB are within the provided range, false - * otherwise. - */ - public static boolean testTwoPrimaryColors(RGB rgb, int from, int to) { - int total = 0; - if (testPrimaryColor(rgb.red, from, to)) - total++; - if (testPrimaryColor(rgb.green, from, to)) - total++; - if (testPrimaryColor(rgb.blue, from, to)) - total++; - return total >= 2; - } - - /** - * Blends two primary color components based on the provided ratio. - * - * @param v1 - * first component - * @param v2 - * second component - * @param ratio - * percentage of the first component in the blend - * @return - */ - private static int blend(int v1, int v2, int ratio) { - int b = (ratio * v1 + (100 - ratio) * v2) / 100; - return Math.min(255, b); - } - - private Color getImpliedBackground() { - if (getBackground() != null) - return getBackground(); - return getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - } - - private static boolean testPrimaryColor(int value, int from, int to) { - return value > from && value < to; - } - - private void createTitleColor() { - /* - * RGB rgb = getSystemColor(SWT.COLOR_LIST_SELECTION); // test too light - * if (testTwoPrimaryColors(rgb, 120, 151)) rgb = blend(rgb, BLACK, 80); - * else if (testTwoPrimaryColors(rgb, 150, 256)) rgb = blend(rgb, BLACK, - * 50); createColor(TITLE, rgb); - */ - RGB bg = getImpliedBackground().getRGB(); - RGB listSelection = getSystemColor(SWT.COLOR_LIST_SELECTION); - RGB listForeground = getSystemColor(SWT.COLOR_LIST_FOREGROUND); - RGB rgb = listSelection; - - // Group 1 - // Rule: If at least 2 of the LIST_SELECTION RGB values are equal to or - // between 0 and 120, then use 100% LIST_SELECTION as it is (no - // additions) - // Examples: XP Default, Win Classic Standard, Win High Con White, Win - // Classic Marine - if (testTwoPrimaryColors(listSelection, -1, 121)) - rgb = listSelection; - // Group 2 - // When LIST_BACKGROUND = white (255, 255, 255) or not black, text - // colour = LIST_SELECTION @ 100% Opacity + 50% LIST_FOREGROUND over - // LIST_BACKGROUND - // Rule: If at least 2 of the LIST_SELECTION RGB values are equal to or - // between 121 and 255, then add 50% LIST_FOREGROUND to LIST_SELECTION - // foreground colour - // Examples: Win Vista, XP Silver, XP Olive , Win Classic Plum, OSX - // Aqua, OSX Graphite, Linux GTK - else if (testTwoPrimaryColors(listSelection, 120, 256) - || (bg.red == 0 && bg.green == 0 && bg.blue == 0)) - rgb = blend(listSelection, listForeground, 50); - // Group 3 - // When LIST_BACKGROUND = black (0, 0, 0), text colour = LIST_SELECTION - // @ 100% Opacity + 50% LIST_FOREGROUND over LIST_BACKGROUND - // Rule: If LIST_BACKGROUND = 0, 0, 0, then add 50% LIST_FOREGROUND to - // LIST_SELECTION foreground colour - // Examples: Win High Con Black, Win High Con #1, Win High Con #2 - // (covered in the second part of the OR clause above) - createColor(IFormColors.TITLE, rgb); - } - - private void createTwistieColors() { - RGB rgb = getColor(IFormColors.TITLE).getRGB(); - RGB white = getSystemColor(SWT.COLOR_WHITE); - createColor(TB_TOGGLE, rgb); - rgb = blend(rgb, white, 60); - createColor(TB_TOGGLE_HOVER, rgb); - } - - private void createTitleBarGradientColors() { - RGB tbBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND); - RGB bg = getImpliedBackground().getRGB(); - - // Group 1 - // Rule: If at least 2 of the RGB values are equal to or between 180 and - // 255, then apply specified opacity for Group 1 - // Examples: Vista, XP Silver, Wn High Con #2 - // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND - // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND - if (testTwoPrimaryColors(tbBg, 179, 256)) - tbBg = blend(tbBg, bg, 30); - - // Group 2 - // Rule: If at least 2 of the RGB values are equal to or between 121 and - // 179, then apply specified opacity for Group 2 - // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black - // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND - // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND - else if (testTwoPrimaryColors(tbBg, 120, 180)) - tbBg = blend(tbBg, bg, 20); - - // Group 3 - // Rule: Everything else - // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX - // Aqua, Wn High Con White, Wn High Con #1 - // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND - // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND - else { - tbBg = blend(tbBg, bg, 10); - } - - createColor(IFormColors.TB_BG, tbBg); - - // for backward compatibility - createColor(TB_GBG, tbBg); - } - - private void createTitleBarOutlineColors() { - // title bar outline - border color - RGB tbBorder = getSystemColor(SWT.COLOR_TITLE_BACKGROUND); - RGB bg = getImpliedBackground().getRGB(); - // Group 1 - // Rule: If at least 2 of the RGB values are equal to or between 180 and - // 255, then apply specified opacity for Group 1 - // Examples: Vista, XP Silver, Wn High Con #2 - // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND - if (testTwoPrimaryColors(tbBorder, 179, 256)) - tbBorder = blend(tbBorder, bg, 70); - - // Group 2 - // Rule: If at least 2 of the RGB values are equal to or between 121 and - // 179, then apply specified opacity for Group 2 - // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black - - // Keyline = TITLE_BACKGROUND @ 50% Opacity over LIST_BACKGROUND - else if (testTwoPrimaryColors(tbBorder, 120, 180)) - tbBorder = blend(tbBorder, bg, 50); - - // Group 3 - // Rule: Everything else - // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX - // Aqua, Wn High Con White, Wn High Con #1 - - // Keyline = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND - else { - tbBorder = blend(tbBorder, bg, 30); - } - createColor(FormColors.TB_BORDER, tbBorder); - } - - private void updateFormHeaderColors() { - if (colorRegistry.containsKey(IFormColors.H_GRADIENT_END)) { - disposeIfFound(IFormColors.H_GRADIENT_END); - disposeIfFound(IFormColors.H_GRADIENT_START); - disposeIfFound(IFormColors.H_BOTTOM_KEYLINE1); - disposeIfFound(IFormColors.H_BOTTOM_KEYLINE2); - disposeIfFound(IFormColors.H_HOVER_LIGHT); - disposeIfFound(IFormColors.H_HOVER_FULL); - initializeFormHeaderColors(); - } - } - - private void disposeIfFound(String key) { - Color color = getColor(key); - if (color != null) { - colorRegistry.remove(key); - // RAP [rh] changes due to missing Color#dispose() -// color.dispose(); - } - } - - private void createFormHeaderColors() { - createFormHeaderGradientColors(); - createFormHeaderKeylineColors(); - createFormHeaderDNDColors(); - } - - private void createFormHeaderGradientColors() { - RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND); - Color bgColor = getImpliedBackground(); - RGB bg = bgColor.getRGB(); - RGB bottom, top; - // Group 1 - // Rule: If at least 2 of the RGB values are equal to or between 180 and - // 255, then apply specified opacity for Group 1 - // Examples: Vista, XP Silver, Wn High Con #2 - // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND - // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND - if (testTwoPrimaryColors(titleBg, 179, 256)) { - bottom = blend(titleBg, bg, 30); - top = bg; - } - - // Group 2 - // Rule: If at least 2 of the RGB values are equal to or between 121 and - // 179, then apply specified opacity for Group 2 - // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black - // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND - // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND - else if (testTwoPrimaryColors(titleBg, 120, 180)) { - bottom = blend(titleBg, bg, 20); - top = bg; - } - - // Group 3 - // Rule: If at least 2 of the RGB values are equal to or between 0 and - // 120, then apply specified opacity for Group 3 - // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX - // Aqua, Wn High Con White, Wn High Con #1 - // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND - // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND - else { - bottom = blend(titleBg, bg, 10); - top = bg; - } - createColor(IFormColors.H_GRADIENT_END, top); - createColor(IFormColors.H_GRADIENT_START, bottom); - } - - private void createFormHeaderKeylineColors() { - RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND); - Color bgColor = getImpliedBackground(); - RGB bg = bgColor.getRGB(); - RGB keyline2; - // H_BOTTOM_KEYLINE1 - createColor(IFormColors.H_BOTTOM_KEYLINE1, new RGB(255, 255, 255)); - - // H_BOTTOM_KEYLINE2 - // Group 1 - // Rule: If at least 2 of the RGB values are equal to or between 180 and - // 255, then apply specified opacity for Group 1 - // Examples: Vista, XP Silver, Wn High Con #2 - // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND - if (testTwoPrimaryColors(titleBg, 179, 256)) - keyline2 = blend(titleBg, bg, 70); - - // Group 2 - // Rule: If at least 2 of the RGB values are equal to or between 121 and - // 179, then apply specified opacity for Group 2 - // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black - // Keyline = TITLE_BACKGROUND @ 50% Opacity over LIST_BACKGROUND - else if (testTwoPrimaryColors(titleBg, 120, 180)) - keyline2 = blend(titleBg, bg, 50); - - // Group 3 - // Rule: If at least 2 of the RGB values are equal to or between 0 and - // 120, then apply specified opacity for Group 3 - // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX - // Aqua, Wn High Con White, Wn High Con #1 - - // Keyline = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND - else - keyline2 = blend(titleBg, bg, 30); - // H_BOTTOM_KEYLINE2 - createColor(IFormColors.H_BOTTOM_KEYLINE2, keyline2); - } - - private void createFormHeaderDNDColors() { - RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT); - Color bgColor = getImpliedBackground(); - RGB bg = bgColor.getRGB(); - RGB light, full; - // ALL Themes - // - // Light Highlight - // When *near* the 'hot' area - // Rule: If near the title in the 'hot' area, show background highlight - // TITLE_BACKGROUND_GRADIENT @ 40% - light = blend(titleBg, bg, 40); - // Full Highlight - // When *on* the title area (regions 1 and 2) - // Rule: If near the title in the 'hot' area, show background highlight - // TITLE_BACKGROUND_GRADIENT @ 60% - full = blend(titleBg, bg, 60); - // H_DND_LIGHT - // H_DND_FULL - createColor(IFormColors.H_HOVER_LIGHT, light); - createColor(IFormColors.H_HOVER_FULL, full); - } - - private LocalResourceManager getResourceManager() { - if (resources == null) - resources = new LocalResourceManager(JFaceResources.getResources()); - return resources; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormFonts.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormFonts.java deleted file mode 100644 index 9e931ba..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormFonts.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -import java.util.HashMap; - -import org.eclipse.jface.resource.DeviceResourceException; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -//import org.eclipse.swt.internal.graphics.Graphics; -import org.eclipse.swt.widgets.Display; - -public class FormFonts { - private static FormFonts instance; - - public static FormFonts getInstance() { - if (instance == null) - instance = new FormFonts(); - return instance; - } - - private LocalResourceManager resources; - private HashMap descriptors; - - private FormFonts() { - } - - private class BoldFontDescriptor extends FontDescriptor { - private FontData[] fFontData; - - BoldFontDescriptor(Font font) { - // RAP [if] Changes due to different way of creating fonts - // fFontData = font.getFontData(); - // for (int i = 0; i < fFontData.length; i++) { - // fFontData[i].setStyle(fFontData[i].getStyle() | SWT.BOLD); - // } - FontData fontData = font.getFontData()[0]; - // Font boldFont = Graphics.getFont( fontData.getName(), - // fontData.getHeight(), - // fontData.getStyle() | SWT.BOLD ); - Font boldFont = new Font(Display.getCurrent(), fontData.getName(), fontData.getHeight(), - fontData.getStyle() | SWT.BOLD); - fFontData = boldFont.getFontData(); - } - - public boolean equals(Object obj) { - if (obj instanceof BoldFontDescriptor) { - BoldFontDescriptor desc = (BoldFontDescriptor) obj; - if (desc.fFontData.length != fFontData.length) - return false; - for (int i = 0; i < fFontData.length; i++) - if (!fFontData[i].equals(desc.fFontData[i])) - return false; - return true; - } - return false; - } - - public int hashCode() { - int hash = 0; - for (int i = 0; i < fFontData.length; i++) - hash = hash * 7 + fFontData[i].hashCode(); - return hash; - } - - public Font createFont(Device device) throws DeviceResourceException { - // RAP [if] Changes due to different way of creating fonts - return new Font(device, fFontData[0]); - // return Graphics.getFont( fFontData[ 0 ] ); - } - - public void destroyFont(Font previouslyCreatedFont) { - // RAP [if] unnecessary - // previouslyCreatedFont.dispose(); - } - } - - public Font getBoldFont(Display display, Font font) { - checkHashMaps(); - BoldFontDescriptor desc = new BoldFontDescriptor(font); - Font result = getResourceManager().createFont(desc); - descriptors.put(result, desc); - return result; - } - - public boolean markFinished(Font boldFont) { - checkHashMaps(); - BoldFontDescriptor desc = (BoldFontDescriptor) descriptors.get(boldFont); - if (desc != null) { - getResourceManager().destroyFont(desc); - if (getResourceManager().find(desc) == null) { - descriptors.remove(boldFont); - validateHashMaps(); - } - return true; - - } - // if the image was not found, dispose of it for the caller - // RAP [if] unnecessary - // boldFont.dispose(); - return false; - } - - private LocalResourceManager getResourceManager() { - if (resources == null) - resources = new LocalResourceManager(JFaceResources.getResources()); - return resources; - } - - private void checkHashMaps() { - if (descriptors == null) - descriptors = new HashMap(); - } - - private void validateHashMaps() { - if (descriptors.size() == 0) - descriptors = null; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormToolkit.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormToolkit.java deleted file mode 100644 index 9927104..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormToolkit.java +++ /dev/null @@ -1,913 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -//import org.eclipse.swt.custom.CCombo; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.FocusAdapter; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -// RAP [rh] Paint events missing -//import org.eclipse.swt.events.PaintEvent; -//import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -//RAP [rh] GC missing -//import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -//import org.eclipse.swt.graphics.RGB; -//import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -//import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -//import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.Widget; -//import org.eclipse.ui.forms.FormColors; -//import org.eclipse.ui.forms.HyperlinkGroup; -//import org.eclipse.ui.forms.IFormColors; -//import org.eclipse.ui.internal.forms.widgets.FormFonts; -//import org.eclipse.ui.internal.forms.widgets.FormUtil; - -/** - * The toolkit is responsible for creating SWT controls adapted to work in - * Eclipse forms. In addition to changing their presentation properties (fonts, - * colors etc.), various listeners are attached to make them behave correctly in - * the form context. - *

- * In addition to being the control factory, the toolkit is also responsible for - * painting flat borders for select controls, managing hyperlink groups and - * control colors. - *

- * The toolkit creates some of the most common controls used to populate Eclipse - * forms. Controls that must be created using their constructors, - * adapt() method is available to change its properties in the - * same way as with the supported toolkit controls. - *

- * Typically, one toolkit object is created per workbench part (for example, an - * editor or a form wizard). The toolkit is disposed when the part is disposed. - * To conserve resources, it is possible to create one color object for the - * entire plug-in and share it between several toolkits. The plug-in is - * responsible for disposing the colors (disposing the toolkit that uses shared - * color object will not dispose the colors). - *

- * FormToolkit is normally instantiated, but can also be subclassed if some of - * the methods needs to be modified. In those cases, super must - * be called to preserve normal behaviour. - * - * @since 1.0 - */ -public class FormToolkit { - public static final String KEY_DRAW_BORDER = "FormWidgetFactory.drawBorder"; //$NON-NLS-1$ - - public static final String TREE_BORDER = "treeBorder"; //$NON-NLS-1$ - - public static final String TEXT_BORDER = "textBorder"; //$NON-NLS-1$ - - private int borderStyle = SWT.NULL; - - private FormColors colors; - - private int orientation = Window.getDefaultOrientation(); - - // private KeyListener deleteListener; - // RAP [rh] Paint events missing -// private BorderPainter borderPainter; - - private BoldFontHolder boldFontHolder; - -// private HyperlinkGroup hyperlinkGroup; - - private boolean isDisposed = false; - - /* default */ - VisibilityHandler visibilityHandler; - - /* default */ - KeyboardHandler keyboardHandler; - - // RAP [rh] Paint events missing -// private class BorderPainter implements PaintListener { -// public void paintControl(PaintEvent event) { -// Composite composite = (Composite) event.widget; -// Control[] children = composite.getChildren(); -// for (int i = 0; i < children.length; i++) { -// Control c = children[i]; -// boolean inactiveBorder = false; -// boolean textBorder = false; -// if (!c.isVisible()) -// continue; -// /* -// * if (c.getEnabled() == false && !(c instanceof CCombo)) -// * continue; -// */ -// if (c instanceof Hyperlink) -// continue; -// Object flag = c.getData(KEY_DRAW_BORDER); -// if (flag != null) { -// if (flag.equals(Boolean.FALSE)) -// continue; -// if (flag.equals(TREE_BORDER)) -// inactiveBorder = true; -// else if (flag.equals(TEXT_BORDER)) -// textBorder = true; -// } -// if (getBorderStyle() == SWT.BORDER) { -// if (!inactiveBorder && !textBorder) { -// continue; -// } -// if (c instanceof Text || c instanceof Table -// || c instanceof Tree) -// continue; -// } -// if (!inactiveBorder -// && (c instanceof Text || c instanceof CCombo || textBorder)) { -// Rectangle b = c.getBounds(); -// GC gc = event.gc; -// gc.setForeground(c.getBackground()); -// gc.drawRectangle(b.x - 1, b.y - 1, b.width + 1, -// b.height + 1); -// // gc.setForeground(getBorderStyle() == SWT.BORDER ? colors -// // .getBorderColor() : colors.getForeground()); -// gc.setForeground(colors.getBorderColor()); -// if (c instanceof CCombo) -// gc.drawRectangle(b.x - 1, b.y - 1, b.width + 1, -// b.height + 1); -// else -// gc.drawRectangle(b.x - 1, b.y - 2, b.width + 1, -// b.height + 3); -// } else if (inactiveBorder || c instanceof Table -// || c instanceof Tree) { -// Rectangle b = c.getBounds(); -// GC gc = event.gc; -// gc.setForeground(colors.getBorderColor()); -// gc.drawRectangle(b.x - 1, b.y - 1, b.width + 1, -// b.height + 1); -// } -// } -// } -// } - - private static class VisibilityHandler extends FocusAdapter { - public void focusGained(FocusEvent e) { - Widget w = e.widget; - if (w instanceof Control) { - FormUtil.ensureVisible((Control) w); - } - } - } - - private static class KeyboardHandler extends KeyAdapter { - public void keyPressed(KeyEvent e) { - Widget w = e.widget; - if (w instanceof Control) { - if (e.doit) - FormUtil.processKey(e.keyCode, (Control) w); - } - } - } - - private class BoldFontHolder { - private Font normalFont; - - private Font boldFont; - - public BoldFontHolder() { - } - - public Font getBoldFont(Font font) { - createBoldFont(font); - return boldFont; - } - - private void createBoldFont(Font font) { - if (normalFont == null || !normalFont.equals(font)) { - normalFont = font; - dispose(); - } - if (boldFont == null) { - boldFont = FormFonts.getInstance().getBoldFont(colors.getDisplay(), - normalFont); - } - } - - public void dispose() { - if (boldFont != null) { - FormFonts.getInstance().markFinished(boldFont); - boldFont = null; - } - } - } - - /** - * Creates a toolkit that is self-sufficient (will manage its own colors). - *

- * Clients that call this method must call {@link #dispose()} when they - * are finished using the toolkit. - * - */ - public FormToolkit(Display display) { - this(new FormColors(display)); - } - - /** - * Creates a toolkit that will use the provided (shared) colors. The toolkit - * will dispose the colors if and only if they are not marked as - * shared via the markShared() method. - *

- * Clients that call this method must call {@link #dispose()} when they - * are finished using the toolkit. - * - * @param colors - * the shared colors - */ - public FormToolkit(FormColors colors) { - this.colors = colors; - initialize(); - } - - /** - * Creates a button as a part of the form. - * - * @param parent - * the button parent - * @param text - * an optional text for the button (can be null) - * @param style - * the button style (for example, SWT.PUSH) - * @return the button widget - */ - public Button createButton(Composite parent, String text, int style) { - Button button = new Button(parent, style | SWT.FLAT | orientation); - if (text != null) - button.setText(text); - adapt(button, true, true); - return button; - } - - /** - * Creates the composite as a part of the form. - * - * @param parent - * the composite parent - * @return the composite widget - */ - public Composite createComposite(Composite parent) { - return createComposite(parent, SWT.NULL); - } - - /** - * Creates the composite as part of the form using the provided style. - * - * @param parent - * the composite parent - * @param style - * the composite style - * @return the composite widget - */ - public Composite createComposite(Composite parent, int style) { -// Composite composite = new LayoutComposite(parent, style | orientation); - Composite composite = new Composite(parent, style | orientation); - adapt(composite); - return composite; - } - - /** - * Creats the composite that can server as a separator between various parts - * of a form. Separator height should be controlled by setting the height - * hint on the layout data for the composite. - * - * @param parent - * the separator parent - * @return the separator widget - */ -// RAP [rh] createCompositeSeparator: currently no useful implementation possible, delete? - public Composite createCompositeSeparator(Composite parent) { - final Composite composite = new Composite(parent, orientation); -// RAP [rh] GC and paint events missing -// composite.addListener(SWT.Paint, new Listener() { -// public void handleEvent(Event e) { -// if (composite.isDisposed()) -// return; -// Rectangle bounds = composite.getBounds(); -// GC gc = e.gc; -// gc.setForeground(colors.getColor(IFormColors.SEPARATOR)); -// if (colors.getBackground() != null) -// gc.setBackground(colors.getBackground()); -// gc.fillGradientRectangle(0, 0, bounds.width, bounds.height, -// false); -// } -// }); -// if (parent instanceof Section) -// ((Section) parent).setSeparatorControl(composite); - return composite; - } - - /** - * Creates a label as a part of the form. - * - * @param parent - * the label parent - * @param text - * the label text - * @return the label widget - */ - public Label createLabel(Composite parent, String text) { - return createLabel(parent, text, SWT.NONE); - } - - /** - * Creates a label as a part of the form. - * - * @param parent - * the label parent - * @param text - * the label text - * @param style - * the label style - * @return the label widget - */ - public Label createLabel(Composite parent, String text, int style) { - Label label = new Label(parent, style | orientation); - if (text != null) - label.setText(text); - adapt(label, false, false); - return label; - } - - /** - * Creates a hyperlink as a part of the form. The hyperlink will be added to - * the hyperlink group that belongs to this toolkit. - * - * @param parent - * the hyperlink parent - * @param text - * the text of the hyperlink - * @param style - * the hyperlink style - * @return the hyperlink widget - */ -// public Hyperlink createHyperlink(Composite parent, String text, int style) { -// Hyperlink hyperlink = new Hyperlink(parent, style | orientation); -// if (text != null) -// hyperlink.setText(text); -// hyperlink.addFocusListener(visibilityHandler); -// hyperlink.addKeyListener(keyboardHandler); -// hyperlinkGroup.add(hyperlink); -// return hyperlink; -// } - - /** - * Creates an image hyperlink as a part of the form. The hyperlink will be - * added to the hyperlink group that belongs to this toolkit. - * - * @param parent - * the hyperlink parent - * @param style - * the hyperlink style - * @return the image hyperlink widget - */ -// public ImageHyperlink createImageHyperlink(Composite parent, int style) { -// ImageHyperlink hyperlink = new ImageHyperlink(parent, style -// | orientation); -// hyperlink.addFocusListener(visibilityHandler); -// hyperlink.addKeyListener(keyboardHandler); -// hyperlinkGroup.add(hyperlink); -// return hyperlink; -// } - - /** - * Creates a rich text as a part of the form. - * - * @param parent - * the rich text parent - * @param trackFocus - * if true, the toolkit will monitor focus - * transfers to ensure that the hyperlink in focus is visible in - * the form. - * @return the rich text widget - * @since 1.2 - */ -// public FormText createFormText(Composite parent, boolean trackFocus) { -// FormText engine = new FormText(parent, SWT.WRAP | orientation); -// engine.marginWidth = 1; -// engine.marginHeight = 0; -// engine.setHyperlinkSettings(getHyperlinkGroup()); -// adapt(engine, trackFocus, true); -// engine.setMenu(parent.getMenu()); -// return engine; -// } - - /** - * Adapts a control to be used in a form that is associated with this - * toolkit. This involves adjusting colors and optionally adding handlers to - * ensure focus tracking and keyboard management. - * - * @param control - * a control to adapt - * @param trackFocus - * if true, form will be scrolled horizontally - * and/or vertically if needed to ensure that the control is - * visible when it gains focus. Set it to false if - * the control is not capable of gaining focus. - * @param trackKeyboard - * if true, the control that is capable of - * gaining focus will be tracked for certain keys that are - * important to the underlying form (for example, PageUp, - * PageDown, ScrollUp, ScrollDown etc.). Set it to - * false if the control is not capable of gaining - * focus or these particular key event are already used by the - * control. - */ - public void adapt(Control control, boolean trackFocus, boolean trackKeyboard) { - control.setBackground(colors.getBackground()); - control.setForeground(colors.getForeground()); -// if (control instanceof ExpandableComposite) { -// ExpandableComposite ec = (ExpandableComposite) control; -// if (ec.toggle != null) { -// if (trackFocus) -// ec.toggle.addFocusListener(visibilityHandler); -// if (trackKeyboard) -// ec.toggle.addKeyListener(keyboardHandler); -// } -// if (ec.textLabel != null) { -// if (trackFocus) -// ec.textLabel.addFocusListener(visibilityHandler); -// if (trackKeyboard) -// ec.textLabel.addKeyListener(keyboardHandler); -// } -// return; -// } - if (trackFocus) - control.addFocusListener(visibilityHandler); - if (trackKeyboard) - control.addKeyListener(keyboardHandler); - } - - /** - * Adapts a composite to be used in a form associated with this toolkit. - * - * @param composite - * the composite to adapt - */ - public void adapt(Composite composite) { - composite.setBackground(colors.getBackground()); - composite.addMouseListener(new MouseAdapter() { - public void mouseDown(MouseEvent e) { - ((Control) e.widget).setFocus(); - } - }); - if (composite.getParent() != null) - composite.setMenu(composite.getParent().getMenu()); - } - - /** - * A helper method that ensures the provided control is visible when - * ScrolledComposite is somewhere in the parent chain. If scroll bars are - * visible and the control is clipped, the client of the scrolled composite - * will be scrolled to reveal the control. - * - * @param c - * the control to reveal - */ - public static void ensureVisible(Control c) { - FormUtil.ensureVisible(c); - } - - /** - * Creates a section as a part of the form. - * - * @param parent - * the section parent - * @param sectionStyle - * the section style - * @return the section widget - */ -// public Section createSection(Composite parent, int sectionStyle) { -// Section section = new Section(parent, orientation, sectionStyle); -// section.setMenu(parent.getMenu()); -// adapt(section, true, true); -// if (section.toggle != null) { -// section.toggle.setHoverDecorationColor(colors -// .getColor(IFormColors.TB_TOGGLE_HOVER)); -// section.toggle.setDecorationColor(colors -// .getColor(IFormColors.TB_TOGGLE)); -// } -// section.setFont(boldFontHolder.getBoldFont(parent.getFont())); -// if ((sectionStyle & Section.TITLE_BAR) != 0 -// || (sectionStyle & Section.SHORT_TITLE_BAR) != 0) { -// colors.initializeSectionToolBarColors(); -// section.setTitleBarBackground(colors.getColor(IFormColors.TB_BG)); -// section.setTitleBarBorderColor(colors -// .getColor(IFormColors.TB_BORDER)); -// } -// // call setTitleBarForeground regardless as it also sets the label color -// section.setTitleBarForeground(colors -// .getColor(IFormColors.TB_TOGGLE)); -// return section; -// } - - /** - * Creates an expandable composite as a part of the form. - * - * @param parent - * the expandable composite parent - * @param expansionStyle - * the expandable composite style - * @return the expandable composite widget - */ -// public ExpandableComposite createExpandableComposite(Composite parent, -// int expansionStyle) { -// ExpandableComposite ec = new ExpandableComposite(parent, orientation, -// expansionStyle); -// ec.setMenu(parent.getMenu()); -// adapt(ec, true, true); -// ec.setFont(boldFontHolder.getBoldFont(ec.getFont())); -// return ec; -// } - - /** - * Creates a separator label as a part of the form. - * - * @param parent - * the separator parent - * @param style - * the separator style - * @return the separator label - */ - public Label createSeparator(Composite parent, int style) { - Label label = new Label(parent, SWT.SEPARATOR | style | orientation); - label.setBackground(colors.getBackground()); - label.setForeground(colors.getBorderColor()); - return label; - } - - /** - * Creates a table as a part of the form. - * - * @param parent - * the table parent - * @param style - * the table style - * @return the table widget - */ - public Table createTable(Composite parent, int style) { - Table table = new Table(parent, style | borderStyle | orientation); - adapt(table, false, false); - // hookDeleteListener(table); - return table; - } - - /** - * Creates a text as a part of the form. - * - * @param parent - * the text parent - * @param value - * the text initial value - * @return the text widget - */ - public Text createText(Composite parent, String value) { - return createText(parent, value, SWT.SINGLE); - } - - /** - * Creates a text as a part of the form. - * - * @param parent - * the text parent - * @param value - * the text initial value - * @param style - * the text style - * @return the text widget - */ - public Text createText(Composite parent, String value, int style) { - Text text = new Text(parent, borderStyle | style | orientation); - if (value != null) - text.setText(value); - text.setForeground(colors.getForeground()); - text.setBackground(colors.getBackground()); - text.addFocusListener(visibilityHandler); - return text; - } - - /** - * Creates a tree widget as a part of the form. - * - * @param parent - * the tree parent - * @param style - * the tree style - * @return the tree widget - */ - public Tree createTree(Composite parent, int style) { - Tree tree = new Tree(parent, borderStyle | style | orientation); - adapt(tree, false, false); - // hookDeleteListener(tree); - return tree; - } - - /** - * Creates a scrolled form widget in the provided parent. If you do not - * require scrolling because there is already a scrolled composite up the - * parent chain, use 'createForm' instead. - * - * @param parent - * the scrolled form parent - * @return the form that can scroll itself - * @see #createForm - */ - public ScrolledComposite createScrolledForm(Composite parent) { - ScrolledComposite form = new ScrolledComposite(parent, SWT.V_SCROLL - | SWT.H_SCROLL | orientation); - form.setExpandHorizontal(true); - form.setExpandVertical(true); - form.setBackground(colors.getBackground()); - form.setForeground(colors.getColor(IFormColors.TITLE)); - form.setFont(JFaceResources.getHeaderFont()); - return form; - } - - /** - * Creates a form widget in the provided parent. Note that this widget does - * not scroll its content, so make sure there is a scrolled composite up the - * parent chain. If you require scrolling, use 'createScrolledForm' instead. - * - * @param parent - * the form parent - * @return the form that does not scroll - * @see #createScrolledForm - */ -// public Form createForm(Composite parent) { -// Form formContent = new Form(parent, orientation); -// formContent.setBackground(colors.getBackground()); -// formContent.setForeground(colors.getColor(IFormColors.TITLE)); -// formContent.setFont(JFaceResources.getHeaderFont()); -// return formContent; -// } - - /** - * Takes advantage of the gradients and other capabilities to decorate the - * form heading using colors computed based on the current skin and - * operating system. - * - * @param form - * the form to decorate - */ - -// public void decorateFormHeading(Form form) { -// Color top = colors.getColor(IFormColors.H_GRADIENT_END); -// Color bot = colors.getColor(IFormColors.H_GRADIENT_START); -// form.setTextBackground(new Color[] { top, bot }, new int[] { 100 }, -// true); -// form.setHeadColor(IFormColors.H_BOTTOM_KEYLINE1, colors -// .getColor(IFormColors.H_BOTTOM_KEYLINE1)); -// form.setHeadColor(IFormColors.H_BOTTOM_KEYLINE2, colors -// .getColor(IFormColors.H_BOTTOM_KEYLINE2)); -// form.setHeadColor(IFormColors.H_HOVER_LIGHT, colors -// .getColor(IFormColors.H_HOVER_LIGHT)); -// form.setHeadColor(IFormColors.H_HOVER_FULL, colors -// .getColor(IFormColors.H_HOVER_FULL)); -// form.setHeadColor(IFormColors.TB_TOGGLE, colors -// .getColor(IFormColors.TB_TOGGLE)); -// form.setHeadColor(IFormColors.TB_TOGGLE_HOVER, colors -// .getColor(IFormColors.TB_TOGGLE_HOVER)); -// form.setSeparatorVisible(true); -// } - - /** - * Creates a scrolled page book widget as a part of the form. - * - * @param parent - * the page book parent - * @param style - * the text style - * @return the scrolled page book widget - */ -// public ScrolledPageBook createPageBook(Composite parent, int style) { -// ScrolledPageBook book = new ScrolledPageBook(parent, style -// | orientation); -// adapt(book, true, true); -// book.setMenu(parent.getMenu()); -// return book; -// } - - /** - * Disposes the toolkit. - */ - public void dispose() { - if (isDisposed) { - return; - } - isDisposed = true; - if (colors.isShared() == false) { - colors.dispose(); - colors = null; - } - boldFontHolder.dispose(); - } - - /** - * Returns the hyperlink group that manages hyperlinks for this toolkit. - * - * @return the hyperlink group - */ -// public HyperlinkGroup getHyperlinkGroup() { -// return hyperlinkGroup; -// } - - /** - * Sets the background color for the entire toolkit. The method delegates - * the call to the FormColors object and also updates the hyperlink group so - * that hyperlinks and other objects are in sync. - * - * @param bg - * the new background color - */ - public void setBackground(Color bg) { -// hyperlinkGroup.setBackground(bg); - colors.setBackground(bg); - } - - /** - * Refreshes the hyperlink colors by loading from JFace settings. - */ -// public void refreshHyperlinkColors() { -// hyperlinkGroup.initializeDefaultForegrounds(colors.getDisplay()); -// } - -// RAP [rh] paintBordersFor not useful as no GC to actually paint borders -// /** -// * Paints flat borders for widgets created by this toolkit within the -// * provided parent. Borders will not be painted if the global border style -// * is SWT.BORDER (i.e. if native borders are used). Call this method during -// * creation of a form composite to get the borders of its children painted. -// * Care should be taken when selection layout margins. At least one pixel -// * pargin width and height must be chosen to allow the toolkit to paint the -// * border on the parent around the widgets. -// *

-// * Borders are painted for some controls that are selected by the toolkit by -// * default. If a control needs a border but is not on its list, it is -// * possible to force border in the following way: -// * -// *

-//	 *
-//	 *
-//	 *
-//	 *             widget.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER);
-//	 *
-//	 *             or
-//	 *
-//	 *             widget.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-//	 *
-//	 *
-//	 *
-//	 * 
-// * -// * @param parent -// * the parent that owns the children for which the border needs -// * to be painted. -// */ -// public void paintBordersFor(Composite parent) { -// // if (borderStyle == SWT.BORDER) -// // return; -// if (borderPainter == null) -// borderPainter = new BorderPainter(); -// parent.addPaintListener(borderPainter); -// } - - /** - * Returns the colors used by this toolkit. - * - * @return the color object - */ - public FormColors getColors() { - return colors; - } - - /** - * Returns the border style used for various widgets created by this - * toolkit. The intent of the toolkit is to create controls with styles that - * yield a 'flat' appearance. On systems where the native borders are - * already flat, we set the style to SWT.BORDER and don't paint the borders - * ourselves. Otherwise, the style is set to SWT.NULL, and borders are - * painted by the toolkit. - * - * @return the global border style - */ - public int getBorderStyle() { - return borderStyle; - } - - /** - * Returns the margin required around the children whose border is being - * painted by the toolkit using {@link #paintBordersFor(Composite)}. Since - * the border is painted around the controls on the parent, a number of - * pixels needs to be reserved for this border. For windowing systems where - * the native border is used, this margin is 0. - * - * @return the margin in the parent when children have their border painted - */ - public int getBorderMargin() { - return getBorderStyle() == SWT.BORDER ? 0 : 2; - } - - /** - * Sets the border style to be used when creating widgets. The toolkit - * chooses the correct style based on the platform but this value can be - * changed using this method. - * - * @param style - * SWT.BORDER or SWT.NULL - * @see #getBorderStyle - */ - public void setBorderStyle(int style) { - this.borderStyle = style; - } - - /** - * A utility method that ensures that the control is visible in the scrolled - * composite. The prerequisite for this method is that the control has a - * class that extends ScrolledComposite somewhere in the parent chain. If - * the control is partially or fully clipped, the composite is scrolled to - * set by setting the origin to the control origin. - * - * @param c - * the control to make visible - * @param verticalOnly - * if true, the scrolled composite will be - * scrolled only vertically if needed. Otherwise, the scrolled - * composite origin will be set to the control origin. - */ - public static void setControlVisible(Control c, boolean verticalOnly) { - ScrolledComposite scomp = FormUtil.getScrolledComposite(c); - if (scomp == null) - return; - Point location = FormUtil.getControlLocation(scomp, c); - scomp.setOrigin(location); - } - - private void initialize() { - initializeBorderStyle(); -// hyperlinkGroup = new HyperlinkGroup(colors.getDisplay()); -// hyperlinkGroup.setBackground(colors.getBackground()); - visibilityHandler = new VisibilityHandler(); - keyboardHandler = new KeyboardHandler(); - boldFontHolder = new BoldFontHolder(); - } - -// RAP [rh] revise detection of border style: can't ask OS here - private void initializeBorderStyle() { -// String osname = System.getProperty("os.name"); //$NON-NLS-1$ -// String osversion = System.getProperty("os.version"); //$NON-NLS-1$ -// if (osname.startsWith("Windows") && "5.1".compareTo(osversion) <= 0) { //$NON-NLS-1$ //$NON-NLS-2$ -// // Skinned widgets used on newer Windows (e.g. XP (5.1), Vista -// // (6.0)) -// // Check for Windows Classic. If not used, set the style to BORDER -// RGB rgb = colors.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); -// if (rgb.red != 212 || rgb.green != 208 || rgb.blue != 200) -// borderStyle = SWT.BORDER; -// } else if (osname.startsWith("Mac")) //$NON-NLS-1$ -// borderStyle = SWT.BORDER; - - borderStyle = SWT.BORDER; - } - - /** - * Returns the orientation that all the widgets created by this toolkit will - * inherit, if set. Can be SWT.NULL, - * SWT.LEFT_TO_RIGHT and SWT.RIGHT_TO_LEFT. - * - * @return orientation style for this toolkit, or SWT.NULL if - * not set. The default orientation is inherited from the Window - * default orientation. - * @see org.eclipse.jface.window.Window#getDefaultOrientation() - */ - - public int getOrientation() { - return orientation; - } - - /** - * Sets the orientation that all the widgets created by this toolkit will - * inherit. Can be SWT.NULL, SWT.LEFT_TO_RIGHT - * and SWT.RIGHT_TO_LEFT. - * - * @param orientation - * style for this toolkit. - */ - - public void setOrientation(int orientation) { - this.orientation = orientation; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormUtil.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormUtil.java deleted file mode 100644 index 76e3f11..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/FormUtil.java +++ /dev/null @@ -1,522 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.MouseEvent; -//import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -//import org.eclipse.swt.graphics.Image; -//import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Layout; -//import org.eclipse.swt.widgets.ScrollBar; -import org.eclipse.swt.widgets.Text; -//import org.eclipse.ui.forms.widgets.ColumnLayout; -//import org.eclipse.ui.forms.widgets.Form; -//import org.eclipse.ui.forms.widgets.FormText; -//import org.eclipse.ui.forms.widgets.FormToolkit; -//import org.eclipse.ui.forms.widgets.ILayoutExtension; -// -//import com.ibm.icu.text.BreakIterator; - -public class FormUtil { - public static final String PLUGIN_ID = "org.eclipse.ui.forms"; //$NON-NLS-1$ - - static final int H_SCROLL_INCREMENT = 5; - - static final int V_SCROLL_INCREMENT = 64; - - public static final String DEBUG = PLUGIN_ID + "/debug"; //$NON-NLS-1$ - - public static final String DEBUG_TEXT = DEBUG + "/text"; //$NON-NLS-1$ - public static final String DEBUG_TEXTSIZE = DEBUG + "/textsize"; //$NON-NLS-1$ - - public static final String DEBUG_FOCUS = DEBUG + "/focus"; //$NON-NLS-1$ - - public static final String FOCUS_SCROLLING = "focusScrolling"; //$NON-NLS-1$ - - public static final String IGNORE_BODY = "__ignore_body__"; //$NON-NLS-1$ - - public static Text createText(Composite parent, String label, - FormToolkit factory) { - return createText(parent, label, factory, 1); - } - - public static Text createText(Composite parent, String label, - FormToolkit factory, int span) { - factory.createLabel(parent, label); - Text text = factory.createText(parent, ""); //$NON-NLS-1$ - int hfill = span == 1 ? GridData.FILL_HORIZONTAL - : GridData.HORIZONTAL_ALIGN_FILL; - GridData gd = new GridData(hfill | GridData.VERTICAL_ALIGN_CENTER); - gd.horizontalSpan = span; - text.setLayoutData(gd); - return text; - } - - public static Text createText(Composite parent, String label, - FormToolkit factory, int span, int style) { - Label l = factory.createLabel(parent, label); - if ((style & SWT.MULTI) != 0) { - GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); - l.setLayoutData(gd); - } - Text text = factory.createText(parent, "", style); //$NON-NLS-1$ - int hfill = span == 1 ? GridData.FILL_HORIZONTAL - : GridData.HORIZONTAL_ALIGN_FILL; - GridData gd = new GridData(hfill | GridData.VERTICAL_ALIGN_CENTER); - gd.horizontalSpan = span; - text.setLayoutData(gd); - return text; - } - - public static Text createText(Composite parent, FormToolkit factory, - int span) { - Text text = factory.createText(parent, ""); //$NON-NLS-1$ - int hfill = span == 1 ? GridData.FILL_HORIZONTAL - : GridData.HORIZONTAL_ALIGN_FILL; - GridData gd = new GridData(hfill | GridData.VERTICAL_ALIGN_CENTER); - gd.horizontalSpan = span; - text.setLayoutData(gd); - return text; - } - - public static int computeMinimumWidth(GC gc, String text) { -// BreakIterator wb = BreakIterator.getWordInstance(); -// wb.setText(text); -// int last = 0; -// -// int width = 0; -// -// for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) { -// String word = text.substring(last, loc); -// Point extent = gc.textExtent(word); -// width = Math.max(width, extent.x); -// last = loc; -// } -// String lastWord = text.substring(last); -// Point extent = gc.textExtent(lastWord); -// width = Math.max(width, extent.x); -// return width; - return 0; - } - - public static Point computeWrapSize(GC gc, String text, int wHint) { -// BreakIterator wb = BreakIterator.getWordInstance(); -// wb.setText(text); - FontMetrics fm = gc.getFontMetrics(); - int lineHeight = fm.getHeight(); - - int saved = 0; - int last = 0; - int height = lineHeight; - int maxWidth = 0; -// for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) { -// String word = text.substring(saved, loc); -// Point extent = gc.textExtent(word); -// if (extent.x > wHint) { -// // overflow -// saved = last; -// height += extent.y; -// // switch to current word so maxWidth will accommodate very long single words -// word = text.substring(last, loc); -// extent = gc.textExtent(word); -// } -// maxWidth = Math.max(maxWidth, extent.x); -// last = loc; -// } - /* - * Correct the height attribute in case it was calculated wrong due to wHint being less than maxWidth. - * The recursive call proved to be the only thing that worked in all cases. Some attempts can be made - * to estimate the height, but the algorithm needs to be run again to be sure. - */ - if (maxWidth > wHint) - return computeWrapSize(gc, text, maxWidth); - return new Point(maxWidth, height); - } - -// RAP [rh] paintWrapText unnecessary -// public static void paintWrapText(GC gc, String text, Rectangle bounds) { -// paintWrapText(gc, text, bounds, false); -// } - -// RAP [rh] paintWrapText unnecessary -// public static void paintWrapText(GC gc, String text, Rectangle bounds, -// boolean underline) { -// BreakIterator wb = BreakIterator.getWordInstance(); -// wb.setText(text); -// FontMetrics fm = gc.getFontMetrics(); -// int lineHeight = fm.getHeight(); -// int descent = fm.getDescent(); -// -// int saved = 0; -// int last = 0; -// int y = bounds.y; -// int width = bounds.width; -// -// for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) { -// String line = text.substring(saved, loc); -// Point extent = gc.textExtent(line); -// -// if (extent.x > width) { -// // overflow -// String prevLine = text.substring(saved, last); -// gc.drawText(prevLine, bounds.x, y, true); -// if (underline) { -// Point prevExtent = gc.textExtent(prevLine); -// int lineY = y + lineHeight - descent + 1; -// gc -// .drawLine(bounds.x, lineY, bounds.x + prevExtent.x, -// lineY); -// } -// -// saved = last; -// y += lineHeight; -// } -// last = loc; -// } -// // paint the last line -// String lastLine = text.substring(saved, last); -// gc.drawText(lastLine, bounds.x, y, true); -// if (underline) { -// int lineY = y + lineHeight - descent + 1; -// Point lastExtent = gc.textExtent(lastLine); -// gc.drawLine(bounds.x, lineY, bounds.x + lastExtent.x, lineY); -// } -// } - - public static ScrolledComposite getScrolledComposite(Control c) { - Composite parent = c.getParent(); - - while (parent != null) { - if (parent instanceof ScrolledComposite) { - return (ScrolledComposite) parent; - } - parent = parent.getParent(); - } - return null; - } - - public static void ensureVisible(Control c) { - ScrolledComposite scomp = getScrolledComposite(c); - if (scomp != null) { - Object data = scomp.getData(FOCUS_SCROLLING); - if (data == null || !data.equals(Boolean.FALSE)) - FormUtil.ensureVisible(scomp, c); - } - } - - public static void ensureVisible(ScrolledComposite scomp, Control control) { - // if the control is a FormText we do not need to scroll since it will - // ensure visibility of its segments as necessary -// if (control instanceof FormText) -// return; - Point controlSize = control.getSize(); - Point controlOrigin = getControlLocation(scomp, control); - ensureVisible(scomp, controlOrigin, controlSize); - } - - public static void ensureVisible(ScrolledComposite scomp, - Point controlOrigin, Point controlSize) { - Rectangle area = scomp.getClientArea(); - Point scompOrigin = scomp.getOrigin(); - - int x = scompOrigin.x; - int y = scompOrigin.y; - - // horizontal right, but only if the control is smaller - // than the client area - if (controlSize.x < area.width - && (controlOrigin.x + controlSize.x > scompOrigin.x - + area.width)) { - x = controlOrigin.x + controlSize.x - area.width; - } - // horizontal left - make sure the left edge of - // the control is showing - if (controlOrigin.x < x) { - if (controlSize.x < area.width) - x = controlOrigin.x + controlSize.x - area.width; - else - x = controlOrigin.x; - } - // vertical bottom - if (controlSize.y < area.height - && (controlOrigin.y + controlSize.y > scompOrigin.y - + area.height)) { - y = controlOrigin.y + controlSize.y - area.height; - } - // vertical top - make sure the top of - // the control is showing - if (controlOrigin.y < y) { - if (controlSize.y < area.height) - y = controlOrigin.y + controlSize.y - area.height; - else - y = controlOrigin.y; - } - - if (scompOrigin.x != x || scompOrigin.y != y) { - // scroll to reveal - scomp.setOrigin(x, y); - } - } - - public static void ensureVisible(ScrolledComposite scomp, Control control, - MouseEvent e) { - Point controlOrigin = getControlLocation(scomp, control); - int rX = controlOrigin.x + e.x; - int rY = controlOrigin.y + e.y; - Rectangle area = scomp.getClientArea(); - Point scompOrigin = scomp.getOrigin(); - - int x = scompOrigin.x; - int y = scompOrigin.y; - // System.out.println("Ensure: area="+area+", origin="+scompOrigin+", - // cloc="+controlOrigin+", csize="+controlSize+", x="+x+", y="+y); - - // horizontal right - if (rX > scompOrigin.x + area.width) { - x = rX - area.width; - } - // horizontal left - else if (rX < x) { - x = rX; - } - // vertical bottom - if (rY > scompOrigin.y + area.height) { - y = rY - area.height; - } - // vertical top - else if (rY < y) { - y = rY; - } - - if (scompOrigin.x != x || scompOrigin.y != y) { - // scroll to reveal - scomp.setOrigin(x, y); - } - } - - public static Point getControlLocation(ScrolledComposite scomp, - Control control) { - int x = 0; - int y = 0; - Control content = scomp.getContent(); - Control currentControl = control; - for (;;) { - if (currentControl == content) - break; - Point location = currentControl.getLocation(); - // if (location.x > 0) - // x += location.x; - // if (location.y > 0) - // y += location.y; - x += location.x; - y += location.y; - currentControl = currentControl.getParent(); - } - return new Point(x, y); - } - - static void scrollVertical(ScrolledComposite scomp, boolean up) { - scroll(scomp, 0, up ? -V_SCROLL_INCREMENT : V_SCROLL_INCREMENT); - } - - static void scrollHorizontal(ScrolledComposite scomp, boolean left) { - scroll(scomp, left ? -H_SCROLL_INCREMENT : H_SCROLL_INCREMENT, 0); - } - - static void scrollPage(ScrolledComposite scomp, boolean up) { - Rectangle clientArea = scomp.getClientArea(); - int increment = up ? -clientArea.height : clientArea.height; - scroll(scomp, 0, increment); - } - - static void scroll(ScrolledComposite scomp, int xoffset, int yoffset) { - Point origin = scomp.getOrigin(); - Point contentSize = scomp.getContent().getSize(); - int xorigin = origin.x + xoffset; - int yorigin = origin.y + yoffset; - xorigin = Math.max(xorigin, 0); - xorigin = Math.min(xorigin, contentSize.x - 1); - yorigin = Math.max(yorigin, 0); - yorigin = Math.min(yorigin, contentSize.y - 1); - scomp.setOrigin(xorigin, yorigin); - } - -// RAP [rh] FormUtil#updatePageIncrement: empty implementation - public static void updatePageIncrement(ScrolledComposite scomp) { -// ScrollBar vbar = scomp.getVerticalBar(); -// if (vbar != null) { -// Rectangle clientArea = scomp.getClientArea(); -// int increment = clientArea.height - 5; -// vbar.setPageIncrement(increment); -// } -// ScrollBar hbar = scomp.getHorizontalBar(); -// if (hbar != null) { -// Rectangle clientArea = scomp.getClientArea(); -// int increment = clientArea.width - 5; -// hbar.setPageIncrement(increment); -// } - } - - public static void processKey(int keyCode, Control c) { - if (c.isDisposed()) { - return; - } - ScrolledComposite scomp = FormUtil.getScrolledComposite(c); - if (scomp != null) { - if (c instanceof Combo) - return; - switch (keyCode) { - case SWT.ARROW_DOWN: - if (scomp.getData("novarrows") == null) //$NON-NLS-1$ - FormUtil.scrollVertical(scomp, false); - break; - case SWT.ARROW_UP: - if (scomp.getData("novarrows") == null) //$NON-NLS-1$ - FormUtil.scrollVertical(scomp, true); - break; - case SWT.ARROW_LEFT: - FormUtil.scrollHorizontal(scomp, true); - break; - case SWT.ARROW_RIGHT: - FormUtil.scrollHorizontal(scomp, false); - break; - case SWT.PAGE_UP: - FormUtil.scrollPage(scomp, true); - break; - case SWT.PAGE_DOWN: - FormUtil.scrollPage(scomp, false); - break; - } - } - } - - public static boolean isWrapControl(Control c) { - if ((c.getStyle() & SWT.WRAP) != 0) - return true; - if (c instanceof Composite) { - return false; -// return ((Composite) c).getLayout() instanceof ILayoutExtension; - } - return false; - } - - public static int getWidthHint(int wHint, Control c) { - boolean wrap = isWrapControl(c); - return wrap ? wHint : SWT.DEFAULT; - } - - public static int getHeightHint(int hHint, Control c) { - if (c instanceof Composite) { - Layout layout = ((Composite) c).getLayout(); -// if (layout instanceof ColumnLayout) -// return hHint; - } - return SWT.DEFAULT; - } - - public static int computeMinimumWidth(Control c, boolean changed) { - if (c instanceof Composite) { - Layout layout = ((Composite) c).getLayout(); -// if (layout instanceof ILayoutExtension) -// return ((ILayoutExtension) layout).computeMinimumWidth( -// (Composite) c, changed); - } - return c.computeSize(FormUtil.getWidthHint(5, c), SWT.DEFAULT, changed).x; - } - - public static int computeMaximumWidth(Control c, boolean changed) { - if (c instanceof Composite) { - Layout layout = ((Composite) c).getLayout(); -// if (layout instanceof ILayoutExtension) -// return ((ILayoutExtension) layout).computeMaximumWidth( -// (Composite) c, changed); - } - return c.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed).x; - } - -// public static Form getForm(Control c) { -// Composite parent = c.getParent(); -// while (parent != null) { -// if (parent instanceof Form) { -// return (Form) parent; -// } -// parent = parent.getParent(); -// } -// return null; -// } - -// RAP [rh] FormUtil#createAlphaMashImage unnecessary -// public static Image createAlphaMashImage(Device device, Image srcImage) { -// Rectangle bounds = srcImage.getBounds(); -// int alpha = 0; -// int calpha = 0; -// ImageData data = srcImage.getImageData(); -// // Create a new image with alpha values alternating -// // between fully transparent (0) and fully opaque (255). -// // This image will show the background through the -// // transparent pixels. -// for (int i = 0; i < bounds.height; i++) { -// // scan line -// alpha = calpha; -// for (int j = 0; j < bounds.width; j++) { -// // column -// data.setAlpha(j, i, alpha); -// alpha = alpha == 255 ? 0 : 255; -// } -// calpha = calpha == 255 ? 0 : 255; -// } -// return new Image(device, data); -// } - - public static boolean mnemonicMatch(String text, char key) { - char mnemonic = findMnemonic(text); - if (mnemonic == '\0') - return false; - return Character.toUpperCase(key) == Character.toUpperCase(mnemonic); - } - - private static char findMnemonic(String string) { - int index = 0; - int length = string.length(); - do { - while (index < length && string.charAt(index) != '&') - index++; - if (++index >= length) - return '\0'; - if (string.charAt(index) != '&') - return string.charAt(index); - index++; - } while (index < length); - return '\0'; - } - - public static void setFocusScrollingEnabled(Control c, boolean enabled) { - ScrolledComposite scomp = null; - - if (c instanceof ScrolledComposite) - scomp = (ScrolledComposite)c; - else - scomp = getScrolledComposite(c); - if (scomp!=null) - scomp.setData(FormUtil.FOCUS_SCROLLING, enabled?null:Boolean.FALSE); - } - - // RAP [rh] FormUtil#setAntialias unnecessary -// public static void setAntialias(GC gc, int style) { -// if (!gc.getAdvanced()) { -// gc.setAdvanced(true); -// if (!gc.getAdvanced()) -// return; -// } -// gc.setAntialias(style); -// } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormColors.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormColors.java deleted file mode 100644 index cf0e5d3..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormColors.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -/** - * A place to hold all the color constants used in the forms package. - * - * @since 1.0 - */ - -public interface IFormColors { - /** - * A prefix for all the keys. - */ - String PREFIX = "org.eclipse.ui.forms."; //$NON-NLS-1$ - /** - * Key for the form title foreground color. - */ - String TITLE = PREFIX + "TITLE"; //$NON-NLS-1$ - - /** - * A prefix for the header color constants. - */ - String H_PREFIX = PREFIX + "H_"; //$NON-NLS-1$ - /* - * A prefix for the section title bar color constants. - */ - String TB_PREFIX = PREFIX + "TB_"; //$NON-NLS-1$ - /** - * Key for the form header background gradient ending color. - */ - String H_GRADIENT_END = H_PREFIX + "GRADIENT_END"; //$NON-NLS-1$ - - /** - * Key for the form header background gradient starting color. - * - */ - String H_GRADIENT_START = H_PREFIX + "GRADIENT_START"; //$NON-NLS-1$ - /** - * Key for the form header bottom keyline 1 color. - * - */ - String H_BOTTOM_KEYLINE1 = H_PREFIX + "BOTTOM_KEYLINE1"; //$NON-NLS-1$ - /** - * Key for the form header bottom keyline 2 color. - * - */ - String H_BOTTOM_KEYLINE2 = H_PREFIX + "BOTTOM_KEYLINE2"; //$NON-NLS-1$ - /** - * Key for the form header light hover color. - * - */ - String H_HOVER_LIGHT = H_PREFIX + "H_HOVER_LIGHT"; //$NON-NLS-1$ - /** - * Key for the form header full hover color. - * - */ - String H_HOVER_FULL = H_PREFIX + "H_HOVER_FULL"; //$NON-NLS-1$ - - /** - * Key for the tree/table border color. - */ - String BORDER = PREFIX + "BORDER"; //$NON-NLS-1$ - - /** - * Key for the section separator color. - */ - String SEPARATOR = PREFIX + "SEPARATOR"; //$NON-NLS-1$ - - /** - * Key for the section title bar background. - */ - String TB_BG = TB_PREFIX + "BG"; //$NON-NLS-1$ - - /** - * Key for the section title bar foreground. - */ - String TB_FG = TB_PREFIX + "FG"; //$NON-NLS-1$ - - /** - * Key for the section title bar gradient. - * @deprecated Since 3.3, this color is not used any more. The - * tool bar gradient is created starting from {@link #TB_BG} to - * the section background color. - */ - String TB_GBG = TB_BG; - - /** - * Key for the section title bar border. - */ - String TB_BORDER = TB_PREFIX + "BORDER"; //$NON-NLS-1$ - - /** - * Key for the section toggle color. Since 3.1, this color is used for all - * section styles. - */ - String TB_TOGGLE = TB_PREFIX + "TOGGLE"; //$NON-NLS-1$ - - /** - * Key for the section toggle hover color. - * - */ - String TB_TOGGLE_HOVER = TB_PREFIX + "TOGGLE_HOVER"; //$NON-NLS-1$ -} \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormPart.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormPart.java deleted file mode 100644 index 954cc03..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IFormPart.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -/** - * Classes that implement this interface can be added to the managed form and - * take part in the form life cycle. The part is initialized with the form and - * will be asked to accept focus. The part can receive form input and can elect - * to do something according to it (for example, select an object that matches - * the input). - *

- * The form part has two 'out of sync' states in respect to the model(s) that - * feed the form: dirty and stale. When a part is dirty, it - * means that the user interacted with it and now its widgets contain state that - * is newer than the model. In order to sync up with the model, 'commit' needs - * to be called. In contrast, the model can change 'under' the form (as a result - * of some actions outside the form), resulting in data in the model being - * 'newer' than the content presented in the form. A 'stale' form part is - * brought in sync with the model by calling 'refresh'. The part is responsible - * for notifying the form when one of these states change in the part. The form - * reserves the right to handle this notification in the most appropriate way - * for the situation (for example, if the form is in a page of the multi-page - * editor, it may do nothing for stale parts if the page is currently not - * showing). - *

- * When the form is disposed, each registered part is disposed as well. Parts - * are responsible for releasing any system resources they created and for - * removing themselves as listeners from all event providers. - * - * @see IManagedForm - * @since 1.0 - * - */ -public interface IFormPart { - /** - * Initializes the part. - * - * @param form - * the managed form that manages the part - */ - void initialize(IManagedForm form); - - /** - * Disposes the part allowing it to release allocated resources. - */ - void dispose(); - - /** - * Returns true if the part has been modified with respect to the data - * loaded from the model. - * - * @return true if the part has been modified with respect to the data - * loaded from the model - */ - boolean isDirty(); - - /** - * If part is displaying information loaded from a model, this method - * instructs it to commit the new (modified) data back into the model. - * - * @param onSave - * indicates if commit is called during 'save' operation or for - * some other reason (for example, if form is contained in a - * wizard or a multi-page editor and the user is about to leave - * the page). - */ - void commit(boolean onSave); - - /** - * Notifies the part that an object has been set as overall form's input. - * The part can elect to react by revealing or selecting the object, or do - * nothing if not applicable. - * - * @return true if the part has selected and revealed the - * input object, false otherwise. - */ - boolean setFormInput(Object input); - - /** - * Instructs form part to transfer focus to the widget that should has focus - * in that part. The method can do nothing (if it has no widgets capable of - * accepting focus). - */ - void setFocus(); - - /** - * Tests whether the form part is stale and needs refreshing. Parts can - * receive notification from models that will make their content stale, but - * may need to delay refreshing to improve performance (for example, there - * is no need to immediately refresh a part on a form that is current on a - * hidden page). - *

- * It is important to differentiate 'stale' and 'dirty' states. Part is - * 'dirty' if user interacted with its editable widgets and changed the - * values. In contrast, part is 'stale' when the data it presents in the - * widgets has been changed in the model without direct user interaction. - * - * @return true if the part needs refreshing, - * false otherwise. - */ - boolean isStale(); - - /** - * Refreshes the part completely from the information freshly obtained from - * the model. The method will not be called if the part is not stale. - * Otherwise, the part is responsible for clearing the 'stale' flag after - * refreshing itself. - */ - void refresh(); -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IManagedForm.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IManagedForm.java deleted file mode 100644 index 490d3a3..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IManagedForm.java +++ /dev/null @@ -1,175 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.swt.custom.ScrolledComposite; -//import org.eclipse.ui.forms.widgets.FormToolkit; -//import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * Managed form wraps a form widget and adds life cycle methods for form parts. - * A form part is a portion of the form that participates in form life cycle - * events. - *

- * There is no 1/1 mapping between widgets and form parts. A widget like Section - * can be a part by itself, but a number of widgets can gather around one form - * part. - *

- * This interface should not be extended or implemented. New form instances - * should be created using ManagedForm. - * - * @see ManagedForm - * @since 1.0 - * @noimplement This interface is not intended to be implemented by clients. - * @noextend This interface is not intended to be extended by clients. - */ -public interface IManagedForm { - /** - * Initializes the form by looping through the managed parts and - * initializing them. Has no effect if already called once. - */ - public void initialize(); - - /** - * Returns the toolkit used by this form. - * - * @return the toolkit - */ - public FormToolkit getToolkit(); - - /** - * Returns the form widget managed by this form. - * - * @return the form widget - */ - public ScrolledComposite getForm(); - - /** - * Reflows the form as a result of the layout change. - * - * @param changed - * if true, discard cached layout information - */ - public void reflow(boolean changed); - - /** - * A part can use this method to notify other parts that implement - * IPartSelectionListener about selection changes. - * - * @param part - * the part that broadcasts the selection - * @param selection - * the selection in the part - */ - public void fireSelectionChanged(IFormPart part, ISelection selection); - - /** - * Returns all the parts currently managed by this form. - * - * @return the managed parts - */ - IFormPart[] getParts(); - - /** - * Adds the new part to the form. - * - * @param part - * the part to add - */ - void addPart(IFormPart part); - - /** - * Removes the part from the form. - * - * @param part - * the part to remove - */ - void removePart(IFormPart part); - - /** - * Sets the input of this page to the provided object. - * - * @param input - * the new page input - * @return true if the form contains this object, - * false otherwise. - */ - boolean setInput(Object input); - - /** - * Returns the current page input. - * - * @return page input object or null if not applicable. - */ - Object getInput(); - - /** - * Tests if form is dirty. A managed form is dirty if at least one managed - * part is dirty. - * - * @return true if at least one managed part is dirty, - * false otherwise. - */ - boolean isDirty(); - - /** - * Notifies the form that the dirty state of one of its parts has changed. - * The global dirty state of the form can be obtained by calling 'isDirty'. - * - * @see #isDirty - */ - void dirtyStateChanged(); - - /** - * Commits the dirty form. All pending changes in the widgets are flushed - * into the model. - * - * @param onSave - */ - void commit(boolean onSave); - - /** - * Tests if form is stale. A managed form is stale if at least one managed - * part is stale. This can happen when the underlying model changes, - * resulting in the presentation of the part being out of sync with the - * model and needing refreshing. - * - * @return true if the form is stale, false - * otherwise. - */ - boolean isStale(); - - /** - * Notifies the form that the stale state of one of its parts has changed. - * The global stale state of the form can be obtained by calling 'isStale'. - */ - void staleStateChanged(); - - /** - * Refreshes the form by refreshing every part that is stale. - */ - void refresh(); - - /** - * Sets the container that owns this form. Depending on the context, the - * container may be wizard, editor page, editor etc. - * - * @param container - * the container of this form - */ - void setContainer(Object container); - - /** - * Returns the container of this form. - * - * @return the form container - */ - Object getContainer(); - - /** - * Returns the message manager that will keep track of messages in this - * form. - * - * @return the message manager instance - */ -// IMessageManager getMessageManager(); -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IPartSelectionListener.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IPartSelectionListener.java deleted file mode 100644 index 0f557d4..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/IPartSelectionListener.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -import org.eclipse.jface.viewers.ISelection; - -/** - * Form parts can implement this interface if they want to be - * notified when another part on the same form changes selection - * state. - * - * @see IFormPart - * @since 1.0 - */ -public interface IPartSelectionListener { - /** - * Called when the provided part has changed selection state. - * - * @param part - * the selection source - * @param selection - * the new selection - */ - public void selectionChanged(IFormPart part, ISelection selection); -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/ManagedForm.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/ManagedForm.java deleted file mode 100644 index 4140465..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/ManagedForm.java +++ /dev/null @@ -1,323 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms; - -import java.util.Vector; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.widgets.Composite; -//import org.eclipse.ui.forms.widgets.FormToolkit; -//import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * Managed form wraps a form widget and adds life cycle methods for form parts. - * A form part is a portion of the form that participates in form life cycle - * events. - *

- * There is requirement for 1/1 mapping between widgets and form parts. A widget - * like Section can be a part by itself, but a number of widgets can join around - * one form part. - *

- * Note to developers: this class is left public to allow its use beyond the - * original intention (inside a multi-page editor's page). You should limit the - * use of this class to make new instances inside a form container (wizard page, - * dialog etc.). Clients that need access to the class should not do it - * directly. Instead, they should do it through IManagedForm interface as much - * as possible. - * - * @since 1.0 - */ -public class ManagedForm implements IManagedForm { - private Object input; - - private ScrolledComposite form; - - private FormToolkit toolkit; - - private Object container; - - private boolean ownsToolkit; - - private boolean initialized; - - private Vector parts = new Vector(); - - /** - * Creates a managed form in the provided parent. Form toolkit and widget - * will be created and owned by this object. - * - * @param parent - * the parent widget - */ - public ManagedForm(Composite parent) { - toolkit = new FormToolkit(parent.getDisplay()); - ownsToolkit = true; - form = toolkit.createScrolledForm(parent); - - } - - /** - * Creates a managed form that will use the provided toolkit and - * - * @param toolkit - * @param form - */ - public ManagedForm(FormToolkit toolkit, ScrolledComposite form) { - this.form = form; - this.toolkit = toolkit; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#addPart(org.eclipse.ui.forms.IFormPart) - */ - public void addPart(IFormPart part) { - parts.add(part); - part.initialize(this); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#removePart(org.eclipse.ui.forms.IFormPart) - */ - public void removePart(IFormPart part) { - parts.remove(part); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#getParts() - */ - public IFormPart[] getParts() { - return (IFormPart[]) parts.toArray(new IFormPart[parts.size()]); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#getToolkit() - */ - public FormToolkit getToolkit() { - return toolkit; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#getForm() - */ - public ScrolledComposite getForm() { - return form; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#reflow(boolean) - */ - public void reflow(boolean changed) { -// form.reflow(changed); - } - - /** - * A part can use this method to notify other parts that implement - * IPartSelectionListener about selection changes. - * - * @param part - * the part that broadcasts the selection - * @param selection - * the selection in the part - * @see IPartSelectionListener - */ - public void fireSelectionChanged(IFormPart part, ISelection selection) { - for (int i = 0; i < parts.size(); i++) { - IFormPart cpart = (IFormPart) parts.get(i); - if (part.equals(cpart)) - continue; -// if (cpart instanceof IPartSelectionListener) { -// ((IPartSelectionListener) cpart).selectionChanged(part, -// selection); -// } - } - } - - /** - * Initializes the form by looping through the managed parts and - * initializing them. Has no effect if already called once. - */ - public void initialize() { - if (initialized) - return; - for (int i = 0; i < parts.size(); i++) { - IFormPart part = (IFormPart) parts.get(i); - part.initialize(this); - } - initialized = true; - } - - /** - * Disposes all the parts in this form. - */ - public void dispose() { - for (int i = 0; i < parts.size(); i++) { - IFormPart part = (IFormPart) parts.get(i); - part.dispose(); - } - if (ownsToolkit) { - toolkit.dispose(); - } - } - - /** - * Refreshes the form by refreshes all the stale parts. Since 3.1, this - * method is performed on a UI thread when called from another thread so it - * is not needed to wrap the call in Display.syncExec or - * asyncExec. - */ - public void refresh() { - Thread t = Thread.currentThread(); - Thread dt = toolkit.getColors().getDisplay().getThread(); - if (t.equals(dt)) - doRefresh(); - else { - toolkit.getColors().getDisplay().asyncExec(new Runnable() { - public void run() { - doRefresh(); - } - }); - } - } - - private void doRefresh() { - int nrefreshed = 0; - for (int i = 0; i < parts.size(); i++) { - IFormPart part = (IFormPart) parts.get(i); - if (part.isStale()) { - part.refresh(); - nrefreshed++; - } - } -// if (nrefreshed > 0) -// form.reflow(true); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#commit(boolean) - */ - public void commit(boolean onSave) { - for (int i = 0; i < parts.size(); i++) { - IFormPart part = (IFormPart) parts.get(i); - if (part.isDirty()) - part.commit(onSave); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#setInput(java.lang.Object) - */ - public boolean setInput(Object input) { - boolean pageResult = false; - - this.input = input; - for (int i = 0; i < parts.size(); i++) { - IFormPart part = (IFormPart) parts.get(i); - boolean result = part.setFormInput(input); - if (result) - pageResult = true; - } - return pageResult; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#getInput() - */ - public Object getInput() { - return input; - } - - /** - * Transfers the focus to the first form part. - */ - public void setFocus() { - if (parts.size() > 0) { - IFormPart part = (IFormPart) parts.get(0); - part.setFocus(); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#isDirty() - */ - public boolean isDirty() { - for (int i = 0; i < parts.size(); i++) { - IFormPart part = (IFormPart) parts.get(i); - if (part.isDirty()) - return true; - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#isStale() - */ - public boolean isStale() { - for (int i = 0; i < parts.size(); i++) { - IFormPart part = (IFormPart) parts.get(i); - if (part.isStale()) - return true; - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#dirtyStateChanged() - */ - public void dirtyStateChanged() { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#staleStateChanged() - */ - public void staleStateChanged() { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#getContainer() - */ - public Object getContainer() { - return container; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ui.forms.IManagedForm#setContainer(java.lang.Object) - */ - public void setContainer(Object container) { - this.container = container; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.forms.IManagedForm#getMessageManager() - */ -// public IMessageManager getMessageManager() { -// return form.getMessageManager(); -// } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormEditor.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormEditor.java deleted file mode 100644 index 484dae8..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormEditor.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms.editor; - -import org.argeo.cms.ui.eclipse.forms.FormToolkit; -import org.eclipse.jface.dialogs.IPageChangeProvider; - -/** - * This class forms a base of multi-page form editors that typically use one or - * more pages with forms and one page for raw source of the editor input. - *

- * Pages are added 'lazily' i.e. adding a page reserves a tab for it but does - * not cause the page control to be created. Page control is created when an - * attempt is made to select the page in question. This allows editors with - * several tabs and complex pages to open quickly. - *

- * Subclasses should extend this class and implement addPages - * method. One of the two addPage methods should be called to - * contribute pages to the editor. One adds complete (standalone) editors as - * nested tabs. These editors will be created right away and will be hooked so - * that key bindings, selection service etc. is compatible with the one for the - * standalone case. The other method adds classes that implement - * IFormPage interface. These pages will be created lazily and - * they will share the common key binding and selection service. Since 3.1, - * FormEditor is a page change provider. It allows listeners to attach to it and - * get notified when pages are changed. This new API in JFace allows dynamic - * help to update on page changes. - * - * @since 1.0 - */ -// RAP [if] As RAP is still using workbench 3.4, the implementation of -// IPageChangeProvider is missing from MultiPageEditorPart. Remove this code -// with the adoption of workbench > 3.5 -//public abstract class FormEditor extends MultiPageEditorPart { -public abstract class FormEditor implements - IPageChangeProvider { - private FormToolkit formToolkit; - - -public FormToolkit getToolkit() { - return formToolkit; - } - -public void editorDirtyStateChanged() { - -} - -public FormPage getActivePageInstance() { - return null; -} - - // RAP [if] As RAP is still using workbench 3.4, the implementation of -// IPageChangeProvider is missing from MultiPageEditorPart. Remove this code -// with the adoption of workbench > 3.5 -// private ListenerList pageListeners = new ListenerList(); -// -// /* -// * (non-Javadoc) -// * -// * @see org.eclipse.jface.dialogs.IPageChangeProvider#addPageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener) -// */ -// public void addPageChangedListener(IPageChangedListener listener) { -// pageListeners.add(listener); -// } -// -// /* -// * (non-Javadoc) -// * -// * @see org.eclipse.jface.dialogs.IPageChangeProvider#removePageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener) -// */ -// public void removePageChangedListener(IPageChangedListener listener) { -// pageListeners.remove(listener); -// } -// -// private void firePageChanged(final PageChangedEvent event) { -// Object[] listeners = pageListeners.getListeners(); -// for (int i = 0; i < listeners.length; ++i) { -// final IPageChangedListener l = (IPageChangedListener) listeners[i]; -// SafeRunnable.run(new SafeRunnable() { -// public void run() { -// l.pageChanged(event); -// } -// }); -// } -// } -// RAPEND [if] -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormPage.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormPage.java deleted file mode 100644 index a788412..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/FormPage.java +++ /dev/null @@ -1,276 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms.editor; -import org.argeo.cms.ui.eclipse.forms.IManagedForm; -import org.argeo.cms.ui.eclipse.forms.ManagedForm; -import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -/** - * A base class that all pages that should be added to FormEditor must subclass. - * Form page has an instance of PageForm that extends managed form. Subclasses - * should override method 'createFormContent(ManagedForm)' to fill the form with - * content. Note that page itself can be loaded lazily (on first open). - * Consequently, the call to create the form content can come after the editor - * has been opened for a while (in fact, it is possible to open and close the - * editor and never create the form because no attempt has been made to show the - * page). - * - * @since 1.0 - */ -public class FormPage implements IFormPage { - private FormEditor editor; - private PageForm mform; - private int index; - private String id; - - private String partName; - - - - public void setPartName(String partName) { - this.partName = partName; - } - private static class PageForm extends ManagedForm { - public PageForm(FormPage page, ScrolledComposite form) { - super(page.getEditor().getToolkit(), form); - setContainer(page); - } - - public FormPage getPage() { - return (FormPage)getContainer(); - } - public void dirtyStateChanged() { - getPage().getEditor().editorDirtyStateChanged(); - } - public void staleStateChanged() { - if (getPage().isActive()) - refresh(); - } - } - /** - * A constructor that creates the page and initializes it with the editor. - * - * @param editor - * the parent editor - * @param id - * the unique identifier - * @param title - * the page title - */ - public FormPage(FormEditor editor, String id, String title) { - this(id, title); - initialize(editor); - } - /** - * The constructor. The parent editor need to be passed in the - * initialize method if this constructor is used. - * - * @param id - * a unique page identifier - * @param title - * a user-friendly page title - */ - public FormPage(String id, String title) { - this.id = id; - setPartName(title); - } - /** - * Initializes the form page. - * - * @see IEditorPart#init - */ -// public void init(IEditorSite site, IEditorInput input) { -// setSite(site); -// setInput(input); -// } - /** - * Primes the form page with the parent editor instance. - * - * @param editor - * the parent editor - */ - public void initialize(FormEditor editor) { - this.editor = editor; - } - /** - * Returns the parent editor. - * - * @return parent editor instance - */ - public FormEditor getEditor() { - return editor; - } - /** - * Returns the managed form owned by this page. - * - * @return the managed form - */ - public IManagedForm getManagedForm() { - return mform; - } - /** - * Implements the required method by refreshing the form when set active. - * Subclasses must call super when overriding this method. - */ - public void setActive(boolean active) { - if (active) { - // We are switching to this page - refresh it - // if needed. - if (mform != null) - mform.refresh(); - } - } - /** - * Tests if the page is active by asking the parent editor if this page is - * the currently active page. - * - * @return true if the page is currently active, - * false otherwise. - */ - public boolean isActive() { - return this.equals(editor.getActivePageInstance()); - } - /** - * Creates the part control by creating the managed form using the parent - * editor's toolkit. Subclasses should override - * createFormContent(IManagedForm) to populate the form with - * content. - * - * @param parent - * the page parent composite - */ - public void createPartControl(Composite parent) { - ScrolledComposite form = editor.getToolkit().createScrolledForm(parent); - mform = new PageForm(this, form); - BusyIndicator.showWhile(parent.getDisplay(), new Runnable() { - public void run() { - createFormContent(mform); - } - }); - } - /** - * Subclasses should override this method to create content in the form - * hosted in this page. - * - * @param managedForm - * the form hosted in this page. - */ - protected void createFormContent(IManagedForm managedForm) { - } - /** - * Returns the form page control. - * - * @return managed form's control - */ - public Control getPartControl() { - return mform != null ? mform.getForm() : null; - } - /** - * Disposes the managed form. - */ - public void dispose() { - if (mform != null) - mform.dispose(); - } - /** - * Returns the unique identifier that can be used to reference this page. - * - * @return the unique page identifier - */ - public String getId() { - return id; - } - /** - * Returns null- form page has no title image. Subclasses - * may override. - * - * @return null - */ - public Image getTitleImage() { - return null; - } - /** - * Sets the focus by delegating to the managed form. - */ - public void setFocus() { - if (mform != null) - mform.setFocus(); - } - /** - * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor) - */ -// public void doSave(IProgressMonitor monitor) { -// if (mform != null) -// mform.commit(true); -// } - /** - * @see org.eclipse.ui.ISaveablePart#doSaveAs() - */ - public void doSaveAs() { - } - /** - * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() - */ - public boolean isSaveAsAllowed() { - return false; - } - /** - * Implemented by testing if the managed form is dirty. - * - * @return true if the managed form is dirty, - * false otherwise. - * - * @see org.eclipse.ui.ISaveablePart#isDirty() - */ - public boolean isDirty() { - return mform != null ? mform.isDirty() : false; - } - /** - * Preserves the page index. - * - * @param index - * the assigned page index - */ - public void setIndex(int index) { - this.index = index; - } - /** - * Returns the saved page index. - * - * @return the page index - */ - public int getIndex() { - return index; - } - /** - * Form pages are not editors. - * - * @return false - */ - public boolean isEditor() { - return false; - } - /** - * Attempts to select and reveal the given object by passing the request to - * the managed form. - * - * @param object - * the object to select and reveal in the page if possible. - * @return true if the page has been successfully selected - * and revealed by one of the managed form parts, false - * otherwise. - */ - public boolean selectReveal(Object object) { - if (mform != null) - return mform.setInput(object); - return false; - } - /** - * By default, editor will be allowed to flip the page. - * @return true - */ - public boolean canLeaveThePage() { - return true; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/IFormPage.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/IFormPage.java deleted file mode 100644 index eb08cb5..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/eclipse/forms/editor/IFormPage.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.argeo.cms.ui.eclipse.forms.editor; -import org.argeo.cms.ui.eclipse.forms.IManagedForm; -import org.eclipse.swt.widgets.Control; -/** - * Interface that all GUI pages need to implement in order - * to be added to FormEditor part. The interface makes - * several assumptions: - *

    - *
  • The form page has a managed form
  • - *
  • The form page has a unique id
  • - *
  • The form page can be GUI but can also wrap a complete - * editor class (in that case, it should return true - * from isEditor() method).
  • - *
  • The form page is lazy i.e. understands that - * its part control will be created at the last possible - * moment.
  • . - *
- *

Existing editors can be wrapped by implementing - * this interface. In this case, 'isEditor' should return true. - * A common editor to wrap in TextEditor that is - * often added to show the raw source code of the file open into - * the multi-page editor. - * - * @since 1.0 - */ -public interface IFormPage { - /** - * @param editor - * the form editor that this page belongs to - */ - void initialize(FormEditor editor); - /** - * Returns the editor this page belongs to. - * - * @return the form editor - */ - FormEditor getEditor(); - /** - * Returns the managed form of this page, unless this is a source page. - * - * @return the managed form or null if this is a source page. - */ - IManagedForm getManagedForm(); - /** - * Indicates whether the page has become the active in the editor. Classes - * that implement this interface may use this method to commit the page (on - * false) or lazily create and/or populate the content on - * true. - * - * @param active - * true if page should be visible, false - * otherwise. - */ - void setActive(boolean active); - /** - * Returns true if page is currently active, false if not. - * - * @return true for active page. - */ - boolean isActive(); - /** - * Tests if the content of the page is in a state that allows the - * editor to flip to another page. Typically, pages that contain - * raw source with syntax errors should not allow editors to - * leave them until errors are corrected. - * @return true if the editor can flip to another page, - * false otherwise. - */ - boolean canLeaveThePage(); - /** - * Returns the control associated with this page. - * - * @return the control of this page if created or null if the - * page has not been shown yet. - */ - Control getPartControl(); - /** - * Page must have a unique id that can be used to show it without knowing - * its relative position in the editor. - * - * @return the unique page identifier - */ - String getId(); - /** - * Returns the position of the page in the editor. - * - * @return the zero-based index of the page in the editor. - */ - int getIndex(); - /** - * Sets the position of the page in the editor. - * - * @param index - * the zero-based index of the page in the editor. - */ - void setIndex(int index); - /** - * Tests whether this page wraps a complete editor that - * can be registered on its own, or represents a page - * that cannot exist outside the multi-page editor context. - * - * @return true if the page wraps an editor, - * false if this is a form page. - */ - boolean isEditor(); - /** - * A hint to bring the provided object into focus. If the object is in a - * tree or table control, select it. If it is shown on a scrollable page, - * ensure that it is visible. If the object is not presented in - * the page, false should be returned to allow another - * page to try. - * - * @param object - * object to select and reveal - * @return true if the request was successful, false - * otherwise. - */ - boolean selectReveal(Object object); -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java index d9c1c12..0526234 100644 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java @@ -18,7 +18,7 @@ import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.Session; -import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.CurrentUser; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.cms.swt.CmsException; import org.argeo.cms.swt.CmsSwtUtils; diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/Activator.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/Activator.java deleted file mode 100644 index e10da3a..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/internal/Activator.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.argeo.cms.ui.internal; - -import org.argeo.api.cms.CmsState; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.util.tracker.ServiceTracker; - -public class Activator implements BundleActivator { - - // avoid dependency to RWT OSGi - private final static String CONTEXT_NAME_PROP = "contextName"; - - private static ServiceTracker nodeState; - - // @Override - public void start(BundleContext bc) throws Exception { - // UI -// bc.registerService(ApplicationConfiguration.class, new MaintenanceUi(), -// LangUtils.dico(CONTEXT_NAME_PROP, "system")); -// bc.registerService(ApplicationConfiguration.class, new UserUi(), LangUtils.dico(CONTEXT_NAME_PROP, "user")); - - nodeState = new ServiceTracker<>(bc, CmsState.class, null); - nodeState.open(); - } - - @Override - public void stop(BundleContext context) throws Exception { - if (nodeState != null) { - nodeState.close(); - nodeState = null; - } - } - - public static CmsState getNodeState() { - return nodeState.getService(); - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java deleted file mode 100644 index 3806341..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.util.Collections; -import java.util.Map; -import java.util.Observable; -import java.util.TreeMap; - -import javax.jcr.Repository; -import javax.jcr.RepositoryException; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.api.cms.CmsLog; - -public class DefaultRepositoryRegister extends Observable implements RepositoryRegister { - /** Key for a JCR repository alias */ - private final static String CN = CmsConstants.CN; - /** Key for a JCR repository URI */ - // public final static String JCR_REPOSITORY_URI = "argeo.jcr.repository.uri"; - private final static CmsLog log = CmsLog.getLog(DefaultRepositoryRegister.class); - - /** Read only map which will be directly exposed. */ - private Map repositories = Collections.unmodifiableMap(new TreeMap()); - - @SuppressWarnings("rawtypes") - public synchronized Repository getRepository(Map parameters) throws RepositoryException { - if (!parameters.containsKey(CN)) - throw new RepositoryException("Parameter " + CN + " has to be defined."); - String alias = parameters.get(CN).toString(); - if (!repositories.containsKey(alias)) - throw new RepositoryException("No repository registered with alias " + alias); - - return repositories.get(alias); - } - - /** Access to the read-only map */ - public synchronized Map getRepositories() { - return repositories; - } - - /** Registers a service, typically called when OSGi services are bound. */ - @SuppressWarnings("rawtypes") - public synchronized void register(Repository repository, Map properties) { - String alias; - if (properties == null || !properties.containsKey(CN)) { - log.warn("Cannot register a repository if no " + CN + " property is specified."); - return; - } - alias = properties.get(CN).toString(); - Map map = new TreeMap(repositories); - map.put(alias, repository); - repositories = Collections.unmodifiableMap(map); - setChanged(); - notifyObservers(alias); - } - - /** Unregisters a service, typically called when OSGi services are unbound. */ - @SuppressWarnings("rawtypes") - public synchronized void unregister(Repository repository, Map properties) { - // TODO: also check bean name? - if (properties == null || !properties.containsKey(CN)) { - log.warn("Cannot unregister a repository without property " + CN); - return; - } - - String alias = properties.get(CN).toString(); - Map map = new TreeMap(repositories); - if (map.remove(alias) == null) { - log.warn("No repository was registered with alias " + alias); - return; - } - repositories = Collections.unmodifiableMap(map); - setChanged(); - notifyObservers(alias); - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/FullVersioningTreeContentProvider.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/FullVersioningTreeContentProvider.java deleted file mode 100644 index 0f7ee77..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/FullVersioningTreeContentProvider.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; -import javax.jcr.version.Version; -import javax.jcr.version.VersionHistory; -import javax.jcr.version.VersionIterator; -import javax.jcr.version.VersionManager; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Display some version information of a JCR full versionable node in a tree - * like structure - */ -public class FullVersioningTreeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = 8691772509491211112L; - - /** - * Sends back the first level of the Tree. input element must be a single - * node object - */ - public Object[] getElements(Object inputElement) { - try { - Node rootNode = (Node) inputElement; - String curPath = rootNode.getPath(); - VersionManager vm = rootNode.getSession().getWorkspace() - .getVersionManager(); - - VersionHistory vh = vm.getVersionHistory(curPath); - List result = new ArrayList(); - VersionIterator vi = vh.getAllLinearVersions(); - - while (vi.hasNext()) { - result.add(vi.nextVersion()); - } - return result.toArray(); - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while getting version elements", re); - } - } - - public Object[] getChildren(Object parentElement) { - try { - if (parentElement instanceof Version) { - List tmp = new ArrayList(); - tmp.add(((Version) parentElement).getFrozenNode()); - return tmp.toArray(); - } - } catch (RepositoryException re) { - throw new EclipseUiException("Unexpected error while getting child " - + "node for version element", re); - } - return null; - } - - public Object getParent(Object element) { - try { - // this will not work in a simpleVersionning environment, parent is - // not a node. - if (element instanceof Node - && ((Node) element).isNodeType(NodeType.NT_FROZEN_NODE)) { - Node node = (Node) element; - return node.getParent(); - } else - return null; - } catch (RepositoryException e) { - return null; - } - } - - public boolean hasChildren(Object element) { - try { - if (element instanceof Version) - return true; - else if (element instanceof Node) - return ((Node) element).hasNodes(); - else - return false; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot check children of " + element, e); - } - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrBrowserUtils.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrBrowserUtils.java deleted file mode 100644 index b36acc3..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrBrowserUtils.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; - -import org.argeo.cms.ui.jcr.model.RepositoriesElem; -import org.argeo.cms.ui.jcr.model.RepositoryElem; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.cms.ui.jcr.model.WorkspaceElem; -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; - -/** Useful methods to manage the JCR Browser */ -public class JcrBrowserUtils { - - public static String getPropertyTypeAsString(Property prop) { - try { - return PropertyType.nameFromValue(prop.getType()); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot check type for " + prop, e); - } - } - - /** Insure that the UI component is not stale, refresh if needed */ - public static void forceRefreshIfNeeded(TreeParent element) { - Node curNode = null; - - boolean doRefresh = false; - - try { - if (element instanceof SingleJcrNodeElem) { - curNode = ((SingleJcrNodeElem) element).getNode(); - } else if (element instanceof WorkspaceElem) { - curNode = ((WorkspaceElem) element).getRootNode(); - } - - if (curNode != null && element.getChildren().length != curNode.getNodes().getSize()) - doRefresh = true; - else if (element instanceof RepositoryElem) { - RepositoryElem rn = (RepositoryElem) element; - if (rn.isConnected()) { - String[] wkpNames = rn.getAccessibleWorkspaceNames(); - if (element.getChildren().length != wkpNames.length) - doRefresh = true; - } - } else if (element instanceof RepositoriesElem) { - doRefresh = true; - // Always force refresh for RepositoriesElem : the condition - // below does not take remote repository into account and it is - // not trivial to do so. - - // RepositoriesElem rn = (RepositoriesElem) element; - // if (element.getChildren().length != - // rn.getRepositoryRegister() - // .getRepositories().size()) - // doRefresh = true; - } - if (doRefresh) { - element.clearChildren(); - element.getChildren(); - } - } catch (RepositoryException re) { - throw new EclipseUiException("Unexpected error while synchronising the UI with the JCR repository", re); - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrDClickListener.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrDClickListener.java deleted file mode 100644 index 1707681..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrDClickListener.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import javax.jcr.Node; - -import org.argeo.cms.ui.jcr.model.RepositoryElem; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.cms.ui.jcr.model.WorkspaceElem; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; - -/** Centralizes the management of double click on a NodeTreeViewer */ -public class JcrDClickListener implements IDoubleClickListener { - // private final static Log log = LogFactory - // .getLog(GenericNodeDoubleClickListener.class); - - private TreeViewer nodeViewer; - - // private JcrFileProvider jfp; - // private FileHandler fileHandler; - - public JcrDClickListener(TreeViewer nodeViewer) { - this.nodeViewer = nodeViewer; - // jfp = new JcrFileProvider(); - // Commented out. see https://www.argeo.org/bugzilla/show_bug.cgi?id=188 - // fileHandler = null; - // fileHandler = new FileHandler(jfp); - } - - public void doubleClick(DoubleClickEvent event) { - if (event.getSelection() == null || event.getSelection().isEmpty()) - return; - Object obj = ((IStructuredSelection) event.getSelection()).getFirstElement(); - if (obj instanceof RepositoryElem) { - RepositoryElem rpNode = (RepositoryElem) obj; - if (rpNode.isConnected()) { - rpNode.logout(); - } else { - rpNode.login(); - } - nodeViewer.refresh(obj); - } else if (obj instanceof WorkspaceElem) { - WorkspaceElem wn = (WorkspaceElem) obj; - if (wn.isConnected()) - wn.logout(); - else - wn.login(); - nodeViewer.refresh(obj); - } else if (obj instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj; - Node node = sjn.getNode(); - openNode(node); - } - } - - protected void openNode(Node node) { - // TODO implement generic behaviour - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrImages.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrImages.java deleted file mode 100644 index d1d1e31..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrImages.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import org.argeo.cms.ui.theme.CmsImages; -import org.eclipse.swt.graphics.Image; - -/** Shared icons. */ -public class JcrImages { - public final static Image NODE = CmsImages.createIcon("node.gif"); - public final static Image FOLDER = CmsImages.createIcon("folder.gif"); - public final static Image FILE = CmsImages.createIcon("file.gif"); - public final static Image BINARY = CmsImages.createIcon("binary.png"); - public final static Image HOME = CmsImages.createIcon("person-logged-in.png"); - public final static Image SORT = CmsImages.createIcon("sort.gif"); - public final static Image REMOVE = CmsImages.createIcon("remove.gif"); - - public final static Image REPOSITORIES = CmsImages.createIcon("repositories.gif"); - public final static Image REPOSITORY_DISCONNECTED = CmsImages.createIcon("repository_disconnected.gif"); - public final static Image REPOSITORY_CONNECTED = CmsImages.createIcon("repository_connected.gif"); - public final static Image REMOTE_DISCONNECTED = CmsImages.createIcon("remote_disconnected.gif"); - public final static Image REMOTE_CONNECTED = CmsImages.createIcon("remote_connected.gif"); - public final static Image WORKSPACE_DISCONNECTED = CmsImages.createIcon("workspace_disconnected.png"); - public final static Image WORKSPACE_CONNECTED = CmsImages.createIcon("workspace_connected.png"); - -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java deleted file mode 100644 index cc8479f..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/JcrTreeContentProvider.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.jcr.util.JcrItemsComparator; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Implementation of the {@code ITreeContentProvider} in order to display a - * single JCR node and its children in a tree like structure - */ -public class JcrTreeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = -2128326504754297297L; - // private Node rootNode; - private JcrItemsComparator itemComparator = new JcrItemsComparator(); - - /** - * Sends back the first level of the Tree. input element must be a single node - * object - */ - public Object[] getElements(Object inputElement) { - Node rootNode = (Node) inputElement; - return childrenNodes(rootNode); - } - - public Object[] getChildren(Object parentElement) { - return childrenNodes((Node) parentElement); - } - - public Object getParent(Object element) { - try { - Node node = (Node) element; - if (!node.getPath().equals("/")) - return node.getParent(); - else - return null; - } catch (RepositoryException e) { - return null; - } - } - - public boolean hasChildren(Object element) { - try { - return ((Node) element).hasNodes(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot check children existence on " + element, e); - } - } - - protected Object[] childrenNodes(Node parentNode) { - try { - List children = new ArrayList(); - NodeIterator nit = parentNode.getNodes(); - while (nit.hasNext()) { - Node node = nit.nextNode(); -// if (node.getName().startsWith("rep:") || node.getName().startsWith("jcr:") -// || node.getName().startsWith("nt:")) -// continue nodes; - children.add(node); - } - Node[] arr = children.toArray(new Node[0]); - Arrays.sort(arr, itemComparator); - return arr; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot list children of " + parentNode, e); - } - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java deleted file mode 100644 index 0625cc8..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java +++ /dev/null @@ -1,175 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.jcr.CmsJcrUtils; -import org.argeo.cms.security.Keyring; -import org.argeo.cms.ui.jcr.model.RepositoriesElem; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.cms.ux.widgets.TreeParent; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Implementation of the {@code ITreeContentProvider} to display multiple - * repository environment in a tree like structure - */ -public class NodeContentProvider implements ITreeContentProvider { - private static final long serialVersionUID = -4083809398848374403L; - final private RepositoryRegister repositoryRegister; - final private RepositoryFactory repositoryFactory; - - // Current user session on the default workspace of the argeo Node - final private Session userSession; - final private Keyring keyring; - private boolean sortChildren; - - // Reference for cleaning - private SingleJcrNodeElem homeNode = null; - private RepositoriesElem repositoriesNode = null; - - // Utils - private TreeBrowserComparator itemComparator = new TreeBrowserComparator(); - - public NodeContentProvider(Session userSession, Keyring keyring, - RepositoryRegister repositoryRegister, - RepositoryFactory repositoryFactory, Boolean sortChildren) { - this.userSession = userSession; - this.keyring = keyring; - this.repositoryRegister = repositoryRegister; - this.repositoryFactory = repositoryFactory; - this.sortChildren = sortChildren; - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput == null)// dispose - return; - - if (userSession != null) { - Node userHome = CmsJcrUtils.getUserHome(userSession); - if (userHome != null) { - // TODO : find a way to dynamically get alias for the node - if (homeNode != null) - homeNode.dispose(); - homeNode = new SingleJcrNodeElem(null, userHome, - userSession.getUserID(), CmsConstants.EGO_REPOSITORY); - } - } - if (repositoryRegister != null) { - if (repositoriesNode != null) - repositoriesNode.dispose(); - repositoriesNode = new RepositoriesElem("Repositories", - repositoryRegister, repositoryFactory, null, userSession, - keyring); - } - } - - /** - * Sends back the first level of the Tree. Independent from inputElement - * that can be null - */ - public Object[] getElements(Object inputElement) { - List objs = new ArrayList(); - if (homeNode != null) - objs.add(homeNode); - if (repositoriesNode != null) - objs.add(repositoriesNode); - return objs.toArray(); - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof TreeParent) { - if (sortChildren) { - Object[] tmpArr = ((TreeParent) parentElement).getChildren(); - if (tmpArr == null) - return new Object[0]; - TreeParent[] arr = new TreeParent[tmpArr.length]; - for (int i = 0; i < tmpArr.length; i++) - arr[i] = (TreeParent) tmpArr[i]; - Arrays.sort(arr, itemComparator); - return arr; - } else - return ((TreeParent) parentElement).getChildren(); - } else - return new Object[0]; - } - - /** - * Sets whether the content provider should order the children nodes or not. - * It is user duty to call a full refresh of the tree after changing this - * parameter. - */ - public void setSortChildren(boolean sortChildren) { - this.sortChildren = sortChildren; - } - - public Object getParent(Object element) { - if (element instanceof TreeParent) { - return ((TreeParent) element).getParent(); - } else - return null; - } - - public boolean hasChildren(Object element) { - if (element instanceof RepositoriesElem) { - RepositoryRegister rr = ((RepositoriesElem) element) - .getRepositoryRegister(); - return rr.getRepositories().size() > 0; - } else if (element instanceof TreeParent) { - TreeParent tp = (TreeParent) element; - return tp.hasChildren(); - } - return false; - } - - public void dispose() { - if (homeNode != null) - homeNode.dispose(); - if (repositoriesNode != null) { - // logs out open sessions - // see https://bugzilla.argeo.org/show_bug.cgi?id=23 - repositoriesNode.dispose(); - } - } - - /** - * Specific comparator for this view. See specification here: - * https://www.argeo.org/bugzilla/show_bug.cgi?id=139 - */ - private class TreeBrowserComparator implements Comparator { - - public int category(TreeParent element) { - if (element instanceof SingleJcrNodeElem) { - Node node = ((SingleJcrNodeElem) element).getNode(); - try { - if (node.isNodeType(NodeType.NT_FOLDER)) - return 5; - } catch (RepositoryException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - return 10; - } - - public int compare(TreeParent o1, TreeParent o2) { - int cat1 = category(o1); - int cat2 = category(o2); - - if (cat1 != cat2) { - return cat1 - cat2; - } - return o1.getName().compareTo(o2.getName()); - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java deleted file mode 100644 index a5751c0..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import javax.jcr.NamespaceException; -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; - -import org.argeo.api.cms.CmsLog; -import org.argeo.cms.ui.jcr.model.RemoteRepositoryElem; -import org.argeo.cms.ui.jcr.model.RepositoriesElem; -import org.argeo.cms.ui.jcr.model.RepositoryElem; -import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; -import org.argeo.cms.ui.jcr.model.WorkspaceElem; -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.swt.graphics.Image; - -/** Provides reasonable defaults for know JCR types. */ -public class NodeLabelProvider extends ColumnLabelProvider { - private static final long serialVersionUID = -3662051696443321843L; - - private final static CmsLog log = CmsLog.getLog(NodeLabelProvider.class); - - public String getText(Object element) { - try { - if (element instanceof SingleJcrNodeElem) { - SingleJcrNodeElem sjn = (SingleJcrNodeElem) element; - return getText(sjn.getNode()); - } else if (element instanceof Node) { - return getText((Node) element); - } else - return super.getText(element); - } catch (RepositoryException e) { - throw new EclipseUiException("Unexpected JCR error while getting node name."); - } - } - - protected String getText(Node node) throws RepositoryException { - String label = node.getName(); - StringBuffer mixins = new StringBuffer(""); - for (NodeType type : node.getMixinNodeTypes()) - mixins.append(' ').append(type.getName()); - - return label + " [" + node.getPrimaryNodeType().getName() + mixins + "]"; - } - - @Override - public Image getImage(Object element) { - if (element instanceof RemoteRepositoryElem) { - if (((RemoteRepositoryElem) element).isConnected()) - return JcrImages.REMOTE_CONNECTED; - else - return JcrImages.REMOTE_DISCONNECTED; - } else if (element instanceof RepositoryElem) { - if (((RepositoryElem) element).isConnected()) - return JcrImages.REPOSITORY_CONNECTED; - else - return JcrImages.REPOSITORY_DISCONNECTED; - } else if (element instanceof WorkspaceElem) { - if (((WorkspaceElem) element).isConnected()) - return JcrImages.WORKSPACE_CONNECTED; - else - return JcrImages.WORKSPACE_DISCONNECTED; - } else if (element instanceof RepositoriesElem) { - return JcrImages.REPOSITORIES; - } else if (element instanceof SingleJcrNodeElem) { - Node nodeElem = ((SingleJcrNodeElem) element).getNode(); - return getImage(nodeElem); - - // if (element instanceof Node) { - // return getImage((Node) element); - // } else if (element instanceof WrappedNode) { - // return getImage(((WrappedNode) element).getNode()); - // } else if (element instanceof NodesWrapper) { - // return getImage(((NodesWrapper) element).getNode()); - // } - } - // try { - // return super.getImage(); - // } catch (RepositoryException e) { - // return null; - // } - return super.getImage(element); - } - - protected Image getImage(Node node) { - try { - if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)) - return JcrImages.FILE; - else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER)) - return JcrImages.FOLDER; - else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_RESOURCE)) - return JcrImages.BINARY; - try { - // TODO check workspace type? - if (node.getDepth() == 1 && node.hasProperty(Property.JCR_ID)) - return JcrImages.HOME; - - // optimizes -// if (node.hasProperty(LdapAttrs.uid.property()) && node.isNodeType(NodeTypes.NODE_USER_HOME)) -// return JcrImages.HOME; - } catch (NamespaceException e) { - // node namespace is not registered in this repo - } - return JcrImages.NODE; - } catch (RepositoryException e) { - log.warn("Error while retrieving type for " + node + " in order to display corresponding image"); - e.printStackTrace(); - return null; - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/OsgiRepositoryRegister.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/OsgiRepositoryRegister.java deleted file mode 100644 index 444350a..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/OsgiRepositoryRegister.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.util.HashMap; -import java.util.Map; - -import javax.jcr.Repository; - -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.ServiceTracker; - -public class OsgiRepositoryRegister extends DefaultRepositoryRegister { - private final static BundleContext bc = FrameworkUtil.getBundle(OsgiRepositoryRegister.class).getBundleContext(); - private final ServiceTracker repositoryTracker; - - public OsgiRepositoryRegister() { - repositoryTracker = new ServiceTracker(bc, Repository.class, null) { - - @Override - public Repository addingService(ServiceReference reference) { - - Repository repository = super.addingService(reference); - Map props = new HashMap<>(); - for (String key : reference.getPropertyKeys()) { - props.put(key, reference.getProperty(key)); - } - register(repository, props); - return repository; - } - - @Override - public void removedService(ServiceReference reference, Repository service) { - Map props = new HashMap<>(); - for (String key : reference.getPropertyKeys()) { - props.put(key, reference.getProperty(key)); - } - unregister(service, props); - super.removedService(reference, service); - } - - }; - } - - public void init() { - repositoryTracker.open(); - } - - public void destroy() { - repositoryTracker.close(); - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertiesContentProvider.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertiesContentProvider.java deleted file mode 100644 index fd544bb..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertiesContentProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.util.Set; -import java.util.TreeSet; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.RepositoryException; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.jcr.util.JcrItemsComparator; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** Simple content provider that displays all properties of a given Node */ -public class PropertiesContentProvider implements IStructuredContentProvider { - private static final long serialVersionUID = 5227554668841613078L; - private JcrItemsComparator itemComparator = new JcrItemsComparator(); - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public Object[] getElements(Object inputElement) { - try { - if (inputElement instanceof Node) { - Set props = new TreeSet(itemComparator); - PropertyIterator pit = ((Node) inputElement).getProperties(); - while (pit.hasNext()) - props.add(pit.nextProperty()); - return props.toArray(); - } - return new Object[] {}; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot get element for " - + inputElement, e); - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java deleted file mode 100644 index 37b90f7..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; - -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; -import javax.jcr.Value; - -import org.argeo.cms.ui.CmsUiConstants; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.jcr.JcrUtils; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ViewerCell; - -/** Default basic label provider for a given JCR Node's properties */ -public class PropertyLabelProvider extends ColumnLabelProvider { - private static final long serialVersionUID = -5405794508731390147L; - - // To be able to change column order easily - public static final int COLUMN_PROPERTY = 0; - public static final int COLUMN_VALUE = 1; - public static final int COLUMN_TYPE = 2; - public static final int COLUMN_ATTRIBUTES = 3; - - // Utils - protected DateFormat timeFormatter = new SimpleDateFormat(CmsUiConstants.DATE_TIME_FORMAT); - - public void update(ViewerCell cell) { - Object element = cell.getElement(); - cell.setText(getColumnText(element, cell.getColumnIndex())); - } - - public String getColumnText(Object element, int columnIndex) { - try { - if (element instanceof Property) { - Property prop = (Property) element; - if (prop.isMultiple()) { - switch (columnIndex) { - case COLUMN_PROPERTY: - return prop.getName(); - case COLUMN_VALUE: - // Corresponding values are listed on children - return ""; - case COLUMN_TYPE: - return JcrBrowserUtils.getPropertyTypeAsString(prop); - case COLUMN_ATTRIBUTES: - return JcrUtils.getPropertyDefinitionAsString(prop); - } - } else { - switch (columnIndex) { - case COLUMN_PROPERTY: - return prop.getName(); - case COLUMN_VALUE: - return formatValueAsString(prop.getValue()); - case COLUMN_TYPE: - return JcrBrowserUtils.getPropertyTypeAsString(prop); - case COLUMN_ATTRIBUTES: - return JcrUtils.getPropertyDefinitionAsString(prop); - } - } - } else if (element instanceof Value) { - Value val = (Value) element; - switch (columnIndex) { - case COLUMN_PROPERTY: - // Nothing to show - return ""; - case COLUMN_VALUE: - return formatValueAsString(val); - case COLUMN_TYPE: - // listed on the parent - return ""; - case COLUMN_ATTRIBUTES: - // Corresponding attributes are listed on the parent - return ""; - } - } - } catch (RepositoryException re) { - throw new EclipseUiException("Cannot retrieve prop value on " + element, re); - } - return null; - } - - private String formatValueAsString(Value value) { - // TODO enhance this method - try { - String strValue; - - if (value.getType() == PropertyType.BINARY) - strValue = ""; - else if (value.getType() == PropertyType.DATE) - strValue = timeFormatter.format(value.getDate().getTime()); - else - strValue = value.getString(); - return strValue; - } catch (RepositoryException e) { - throw new EclipseUiException("unexpected error while formatting value", e); - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/RepositoryRegister.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/RepositoryRegister.java deleted file mode 100644 index 802c756..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/RepositoryRegister.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import java.util.Map; - -import javax.jcr.Repository; -import javax.jcr.RepositoryFactory; - -/** Allows to register repositories by name. */ -public interface RepositoryRegister extends RepositoryFactory { - /** - * The registered {@link Repository} as a read-only map. Note that this - * method should be called for each access in order to be sure to be up to - * date in case repositories have registered/unregistered - */ - public Map getRepositories(); -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/VersionLabelProvider.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/VersionLabelProvider.java deleted file mode 100644 index 37dfe2b..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/VersionLabelProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.argeo.cms.ui.jcr; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.version.Version; - -import org.argeo.eclipse.ui.EclipseUiException; -import org.eclipse.jface.viewers.ColumnLabelProvider; - -/** - * Simple wrapping of the ColumnLabelProvider class to provide text display in - * order to build a tree for version. The getText() method does not assume that - * {@link Version} extends {@link Node} class to respect JCR 2.0 specification - * - */ -public class VersionLabelProvider extends ColumnLabelProvider { - private static final long serialVersionUID = 5270739851193688238L; - - public String getText(Object element) { - try { - if (element instanceof Version) { - Version version = (Version) element; - return version.getName(); - } else if (element instanceof Node) { - return ((Node) element).getName(); - } - } catch (RepositoryException re) { - throw new EclipseUiException( - "Unexpected error while getting element name", re); - } - return super.getText(element); - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/MaintainedRepositoryElem.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/MaintainedRepositoryElem.java deleted file mode 100644 index d33b33f..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/MaintainedRepositoryElem.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.argeo.cms.ui.jcr.model; - -import javax.jcr.Repository; - -import org.argeo.cms.ux.widgets.TreeParent; - -/** Wrap a MaintainedRepository */ -public class MaintainedRepositoryElem extends RepositoryElem { - - public MaintainedRepositoryElem(String alias, Repository repository, TreeParent parent) { - super(alias, repository, parent); - // if (!(repository instanceof MaintainedRepository)) { - // throw new ArgeoException("Repository " + alias - // + " is not a maintained repository"); - // } - } - - // protected MaintainedRepository getMaintainedRepository() { - // return (MaintainedRepository) getRepository(); - // } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java deleted file mode 100644 index 908d1b1..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.argeo.cms.ui.jcr.model; - -import java.util.Arrays; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; -import javax.jcr.SimpleCredentials; - -import org.argeo.cms.ArgeoNames; -import org.argeo.cms.jcr.CmsJcrUtils; -import org.argeo.cms.security.Keyring; -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; - -/** Root of a remote repository */ -public class RemoteRepositoryElem extends RepositoryElem { - private final Keyring keyring; - /** - * A session of the logged in user on the default workspace of the node - * repository. - */ - private final Session userSession; - private final String remoteNodePath; - - private final RepositoryFactory repositoryFactory; - private final String uri; - - public RemoteRepositoryElem(String alias, RepositoryFactory repositoryFactory, String uri, TreeParent parent, - Session userSession, Keyring keyring, String remoteNodePath) { - super(alias, null, parent); - this.repositoryFactory = repositoryFactory; - this.uri = uri; - this.keyring = keyring; - this.userSession = userSession; - this.remoteNodePath = remoteNodePath; - } - - @Override - protected Session repositoryLogin(String workspaceName) throws RepositoryException { - Node remoteRepository = userSession.getNode(remoteNodePath); - String userID = remoteRepository.getProperty(ArgeoNames.ARGEO_USER_ID).getString(); - if (userID.trim().equals("")) { - return getRepository().login(workspaceName); - } else { - String pwdPath = remoteRepository.getPath() + '/' + ArgeoNames.ARGEO_PASSWORD; - char[] password = keyring.getAsChars(pwdPath); - try { - SimpleCredentials credentials = new SimpleCredentials(userID, password); - return getRepository().login(credentials, workspaceName); - } finally { - Arrays.fill(password, 0, password.length, ' '); - } - } - } - - @Override - public Repository getRepository() { - if (repository == null) - repository = CmsJcrUtils.getRepositoryByUri(repositoryFactory, uri); - return super.getRepository(); - } - - public void remove() { - try { - Node remoteNode = userSession.getNode(remoteNodePath); - remoteNode.remove(); - remoteNode.getSession().save(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot remove " + remoteNodePath, e); - } - } - -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java deleted file mode 100644 index 8c40f8b..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.argeo.cms.ui.jcr.model; - -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.RepositoryFactory; -import javax.jcr.Session; - -import org.argeo.cms.ArgeoNames; -import org.argeo.cms.jcr.CmsJcrUtils; -import org.argeo.cms.security.Keyring; -import org.argeo.cms.ui.jcr.RepositoryRegister; -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.eclipse.ui.dialogs.ErrorFeedback; - -/** - * UI Tree component that implements the Argeo abstraction of a - * {@link RepositoryFactory} that enable a user to "mount" various repositories - * in a single Tree like View. It is usually meant to be at the root of the UI - * Tree and thus {@link #getParent()} method will return null. - * - * The {@link RepositoryFactory} is injected at instantiation time and must be - * use get or register new {@link Repository} objects upon which a reference is - * kept here. - */ - -public class RepositoriesElem extends TreeParent implements ArgeoNames { - private final RepositoryRegister repositoryRegister; - private final RepositoryFactory repositoryFactory; - - /** - * A session of the logged in user on the default workspace of the node - * repository. - */ - private final Session userSession; - private final Keyring keyring; - - public RepositoriesElem(String name, RepositoryRegister repositoryRegister, RepositoryFactory repositoryFactory, - TreeParent parent, Session userSession, Keyring keyring) { - super(name); - this.repositoryRegister = repositoryRegister; - this.repositoryFactory = repositoryFactory; - this.userSession = userSession; - this.keyring = keyring; - } - - /** - * Override normal behavior to initialize the various repositories only at - * request time - */ - @Override - public synchronized Object[] getChildren() { - if (isLoaded()) { - return super.getChildren(); - } else { - // initialize current object - Map refRepos = repositoryRegister.getRepositories(); - for (String name : refRepos.keySet()) { - Repository repository = refRepos.get(name); - // if (repository instanceof MaintainedRepository) - // super.addChild(new MaintainedRepositoryElem(name, - // repository, this)); - // else - super.addChild(new RepositoryElem(name, repository, this)); - } - - // remote - if (keyring != null) { - try { - addRemoteRepositories(keyring); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot browse remote repositories", e); - } - } - return super.getChildren(); - } - } - - protected void addRemoteRepositories(Keyring jcrKeyring) throws RepositoryException { - Node userHome = CmsJcrUtils.getUserHome(userSession); - if (userHome != null && userHome.hasNode(ARGEO_REMOTE)) { - NodeIterator it = userHome.getNode(ARGEO_REMOTE).getNodes(); - while (it.hasNext()) { - Node remoteNode = it.nextNode(); - String uri = remoteNode.getProperty(ARGEO_URI).getString(); - try { - RemoteRepositoryElem remoteRepositoryNode = new RemoteRepositoryElem(remoteNode.getName(), - repositoryFactory, uri, this, userSession, jcrKeyring, remoteNode.getPath()); - super.addChild(remoteRepositoryNode); - } catch (Exception e) { - ErrorFeedback.show("Cannot add remote repository " + remoteNode, e); - } - } - } - } - - public void registerNewRepository(String alias, Repository repository) { - // TODO: implement this - // Create a new RepositoryNode Object - // add it - // super.addChild(new RepositoriesNode(...)); - } - - /** Returns the {@link RepositoryRegister} wrapped by this object. */ - public RepositoryRegister getRepositoryRegister() { - return repositoryRegister; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java deleted file mode 100644 index 296c369..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.argeo.cms.ui.jcr.model; - -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.jcr.JcrUtils; - -/** - * UI Tree component that wraps a JCR {@link Repository}. It also keeps a - * reference to its parent Tree Ui component; typically the unique - * {@link RepositoriesElem} object of the current view to enable bi-directionnal - * browsing in the tree. - */ - -public class RepositoryElem extends TreeParent { - private String alias; - protected Repository repository; - private Session defaultSession = null; - - /** Create a new repository with distinct name and alias */ - public RepositoryElem(String alias, Repository repository, TreeParent parent) { - super(alias); - this.repository = repository; - setParent(parent); - this.alias = alias; - } - - public void login() { - try { - defaultSession = repositoryLogin(CmsConstants.SYS_WORKSPACE); - String[] wkpNames = defaultSession.getWorkspace().getAccessibleWorkspaceNames(); - for (String wkpName : wkpNames) { - if (wkpName.equals(defaultSession.getWorkspace().getName())) - addChild(new WorkspaceElem(this, wkpName, defaultSession)); - else - addChild(new WorkspaceElem(this, wkpName)); - } - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot connect to repository " + alias, e); - } - } - - public synchronized void logout() { - for (Object child : getChildren()) { - if (child instanceof WorkspaceElem) - ((WorkspaceElem) child).logout(); - } - clearChildren(); - JcrUtils.logoutQuietly(defaultSession); - defaultSession = null; - } - - /** - * Actual call to the {@link Repository#login(javax.jcr.Credentials, String)} - * method. To be overridden. - */ - protected Session repositoryLogin(String workspaceName) throws RepositoryException { - return repository.login(workspaceName); - } - - public String[] getAccessibleWorkspaceNames() { - try { - return defaultSession.getWorkspace().getAccessibleWorkspaceNames(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot retrieve workspace names", e); - } - } - - public void createWorkspace(String workspaceName) { - if (!isConnected()) - login(); - try { - defaultSession.getWorkspace().createWorkspace(workspaceName); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot create workspace", e); - } - } - - /** returns the {@link Repository} referenced by the current UI Node */ - public Repository getRepository() { - return repository; - } - - public String getAlias() { - return alias; - } - - public Boolean isConnected() { - if (defaultSession != null && defaultSession.isLive()) - return true; - else - return false; - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/SingleJcrNodeElem.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/SingleJcrNodeElem.java deleted file mode 100644 index a2584a5..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/SingleJcrNodeElem.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.argeo.cms.ui.jcr.model; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Workspace; - -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; - -/** - * UI Tree component. Wraps a node of a JCR {@link Workspace}. It also keeps a - * reference to its parent node that can either be a {@link WorkspaceElem}, a - * {@link SingleJcrNodeElem} or null if the node is "mounted" as the root of the - * UI tree. - */ -public class SingleJcrNodeElem extends TreeParent { - - private final Node node; - private String alias = null; - - /** Creates a new UiNode in the UI Tree */ - public SingleJcrNodeElem(TreeParent parent, Node node, String name) { - super(name); - setParent(parent); - this.node = node; - } - - /** - * Creates a new UiNode in the UI Tree, keeping a reference to the alias of - * the corresponding repository in the current UI environment. It is useful - * to be able to mount nodes as roots of the UI tree. - */ - public SingleJcrNodeElem(TreeParent parent, Node node, String name, String alias) { - super(name); - setParent(parent); - this.node = node; - this.alias = alias; - } - - /** Returns the node wrapped by the current UI object */ - public Node getNode() { - return node; - } - - protected String getRepositoryAlias() { - return alias; - } - - /** - * Overrides normal behaviour to initialise children only when first - * requested - */ - @Override - public synchronized Object[] getChildren() { - if (isLoaded()) { - return super.getChildren(); - } else { - // initialize current object - try { - NodeIterator ni = node.getNodes(); - while (ni.hasNext()) { - Node curNode = ni.nextNode(); - addChild(new SingleJcrNodeElem(this, curNode, curNode.getName())); - } - return super.getChildren(); - } catch (RepositoryException re) { - throw new EclipseUiException("Cannot initialize SingleJcrNode children", re); - } - } - } - - @Override - public boolean hasChildren() { - try { - if (node.getSession().isLive()) - return node.hasNodes(); - else - return false; - } catch (RepositoryException re) { - throw new EclipseUiException("Cannot check children node existence", re); - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/WorkspaceElem.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/WorkspaceElem.java deleted file mode 100644 index 2d78666..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/WorkspaceElem.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.argeo.cms.ui.jcr.model; - -import javax.jcr.AccessDeniedException; -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -// import javax.jcr.Workspace; -import javax.jcr.Workspace; - -import org.argeo.cms.ux.widgets.TreeParent; -import org.argeo.eclipse.ui.EclipseUiException; -import org.argeo.jcr.JcrUtils; - -/** - * UI Tree component. Wraps the root node of a JCR {@link Workspace}. It also - * keeps a reference to its parent {@link RepositoryElem}, to be able to - * retrieve alias of the current used repository - */ -public class WorkspaceElem extends TreeParent { - private Session session = null; - - public WorkspaceElem(RepositoryElem parent, String name) { - this(parent, name, null); - } - - public WorkspaceElem(RepositoryElem parent, String name, Session session) { - super(name); - this.session = session; - setParent(parent); - } - - public synchronized Session getSession() { - return session; - } - - public synchronized Node getRootNode() { - try { - if (session != null) - return session.getRootNode(); - else - return null; - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot get root node of workspace " + getName(), e); - } - } - - public synchronized void login() { - try { - session = ((RepositoryElem) getParent()).repositoryLogin(getName()); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot connect to repository " + getName(), e); - } - } - - public Boolean isConnected() { - if (session != null && session.isLive()) - return true; - else - return false; - } - - @Override - public synchronized void dispose() { - logout(); - super.dispose(); - } - - /** Logouts the session, does not nothing if there is no live session. */ - public synchronized void logout() { - clearChildren(); - JcrUtils.logoutQuietly(session); - session = null; - } - - @Override - public synchronized boolean hasChildren() { - try { - if (isConnected()) - try { - return session.getRootNode().hasNodes(); - } catch (AccessDeniedException e) { - // current user may not have access to the root node - return false; - } - else - return false; - } catch (RepositoryException re) { - throw new EclipseUiException("Unexpected error while checking children node existence", re); - } - } - - /** Override normal behaviour to initialize display of the workspace */ - @Override - public synchronized Object[] getChildren() { - if (isLoaded()) { - return super.getChildren(); - } else { - // initialize current object - try { - Node rootNode; - if (session == null) - return null; - else - rootNode = session.getRootNode(); - NodeIterator ni = rootNode.getNodes(); - while (ni.hasNext()) { - Node node = ni.nextNode(); - addChild(new SingleJcrNodeElem(this, node, node.getName())); - } - return super.getChildren(); - } catch (RepositoryException e) { - throw new EclipseUiException("Cannot initialize WorkspaceNode UI object." + getName(), e); - } - } - } -} diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/package-info.java deleted file mode 100644 index 8f54744..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/model/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Model for SWT/JFace JCR components. */ -package org.argeo.cms.ui.jcr.model; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/package-info.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/package-info.java deleted file mode 100644 index 26ae330..0000000 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/jcr/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** SWT/JFace JCR components. */ -package org.argeo.cms.ui.jcr; \ No newline at end of file diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsLink.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsLink.java index e91f9ba..4bd9137 100644 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsLink.java +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/CmsLink.java @@ -10,7 +10,7 @@ import javax.jcr.RepositoryException; import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.ux.CmsStyle; -import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.CurrentUser; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.cms.ui.CmsUiProvider; diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenuLink.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenuLink.java index 317a7b5..2f3cdd0 100644 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenuLink.java +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/util/UserMenuLink.java @@ -3,7 +3,7 @@ package org.argeo.cms.ui.util; import javax.jcr.Node; import org.argeo.cms.CmsMsg; -import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.CurrentUser; import org.argeo.cms.swt.CmsStyles; import org.argeo.cms.swt.auth.CmsLoginShell; import org.eclipse.swt.events.DisposeEvent; diff --git a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/JcrVersionCmsEditable.java b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/JcrVersionCmsEditable.java index 298fbde..2568314 100644 --- a/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/JcrVersionCmsEditable.java +++ b/swt/org.argeo.cms.jcr.ui/src/org/argeo/cms/ui/viewers/JcrVersionCmsEditable.java @@ -1,11 +1,13 @@ package org.argeo.cms.ui.viewers; +import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; import javax.jcr.version.VersionManager; +import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.ux.CmsEditionEvent; import org.argeo.cms.ux.AbstractCmsEditable; import org.argeo.jcr.JcrException; @@ -17,6 +19,8 @@ import org.eclipse.swt.widgets.Listener; /** Provides the CmsEditable semantic based on JCR versioning. */ public class JcrVersionCmsEditable extends AbstractCmsEditable { + private final static CmsLog log = CmsLog.getLog(JcrVersionCmsEditable.class); + private final String nodePath;// cache private final VersionManager versionManager; private final Boolean canEdit; @@ -74,8 +78,8 @@ public class JcrVersionCmsEditable extends AbstractCmsEditable { try { versionManager.checkout(nodePath); // setChanged(); - } catch (RepositoryException e1) { - throw new JcrException("Cannot publish " + nodePath, e1); + } catch (RepositoryException e) { + throw new JcrException("Cannot publish " + nodePath, e); } notifyListeners(new CmsEditionEvent(nodePath, CmsEditionEvent.START_EDITING, this)); } @@ -85,8 +89,14 @@ public class JcrVersionCmsEditable extends AbstractCmsEditable { try { versionManager.checkin(nodePath); // setChanged(); - } catch (RepositoryException e1) { - throw new JcrException("Cannot publish " + nodePath, e1); + } catch (ItemNotFoundException e) { + // we ignore that the version was not found + // since it is most likely because the user doesn't have the rights + // on the whole workspace + if (log.isTraceEnabled()) + log.trace("Cannot retrieve version after check in", e); + } catch (RepositoryException e) { + throw new JcrException("Cannot publish " + nodePath, e); } notifyListeners(new CmsEditionEvent(nodePath, CmsEditionEvent.STOP_EDITING, this)); } 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