Improve files UI
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 11 Dec 2018 11:43:27 +0000 (12:43 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 11 Dec 2018 11:43:27 +0000 (12:43 +0100)
org.argeo.cms/src/org/argeo/cms/internal/http/webdav-config.xml
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java
org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/fs/FsTableViewer.java
org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/fs/NioFileLabelProvider.java
org.argeo.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java
org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java
org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java
org.argeo.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java

index da4e18b1163edffa2eeff3a7feb72627231e4739..4363898987980c257e948b2fdae8e8d57cffea8c 100644 (file)
         <namespaces>
             <prefix>rep</prefix>
             <prefix>jcr</prefix>
+            <!-- Argeo namespaces -->
+            <prefix>node</prefix>
+            <prefix>argeo</prefix>
+            <prefix>cms</prefix>
+            <prefix>slc</prefix>
+            <prefix>connect</prefix>
+            <prefix>activities</prefix>
+            <prefix>people</prefix>
+            <prefix>documents</prefix>
+            <prefix>tracker</prefix>
             <!--
             <uri>internal</uri>
             <uri>http://www.jcp.org/jcr/1.0</uri>
index 32f7427714a568e89e08a55b3011851cfae38534..7b3b8d9783f39588be5de067bf501062bbff262d 100644 (file)
@@ -10,21 +10,25 @@ import java.util.Map;
 
 import javax.jcr.Node;
 import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
 
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider;
 import org.argeo.jcr.fs.JcrFileSystem;
+import org.argeo.jcr.fs.JcrFileSystemProvider;
 import org.argeo.jcr.fs.JcrFsException;
 import org.argeo.node.NodeConstants;
+import org.argeo.node.NodeTypes;
 import org.argeo.node.NodeUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 
 public class CmsFsProvider extends AbstractJackrabbitFsProvider {
-       private Map<String, JcrFileSystem> fileSystems = new HashMap<>();
+       private Map<String, CmsFileSystem> fileSystems = new HashMap<>();
 
        @Override
        public String getScheme() {
@@ -49,14 +53,14 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider {
                                RepositoryFactory repositoryFactory = bc.getService(bc.getServiceReference(RepositoryFactory.class));
                                Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory, repoUri.toString());
                                Session session = repository.login("main");
-                               JcrFileSystem fileSystem = new JcrFileSystem(this, session);
+                               CmsFileSystem fileSystem = new CmsFileSystem(this, session);
                                fileSystems.put(username, fileSystem);
                                return fileSystem;
                        } else {
                                Repository repository = bc.getService(
                                                bc.getServiceReferences(Repository.class, "(cn=" + NodeConstants.HOME + ")").iterator().next());
                                Session session = repository.login();
-                               JcrFileSystem fileSystem = new JcrFileSystem(this, session);
+                               CmsFileSystem fileSystem = new CmsFileSystem(this, session);
                                fileSystems.put(username, fileSystem);
                                return fileSystem;
                        }
@@ -91,4 +95,18 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider {
        public Node getUserHome(Session session) {
                return NodeUtils.getUserHome(session);
        }
+
+       static class CmsFileSystem extends JcrFileSystem {
+               public CmsFileSystem(JcrFileSystemProvider provider, Session session) throws IOException {
+                       super(provider, session);
+               }
+
+               public boolean skipNode(Node node) throws RepositoryException {
+                       if (node.isNodeType(NodeType.NT_HIERARCHY_NODE) || node.isNodeType(NodeTypes.NODE_USER_HOME)
+                                       || node.isNodeType(NodeTypes.NODE_GROUP_HOME))
+                               return false;
+                       return true;
+               }
+
+       }
 }
index 92f804d252d1ae970f2d8f35a9b4fbf7ceffcc72..1e11b7d7f6105358a4dea515dab7a9cf8d9ba39e 100644 (file)
@@ -44,7 +44,8 @@ public class NodeHttp implements KernelConstants {
        private ServiceTracker<Repository, Repository> repositories;
        private final ServiceTracker<HttpService, HttpService> httpServiceTracker;
 
-       private static String httpRealm = "Argeo";
+       private String httpRealm = "Argeo";
+       private String webDavConfig = HttpUtils.WEBDAV_CONFIG;
        private final boolean cleanState;
 
        public NodeHttp(boolean cleanState) {
@@ -59,7 +60,7 @@ public class NodeHttp implements KernelConstants {
                        repositories.close();
        }
 
-       public static void registerRepositoryServlets(HttpService httpService, String alias, Repository repository) {
+       public void registerRepositoryServlets(HttpService httpService, String alias, Repository repository) {
                if (httpService == null)
                        throw new CmsException("No HTTP service available");
                try {
@@ -89,29 +90,29 @@ public class NodeHttp implements KernelConstants {
                }
        }
 
-       static void registerWebdavServlet(HttpService httpService, String alias, Repository repository)
+       void registerWebdavServlet(HttpService httpService, String alias, Repository repository)
                        throws NamespaceException, ServletException {
                // WebdavServlet webdavServlet = new WebdavServlet(repository, new
                // OpenInViewSessionProvider(alias));
                WebdavServlet webdavServlet = new WebdavServlet(repository, new CmsSessionProvider(alias));
                String path = webdavPath(alias);
                Properties ip = new Properties();
-               ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_CONFIG, HttpUtils.WEBDAV_CONFIG);
+               ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_CONFIG, webDavConfig);
                ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path);
                httpService.registerServlet(path, webdavServlet, ip, new DataHttpContext(httpRealm));
        }
 
-       static void registerFilesServlet(HttpService httpService, String alias, Repository repository)
+       void registerFilesServlet(HttpService httpService, String alias, Repository repository)
                        throws NamespaceException, ServletException {
                WebdavServlet filesServlet = new WebdavServlet(repository, new CmsSessionProvider(alias));
                String path = filesPath(alias);
                Properties ip = new Properties();
-               ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_CONFIG, HttpUtils.WEBDAV_CONFIG);
+               ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_CONFIG, webDavConfig);
                ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path);
                httpService.registerServlet(path, filesServlet, ip, new PrivateHttpContext(httpRealm, true));
        }
 
-       static void registerRemotingServlet(HttpService httpService, String alias, Repository repository)
+       void registerRemotingServlet(HttpService httpService, String alias, Repository repository)
                        throws NamespaceException, ServletException {
                RemotingServlet remotingServlet = new RemotingServlet(repository, new CmsSessionProvider(alias));
                String path = remotingPath(alias);
@@ -145,23 +146,7 @@ public class NodeHttp implements KernelConstants {
                return NodeConstants.PATH_FILES;
        }
 
-       // private Subject subjectFromRequest(HttpServletRequest request,
-       // HttpServletResponse response) {
-       // Authorization authorization = (Authorization)
-       // request.getAttribute(HttpContext.AUTHORIZATION);
-       // if (authorization == null)
-       // throw new CmsException("Not authenticated");
-       // try {
-       // LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
-       // new HttpRequestCallbackHandler(request, response));
-       // lc.login();
-       // return lc.getSubject();
-       // } catch (LoginException e) {
-       // throw new CmsException("Cannot login", e);
-       // }
-       // }
-
-       static class RepositoriesStc extends ServiceTracker<Repository, Repository> {
+       class RepositoriesStc extends ServiceTracker<Repository, Repository> {
                private final HttpService httpService;
 
                private final BundleContext bc;
@@ -198,9 +183,6 @@ public class NodeHttp implements KernelConstants {
        }
 
        private class PrepareHttpStc extends ServiceTracker<HttpService, HttpService> {
-               // private DataHttp dataHttp;
-               // private NodeHttp nodeHttp;
-
                public PrepareHttpStc() {
                        super(bc, HttpService.class, null);
                }
@@ -218,13 +200,6 @@ public class NodeHttp implements KernelConstants {
 
                @Override
                public void removedService(ServiceReference<HttpService> reference, HttpService service) {
-                       // if (dataHttp != null)
-                       // dataHttp.destroy();
-                       // dataHttp = null;
-                       // if (nodeHttp != null)
-                       // nodeHttp.destroy();
-                       // nodeHttp = null;
-                       // destroy();
                        repositories.close();
                        repositories = null;
                }
index 3476739bcbd2e24fdc0a95607e23f2fb47418eb6..3b126e90bcdcc33dcc1b380e22f228f76a31ceb4 100644 (file)
@@ -1,6 +1,5 @@
 package org.argeo.eclipse.ui.fs;
 
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.List;
 
@@ -28,6 +27,8 @@ public class FsTableViewer extends TableViewer {
        private boolean reverseOrder = false;
        private String orderProperty = FsUiConstants.PROPERTY_NAME;
 
+       private Path initialPath = null;
+
        public FsTableViewer(Composite parent, int style) {
                super(parent, style | SWT.VIRTUAL);
        }
@@ -88,6 +89,8 @@ public class FsTableViewer extends TableViewer {
                final Object[] res;
                if (isRoot)
                        res = rows;
+               else if (initialPath != null && initialPath.equals(dir))
+                       res = rows;
                else {
                        res = new Object[rows.length + 1];
                        res[0] = new ParentDir(dir.getParent());
@@ -108,6 +111,14 @@ public class FsTableViewer extends TableViewer {
                this.refresh();
        }
 
+       /**
+        * A path which is to be considered as root (and thus provide no link to a
+        * parent directory)
+        */
+       public void setInitialPath(Path initialPath) {
+               this.initialPath = initialPath;
+       }
+
        private class MyLazyCP implements ILazyContentProvider {
                private static final long serialVersionUID = 9096550041395433128L;
                private Object[] elements;
index d8cb1d83befd08062fb9964be3c068b9de36ca5d..6b2c06d50ae89b8044889bf0223f54c1d05f2d52 100644 (file)
@@ -3,15 +3,26 @@ package org.argeo.eclipse.ui.fs;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.attribute.FileTime;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
 
 /** Expect a {@link Path} as input element */
 public class NioFileLabelProvider extends ColumnLabelProvider {
+       private final static FileTime EPOCH = FileTime.fromMillis(0);
        private static final long serialVersionUID = 2160026425187796930L;
        private final String propName;
+       private DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd hh:mm");
 
+       // TODO use new formatting
+       // DateTimeFormatter formatter =
+       // DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT )
+       // .withLocale( Locale.UK )
+       // .withZone( ZoneId.systemDefault() );
        public NioFileLabelProvider(String propName) {
                this.propName = propName;
        }
@@ -19,19 +30,20 @@ public class NioFileLabelProvider extends ColumnLabelProvider {
        @Override
        public String getText(Object element) {
                try {
+                       Path path;
                        if (element instanceof ParentDir) {
-                               switch (propName) {
-                               case FsUiConstants.PROPERTY_SIZE:
-                                       return "-";
-                               case FsUiConstants.PROPERTY_LAST_MODIFIED:
-                                       return "-";
-                               // return Files.getLastModifiedTime(((ParentDir) element).getPath()).toString();
-                               case FsUiConstants.PROPERTY_TYPE:
-                                       return "Folder";
-                               }
-                       }
-
-                       Path path = (Path) element;
+//                             switch (propName) {
+//                             case FsUiConstants.PROPERTY_SIZE:
+//                                     return "-";
+//                             case FsUiConstants.PROPERTY_LAST_MODIFIED:
+//                                     return "-";
+//                             // return Files.getLastModifiedTime(((ParentDir) element).getPath()).toString();
+//                             case FsUiConstants.PROPERTY_TYPE:
+//                                     return "Folder";
+//                             }
+                               path = ((ParentDir) element).getPath();
+                       } else
+                               path = (Path) element;
                        switch (propName) {
                        case FsUiConstants.PROPERTY_SIZE:
                                if (Files.isDirectory(path))
@@ -39,7 +51,13 @@ public class NioFileLabelProvider extends ColumnLabelProvider {
                                else
                                        return FsUiUtils.humanReadableByteCount(Files.size(path), false);
                        case FsUiConstants.PROPERTY_LAST_MODIFIED:
-                               return Files.getLastModifiedTime(path).toString();
+                               if (Files.isDirectory(path))
+                                       return "-";
+                               FileTime time = Files.getLastModifiedTime(path);
+                               if (time.equals(EPOCH))
+                                       return "-";
+                               else
+                                       return dateFormat.format(new Date(time.toMillis()));
                        case FsUiConstants.PROPERTY_TYPE:
                                if (Files.isDirectory(path))
                                        return "Folder";
index 92d9152d9231c1f043d5d21bcdf71319b6b86e29..f9f605eee60e989408b22bec6fe45306f7eee858 100644 (file)
@@ -1,5 +1,8 @@
 package org.argeo.jcr.fs;
 
+import static javax.jcr.Property.JCR_CREATED;
+import static javax.jcr.Property.JCR_LAST_MODIFIED;
+
 import java.nio.file.attribute.FileTime;
 import java.time.Instant;
 
@@ -14,7 +17,7 @@ import org.argeo.jcr.JcrUtils;
 public class JcrBasicfileAttributes implements NodeFileAttributes {
        private final Node node;
 
-       private FileTime EPOCH = FileTime.fromMillis(0);
+       private final static FileTime EPOCH = FileTime.fromMillis(0);
 
        public JcrBasicfileAttributes(Node node) {
                if (node == null)
@@ -25,10 +28,17 @@ public class JcrBasicfileAttributes implements NodeFileAttributes {
        @Override
        public FileTime lastModifiedTime() {
                try {
-                       if (node.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
-                               Instant instant = node.getProperty(Property.JCR_LAST_MODIFIED).getDate().toInstant();
+                       if (node.hasProperty(JCR_LAST_MODIFIED)) {
+                               Instant instant = node.getProperty(JCR_LAST_MODIFIED).getDate().toInstant();
+                               return FileTime.from(instant);
+                       } else if (node.hasProperty(JCR_CREATED)) {
+                               Instant instant = node.getProperty(JCR_CREATED).getDate().toInstant();
                                return FileTime.from(instant);
                        }
+//                     if (node.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
+//                             Instant instant = node.getProperty(Property.JCR_LAST_MODIFIED).getDate().toInstant();
+//                             return FileTime.from(instant);
+//                     }
                        return EPOCH;
                } catch (RepositoryException e) {
                        throw new JcrFsException("Cannot get last modified time", e);
@@ -43,10 +53,17 @@ public class JcrBasicfileAttributes implements NodeFileAttributes {
        @Override
        public FileTime creationTime() {
                try {
-                       if (node.isNodeType(NodeType.MIX_CREATED)) {
-                               Instant instant = node.getProperty(Property.JCR_CREATED).getDate().toInstant();
+                       if (node.hasProperty(JCR_CREATED)) {
+                               Instant instant = node.getProperty(JCR_CREATED).getDate().toInstant();
+                               return FileTime.from(instant);
+                       } else if (node.hasProperty(JCR_LAST_MODIFIED)) {
+                               Instant instant = node.getProperty(JCR_LAST_MODIFIED).getDate().toInstant();
                                return FileTime.from(instant);
                        }
+//                     if (node.isNodeType(NodeType.MIX_CREATED)) {
+//                             Instant instant = node.getProperty(JCR_CREATED).getDate().toInstant();
+//                             return FileTime.from(instant);
+//                     }
                        return EPOCH;
                } catch (RepositoryException e) {
                        throw new JcrFsException("Cannot get creation time", e);
index d11f0c51d6bea7896c6d9fa8fa85052aca9bc2bc..65edf1d91bffde5d44f23722888bde750c994d35 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Set;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
 
 import org.argeo.jcr.JcrUtils;
 
@@ -35,6 +36,14 @@ public class JcrFileSystem extends FileSystem {
                        }
        }
 
+       /** Whetehr this node should be skippe din directory listings */
+       public boolean skipNode(Node node) throws RepositoryException {
+               if (node.isNodeType(NodeType.NT_HIERARCHY_NODE) || node.isNodeType("node:userHome")
+                               || node.isNodeType("node:groupHome"))
+                       return false;
+               return true;
+       }
+
        public String getUserHomePath() {
                return userHomePath;
        }
index 804be94fdb752f83aa6ce830cbe39f085efbe46f..096546556e00b6d7931ae6ee0e96c65e42e37317 100644 (file)
@@ -171,7 +171,7 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
 
        @Override
        public boolean isHidden(Path path) throws IOException {
-               return false;
+               return path.getFileName().toString().charAt(0) == '.';
        }
 
        @Override
index 892aaee1aa2b1084f94f6cfec692b05d0511bbaa..84dd22d6ae8f4951824f3a808a85aa27e33517dd 100644 (file)
@@ -38,6 +38,8 @@ public class NodeDirectoryStream implements DirectoryStream<Path> {
                                                String nodeName = node.getName();
                                                if (nodeName.startsWith("rep:") || nodeName.startsWith("jcr:"))
                                                        continue nodes;
+                                               if (fs.skipNode(node))
+                                                       continue nodes;
                                                next = new JcrPath(fs, node);
                                                if (filter != null) {
                                                        if (filter.accept(next))