Add a core bundle to keep separation between Workbench and web clean
authorbsinou <bsinou@argeo.org>
Mon, 30 Jan 2017 22:44:06 +0000 (23:44 +0100)
committerbsinou <bsinou@argeo.org>
Mon, 30 Jan 2017 22:44:06 +0000 (23:44 +0100)
35 files changed:
org.argeo.suite.core/.classpath [new file with mode: 0644]
org.argeo.suite.core/.gitignore [new file with mode: 0644]
org.argeo.suite.core/.project [new file with mode: 0644]
org.argeo.suite.core/META-INF/.gitignore [new file with mode: 0644]
org.argeo.suite.core/META-INF/spring/application.xml [new file with mode: 0644]
org.argeo.suite.core/META-INF/spring/osgi.xml [new file with mode: 0644]
org.argeo.suite.core/apps.properties [new file with mode: 0644]
org.argeo.suite.core/bnd.bnd [new file with mode: 0644]
org.argeo.suite.core/build.properties [new file with mode: 0644]
org.argeo.suite.core/pom.xml [new file with mode: 0644]
org.argeo.suite.core/src/org/argeo/suite/SuiteException.java [new file with mode: 0644]
org.argeo.suite.core/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java [new file with mode: 0644]
org.argeo.suite.web/META-INF/spring/application.xml
org.argeo.suite.web/META-INF/spring/osgi.xml
org.argeo.suite.web/pom.xml
org.argeo.suite.web/src/org/argeo/suite/SuiteException.java [deleted file]
org.argeo.suite.web/src/org/argeo/suite/fs/MyFilesBrowserPage.java [deleted file]
org.argeo.suite.web/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java [deleted file]
org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java
org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java [new file with mode: 0644]
org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml
org.argeo.suite.workbench.rap/META-INF/spring/parts.xml
org.argeo.suite.workbench.rap/bnd.bnd
org.argeo.suite.workbench.rap/plugin.xml
org.argeo.suite.workbench.rap/pom.xml
org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java
org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsAppService.java [new file with mode: 0644]
org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsImages.java [new file with mode: 0644]
org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsSingleColumnLabelProvider.java [new file with mode: 0644]
org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java
org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/MyFilesView.java [new file with mode: 0644]
org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/file.gif [new file with mode: 0644]
org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/folder.gif [new file with mode: 0644]
org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/fsBrowser.png [new file with mode: 0644]
pom.xml

diff --git a/org.argeo.suite.core/.classpath b/org.argeo.suite.core/.classpath
new file mode 100644 (file)
index 0000000..191b71a
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" output="bin" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.argeo.suite.core/.gitignore b/org.argeo.suite.core/.gitignore
new file mode 100644 (file)
index 0000000..016bb39
--- /dev/null
@@ -0,0 +1,3 @@
+/target
+/*.target
+/bin/
diff --git a/org.argeo.suite.core/.project b/org.argeo.suite.core/.project
new file mode 100644 (file)
index 0000000..e3b8ec5
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.suite.core</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments />
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments />
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments />
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.pde.PluginNature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.argeo.suite.core/META-INF/.gitignore b/org.argeo.suite.core/META-INF/.gitignore
new file mode 100644 (file)
index 0000000..4854a41
--- /dev/null
@@ -0,0 +1 @@
+/MANIFEST.MF
diff --git a/org.argeo.suite.core/META-INF/spring/application.xml b/org.argeo.suite.core/META-INF/spring/application.xml
new file mode 100644 (file)
index 0000000..460fc85
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="
+               http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
+
+       <bean id="peopleService" class="org.argeo.suite.people.PeopleSuiteServiceImpl"
+               init-method="init" destroy-method="destroy">
+               <property name="repository" ref="repository" />
+               <property name="workspaceName" value="main" />
+               <property name="userAdminService" ref="userAdminService" />
+       </bean>
+
+       <bean id="userAdminService" class="org.argeo.connect.people.core.UserAdminServiceImpl"
+               scope="singleton" lazy-init="false">
+               <property name="userTransaction" ref="userTransaction" />
+               <property name="userAdmin" ref="userAdmin" />
+               <property name="userAdminServiceReference" ref="userAdmin" />
+       </bean>
+
+       <!-- Execute initialization with a system authentication -->
+       <bean
+               class="org.argeo.cms.spring.AuthenticatedApplicationContextInitialization" />
+
+</beans>
diff --git a/org.argeo.suite.core/META-INF/spring/osgi.xml b/org.argeo.suite.core/META-INF/spring/osgi.xml
new file mode 100644 (file)
index 0000000..3301729
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/osgi  \r
+       http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+       http://www.springframework.org/schema/beans   \r
+       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+       <!-- REFERENCES -->\r
+       <!--  Insure a home is present for each user that logs in -->\r
+       <reference id="repository" interface="javax.jcr.Repository" filter="(cn=home)" />\r
+       <reference id="userAdmin" interface="org.osgi.service.useradmin.UserAdmin" />\r
+       <reference id="userTransaction" interface="javax.transaction.UserTransaction" />\r
+       <reference id="nodeFileSystemProvider" interface="java.nio.file.spi.FileSystemProvider"\r
+               filter="(service.pid=org.argeo.node.fsProvider)" />\r
+       \r
+       <!-- SERVICES -->\r
+       <!-- Exposes Argeo Suite specific implementation of the People Service -->\r
+       <service ref="peopleService" interface="org.argeo.connect.people.PeopleService" />\r
+</beans:beans>\r
diff --git a/org.argeo.suite.core/apps.properties b/org.argeo.suite.core/apps.properties
new file mode 100644 (file)
index 0000000..e0227a3
--- /dev/null
@@ -0,0 +1 @@
+argeo.security.systemKey=argeo
\ No newline at end of file
diff --git a/org.argeo.suite.core/bnd.bnd b/org.argeo.suite.core/bnd.bnd
new file mode 100644 (file)
index 0000000..68b918c
--- /dev/null
@@ -0,0 +1,8 @@
+Import-Package:\
+javax.jcr.nodetype,\
+org.argeo.node,\
+javax.jcr.security,\
+*
+
+
+    
diff --git a/org.argeo.suite.core/build.properties b/org.argeo.suite.core/build.properties
new file mode 100644 (file)
index 0000000..3166058
--- /dev/null
@@ -0,0 +1,3 @@
+source.. = src/
+output.. = bin/
+
diff --git a/org.argeo.suite.core/pom.xml b/org.argeo.suite.core/pom.xml
new file mode 100644 (file)
index 0000000..a8eb095
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.argeo.suite</groupId>
+               <artifactId>argeo-suite</artifactId>
+               <version>0.1.1-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.suite.core</artifactId>
+       <name>Argeo Suite Core</name>
+       <packaging>jar</packaging>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.argeo.connect</groupId>
+                       <artifactId>org.argeo.connect.people.core</artifactId>
+                       <version>${version.argeo-connect}</version>
+               </dependency>
+       </dependencies>
+</project>
diff --git a/org.argeo.suite.core/src/org/argeo/suite/SuiteException.java b/org.argeo.suite.core/src/org/argeo/suite/SuiteException.java
new file mode 100644 (file)
index 0000000..6351804
--- /dev/null
@@ -0,0 +1,14 @@
+package org.argeo.suite;
+
+/** Argeo Suite specific exception. Wraps a usual RuntimeException */
+public class SuiteException extends RuntimeException {
+       private static final long serialVersionUID = 9048360857209165816L;
+
+       public SuiteException(String message) {
+               super(message);
+       }
+
+       public SuiteException(String message, Throwable e) {
+               super(message, e);
+       }
+}
diff --git a/org.argeo.suite.core/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java b/org.argeo.suite.core/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java
new file mode 100644 (file)
index 0000000..27efb4d
--- /dev/null
@@ -0,0 +1,143 @@
+package org.argeo.suite.people;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.security.Privilege;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.connect.people.PeopleConstants;
+import org.argeo.connect.people.PeopleNames;
+import org.argeo.connect.people.PeopleService;
+import org.argeo.connect.people.PeopleTypes;
+import org.argeo.connect.people.ResourceService;
+import org.argeo.connect.people.core.PeopleServiceImpl;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.node.NodeConstants;
+import org.argeo.suite.SuiteException;
+
+/** Default implementation of an Argeo Suite specific People Backend */
+public class PeopleSuiteServiceImpl extends PeopleServiceImpl implements PeopleService, PeopleConstants {
+       private final static Log log = LogFactory.getLog(PeopleSuiteServiceImpl.class);
+
+       /* DEPENDENCY INJECTION */
+       private Repository repository;
+       private String workspaceName;
+       // private UserAdminService userAdminService;
+
+       public void init() {
+               super.init();
+               Session adminSession = null;
+               try {
+                       adminSession = repository.login(workspaceName);
+                       initialiseModel(adminSession);
+               } catch (Exception e) {
+                       throw new SuiteException("Cannot initialise model", e);
+               } finally {
+                       JcrUtils.logoutQuietly(adminSession);
+               }
+       }
+
+       // HELPERS
+
+       // TODO Hard-coded creation of default public and shared file directories
+       // To be cleaned once first init and configuration mechanisms have been
+       // implemented
+       private final static String publicPath = "/public";
+       private final static String sharedFilePath = "/sharedFiles";
+
+       @Override
+       protected void initialiseModel(Session adminSession) throws RepositoryException {
+               super.initialiseModel(adminSession);
+
+               JcrUtils.mkdirs(adminSession, publicPath, NodeType.NT_UNSTRUCTURED);
+               JcrUtils.mkdirs(adminSession, sharedFilePath, NodeType.NT_FOLDER);
+               initModelResources(adminSession);
+               if (adminSession.hasPendingChanges()) {
+                       adminSession.save();
+                       log.info("Repository has been initialized " + "with People's model");
+                       configureACL(adminSession);
+               }
+       }
+
+       // First draft of configuration of the people specific rights
+       private void configureACL(Session session) throws RepositoryException {
+               String memberGroupDn = "cn=" + PeopleConstants.ROLE_MEMBER + ",ou=roles,ou=node";
+               JcrUtils.addPrivilege(session, getBasePath(null), memberGroupDn, Privilege.JCR_ALL);
+               JcrUtils.addPrivilege(session, "/", NodeConstants.ROLE_ADMIN, Privilege.JCR_ALL);
+               JcrUtils.addPrivilege(session, publicPath, NodeConstants.ROLE_USER, Privilege.JCR_READ);
+               JcrUtils.addPrivilege(session, publicPath, "anonymous", Privilege.JCR_READ);
+               JcrUtils.addPrivilege(session, publicPath, NodeConstants.ROLE_ANONYMOUS, Privilege.JCR_READ);
+               JcrUtils.addPrivilege(session, sharedFilePath, NodeConstants.ROLE_USER, Privilege.JCR_ALL);
+               session.save();
+               log.info("Access control configured");
+       }
+
+       /**
+        * Initialises People resource model and optionally imports legacy resources
+        */
+       protected void initModelResources(Session adminSession) throws RepositoryException {
+               // initialisation
+               ResourceService resourceService = getResourceService();
+               resourceService.initialiseResources(adminSession);
+
+               // Resource resource = initResources.get("Countries");
+               // if (resourceService.getTagLikeResourceParent(adminSession,
+               // PeopleConstants.RESOURCE_COUNTRY) == null
+               // && resource != null) {
+               // resourceService.createTagLikeResourceParent(adminSession,
+               // PeopleConstants.RESOURCE_COUNTRY,
+               // PeopleTypes.PEOPLE_TAG_ENCODED_INSTANCE, PeopleNames.PEOPLE_CODE,
+               // getBasePath(null),
+               // JcrUiUtils.getLocalJcrItemName(NodeType.NT_UNSTRUCTURED), new
+               // ArrayList<String>());
+               // String EN_SHORT_NAME = "English short name (upper-lower case)";
+               // String ISO_CODE = "Alpha-2 code";
+               // new EncodedTagCsvFileParser(resourceService, adminSession,
+               // PeopleConstants.RESOURCE_COUNTRY, ISO_CODE,
+               // EN_SHORT_NAME).parse(resource.getInputStream(), "UTF-8");
+               // }
+               //
+               // resource = initResources.get("Languages");
+               // if (resourceService.getTagLikeResourceParent(adminSession,
+               // PeopleConstants.RESOURCE_LANG) == null
+               // && resource != null) {
+               // resourceService.createTagLikeResourceParent(adminSession,
+               // PeopleConstants.RESOURCE_LANG,
+               // PeopleTypes.PEOPLE_TAG_ENCODED_INSTANCE, PeopleNames.PEOPLE_CODE,
+               // getBasePath(null),
+               // JcrUiUtils.getLocalJcrItemName(NodeType.NT_UNSTRUCTURED), new
+               // ArrayList<String>());
+               // String EN_SHORT_NAME = "Language name";
+               // String ISO_CODE = "639-1";
+               // new EncodedTagCsvFileParser(resourceService, adminSession,
+               // PeopleConstants.RESOURCE_LANG, ISO_CODE,
+               // EN_SHORT_NAME).parse(resource.getInputStream(), "UTF-8");
+               // }
+
+               // Create tag & mailing list parents
+               if (resourceService.getTagLikeResourceParent(adminSession, PeopleConstants.RESOURCE_TAG) == null)
+                       resourceService.createTagLikeResourceParent(adminSession, PeopleConstants.RESOURCE_TAG,
+                                       PeopleTypes.PEOPLE_TAG_INSTANCE, null, getBasePath(null), PeopleTypes.PEOPLE_ENTITY,
+                                       PeopleNames.PEOPLE_TAGS);
+               if (resourceService.getTagLikeResourceParent(adminSession, PeopleTypes.PEOPLE_MAILING_LIST) == null)
+                       resourceService.createTagLikeResourceParent(adminSession, null, PeopleTypes.PEOPLE_MAILING_LIST, null,
+                                       getBasePath(null), PeopleTypes.PEOPLE_ENTITY, PeopleNames.PEOPLE_MAILING_LISTS);
+
+               if (adminSession.hasPendingChanges()) {
+                       adminSession.save();
+                       log.info("Resources have been added to People's model");
+               }
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setWorkspaceName(String workspaceName) {
+               this.workspaceName = workspaceName;
+       }
+}
index 59fd51c5fec3203e2c04c540ee2f2551a5af7493..aaca5d8aa03c2e707470996ed4046ee5cfe46854 100644 (file)
@@ -6,20 +6,6 @@
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
 
-       <bean id="peopleService" class="org.argeo.suite.people.PeopleSuiteServiceImpl"
-               init-method="init" destroy-method="destroy">
-               <property name="repository" ref="repository" />
-               <property name="workspaceName" value="main" />
-               <property name="userAdminService" ref="userAdminService" />
-       </bean>
-
-       <bean id="userAdminService" class="org.argeo.connect.people.core.UserAdminServiceImpl"
-               scope="singleton" lazy-init="false">
-               <property name="userTransaction" ref="userTransaction" />
-               <property name="userAdmin" ref="userAdmin" />
-               <property name="userAdminServiceReference" ref="userAdmin" />
-       </bean>
-
        <!-- The UI Service - Enables among other definition of specific commands 
                and editors. -->
        <bean id="peopleWbService" class="org.argeo.connect.people.workbench.rap.PeopleWbServiceImpl"
index 330172969e92f100cb5cd422c8b86e792d9a127f..c00bc83f64798652cc93be0a8081c7d868f9676b 100644 (file)
@@ -9,12 +9,9 @@
        <!-- REFERENCES -->\r
        <!--  Insure a home is present for each user that logs in -->\r
        <reference id="repository" interface="javax.jcr.Repository" filter="(cn=home)" />\r
-       <reference id="userAdmin" interface="org.osgi.service.useradmin.UserAdmin" />\r
-       <reference id="userTransaction" interface="javax.transaction.UserTransaction" />\r
+       <reference id="peopleService" interface="org.argeo.connect.people.PeopleService" />\r
        <reference id="nodeFileSystemProvider" interface="java.nio.file.spi.FileSystemProvider"\r
                filter="(service.pid=org.argeo.node.fsProvider)" />\r
        \r
        <!-- SERVICES -->\r
-       <!-- Exposes Argeo Suite specific implementation of the People Service -->\r
-       <service ref="peopleService" interface="org.argeo.connect.people.PeopleService" />\r
 </beans:beans>\r
index 998fb83bfa1a64b05b057e30d774b048fe7d2e7f..a252f56c08a0913b306d40c5ac86f2b6cad7f433 100644 (file)
        <artifactId>org.argeo.suite.web</artifactId>
        <name>Argeo Suite Web UI</name>
        <packaging>jar</packaging>
-
        <dependencies>
+               <dependency>
+                       <groupId>org.argeo.suite</groupId>
+                       <artifactId>org.argeo.suite.core</artifactId>
+                       <version>0.1.1-SNAPSHOT</version>
+               </dependency>
                <dependency>
                        <groupId>org.argeo.connect</groupId>
                        <artifactId>org.argeo.connect.people.web</artifactId>
diff --git a/org.argeo.suite.web/src/org/argeo/suite/SuiteException.java b/org.argeo.suite.web/src/org/argeo/suite/SuiteException.java
deleted file mode 100644 (file)
index 6351804..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.argeo.suite;
-
-/** Argeo Suite specific exception. Wraps a usual RuntimeException */
-public class SuiteException extends RuntimeException {
-       private static final long serialVersionUID = 9048360857209165816L;
-
-       public SuiteException(String message) {
-               super(message);
-       }
-
-       public SuiteException(String message, Throwable e) {
-               super(message, e);
-       }
-}
diff --git a/org.argeo.suite.web/src/org/argeo/suite/fs/MyFilesBrowserPage.java b/org.argeo.suite.web/src/org/argeo/suite/fs/MyFilesBrowserPage.java
deleted file mode 100644 (file)
index e34f964..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.argeo.suite.fs;
-
-import java.nio.file.spi.FileSystemProvider;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.fs.CmsFsBrowser;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** Default file browser page for the CMS */
-public class MyFilesBrowserPage implements CmsUiProvider {
-
-       private FileSystemProvider nodeFileSystemProvider;
-
-       public MyFilesBrowserPage(FileSystemProvider nodeFileSystemProvider) {
-               this.nodeFileSystemProvider = nodeFileSystemProvider;
-       }
-
-       @Override
-       public Control createUi(Composite parent, Node context) throws RepositoryException {
-               parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
-               if (CurrentUser.isAnonymous())
-                       // TODO implement public file display
-                       return null;
-
-               CmsFsBrowser browser = new CmsFsBrowser(parent, SWT.NO_FOCUS, context, nodeFileSystemProvider);
-               browser.setLayoutData(EclipseUiUtils.fillAll());
-
-               // TODO set input on the default home folder parent for one user's
-               // files
-               return browser;
-       }
-}
diff --git a/org.argeo.suite.web/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java b/org.argeo.suite.web/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java
deleted file mode 100644 (file)
index 27efb4d..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.argeo.suite.people;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.security.Privilege;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.connect.people.PeopleConstants;
-import org.argeo.connect.people.PeopleNames;
-import org.argeo.connect.people.PeopleService;
-import org.argeo.connect.people.PeopleTypes;
-import org.argeo.connect.people.ResourceService;
-import org.argeo.connect.people.core.PeopleServiceImpl;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.node.NodeConstants;
-import org.argeo.suite.SuiteException;
-
-/** Default implementation of an Argeo Suite specific People Backend */
-public class PeopleSuiteServiceImpl extends PeopleServiceImpl implements PeopleService, PeopleConstants {
-       private final static Log log = LogFactory.getLog(PeopleSuiteServiceImpl.class);
-
-       /* DEPENDENCY INJECTION */
-       private Repository repository;
-       private String workspaceName;
-       // private UserAdminService userAdminService;
-
-       public void init() {
-               super.init();
-               Session adminSession = null;
-               try {
-                       adminSession = repository.login(workspaceName);
-                       initialiseModel(adminSession);
-               } catch (Exception e) {
-                       throw new SuiteException("Cannot initialise model", e);
-               } finally {
-                       JcrUtils.logoutQuietly(adminSession);
-               }
-       }
-
-       // HELPERS
-
-       // TODO Hard-coded creation of default public and shared file directories
-       // To be cleaned once first init and configuration mechanisms have been
-       // implemented
-       private final static String publicPath = "/public";
-       private final static String sharedFilePath = "/sharedFiles";
-
-       @Override
-       protected void initialiseModel(Session adminSession) throws RepositoryException {
-               super.initialiseModel(adminSession);
-
-               JcrUtils.mkdirs(adminSession, publicPath, NodeType.NT_UNSTRUCTURED);
-               JcrUtils.mkdirs(adminSession, sharedFilePath, NodeType.NT_FOLDER);
-               initModelResources(adminSession);
-               if (adminSession.hasPendingChanges()) {
-                       adminSession.save();
-                       log.info("Repository has been initialized " + "with People's model");
-                       configureACL(adminSession);
-               }
-       }
-
-       // First draft of configuration of the people specific rights
-       private void configureACL(Session session) throws RepositoryException {
-               String memberGroupDn = "cn=" + PeopleConstants.ROLE_MEMBER + ",ou=roles,ou=node";
-               JcrUtils.addPrivilege(session, getBasePath(null), memberGroupDn, Privilege.JCR_ALL);
-               JcrUtils.addPrivilege(session, "/", NodeConstants.ROLE_ADMIN, Privilege.JCR_ALL);
-               JcrUtils.addPrivilege(session, publicPath, NodeConstants.ROLE_USER, Privilege.JCR_READ);
-               JcrUtils.addPrivilege(session, publicPath, "anonymous", Privilege.JCR_READ);
-               JcrUtils.addPrivilege(session, publicPath, NodeConstants.ROLE_ANONYMOUS, Privilege.JCR_READ);
-               JcrUtils.addPrivilege(session, sharedFilePath, NodeConstants.ROLE_USER, Privilege.JCR_ALL);
-               session.save();
-               log.info("Access control configured");
-       }
-
-       /**
-        * Initialises People resource model and optionally imports legacy resources
-        */
-       protected void initModelResources(Session adminSession) throws RepositoryException {
-               // initialisation
-               ResourceService resourceService = getResourceService();
-               resourceService.initialiseResources(adminSession);
-
-               // Resource resource = initResources.get("Countries");
-               // if (resourceService.getTagLikeResourceParent(adminSession,
-               // PeopleConstants.RESOURCE_COUNTRY) == null
-               // && resource != null) {
-               // resourceService.createTagLikeResourceParent(adminSession,
-               // PeopleConstants.RESOURCE_COUNTRY,
-               // PeopleTypes.PEOPLE_TAG_ENCODED_INSTANCE, PeopleNames.PEOPLE_CODE,
-               // getBasePath(null),
-               // JcrUiUtils.getLocalJcrItemName(NodeType.NT_UNSTRUCTURED), new
-               // ArrayList<String>());
-               // String EN_SHORT_NAME = "English short name (upper-lower case)";
-               // String ISO_CODE = "Alpha-2 code";
-               // new EncodedTagCsvFileParser(resourceService, adminSession,
-               // PeopleConstants.RESOURCE_COUNTRY, ISO_CODE,
-               // EN_SHORT_NAME).parse(resource.getInputStream(), "UTF-8");
-               // }
-               //
-               // resource = initResources.get("Languages");
-               // if (resourceService.getTagLikeResourceParent(adminSession,
-               // PeopleConstants.RESOURCE_LANG) == null
-               // && resource != null) {
-               // resourceService.createTagLikeResourceParent(adminSession,
-               // PeopleConstants.RESOURCE_LANG,
-               // PeopleTypes.PEOPLE_TAG_ENCODED_INSTANCE, PeopleNames.PEOPLE_CODE,
-               // getBasePath(null),
-               // JcrUiUtils.getLocalJcrItemName(NodeType.NT_UNSTRUCTURED), new
-               // ArrayList<String>());
-               // String EN_SHORT_NAME = "Language name";
-               // String ISO_CODE = "639-1";
-               // new EncodedTagCsvFileParser(resourceService, adminSession,
-               // PeopleConstants.RESOURCE_LANG, ISO_CODE,
-               // EN_SHORT_NAME).parse(resource.getInputStream(), "UTF-8");
-               // }
-
-               // Create tag & mailing list parents
-               if (resourceService.getTagLikeResourceParent(adminSession, PeopleConstants.RESOURCE_TAG) == null)
-                       resourceService.createTagLikeResourceParent(adminSession, PeopleConstants.RESOURCE_TAG,
-                                       PeopleTypes.PEOPLE_TAG_INSTANCE, null, getBasePath(null), PeopleTypes.PEOPLE_ENTITY,
-                                       PeopleNames.PEOPLE_TAGS);
-               if (resourceService.getTagLikeResourceParent(adminSession, PeopleTypes.PEOPLE_MAILING_LIST) == null)
-                       resourceService.createTagLikeResourceParent(adminSession, null, PeopleTypes.PEOPLE_MAILING_LIST, null,
-                                       getBasePath(null), PeopleTypes.PEOPLE_ENTITY, PeopleNames.PEOPLE_MAILING_LISTS);
-
-               if (adminSession.hasPendingChanges()) {
-                       adminSession.save();
-                       log.info("Resources have been added to People's model");
-               }
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setWorkspaceName(String workspaceName) {
-               this.workspaceName = workspaceName;
-       }
-}
index d1ecbf272373c88a724529b1d3fb17fc77bd3253..7b3ae2efdbbd1922ba3e976c466c3c9e164defc5 100644 (file)
@@ -21,7 +21,7 @@ import org.argeo.connect.people.PeopleService;
 import org.argeo.connect.people.PeopleTypes;
 import org.argeo.connect.people.web.pages.PeopleDefaultPage;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.suite.fs.MyFilesBrowserPage;
+import org.argeo.suite.web.fs.MyFilesBrowserPage;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.layout.GridData;
diff --git a/org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java b/org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java
new file mode 100644 (file)
index 0000000..cb4bdba
--- /dev/null
@@ -0,0 +1,40 @@
+package org.argeo.suite.web.fs;
+
+import java.nio.file.spi.FileSystemProvider;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.fs.CmsFsBrowser;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/** Default file browser page for the CMS */
+public class MyFilesBrowserPage implements CmsUiProvider {
+
+       private FileSystemProvider nodeFileSystemProvider;
+
+       public MyFilesBrowserPage(FileSystemProvider nodeFileSystemProvider) {
+               this.nodeFileSystemProvider = nodeFileSystemProvider;
+       }
+
+       @Override
+       public Control createUi(Composite parent, Node context) throws RepositoryException {
+               parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+
+               if (CurrentUser.isAnonymous())
+                       // TODO implement public file display
+                       return null;
+
+               CmsFsBrowser browser = new CmsFsBrowser(parent, SWT.NO_FOCUS, context, nodeFileSystemProvider);
+               browser.setLayoutData(EclipseUiUtils.fillAll());
+
+               // TODO set input on the default home folder parent for one user's
+               // files
+               return browser;
+       }
+}
index 3f9c473cbe42adfdce183c9d1712de709955acc5..9b36c038f0be54cf0796db8dab615efbc524d353 100644 (file)
        <reference id="peopleService" interface="org.argeo.connect.people.PeopleService" />\r
        <reference id="peopleWorkbenchService"\r
                interface="org.argeo.connect.people.workbench.rap.PeopleWorkbenchService" />\r
+       <reference id="nodeFileSystemProvider" interface="java.nio.file.spi.FileSystemProvider"\r
+               filter="(service.pid=org.argeo.node.fsProvider)" />\r
+\r
+\r
+       <!-- Local beans to be cleaned -->\r
+       <beans:bean id="fsAppService" class="org.argeo.suite.workbench.fs.FsAppService">\r
+       </beans:bean>\r
+\r
 </beans:beans>\r
index a5bfde6ed2d8192d85e6d7a21512fb0efe8ac448..f2ae1fd8cac25cab990928a07ec637770781cf80 100644 (file)
        </bean>
 
        <!-- VIEWS -->
+       <bean id="myFilesView" class="org.argeo.suite.workbench.parts.MyFilesView"
+               scope="prototype">
+               <property name="repository" ref="repository" />
+               <property name="nodeFileSystemProvider" ref="nodeFileSystemProvider" />
+               <property name="fsAppService" ref="fsAppService" />
+       </bean>
+       
+
        <bean id="testView" class="org.argeo.suite.workbench.parts.TestView"
                scope="prototype">
                <property name="repository" ref="repository" />
index 9e3c867f31fd4b91809b7a3c2fc5bc933157776b..99121fca3fe534d968655338038cc891e61b2ca5 100644 (file)
@@ -11,9 +11,11 @@ javax.jcr.nodetype,\
 javax.jcr.security,\
 org.argeo.cms,\
 org.argeo.cms.ui.workbench,\
+org.argeo.connect,\
 org.argeo.connect.people.workbench.rap.views,\
 org.argeo.connect.ui,\
 org.argeo.eclipse.spring,\
 org.argeo.node,\
 org.argeo.util,\
+org.argeo.cms.ui.workbench.jcr,\
 *
\ No newline at end of file
index 5315b88ceb92ca4e21c2e187934f4eddf816dc7a..bdc68088c93af5afd1e76f25e97821cad6811b8d 100644 (file)
                        name="Test View"
                        restorable="true">
                </view>
+               <view
+                       id="org.argeo.suite.workbench.rap.myFilesView"
+                       class="org.argeo.eclipse.spring.SpringExtensionFactory"
+                       icon="theme/argeo-classic/icons/fs/fsBrowser.png"
+                       name="Files"
+                       restorable="true">
+               </view>
        </extension>
                
        <!-- EDITORS --> 
index df9f8cdf459b37ce1609a8d48dca0f6e1ea822d5..d6ec915724ac85cf06d34075870d58bf5de38dd1 100644 (file)
@@ -14,7 +14,7 @@
        <dependencies>
                <dependency>
                        <groupId>org.argeo.suite</groupId>
-                       <artifactId>org.argeo.suite.web</artifactId>
+                       <artifactId>org.argeo.suite.core</artifactId>
                        <version>0.1.1-SNAPSHOT</version>
                </dependency>
                <dependency>
index edf357a98166be26a9998eb83de85ca74d8b0d71..f723e8d0c0af9186fd759404a7bd9a0a92712a9e 100644 (file)
@@ -1,8 +1,8 @@
 package org.argeo.suite.workbench;
 
-import org.argeo.cms.ui.workbench.jcr.NodeFsBrowserView;
 import org.argeo.connect.people.workbench.rap.views.MyTasksView;
 import org.argeo.connect.people.workbench.rap.views.QuickSearchView;
+import org.argeo.suite.workbench.parts.MyFilesView;
 import org.eclipse.ui.IFolderLayout;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveFactory;
@@ -15,11 +15,11 @@ public class DashboardPerspective implements IPerspectiveFactory {
                layout.setEditorAreaVisible(true);
                layout.setFixed(false);
 
-               IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.33f, editorArea);
+               IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.25f, editorArea);
                // Only show contacts if current user is a coworker
                // if (CurrentUser.isInRole(Role.coworker.dn()))
                left.addView(MyTasksView.ID);
                left.addView(QuickSearchView.ID);
-               left.addView(NodeFsBrowserView.ID);
+               left.addView(MyFilesView.ID);
        }
 }
diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsAppService.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsAppService.java
new file mode 100644 (file)
index 0000000..fc9563d
--- /dev/null
@@ -0,0 +1,70 @@
+package org.argeo.suite.workbench.fs;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.spi.FileSystemProvider;
+import java.security.PrivilegedActionException;
+
+import javax.jcr.Session;
+
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.node.NodeUtils;
+import org.argeo.suite.SuiteException;
+
+public class FsAppService {
+       private final static String NODE_PREFIX = "node://";
+
+       private String getCurrentHomePath(Session session) {
+               try {
+                       // Make in a do as if not from the workbench
+                       // Repository repo = session.getRepository();
+                       // session = CurrentUser.tryAs(() -> repo.login());
+                       String homepath = NodeUtils.getUserHome(session).getPath();
+                       return homepath;
+               } catch (Exception e) {
+                       throw new SuiteException("Cannot retrieve Current User Home Path", e);
+                       // } finally {
+                       // JcrUtils.logoutQuietly(session);
+               }
+       }
+
+       public Path[] getMyFilesPath(FileSystemProvider nodeFileSystemProvider, Session session) {
+               // return Paths.get(System.getProperty("user.dir"));
+               String currHomeUriStr = NODE_PREFIX + getCurrentHomePath(session);
+               try {
+                       URI uri = new URI(currHomeUriStr);
+                       FileSystem fileSystem = nodeFileSystemProvider.getFileSystem(uri);
+                       if (fileSystem == null) {
+                               fileSystem = CurrentUser.tryAs(() -> nodeFileSystemProvider.newFileSystem(uri, null));
+                               // PrivilegedExceptionAction<FileSystem> pea = new
+                               // PrivilegedExceptionAction<FileSystem>() {
+                               // @Override
+                               // public FileSystem run() throws Exception {
+                               // return nodeFileSystemProvider.newFileSystem(uri, null);
+                               // }
+                               //
+                               // };
+                               // fileSystem = CurrentUser.tryAs(pea);
+                       }
+                       Path[] paths = { fileSystem.getPath(getCurrentHomePath(session)), fileSystem.getPath("/") };
+                       return paths;
+               } catch (URISyntaxException | PrivilegedActionException e) {
+                       throw new RuntimeException("unable to initialise home file system for " + currHomeUriStr, e);
+               }
+       }
+
+       public Path[] getMyGroupsFilesPath(FileSystemProvider nodeFileSystemProvider, Session session) {
+               // TODO
+               Path[] paths = { Paths.get(System.getProperty("user.dir")), Paths.get("/tmp") };
+               return paths;
+       }
+
+       public Path[] getMyBookmarks(FileSystemProvider nodeFileSystemProvider, Session session) {
+               // TODO
+               Path[] paths = { Paths.get(System.getProperty("user.dir")), Paths.get("/tmp"), Paths.get("/opt") };
+               return paths;
+       }
+}
diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsImages.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsImages.java
new file mode 100644 (file)
index 0000000..ec6304f
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.suite.workbench.fs;
+
+import org.argeo.suite.workbench.AsUiPlugin;
+import org.eclipse.swt.graphics.Image;
+
+/** Shared icons for the file system RAP workbench */
+public class FsImages {
+       final private static String BASE_PATH = "/theme/argeo-classic/icons/fs/";
+       // Various types
+       public final static Image ICON_FOLDER = AsUiPlugin.getImageDescriptor(BASE_PATH + "folder.gif").createImage();
+       public final static Image ICON_FILE = AsUiPlugin.getImageDescriptor(BASE_PATH + "file.gif").createImage();
+}
diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsSingleColumnLabelProvider.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsSingleColumnLabelProvider.java
new file mode 100644 (file)
index 0000000..d3c62ff
--- /dev/null
@@ -0,0 +1,56 @@
+package org.argeo.suite.workbench.fs;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.connect.people.PeopleNames;
+import org.argeo.connect.ui.ConnectUiUtils;
+import org.argeo.suite.SuiteException;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Provide a single column label provider for file and directory lists. Icon and
+ * displayed text vary with the element node type
+ */
+public class FsSingleColumnLabelProvider extends LabelProvider implements PeopleNames {
+       private static final long serialVersionUID = -8895136766988459632L;
+
+       public FsSingleColumnLabelProvider() {
+       }
+
+       @Override
+       public String getText(Object element) {
+               try {
+                       Node entity = (Node) element;
+                       String result;
+                       if (entity.isNodeType(NodeType.NT_FILE))
+                               result = entity.getName();
+                       // result = ConnectJcrUtils.get(entity, Property.JCR_TITLE);
+                       else if (entity.isNodeType(NodeType.NT_FOLDER))
+                               result = entity.getName();
+                       // result = ConnectJcrUtils.get(entity, Property.JCR_TITLE);
+                       else
+                               result = "";
+                       return ConnectUiUtils.replaceAmpersand(result);
+               } catch (RepositoryException re) {
+                       throw new SuiteException("Unable to get formatted value for node", re);
+               }
+       }
+
+       /** Overwrite this method to provide project specific images */
+       @Override
+       public Image getImage(Object element) {
+               try {
+                       Node entity = (Node) element;
+                       if (entity.isNodeType(NodeType.NT_FILE))
+                               return FsImages.ICON_FILE;
+                       else if (entity.isNodeType(NodeType.NT_FOLDER))
+                               return FsImages.ICON_FOLDER;
+                       return null;
+               } catch (RepositoryException re) {
+                       throw new SuiteException("Cannot get icon for " + element, re);
+               }
+       }
+}
index 052d2c60b4154286f9f0debc9ed201d4b9c7f6c0..cfbe2eef88acd9dff03934bce5cceca4baa32120 100644 (file)
@@ -1,9 +1,13 @@
 package org.argeo.suite.workbench.parts;
 
+import javax.jcr.Node;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.connect.people.PeopleConstants;
 import org.argeo.connect.people.PeopleTypes;
 import org.argeo.connect.people.workbench.rap.PeopleRapUtils;
+import org.argeo.connect.util.ConnectJcrUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.suite.workbench.AsUiPlugin;
 import org.eclipse.swt.SWT;
@@ -73,10 +77,26 @@ public class DefaultDashboardEditor extends AbstractSuiteDashboard {
                parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
                createGadgetTitleCmp(parent, "Contacts");
                Composite bodyCmp = createGadgetBodyCmp(parent);
+               
                PeopleRapUtils.createOpenSearchEditorLink(getPeopleWorkbenchService(), bodyCmp, "Persons",
                                PeopleTypes.PEOPLE_PERSON, getPeopleService().getBasePath(PeopleTypes.PEOPLE_PERSON));
 
                PeopleRapUtils.createOpenSearchEditorLink(getPeopleWorkbenchService(), bodyCmp, "Organisations",
                                PeopleTypes.PEOPLE_ORG, getPeopleService().getBasePath(PeopleTypes.PEOPLE_ORG));
+
+               Node tagParent = getPeopleService().getResourceService().getTagLikeResourceParent(getSession(),
+                               PeopleTypes.PEOPLE_MAILING_LIST);
+               PeopleRapUtils.createOpenSearchEditorLink(getPeopleWorkbenchService(), bodyCmp, "Mailing lists",
+                               PeopleTypes.PEOPLE_MAILING_LIST, ConnectJcrUtils.getPath(tagParent));
+               
+               PeopleRapUtils.createOpenSearchEditorLink(getPeopleWorkbenchService(), bodyCmp, "Tasks",
+                               PeopleTypes.PEOPLE_TASK, getPeopleService().getBasePath(null));
+               
+               tagParent = getPeopleService().getResourceService().getTagLikeResourceParent(getSession(),
+                               PeopleConstants.RESOURCE_TAG);
+               
+               PeopleRapUtils.createOpenSearchEditorLink(getPeopleWorkbenchService(), bodyCmp, "Tags",
+                               PeopleTypes.PEOPLE_TAG_INSTANCE, ConnectJcrUtils.getPath(tagParent));
+
        }
 }
diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/MyFilesView.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/MyFilesView.java
new file mode 100644 (file)
index 0000000..d89a228
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * 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.suite.workbench.parts;
+
+import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty;
+
+import java.nio.file.spi.FileSystemProvider;
+
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+
+import org.argeo.cms.util.CmsUtils;
+import org.argeo.connect.ConnectConstants;
+import org.argeo.connect.people.PeopleException;
+import org.argeo.connect.people.workbench.rap.providers.BasicNodeListContentProvider;
+import org.argeo.connect.ui.ConnectUiConstants;
+import org.argeo.connect.ui.widgets.DelayedText;
+import org.argeo.connect.util.ConnectJcrUtils;
+import org.argeo.connect.util.XPathUtils;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.eclipse.ui.fs.FsTableViewer;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.suite.workbench.AsUiPlugin;
+import org.argeo.suite.workbench.fs.FsAppService;
+import org.argeo.suite.workbench.fs.FsSingleColumnLabelProvider;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.rap.rwt.service.ServerPushSession;
+import org.eclipse.swt.SWT;
+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.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.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.part.ViewPart;
+
+/** Browse the node file system. */
+public class MyFilesView extends ViewPart implements IDoubleClickListener {
+       public final static String ID = AsUiPlugin.PLUGIN_ID + ".myFilesView";
+
+       private FileSystemProvider nodeFileSystemProvider;
+       private FsAppService fsAppService;
+       private Repository repository;
+       private Session session;
+
+       private DelayedText filterTxt;
+       private TableViewer searchResultsViewer;
+       private Composite searchCmp;
+
+       @Override
+       public void createPartControl(Composite parent) {
+               session = ConnectJcrUtils.login(repository);
+               // MainLayout
+               parent.setLayout(new GridLayout());
+               addFilterPanel(parent);
+               searchCmp = new Composite(parent, SWT.NO_FOCUS);
+               searchCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
+               searchResultsViewer = createListPart(searchCmp, new FsSingleColumnLabelProvider());
+               GridData gd = EclipseUiUtils.fillWidth();
+               gd.heightHint = 0;
+               searchCmp.setLayoutData(gd);
+
+               Composite bookmarkCmp = new Composite(parent, SWT.NO_FOCUS);
+               bookmarkCmp.setLayoutData(EclipseUiUtils.fillAll());
+               populateBookmarks(bookmarkCmp);
+       }
+
+       public void addFilterPanel(Composite parent) {
+               // Use a delayed text: the query won't be done until the user stop
+               // typing for 800ms
+               int style = SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL;
+               filterTxt = new DelayedText(parent, style, ConnectUiConstants.SEARCH_TEXT_DELAY);
+               filterTxt.setLayoutData(EclipseUiUtils.fillWidth());
+
+               final ServerPushSession pushSession = new ServerPushSession();
+               filterTxt.addDelayedModifyListener(pushSession, new ModifyListener() {
+                       private static final long serialVersionUID = 5003010530960334977L;
+
+                       public void modifyText(ModifyEvent event) {
+                               filterTxt.getDisplay().asyncExec(new Runnable() {
+                                       @Override
+                                       public void run() {
+                                               int resultNb = refreshFilteredList();
+                                               if (resultNb > 0)
+                                                       ((GridData) searchCmp.getLayoutData()).heightHint = 120;
+                                               else
+                                                       ((GridData) searchCmp.getLayoutData()).heightHint = 0;
+                                               parent.layout(true, true);
+                                       }
+                               });
+                               pushSession.stop();
+                       }
+               });
+
+               // Jump to the first item of the list using the down arrow
+               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;
+                               if (e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.TAB) {
+                                       Object first = searchResultsViewer.getElementAt(0);
+                                       if (first != null) {
+                                               searchResultsViewer.getTable().setFocus();
+                                               searchResultsViewer.setSelection(new StructuredSelection(first), true);
+                                       }
+                                       e.doit = false;
+                               }
+                       }
+               });
+       }
+
+       protected TableViewer createListPart(Composite parent, ILabelProvider labelProvider) {
+               parent.setLayout(new GridLayout());
+
+               Composite tableComposite = new Composite(parent, SWT.NONE);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL
+                               | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
+               tableComposite.setLayoutData(gd);
+
+               TableViewer v = new TableViewer(tableComposite);
+               v.setLabelProvider(labelProvider);
+
+               TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL);
+               TableColumnLayout tableColumnLayout = new TableColumnLayout();
+               tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85));
+               tableComposite.setLayout(tableColumnLayout);
+
+               // Corresponding table & style
+               Table table = v.getTable();
+               table.setLinesVisible(true);
+               table.setHeaderVisible(false);
+               CmsUtils.markup(table);
+               CmsUtils.setItemHeight(table, 26);
+
+               v.setContentProvider(new BasicNodeListContentProvider());
+               v.addDoubleClickListener(this);
+               return v;
+       }
+
+       @Override
+       public void dispose() {
+               JcrUtils.logoutQuietly(session);
+               super.dispose();
+       }
+
+       protected int refreshFilteredList() {
+               try {
+                       String filter = filterTxt.getText();
+                       // Prevents the query on the full repository
+                       if (EclipseUiUtils.isEmpty(filter)) {
+                               searchResultsViewer.setInput(null);
+                               return 0;
+                       }
+
+                       QueryManager queryManager = session.getWorkspace().getQueryManager();
+
+                       // XPATH Query
+                       // TODO manage cleanly jcr: prefix
+                       // String xpathQueryStr = "//element(*, " + NodeType.NT_FILE + ")";
+                       String xpathQueryStr = "//element(*, nt:file)";
+                       String xpathFilter = XPathUtils.getFreeTextConstraint(filter);
+                       if (notEmpty(xpathFilter))
+                               xpathQueryStr += "[" + xpathFilter + "]";
+
+                       Query xpathQuery = queryManager.createQuery(xpathQueryStr, ConnectConstants.QUERY_XPATH);
+
+                       // xpathQuery.setLimit(TrackerUiConstants.SEARCH_DEFAULT_LIMIT);
+                       QueryResult result = xpathQuery.execute();
+
+                       NodeIterator nit = result.getNodes();
+                       searchResultsViewer.setInput(JcrUtils.nodeIteratorToList(nit));
+
+                       return (int) nit.getSize();
+               } catch (RepositoryException e) {
+                       throw new PeopleException("Unable to list files", e);
+               }
+       }
+
+       private void populateBookmarks(Composite parent) {
+               CmsUtils.clear(parent);
+               parent.setLayout(new GridLayout());
+
+               int bookmarkColWith = 200;
+
+               FsTableViewer homeViewer = new FsTableViewer(parent, SWT.SINGLE | SWT.NO_SCROLL);
+               Table table = homeViewer.configureDefaultSingleColumnTable(bookmarkColWith);
+               GridData gd = EclipseUiUtils.fillWidth();
+               gd.horizontalIndent = 10;
+               table.setLayoutData(gd);
+               homeViewer.addDoubleClickListener(this);
+               homeViewer.setPathsInput(fsAppService.getMyFilesPath(nodeFileSystemProvider, session));
+
+               appendTitle(parent, "Shared files");
+               FsTableViewer groupsViewer = new FsTableViewer(parent, SWT.SINGLE | SWT.NO_SCROLL);
+               table = groupsViewer.configureDefaultSingleColumnTable(bookmarkColWith);
+               gd = EclipseUiUtils.fillWidth();
+               gd.horizontalIndent = 10;
+               table.setLayoutData(gd);
+               groupsViewer.addDoubleClickListener(this);
+               groupsViewer.setPathsInput(fsAppService.getMyGroupsFilesPath(nodeFileSystemProvider, session));
+
+               appendTitle(parent, "My bookmarks");
+               FsTableViewer bookmarksViewer = new FsTableViewer(parent, SWT.SINGLE | SWT.NO_SCROLL);
+               table = bookmarksViewer.configureDefaultSingleColumnTable(bookmarkColWith);
+               gd = EclipseUiUtils.fillWidth();
+               gd.horizontalIndent = 10;
+               table.setLayoutData(gd);
+               bookmarksViewer.addDoubleClickListener(this);
+               bookmarksViewer.setPathsInput(fsAppService.getMyBookmarks(nodeFileSystemProvider, session));
+       }
+
+       private Label appendTitle(Composite parent, String value) {
+               Label titleLbl = new Label(parent, SWT.NONE);
+               titleLbl.setText(value);
+               titleLbl.setFont(EclipseUiUtils.getBoldFont(parent));
+               GridData gd = EclipseUiUtils.fillWidth();
+               gd.horizontalIndent = 5;
+               gd.verticalIndent = 5;
+               titleLbl.setLayoutData(gd);
+               return titleLbl;
+       }
+
+       @Override
+       public void doubleClick(DoubleClickEvent event) {
+               IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+               if (selection.isEmpty())
+                       return;
+               else {
+                       System.out.println("Double clicked");
+                       // TODO open corresponding editor
+                       // Path newSelected = (Path) selection.getFirstElement();
+                       // if (newSelected.equals(currDisplayedFolder) &&
+                       // newSelected.equals(initialPath))
+                       // return;
+                       // initialPath = newSelected;
+                       // setInput(newSelected);
+               }
+       }
+
+       @Override
+       public void setFocus() {
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) {
+               this.nodeFileSystemProvider = nodeFileSystemProvider;
+       }
+
+       public void setFsAppService(FsAppService fsAppService) {
+               this.fsAppService = fsAppService;
+       }
+}
diff --git a/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/file.gif b/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/file.gif
new file mode 100644 (file)
index 0000000..ef30288
Binary files /dev/null and b/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/file.gif differ
diff --git a/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/folder.gif b/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/folder.gif
new file mode 100644 (file)
index 0000000..42e027c
Binary files /dev/null and b/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/folder.gif differ
diff --git a/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/fsBrowser.png b/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/fsBrowser.png
new file mode 100644 (file)
index 0000000..3f56074
Binary files /dev/null and b/org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/fsBrowser.png differ
diff --git a/pom.xml b/pom.xml
index f743512c4b6d00e80d6e3b0637ec80fc877114ef..14d4581e05f8225af60984279f976357e15f6f8e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,7 @@
        <description></description>
        <version>0.1.1-SNAPSHOT</version>
        <modules>
+               <module>org.argeo.suite.core</module>
                <module>org.argeo.suite.web</module>
                <module>org.argeo.suite.workbench.rap</module>
                <module>sdk</module>