Introduce node file system provider
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 13 Jan 2017 14:13:22 +0000 (15:13 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 13 Jan 2017 14:13:22 +0000 (15:13 +0100)
org.argeo.cms.ui.workbench/META-INF/spring/osgi.xml
org.argeo.cms.ui.workbench/META-INF/spring/parts.xml
org.argeo.cms.ui.workbench/plugin.xml
org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/JcrBrowserPerspective.java
org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/jcr/NodeFsBrowserView.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java
org.argeo.node.api/src/org/argeo/node/NodeConstants.java

index b2b42fcf0fd0e11f65a62a4b148ff1393f30fe16..7fa7adb8fac4eff9bb486fd3d134df28bf6d19d6 100644 (file)
@@ -19,6 +19,8 @@
 \r
        <reference id="nodeRepository" interface="javax.jcr.Repository"\r
                filter="(cn=home)" />\r
+       <reference id="nodeFileSystemProvider" interface="java.nio.file.spi.FileSystemProvider"\r
+               filter="(service.pid=org.argeo.node.fsProvider)" />\r
 \r
        <!-- UserAdmin -->\r
        <reference id="userAdmin" interface="org.osgi.service.useradmin.UserAdmin" />\r
index 8fc1adb66518721e8338f00f867cc7ed07144cd3..07dc01e5373d26fd8c25aa7e1c78ce86422ad375 100644 (file)
                <property name="nodeRepository" ref="nodeRepository" />
                <property name="keyring" ref="keyring" />
        </bean>
+       <bean id="nodeFsBrowserView" class="org.argeo.cms.ui.workbench.jcr.NodeFsBrowserView"
+               scope="prototype">
+               <property name="nodeFileSystemProvider" ref="nodeFileSystemProvider" />
+               <!-- <property name="keyring" ref="keyring" /> -->
+       </bean>
 
        <!-- LOGGERS -->
        <bean id="logView" class="org.argeo.cms.ui.workbench.useradmin.LogView"
index b44d373633804df4ab08b2d00a85dae31aafba2a..aaacb22439c7987e2a14a801387cbd70da8eece7 100644 (file)
                </view>
                <!-- Data Explorer -->
                <view
-          name="JCR Browser"
+          name="JCR"
           id="org.argeo.cms.ui.workbench.jcrBrowserView"
           icon="icons/browser.gif"
+          class="org.argeo.eclipse.spring.SpringExtensionFactory">
+          </view>
+               <view
+          name="Files"
+          id="org.argeo.cms.ui.workbench.nodeFsBrowserView"
+          icon="icons/browser.gif"
           class="org.argeo.eclipse.spring.SpringExtensionFactory">
           </view>
     </extension> 
index ce8985760d513320872089f7f90f370eba6db4b1..634a24ab42dd953b1b6a3d74920fe13d4a65ceb9 100644 (file)
@@ -16,6 +16,7 @@
 package org.argeo.cms.ui.workbench;
 
 import org.argeo.cms.ui.workbench.jcr.JcrBrowserView;
+import org.argeo.cms.ui.workbench.jcr.NodeFsBrowserView;
 import org.eclipse.ui.IFolderLayout;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveFactory;
@@ -29,5 +30,6 @@ public class JcrBrowserPerspective implements IPerspectiveFactory {
                                WorkbenchUiPlugin.PLUGIN_ID + ".upperLeft", IPageLayout.LEFT,
                                0.4f, layout.getEditorArea());
                upperLeft.addView(JcrBrowserView.ID);
+               upperLeft.addView(NodeFsBrowserView.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
new file mode 100644 (file)
index 0000000..cfbf520
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.cms.ui.workbench.jcr;
+
+import java.nio.file.spi.FileSystemProvider;
+
+import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * Browse the node file system.
+ */
+public class NodeFsBrowserView extends ViewPart {
+       public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".nodeFsBrowserView";
+       
+       private FileSystemProvider nodeFileSystemProvider;
+
+       @Override
+       public void createPartControl(Composite parent) {
+//             SimpleFsBrowser browser = new SimpleFsBrowser(parent, SWT.NO_FOCUS);
+//             Path path = Paths.get("/");
+//             browser.setInput(path);
+//             browser.setLayoutData(EclipseUiUtils.fillAll());
+       }
+
+       @Override
+       public void setFocus() {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) {
+               this.nodeFileSystemProvider = nodeFileSystemProvider;
+       }
+
+       
+}
index 44922aced77eccb4a26f4d84623c3a23d07c2c98..24c2f6bccc7d1c7e9d8e004f94d56623e92513dc 100644 (file)
@@ -10,6 +10,8 @@ import java.util.Locale;
 
 import javax.security.auth.login.Configuration;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsException;
 import org.argeo.node.ArgeoLogger;
 import org.argeo.node.NodeConstants;
@@ -28,6 +30,8 @@ import org.osgi.service.log.LogReaderService;
  * access to kernel information for the rest of the bundle (and only it)
  */
 public class Activator implements BundleActivator {
+       private final static Log log = LogFactory.getLog(Activator.class);
+
        private static Activator instance;
 
        private BundleContext bc;
@@ -51,8 +55,8 @@ public class Activator implements BundleActivator {
                        initArgeoLogger();
                        initNode();
                } catch (Exception e) {
-                       e.printStackTrace();
-                       throw new CmsException("Cannot initialize node", e);
+                       log.error("## FATAL: CMS activator failed", e);
+                       // throw new CmsException("Cannot initialize node", e);
                }
        }
 
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
new file mode 100644 (file)
index 0000000..6ad3e38
--- /dev/null
@@ -0,0 +1,75 @@
+package org.argeo.cms.internal.kernel;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystemAlreadyExistsException;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+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.JcrFsException;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+public class CmsFsProvider extends AbstractJackrabbitFsProvider {
+       private Map<String, JcrFileSystem> fileSystems = new HashMap<>();
+       private BundleContext bc = FrameworkUtil.getBundle(CmsFsProvider.class).getBundleContext();
+
+       @Override
+       public String getScheme() {
+               return "node";
+       }
+
+       @Override
+       public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
+               String username = CurrentUser.getUsername();
+               if (username == null) {
+                       // TODO deal with anonymous
+                       return null;
+               }
+               if (fileSystems.containsKey(username))
+                       throw new FileSystemAlreadyExistsException("CMS file system already exists for user " + username);
+
+               try {
+                       Repository repository = bc
+                                       .getService(bc.getServiceReferences(Repository.class, "(cn=node)").iterator().next());
+                       Session session = repository.login();
+                       JcrFileSystem fileSystem = new JcrFileSystem(this, session);
+                       fileSystems.put(username, fileSystem);
+                       return fileSystem;
+               } catch (Exception e) {
+                       throw new CmsException("Cannot open file system " + uri + " for user " + username, e);
+               }
+       }
+
+       @Override
+       public FileSystem getFileSystem(URI uri) {
+               return currentUserFileSystem();
+       }
+
+       @Override
+       public Path getPath(URI uri) {
+               JcrFileSystem fileSystem = currentUserFileSystem();
+               String path = uri.getPath();
+               if (fileSystem == null)
+                       try {
+                               fileSystem = (JcrFileSystem) newFileSystem(uri, new HashMap<String, Object>());
+                       } catch (IOException e) {
+                               throw new JcrFsException("Could not autocreate file system", e);
+                       }
+               return fileSystem.getPath(path);
+       }
+
+       protected JcrFileSystem currentUserFileSystem() {
+               String username = CurrentUser.getUsername();
+               return fileSystems.get(username);
+       }
+}
index e01bd2c54b8b88750b819685d415c1177bb49faa..a5cc0b74630bafdf8d76bb937a1d3c86e0790934 100644 (file)
@@ -7,6 +7,7 @@ import static java.util.Locale.ENGLISH;
 import java.io.File;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.nio.file.spi.FileSystemProvider;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -60,7 +61,7 @@ public class CmsState implements NodeState {
                try {
                        this.hostname = InetAddress.getLocalHost().getHostName();
                } catch (UnknownHostException e) {
-                       log.error("Cannot set hostname: "+ e);
+                       log.error("Cannot set hostname: " + e);
                }
 
                availableSince = System.currentTimeMillis();
@@ -101,6 +102,11 @@ public class CmsState implements NodeState {
                shutdownHooks.add(() -> userAdmin.destroy());
                bc.registerService(ManagedServiceFactory.class, userAdmin,
                                LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_USER_ADMIN_PID));
+
+               // File System
+               CmsFsProvider cmsFsProvider = new CmsFsProvider();
+               bc.registerService(FileSystemProvider.class, cmsFsProvider,
+                               LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_FS_PROVIDER_PID));
        }
 
        private void initTransactionManager() {
index 2a221abe858386cd1f81cccf16a500c6ad9b0312..8b1a1d3cc4a14d1601f2eb2a689c5271dad5df35 100644 (file)
@@ -10,6 +10,7 @@ public interface NodeConstants {
 
        String NODE_USER_ADMIN_PID = "org.argeo.node.userAdmin";
        String NODE_KEYRING_PID = "org.argeo.node.keyring";
+       String NODE_FS_PROVIDER_PID = "org.argeo.node.fsProvider";
 
        /*
         * FACTORY PIDs