From 36c14000ab482f558a9679f75ac7bfb0953171f4 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Wed, 15 Nov 2017 10:43:50 +0100 Subject: [PATCH] Improve workgroups and JCR file system. Introduce '~' shortcut to home --- .../cms/ui/workbench/UserHomePerspective.java | 7 +++--- .../ui/workbench/jcr/NodeFsBrowserView.java | 25 ++++++++----------- .../cms/internal/kernel/CmsFsProvider.java | 6 +++++ .../cms/internal/kernel/HomeRepository.java | 5 ++-- org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java | 24 ++++++++---------- .../argeo/jcr/fs/JcrBasicfileAttributes.java | 2 ++ .../src/org/argeo/jcr/fs/JcrFileSystem.java | 13 ++++++++++ .../argeo/jcr/fs/JcrFileSystemProvider.java | 12 +++++++++ .../src/org/argeo/jcr/fs/JcrPath.java | 9 +++++-- .../org/argeo/jcr/fs/NodeDirectoryStream.java | 3 +++ 10 files changed, 72 insertions(+), 34 deletions(-) diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java index ee91b4ea1..e5e98170a 100644 --- a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/UserHomePerspective.java @@ -15,7 +15,7 @@ */ package org.argeo.cms.ui.workbench; -import org.argeo.cms.ui.workbench.useradmin.LogView; +import org.argeo.cms.ui.workbench.jcr.NodeFsBrowserView; import org.argeo.cms.ui.workbench.useradmin.UserProfile; import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; @@ -30,8 +30,9 @@ public class UserHomePerspective implements IPerspectiveFactory { layout.setEditorAreaVisible(true); layout.setFixed(false); - IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.30f, editorArea); + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.40f, editorArea); + left.addView(NodeFsBrowserView.ID); left.addView(UserProfile.ID); - left.addView(LogView.ID); + // left.addView(LogView.ID); } } diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java index 578fe1009..cba228f2d 100644 --- a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java @@ -21,10 +21,8 @@ import java.nio.file.Path; import java.nio.file.spi.FileSystemProvider; import org.argeo.cms.CmsException; -import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.ui.workbench.WorkbenchUiPlugin; import org.argeo.eclipse.ui.fs.SimpleFsBrowser; -import org.argeo.node.NodeConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.part.ViewPart; @@ -37,18 +35,17 @@ public class NodeFsBrowserView extends ViewPart { @Override public void createPartControl(Composite parent) { - if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN)) - try { - URI uri = new URI("node:///home"); - FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri); - if (fileSystem == null) - fileSystem = nodeFileSystemProvider.newFileSystem(uri, null); - Path nodePath = fileSystem.getPath("/home"); - SimpleFsBrowser browser = new SimpleFsBrowser(parent, SWT.NO_FOCUS); - browser.setInput(nodePath); - } catch (Exception e) { - throw new CmsException("Cannot open file system browser", e); - } + try { + URI uri = new URI("node:///"); + FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri); + if (fileSystem == null) + fileSystem = nodeFileSystemProvider.newFileSystem(uri, null); + Path nodePath = fileSystem.getPath("~"); + SimpleFsBrowser browser = new SimpleFsBrowser(parent, SWT.NO_FOCUS); + browser.setInput(nodePath); + } catch (Exception e) { + throw new CmsException("Cannot open file system browser", e); + } } @Override diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java index f3d91ee45..f42646ec5 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java @@ -8,6 +8,7 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; +import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.Session; @@ -17,6 +18,7 @@ import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider; import org.argeo.jcr.fs.JcrFileSystem; import org.argeo.jcr.fs.JcrFsException; import org.argeo.node.NodeConstants; +import org.argeo.node.NodeUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; @@ -73,4 +75,8 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider { String username = CurrentUser.getUsername(); return fileSystems.get(username); } + + public Node getUserHome(Session session) { + return NodeUtils.getUserHome(session); + } } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/HomeRepository.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/HomeRepository.java index bfcb940c1..1546a0b67 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/HomeRepository.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/HomeRepository.java @@ -165,12 +165,13 @@ class HomeRepository extends JcrRepositoryWrapper implements KernelConstants { } try { // TODO enhance transformation of cn to a valid node name - String relPath = cn.replaceAll("[^a-zA-Z0-9]", "_"); + // String relPath = cn.replaceAll("[^a-zA-Z0-9]", "_"); + String relPath = JcrUtils.replaceInvalidChars(cn); newWorkgroup = JcrUtils.mkdirs(adminSession.getNode(groupsBasePath), relPath, NodeType.NT_UNSTRUCTURED); newWorkgroup.addMixin(NodeTypes.NODE_GROUP_HOME); newWorkgroup.setProperty(NodeNames.LDAP_CN, cn); adminSession.save(); - JcrUtils.addPrivilege(adminSession, newWorkgroup.getPath(), dn.toString(), Privilege.JCR_ALL); + JcrUtils.addPrivilege(adminSession, newWorkgroup.getPath(), dn.toString(), Privilege.JCR_READ); adminSession.save(); } catch (RepositoryException e) { throw new CmsException("Cannot create workgroup", e); diff --git a/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java b/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java index 8ae143d7a..1fa62b37f 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java +++ b/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java @@ -75,10 +75,8 @@ public class JcrUtils { * http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.2.2%20Local * %20Names */ - public final static char[] INVALID_NAME_CHARACTERS = { '/', ':', '[', ']', '|', '*', /* - * invalid XML chars : - */ - '<', '>', '&' }; + public final static char[] INVALID_NAME_CHARACTERS = { '/', ':', '[', ']', '|', '*', /* invalid for XML: */ '<', + '>', '&' }; /** Prevents instantiation */ private JcrUtils() { @@ -949,15 +947,15 @@ public class JcrUtils { return name; } - /** - * Removes forbidden characters from a path, replacing them with '_' - * - * @deprecated use {@link #replaceInvalidChars(String)} instead - */ - public static String removeForbiddenCharacters(String str) { - return str.replace('[', '_').replace(']', '_').replace('/', '_').replace('*', '_'); - - } +// /** +// * Removes forbidden characters from a path, replacing them with '_' +// * +// * @deprecated use {@link #replaceInvalidChars(String)} instead +// */ +// public static String removeForbiddenCharacters(String str) { +// return str.replace('[', '_').replace(']', '_').replace('/', '_').replace('*', '_'); +// +// } /** Cleanly disposes a {@link Binary} even if it is null. */ public static void closeQuietly(Binary binary) { diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java index 7ce9ca667..92d9152d9 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrBasicfileAttributes.java @@ -17,6 +17,8 @@ public class JcrBasicfileAttributes implements NodeFileAttributes { private FileTime EPOCH = FileTime.fromMillis(0); public JcrBasicfileAttributes(Node node) { + if (node == null) + throw new JcrFsException("Node underlying the attributes cannot be null"); this.node = node; } diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java index 885eaf19f..88fdb207e 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystem.java @@ -11,6 +11,7 @@ import java.nio.file.spi.FileSystemProvider; import java.util.HashSet; import java.util.Set; +import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -19,11 +20,23 @@ import org.argeo.jcr.JcrUtils; public class JcrFileSystem extends FileSystem { private final JcrFileSystemProvider provider; private final Session session; + private String userHomePath = null; public JcrFileSystem(JcrFileSystemProvider provider, Session session) { super(); this.provider = provider; this.session = session; + Node userHome = provider.getUserHome(session); + if (userHome != null) + try { + userHomePath = userHome.getPath(); + } catch (RepositoryException e) { + throw new JcrFsException("Cannot retrieve user home path", e); + } + } + + public String getUserHomePath() { + return userHomePath; } @Override diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java index dcc59476f..1e2864d24 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java @@ -197,6 +197,9 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider { try { // TODO check if assignable Node node = toNode(path); + if(node==null) { + throw new JcrFsException("JCR node not found for "+path); + } return (A) new JcrBasicfileAttributes(node); } catch (RepositoryException e) { throw new JcrFsException("Cannot read basic attributes of " + path, e); @@ -264,4 +267,13 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider { return ((JcrPath) path).getNode(); } + /** + * To be overriden in order to support the ~ path, with an implementation + * specific concept of user home. + * + * @return null by default + */ + public Node getUserHome(Session session) { + return null; + } } diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java index 09b3e0e7a..8917f13a1 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java @@ -31,8 +31,6 @@ public class JcrPath implements Path { private final int hashCode; public JcrPath(JcrFileSystem filesSystem, String path) { - // this(filesSystem, path.equals("/") ? null : path.split("/"), path == - // null ? true : path.startsWith("/")); this.fs = filesSystem; if (path == null) throw new JcrFsException("Path cannot be null"); @@ -47,6 +45,13 @@ public class JcrPath implements Path { this.hashCode = "".hashCode(); return; } + + if (path.equals("~")) {// home + path = filesSystem.getUserHomePath(); + if (path == null) + throw new JcrFsException("No home directory available"); + } + this.absolute = path.charAt(0) == delimChar ? true : false; String trimmedPath = path.substring(absolute ? 1 : 0, path.charAt(path.length() - 1) == delimChar ? path.length() - 1 : path.length()); diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java b/org.argeo.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java index dbf674536..892aaee1a 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/NodeDirectoryStream.java @@ -35,6 +35,9 @@ public class NodeDirectoryStream implements DirectoryStream { nodes: while (nodeIterator.hasNext()) { try { Node node = nodeIterator.nextNode(); + String nodeName = node.getName(); + if (nodeName.startsWith("rep:") || nodeName.startsWith("jcr:")) + continue nodes; next = new JcrPath(fs, node); if (filter != null) { if (filter.accept(next)) -- 2.30.2