From f2bf1e12e3aad9c2507e86e1d33fef2fd3e67489 Mon Sep 17 00:00:00 2001 From: bsinou Date: Mon, 30 Jan 2017 23:44:06 +0100 Subject: [PATCH] Add a core bundle to keep separation between Workbench and web clean --- org.argeo.suite.core/.classpath | 7 + org.argeo.suite.core/.gitignore | 3 + org.argeo.suite.core/.project | 25 ++ org.argeo.suite.core/META-INF/.gitignore | 1 + .../META-INF/spring/application.xml | 27 ++ org.argeo.suite.core/META-INF/spring/osgi.xml | 20 ++ org.argeo.suite.core/apps.properties | 1 + org.argeo.suite.core/bnd.bnd | 8 + org.argeo.suite.core/build.properties | 3 + org.argeo.suite.core/pom.xml | 22 ++ .../src/org/argeo/suite/SuiteException.java | 0 .../suite/people/PeopleSuiteServiceImpl.java | 0 .../META-INF/spring/application.xml | 14 - org.argeo.suite.web/META-INF/spring/osgi.xml | 5 +- org.argeo.suite.web/pom.xml | 6 +- .../org/argeo/suite/web/DefaultMainPage.java | 2 +- .../{ => web}/fs/MyFilesBrowserPage.java | 2 +- .../META-INF/spring/osgi.xml | 8 + .../META-INF/spring/parts.xml | 8 + org.argeo.suite.workbench.rap/bnd.bnd | 2 + org.argeo.suite.workbench.rap/plugin.xml | 7 + org.argeo.suite.workbench.rap/pom.xml | 2 +- .../suite/workbench/DashboardPerspective.java | 6 +- .../suite/workbench/fs/FsAppService.java | 70 +++++ .../argeo/suite/workbench/fs/FsImages.java | 12 + .../fs/FsSingleColumnLabelProvider.java | 56 ++++ .../parts/DefaultDashboardEditor.java | 20 ++ .../suite/workbench/parts/MyFilesView.java | 293 ++++++++++++++++++ .../theme/argeo-classic/icons/fs/file.gif | Bin 0 -> 577 bytes .../theme/argeo-classic/icons/fs/folder.gif | Bin 0 -> 219 bytes .../argeo-classic/icons/fs/fsBrowser.png | Bin 0 -> 496 bytes pom.xml | 1 + 32 files changed, 606 insertions(+), 25 deletions(-) create mode 100644 org.argeo.suite.core/.classpath create mode 100644 org.argeo.suite.core/.gitignore create mode 100644 org.argeo.suite.core/.project create mode 100644 org.argeo.suite.core/META-INF/.gitignore create mode 100644 org.argeo.suite.core/META-INF/spring/application.xml create mode 100644 org.argeo.suite.core/META-INF/spring/osgi.xml create mode 100644 org.argeo.suite.core/apps.properties create mode 100644 org.argeo.suite.core/bnd.bnd create mode 100644 org.argeo.suite.core/build.properties create mode 100644 org.argeo.suite.core/pom.xml rename {org.argeo.suite.web => org.argeo.suite.core}/src/org/argeo/suite/SuiteException.java (100%) rename {org.argeo.suite.web => org.argeo.suite.core}/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java (100%) rename org.argeo.suite.web/src/org/argeo/suite/{ => web}/fs/MyFilesBrowserPage.java (97%) create mode 100644 org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsAppService.java create mode 100644 org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsImages.java create mode 100644 org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsSingleColumnLabelProvider.java create mode 100644 org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/MyFilesView.java create mode 100644 org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/file.gif create mode 100644 org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/folder.gif create mode 100644 org.argeo.suite.workbench.rap/theme/argeo-classic/icons/fs/fsBrowser.png diff --git a/org.argeo.suite.core/.classpath b/org.argeo.suite.core/.classpath new file mode 100644 index 0000000..191b71a --- /dev/null +++ b/org.argeo.suite.core/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.core/.gitignore b/org.argeo.suite.core/.gitignore new file mode 100644 index 0000000..016bb39 --- /dev/null +++ b/org.argeo.suite.core/.gitignore @@ -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 index 0000000..e3b8ec5 --- /dev/null +++ b/org.argeo.suite.core/.project @@ -0,0 +1,25 @@ + + + org.argeo.suite.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + org.eclipse.pde.ManifestBuilder + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/org.argeo.suite.core/META-INF/.gitignore b/org.argeo.suite.core/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.core/META-INF/.gitignore @@ -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 index 0000000..460fc85 --- /dev/null +++ b/org.argeo.suite.core/META-INF/spring/application.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + 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 index 0000000..3301729 --- /dev/null +++ b/org.argeo.suite.core/META-INF/spring/osgi.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/org.argeo.suite.core/apps.properties b/org.argeo.suite.core/apps.properties new file mode 100644 index 0000000..e0227a3 --- /dev/null +++ b/org.argeo.suite.core/apps.properties @@ -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 index 0000000..68b918c --- /dev/null +++ b/org.argeo.suite.core/bnd.bnd @@ -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 index 0000000..3166058 --- /dev/null +++ b/org.argeo.suite.core/build.properties @@ -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 index 0000000..a8eb095 --- /dev/null +++ b/org.argeo.suite.core/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 0.1.1-SNAPSHOT + .. + + org.argeo.suite.core + Argeo Suite Core + jar + + + + org.argeo.connect + org.argeo.connect.people.core + ${version.argeo-connect} + + + diff --git a/org.argeo.suite.web/src/org/argeo/suite/SuiteException.java b/org.argeo.suite.core/src/org/argeo/suite/SuiteException.java similarity index 100% rename from org.argeo.suite.web/src/org/argeo/suite/SuiteException.java rename to org.argeo.suite.core/src/org/argeo/suite/SuiteException.java diff --git a/org.argeo.suite.web/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java b/org.argeo.suite.core/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java similarity index 100% rename from org.argeo.suite.web/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java rename to org.argeo.suite.core/src/org/argeo/suite/people/PeopleSuiteServiceImpl.java diff --git a/org.argeo.suite.web/META-INF/spring/application.xml b/org.argeo.suite.web/META-INF/spring/application.xml index 59fd51c..aaca5d8 100644 --- a/org.argeo.suite.web/META-INF/spring/application.xml +++ b/org.argeo.suite.web/META-INF/spring/application.xml @@ -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"> - - - - - - - - - - - - - - + - - diff --git a/org.argeo.suite.web/pom.xml b/org.argeo.suite.web/pom.xml index 998fb83..a252f56 100644 --- a/org.argeo.suite.web/pom.xml +++ b/org.argeo.suite.web/pom.xml @@ -11,8 +11,12 @@ org.argeo.suite.web Argeo Suite Web UI jar - + + org.argeo.suite + org.argeo.suite.core + 0.1.1-SNAPSHOT + org.argeo.connect org.argeo.connect.people.web diff --git a/org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java b/org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java index d1ecbf2..7b3ae2e 100644 --- a/org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java +++ b/org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java @@ -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/fs/MyFilesBrowserPage.java b/org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java similarity index 97% rename from org.argeo.suite.web/src/org/argeo/suite/fs/MyFilesBrowserPage.java rename to org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java index e34f964..cb4bdba 100644 --- a/org.argeo.suite.web/src/org/argeo/suite/fs/MyFilesBrowserPage.java +++ b/org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java @@ -1,4 +1,4 @@ -package org.argeo.suite.fs; +package org.argeo.suite.web.fs; import java.nio.file.spi.FileSystemProvider; diff --git a/org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml b/org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml index 3f9c473..9b36c03 100644 --- a/org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml +++ b/org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml @@ -12,4 +12,12 @@ + + + + + + + diff --git a/org.argeo.suite.workbench.rap/META-INF/spring/parts.xml b/org.argeo.suite.workbench.rap/META-INF/spring/parts.xml index a5bfde6..f2ae1fd 100644 --- a/org.argeo.suite.workbench.rap/META-INF/spring/parts.xml +++ b/org.argeo.suite.workbench.rap/META-INF/spring/parts.xml @@ -12,6 +12,14 @@ + + + + + + + diff --git a/org.argeo.suite.workbench.rap/bnd.bnd b/org.argeo.suite.workbench.rap/bnd.bnd index 9e3c867..99121fc 100644 --- a/org.argeo.suite.workbench.rap/bnd.bnd +++ b/org.argeo.suite.workbench.rap/bnd.bnd @@ -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 diff --git a/org.argeo.suite.workbench.rap/plugin.xml b/org.argeo.suite.workbench.rap/plugin.xml index 5315b88..bdc6808 100644 --- a/org.argeo.suite.workbench.rap/plugin.xml +++ b/org.argeo.suite.workbench.rap/plugin.xml @@ -33,6 +33,13 @@ name="Test View" restorable="true"> + + diff --git a/org.argeo.suite.workbench.rap/pom.xml b/org.argeo.suite.workbench.rap/pom.xml index df9f8cd..d6ec915 100644 --- a/org.argeo.suite.workbench.rap/pom.xml +++ b/org.argeo.suite.workbench.rap/pom.xml @@ -14,7 +14,7 @@ org.argeo.suite - org.argeo.suite.web + org.argeo.suite.core 0.1.1-SNAPSHOT diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java index edf357a..f723e8d 100644 --- a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java @@ -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 index 0000000..fc9563d --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsAppService.java @@ -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 pea = new + // PrivilegedExceptionAction() { + // @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 index 0000000..ec6304f --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsImages.java @@ -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 index 0000000..d3c62ff --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/fs/FsSingleColumnLabelProvider.java @@ -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); + } + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java index 052d2c6..cfbe2ee 100644 --- a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java @@ -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 index 0000000..d89a228 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/MyFilesView.java @@ -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 index 0000000000000000000000000000000000000000..ef302880717d12cc7dcc93a5ec9409488a788e7f GIT binary patch literal 577 zcmZ?wbhEHb6krfwc*elsm$lF@Yk_~(g0RA6@s(>r3zvl!E{&^PlisvBy=hZM)24#1 z9pw}ERe;dm+Gz(r{{H{r&;OtQ{(t!Q|KtDv-~Rvq{{R1v|Nnpf|Nra%|KI=r|M~y_ z-~a!`S@y+Q4#n9HCE1Rpxvu3o4n>&`#aWIO`R*0@-c7}JwfXjydCp}yuI;7P)2fXp zRG4;`S*&W)UD#kSyUuV%wZWWvqeU&IE7~m{9cy0KrnROYC}Z5GBYybE5lN#yT~U6Xo$Ra(3=+D1dScga+z`_1)0SMcgq@9vNlLp4}NkYYq1|o9u5f+1+4#yxaU}r`gdi^F!@s8_V^#R2r-=)!$xYw6WY^bAj4_ zFkpZI#h)yU3=A?1Iv@d%oeZoI3hI3+ne)<@xV>1B`(fEuK?V+&Lu+13upU?-aN>~% z+leJYmV$v?7gmUP30m^pSR?jZz)|4A1_>U)M7|eWr0xntihbB2lP8!e@?(!&ykzXZ OhQ@l`mR1!-25SJE4`R#! literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..3f56074f7817b41c52e978b6d405b1d8a60cb9a9 GIT binary patch literal 496 zcmVTL+@c706Xc<2?0}cp_ zh%g*Ia)jaSn>U1l!~v@TTwGiXrR5b2>KYnwiSEu0hQkLBFnD=*fbqGrXBh6@xr1Q< zBQ)UN@7}db;PK-}3`xl;V2MYM9x)`w$1x} 0.1.1-SNAPSHOT + org.argeo.suite.core org.argeo.suite.web org.argeo.suite.workbench.rap sdk -- 2.30.2