Improve CmsView capabilities.
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 24 Oct 2020 11:04:45 +0000 (13:04 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 24 Oct 2020 11:04:45 +0000 (13:04 +0200)
org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
org.argeo.cms.ui/src/org/argeo/cms/ui/CmsView.java
org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java
org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/TabbedArea.java
org.argeo.cms/src/org/argeo/cms/fs/CmsFsUtils.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java

index 2961eead9c386951f21b2156d62f909a77f6b90b..62786f5afa0e477a180db2547792514feda3df62 100644 (file)
@@ -39,6 +39,7 @@ import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
 
 /** The {@link CmsView} for a {@link CmsWebApp}. */
+@SuppressWarnings("restriction")
 public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationListener {
        private static final long serialVersionUID = 7733510691684570402L;
        private final static Log log = LogFactory.getLog(CmsWebEntryPoint.class);
@@ -116,6 +117,10 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL
                return loginContext.getSubject();
        }
 
+       public <T> T doAs(PrivilegedAction<T> action) {
+               return Subject.doAs(getSubject(), action);
+       }
+
        @Override
        public boolean isAnonymous() {
                return CurrentUser.isAnonymous(getSubject());
index 311d10fbe9d22f2c1db2db8e9f55d14a9db7a850..8011dce59a9af024ef40ecb025c30cde7e80be31 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.cms.ui;
 
+import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -51,9 +52,13 @@ public interface CmsView {
                properties.put(param, value);
                sendEvent(topic, properties);
        }
-       
+
        default void applyStyles(Object widget) {
-               
+
+       }
+
+       default <T> T doAs(PrivilegedAction<T> action) {
+               throw new UnsupportedOperationException();
        }
 
        static CmsView getCmsView(Control parent) {
index e9ca4e5be53fc73cec93fca5136a9225e3bc895c..e72965893cf4cc5e57a6b6ee24e819e8250846dc 100644 (file)
@@ -164,7 +164,7 @@ public class CmsUiUtils implements CmsConstants {
         * FORM LAYOUT
         */
 
-       public static FormData coversAll() {
+       public static FormData coverAll() {
                FormData fdLabel = new FormData();
                fdLabel.top = new FormAttachment(0, 0);
                fdLabel.left = new FormAttachment(0, 0);
index a9459519aab4bf40ae24a6d2b82df73972616085..12ef97557bb79e8a886a054f136eee8894466953 100644 (file)
@@ -132,7 +132,7 @@ public class TabbedArea extends Composite {
                }
                currentUiProvider = uiProvider;
                section.setNode(context);
-               section.setLayoutData(CmsUiUtils.coversAll());
+               section.setLayoutData(CmsUiUtils.coverAll());
                build(section, uiProvider, context);
                if (sections.size() == 0)
                        sections.add(section);
@@ -159,7 +159,7 @@ public class TabbedArea extends Composite {
                int currentIndex = sections.indexOf(currentSection);
                Section previousSection = new Section(body, SWT.NONE, context);
                build(previousSection, previousUiProvider, previousNode);
-               previousSection.setLayoutData(CmsUiUtils.coversAll());
+               previousSection.setLayoutData(CmsUiUtils.coverAll());
 //             sections.remove(currentSection);
                sections.add(currentIndex + 1, previousSection);
 //             sections.add(currentSection);
diff --git a/org.argeo.cms/src/org/argeo/cms/fs/CmsFsUtils.java b/org.argeo.cms/src/org/argeo/cms/fs/CmsFsUtils.java
new file mode 100644 (file)
index 0000000..e152c00
--- /dev/null
@@ -0,0 +1,88 @@
+package org.argeo.cms.fs;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.spi.FileSystemProvider;
+
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+
+import org.argeo.api.NodeConstants;
+import org.argeo.jcr.Jcr;
+
+/** Utilities around documents. */
+public class CmsFsUtils {
+       // TODO make it more robust and configurable
+       private static String baseWorkspaceName = NodeConstants.SYS_WORKSPACE;
+
+       public static Node getNode(Repository repository, Path path) {
+               String workspaceName = path.getNameCount() == 0 ? baseWorkspaceName : path.getName(0).toString();
+               String jcrPath = '/' + path.subpath(1, path.getNameCount()).toString();
+               try {
+                       Session newSession;
+                       try {
+                               newSession = repository.login(workspaceName);
+                       } catch (NoSuchWorkspaceException e) {
+                               // base workspace
+                               newSession = repository.login(baseWorkspaceName);
+                               jcrPath = path.toString();
+                       }
+                       return newSession.getNode(jcrPath);
+               } catch (RepositoryException e) {
+                       throw new IllegalStateException("Cannot get node from path " + path, e);
+               }
+       }
+
+       public static NodeIterator getLastUpdatedDocuments(Session session) {
+               try {
+                       String qStr = "//element(*, nt:file)";
+                       qStr += " order by @jcr:lastModified descending";
+                       QueryManager queryManager = session.getWorkspace().getQueryManager();
+                       @SuppressWarnings("deprecation")
+                       Query xpathQuery = queryManager.createQuery(qStr, Query.XPATH);
+                       xpathQuery.setLimit(8);
+                       NodeIterator nit = xpathQuery.execute().getNodes();
+                       return nit;
+               } catch (RepositoryException e) {
+                       throw new IllegalStateException("Unable to retrieve last updated documents", e);
+               }
+       }
+
+       public static Path getPath(FileSystemProvider nodeFileSystemProvider, URI uri) {
+               try {
+                       FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri);
+                       if (fileSystem == null)
+                               fileSystem = nodeFileSystemProvider.newFileSystem(uri, null);
+                       String path = uri.getPath();
+                       return fileSystem.getPath(path);
+               } catch (IOException e) {
+                       throw new IllegalStateException("Unable to initialise file system for " + uri, e);
+               }
+       }
+
+       public static Path getPath(FileSystemProvider nodeFileSystemProvider, Node node) {
+               String workspaceName = Jcr.getWorkspaceName(node);
+               String fullPath = baseWorkspaceName.equals(workspaceName) ? Jcr.getPath(node)
+                               : '/' + workspaceName + Jcr.getPath(node);
+               URI uri;
+               try {
+                       uri = new URI(NodeConstants.SCHEME_NODE, null, fullPath, null);
+               } catch (URISyntaxException e) {
+                       throw new IllegalArgumentException("Cannot interpret " + fullPath + " as an URI", e);
+               }
+               return getPath(nodeFileSystemProvider, uri);
+       }
+
+       /** Singleton. */
+       private CmsFsUtils() {
+       }
+}
index e4ca87c12ab3a3742c2c62d0081894a713b3dc73..6cd0bf87415f7138c8d89c46370543f567c289d9 100644 (file)
@@ -6,6 +6,7 @@ import java.net.URISyntaxException;
 import java.nio.file.FileSystem;
 import java.nio.file.FileSystemAlreadyExistsException;
 import java.nio.file.Path;
+import java.nio.file.spi.FileSystemProvider;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -28,6 +29,7 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
 
+/** Implementation of an {@link FileSystemProvider} based on Jackrabbit. */
 public class CmsFsProvider extends AbstractJackrabbitFsProvider {
        private Map<String, CmsFileSystem> fileSystems = new HashMap<>();
 
index 7ff650254b1149a45801e9623fed7e44c01645f6..53a3de8ef6edb660eded8add8c259db2d637c649 100644 (file)
@@ -17,7 +17,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.api.NodeConstants;
 import org.argeo.api.NodeState;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.LocaleUtils;
 import org.argeo.transaction.simple.SimpleTransactionManager;
 import org.argeo.util.LangUtils;
@@ -26,6 +25,9 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.service.cm.ManagedServiceFactory;
 
+/**
+ * Implementation of a {@link NodeState}, initialising the required services.
+ */
 public class CmsState implements NodeState {
        private final static Log log = LogFactory.getLog(CmsState.class);
        private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext();
@@ -88,7 +90,7 @@ public class CmsState implements NodeState {
                        throw new UnsupportedOperationException(
                                        "Bitronix is not supported anymore, but could be again if there is enough interest.");
                } else {
-                       throw new CmsException("Usupported transaction manager type " + tmType);
+                       throw new IllegalArgumentException("Usupported transaction manager type " + tmType);
                }
 
                // POI
@@ -109,7 +111,7 @@ public class CmsState implements NodeState {
                RepositoryServiceFactory repositoryServiceFactory = new RepositoryServiceFactory();
                stopHooks.add(() -> repositoryServiceFactory.shutdown());
                bc.registerService(ManagedServiceFactory.class, repositoryServiceFactory,
-                               LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID));
+                               LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID));
 
                NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory();
                bc.registerService(RepositoryFactory.class, repositoryFactory, null);
@@ -118,7 +120,7 @@ public class CmsState implements NodeState {
                NodeUserAdmin userAdmin = new NodeUserAdmin(NodeConstants.ROLES_BASEDN, NodeConstants.TOKENS_BASEDN);
                stopHooks.add(() -> userAdmin.destroy());
                bc.registerService(ManagedServiceFactory.class, userAdmin,
-                               LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_USER_ADMIN_PID));
+                               LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_USER_ADMIN_PID));
 
                // File System
                CmsFsProvider cmsFsProvider = new CmsFsProvider();
@@ -133,7 +135,7 @@ public class CmsState implements NodeState {
 //                     log.debug("Installed FileSystemProvider " + fsp);
 //             }
                bc.registerService(FileSystemProvider.class, cmsFsProvider,
-                               LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_FS_PROVIDER_PID));
+                               LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_FS_PROVIDER_PID));
        }
 
        private void initSimpleTransactionManager() {