Work on CMS file system implementation
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 22 Oct 2023 09:22:21 +0000 (11:22 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 22 Oct 2023 09:22:21 +0000 (11:22 +0200)
14 files changed:
org.argeo.api.acr/src/org/argeo/api/acr/Content.java
org.argeo.cms/OSGI-INF/cmsFileSystemProvider.xml [new file with mode: 0644]
org.argeo.cms/bnd.bnd
org.argeo.cms/build.properties
org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileStore.java
org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystem.java
org.argeo.cms/src/org/argeo/cms/file/provider/CmsFileSystemProvider.java
org.argeo.cms/src/org/argeo/cms/file/provider/CmsPath.java
org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributeView.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/file/provider/ContentDirectoryStream.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java
sdk/cms-rcp.properties
swt/org.argeo.cms.swt/OSGI-INF/cmsUserApp.xml
swt/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java

index f7600f540e63ea3b20311c94f2824cd2c7703151..7ec29594713e885d8f39a2efa00c0a24b186f7f3 100644 (file)
@@ -90,7 +90,11 @@ public interface Content extends Iterable<Content>, Map<QName, Object> {
         * CONTENT OPERATIONS
         */
        /** Adds a new empty {@link Content} to this {@link Content}. */
-       Content add(QName name, QName... classes);
+       Content add(QName name, QName... contentClass);
+
+       default Content add(QName name, QNamed... contentClass) {
+               return add(name, toQNames(contentClass));
+       }
 
        /**
         * Adds a new {@link Content} to this {@link Content}, setting the provided
@@ -135,10 +139,7 @@ public interface Content extends Iterable<Content>, Map<QName, Object> {
 
        /** AND */
        default boolean isContentClass(QNamed... contentClass) {
-               List<QName> lst = new ArrayList<>();
-               for (QNamed qNamed : contentClass)
-                       lst.add(qNamed.qName());
-               return isContentClass(lst.toArray(new QName[lst.size()]));
+               return isContentClass(toQNames(contentClass));
        }
 
        /** OR */
@@ -153,10 +154,14 @@ public interface Content extends Iterable<Content>, Map<QName, Object> {
 
        /** OR */
        default boolean hasContentClass(QNamed... contentClass) {
-               List<QName> lst = new ArrayList<>();
-               for (QNamed qNamed : contentClass)
-                       lst.add(qNamed.qName());
-               return hasContentClass(lst.toArray(new QName[lst.size()]));
+               return hasContentClass(toQNames(contentClass));
+       }
+
+       static QName[] toQNames(QNamed... names) {
+               QName[] res = new QName[names.length];
+               for (int i = 0; i < names.length; i++)
+                       res[i] = names[i].qName();
+               return res;
        }
 
        /*
diff --git a/org.argeo.cms/OSGI-INF/cmsFileSystemProvider.xml b/org.argeo.cms/OSGI-INF/cmsFileSystemProvider.xml
new file mode 100644 (file)
index 0000000..b1402fa
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" name="org.argeo.cms.cmsFileSystemProvider">
+   <implementation class="org.argeo.cms.file.provider.CmsFileSystemProvider"/>
+   <reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.spi.ProvidedRepository" name="ProvidedRepository" policy="static"/>
+   <service>
+      <provide interface="java.nio.file.spi.FileSystemProvider"/>
+   </service>
+</scr:component>
index ade2f3aa94f72ac1f1d2eee2616dffb48a30a4ef..01443b5e8150215f77435c4f4a8ce56850f3895e 100644 (file)
@@ -16,4 +16,5 @@ OSGI-INF/cmsContentRepository.xml,\
 OSGI-INF/cmsAcrHttpHandler.xml,\
 OSGI-INF/cmsDeployment.xml,\
 OSGI-INF/cmsContext.xml,\
+OSGI-INF/cmsFileSystemProvider.xml,\
 
index 6ca041a2a19c39c0db563da5d0bc0ab660494744..04d4cb94a07bb3fb1817dd5540142b7f48758353 100644 (file)
@@ -2,6 +2,7 @@ bin.includes = META-INF/,\
                .,\
                bin/,\
                OSGI-INF/,\
-               OSGI-INF/cmsEventBus.xml
+               OSGI-INF/cmsEventBus.xml,\
+               OSGI-INF/cmsFileSystemProvider.xml
 source.. = src/
 output.. = bin/
index a4da893b6d627259c11d1a839604c46021bd1a57..7abeec4e6cb74a04b72c4fe3230691ab6b6641ce 100644 (file)
@@ -5,24 +5,30 @@ import java.nio.file.attribute.FileAttributeView;
 import java.nio.file.attribute.FileStoreAttributeView;
 
 import org.argeo.api.acr.fs.AbstractFsStore;
+import org.argeo.api.acr.spi.ContentProvider;
 
 public class CmsFileStore extends AbstractFsStore {
+       private final ContentProvider contentProvider;
+
+       public CmsFileStore(ContentProvider contentProvider) {
+               this.contentProvider = contentProvider;
+       }
 
        @Override
        public String name() {
-               // TODO Auto-generated method stub
-               return null;
+               // TODO return an URI
+               String name = contentProvider.getMountPath();
+               return name;
        }
 
        @Override
        public String type() {
-               // TODO Auto-generated method stub
-               return null;
+               String type = contentProvider.getClass().getName();
+               return type;
        }
 
        @Override
        public boolean isReadOnly() {
-               // TODO Auto-generated method stub
                return false;
        }
 
@@ -46,13 +52,15 @@ public class CmsFileStore extends AbstractFsStore {
 
        @Override
        public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
-               // TODO Auto-generated method stub
+               if (ContentAttributeView.class.isAssignableFrom(type))
+                       return true;
                return false;
        }
 
        @Override
        public boolean supportsFileAttributeView(String name) {
-               // TODO Auto-generated method stub
+               if (ContentAttributeView.NAME.equals(name))
+                       return true;
                return false;
        }
 
index 6d4eea279c85f42f040ca5c6d599c881106f8617..f581ea1c4bc97bfef25545ae60fc27f4425fe0ce 100644 (file)
@@ -7,94 +7,131 @@ import java.nio.file.PathMatcher;
 import java.nio.file.WatchService;
 import java.nio.file.attribute.UserPrincipalLookupService;
 import java.nio.file.spi.FileSystemProvider;
+import java.util.Collections;
 import java.util.Set;
 
 import org.argeo.api.acr.fs.AbstractFsSystem;
+import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.api.acr.spi.ProvidedRepository;
+import org.argeo.api.acr.spi.ProvidedSession;
+import org.argeo.api.cms.CmsSession;
+import org.argeo.cms.acr.ContentUtils;
 
 public class CmsFileSystem extends AbstractFsSystem<CmsFileStore> {
+       private final CmsFileSystemProvider provider;
+//     private final ProvidedRepository contentRepository;
+       private final CmsSession cmsSession;
+       private final ProvidedSession contentSession;
+
+       private final CmsPath rootPath;
+       private final CmsFileStore baseFileStore;
+
+       public CmsFileSystem(CmsFileSystemProvider provider, ProvidedRepository contentRepository, CmsSession cmsSession) {
+               this.provider = provider;
+//             this.contentRepository = contentRepository;
+               this.cmsSession = cmsSession;
+               this.contentSession = (ProvidedSession) ContentUtils.openSession(contentRepository, cmsSession);
+
+               rootPath = new CmsPath(this, ProvidedContent.ROOT_PATH);
+               baseFileStore = new CmsFileStore(rootPath.getContent().getProvider());
+       }
 
        @Override
        public CmsFileStore getBaseFileStore() {
-               // TODO Auto-generated method stub
-               return null;
+               return baseFileStore;
        }
 
        @Override
        public CmsFileStore getFileStore(String path) {
-               // TODO Auto-generated method stub
-               return null;
+               ProvidedContent c = (ProvidedContent) contentSession.get(path);
+               return new CmsFileStore(c.getProvider());
        }
 
        @Override
        public FileSystemProvider provider() {
-               // TODO Auto-generated method stub
-               return null;
+               return provider;
        }
 
        @Override
        public void close() throws IOException {
-               // TODO Auto-generated method stub
-
+               // TODO close content session?
+               provider.close(this);
        }
 
        @Override
        public boolean isOpen() {
-               // TODO Auto-generated method stub
-               return false;
+               // TODO check provider
+               return true;
        }
 
        @Override
        public boolean isReadOnly() {
-               // TODO Auto-generated method stub
                return false;
        }
 
        @Override
        public String getSeparator() {
-               // TODO Auto-generated method stub
-               return null;
+               return CmsPath.SEPARATOR;
        }
 
        @Override
        public Iterable<Path> getRootDirectories() {
-               // TODO Auto-generated method stub
-               return null;
+               return Collections.singleton(rootPath);
        }
 
        @Override
        public Iterable<FileStore> getFileStores() {
-               // TODO Auto-generated method stub
-               return null;
+               // TODO return all mount points
+               return Collections.singleton(baseFileStore);
        }
 
        @Override
        public Set<String> supportedFileAttributeViews() {
-               // TODO Auto-generated method stub
-               return null;
+               return Collections.singleton(ContentAttributeView.NAME);
        }
 
        @Override
        public Path getPath(String first, String... more) {
-               // TODO Auto-generated method stub
-               return null;
+               StringBuilder sb = new StringBuilder(first);
+               // TODO Make it more robust
+               for (String part : more)
+                       sb.append('/').append(part);
+               return new CmsPath(this, sb.toString());
        }
 
        @Override
        public PathMatcher getPathMatcher(String syntaxAndPattern) {
-               // TODO Auto-generated method stub
                return null;
        }
 
        @Override
        public UserPrincipalLookupService getUserPrincipalLookupService() {
-               // TODO Auto-generated method stub
                return null;
        }
 
        @Override
        public WatchService newWatchService() throws IOException {
-               // TODO Auto-generated method stub
                return null;
        }
 
+       /*
+        * ACR
+        */
+
+       ProvidedContent getContent(String acrPath) {
+               return (ProvidedContent) contentSession.get(acrPath);
+       }
+
+       ProvidedSession getContentSession() {
+               return contentSession;
+       }
+
+       /*
+        * CMS
+        */
+
+       CmsSession getCmsSession() {
+               return cmsSession;
+       }
+
 }
index 51eb84e713204f057f509ae5613949192436dfe4..5d93b7b580ac5b51223f74d83f64b99b1189a71f 100644 (file)
@@ -1,26 +1,53 @@
 package org.argeo.cms.file.provider;
 
 import java.io.IOException;
+import java.io.UncheckedIOException;
 import java.net.URI;
 import java.nio.channels.SeekableByteChannel;
 import java.nio.file.AccessMode;
 import java.nio.file.CopyOption;
 import java.nio.file.DirectoryStream;
 import java.nio.file.DirectoryStream.Filter;
+import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.FileStore;
 import java.nio.file.FileSystem;
+import java.nio.file.FileSystemAlreadyExistsException;
 import java.nio.file.LinkOption;
+import java.nio.file.NoSuchFileException;
 import java.nio.file.OpenOption;
 import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.nio.file.attribute.FileAttribute;
 import java.nio.file.attribute.FileAttributeView;
 import java.nio.file.spi.FileSystemProvider;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.DName;
+import org.argeo.api.acr.NamespaceUtils;
+import org.argeo.api.acr.spi.ProvidedRepository;
+import org.argeo.api.acr.spi.ProvidedSession;
+import org.argeo.api.cms.CmsSession;
+import org.argeo.cms.CurrentUser;
+
 public class CmsFileSystemProvider extends FileSystemProvider {
+       private Map<CmsSession, CmsFileSystem> fileSystems = Collections.synchronizedMap(new HashMap<>());
 
+       private ProvidedRepository contentRepository;
+
+       
+       public void start() {
+               
+       }
+       
+       public void stop() {
+               
+       }
+       
        @Override
        public String getScheme() {
                return "cms";
@@ -28,20 +55,48 @@ public class CmsFileSystemProvider extends FileSystemProvider {
 
        @Override
        public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
-               // TODO Auto-generated method stub
-               return null;
+               CmsSession cmsSession = CurrentUser.getCmsSession();
+               if (cmsSession.isAnonymous()) {
+                       // TODO deal with anonymous
+                       return null;
+               }
+               if (fileSystems.containsKey(cmsSession))
+                       throw new FileSystemAlreadyExistsException("CMS file system already exists for user " + cmsSession);
+
+               String host = uri.getHost();
+               if (host != null && !host.trim().equals("")) {
+//                             URI repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), "/jcr/node", null, null);
+                       // FIXME deal with remote
+                       CmsFileSystem fileSystem = null;
+                       fileSystems.put(cmsSession, fileSystem);
+                       return fileSystem;
+               } else {
+                       // FIXME send exception if it exists already
+                       CmsFileSystem fileSystem = new CmsFileSystem(this, contentRepository, cmsSession);
+                       fileSystems.put(cmsSession, fileSystem);
+                       cmsSession.addOnCloseCallback((s) -> {
+                               fileSystems.remove(s);
+                       });
+                       return fileSystem;
+               }
        }
 
        @Override
        public FileSystem getFileSystem(URI uri) {
-               // TODO Auto-generated method stub
-               return null;
+               return currentUserFileSystem();
        }
 
        @Override
        public Path getPath(URI uri) {
-               // TODO Auto-generated method stub
-               return null;
+               CmsFileSystem fileSystem = currentUserFileSystem();
+               String path = uri.getPath();
+               if (fileSystem == null)
+                       try {
+                               fileSystem = (CmsFileSystem) newFileSystem(uri, new HashMap<String, Object>());
+                       } catch (IOException e) {
+                               throw new UncheckedIOException("Could not autocreate file system for " + uri, e);
+                       }
+               return fileSystem.getPath(path);
        }
 
        @Override
@@ -53,20 +108,34 @@ public class CmsFileSystemProvider extends FileSystemProvider {
 
        @Override
        public DirectoryStream<Path> newDirectoryStream(Path dir, Filter<? super Path> filter) throws IOException {
-               // TODO Auto-generated method stub
-               return null;
+               CmsPath cmsPath = (CmsPath) dir;
+               return new ContentDirectoryStream(cmsPath, filter);
        }
 
        @Override
        public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
-               // TODO Auto-generated method stub
+               CmsPath cmsPath = (CmsPath) dir;
+               ProvidedSession contentSession = cmsPath.getContentSession();
+               if (contentSession.exists(dir.toString()))
+                       throw new FileAlreadyExistsException(dir.toString());
 
+               CmsPath parent = (CmsPath) cmsPath.getParent();
+               if (!contentSession.exists(parent.toString()))
+                       throw new NoSuchFileException(parent.toString());
+               // TODO use a proper naming context
+               QName fileName = NamespaceUtils.parsePrefixedName(dir.getFileName().toString());
+               parent.getContent().add(fileName, DName.collection);
        }
 
        @Override
        public void delete(Path path) throws IOException {
-               // TODO Auto-generated method stub
-
+               CmsPath cmsPath = (CmsPath) path;
+               ProvidedSession contentSession = cmsPath.getContentSession();
+               if (!contentSession.exists(cmsPath.toString()))
+                       throw new NoSuchFileException(cmsPath.toString());
+               contentSession.edit((s) -> {
+                       cmsPath.getContent().remove();
+               });
        }
 
        @Override
@@ -83,26 +152,23 @@ public class CmsFileSystemProvider extends FileSystemProvider {
 
        @Override
        public boolean isSameFile(Path path, Path path2) throws IOException {
-               // TODO Auto-generated method stub
-               return false;
+               // TODO make it smarter
+               return path.toString().equals(path2.toString());
        }
 
        @Override
        public boolean isHidden(Path path) throws IOException {
-               // TODO Auto-generated method stub
                return false;
        }
 
        @Override
        public FileStore getFileStore(Path path) throws IOException {
-               // TODO Auto-generated method stub
-               return null;
+               CmsFileSystem fileSystem = (CmsFileSystem) path.getFileSystem();
+               return fileSystem.getFileStore(path.toString());
        }
 
        @Override
        public void checkAccess(Path path, AccessMode... modes) throws IOException {
-               // TODO Auto-generated method stub
-
        }
 
        @Override
@@ -130,4 +196,26 @@ public class CmsFileSystemProvider extends FileSystemProvider {
 
        }
 
+       /*
+        * UTILITIES
+        */
+
+       CmsFileSystem currentUserFileSystem() {
+               CmsSession cmsSession = CurrentUser.getCmsSession();
+               return fileSystems.get(cmsSession);
+       }
+
+       void close(CmsFileSystem fileSystem) {
+               CmsSession cmsSession = fileSystem.getCmsSession();
+               CmsFileSystem ref = fileSystems.remove(cmsSession);
+               assert ref == fileSystem;
+       }
+
+       /*
+        * DEPENDENCY INJECTION
+        */
+       public void setContentRepository(ProvidedRepository contentRepository) {
+               this.contentRepository = contentRepository;
+       }
+
 }
index 504e69bff99c2e86e5438faa9bb1401f07e0d0d4..ce5e4b9e549c7dd78f3efefa99c1d14ac72b350b 100644 (file)
@@ -1,8 +1,27 @@
 package org.argeo.cms.file.provider;
 
+import org.argeo.api.acr.Content;
 import org.argeo.api.acr.fs.AbstractFsPath;
+import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.api.acr.spi.ProvidedSession;
 
 public class CmsPath extends AbstractFsPath<CmsFileSystem, CmsFileStore> {
+       final static String SEPARATOR = "/";
+
+       // lazy loaded
+       private ProvidedContent content;
+
+       ProvidedContent getContent() {
+               if (content == null) {
+                       content = getFileSystem().getContent(toString());
+               }
+               return content;
+       }
+
+       CmsPath(CmsFileSystem fileSystem, Content content) {
+               this(fileSystem, content.getPath());
+               this.content = (ProvidedContent) content;
+       }
 
        public CmsPath(CmsFileSystem filesSystem, CmsFileStore fileStore, String[] segments, boolean absolute) {
                super(filesSystem, fileStore, segments, absolute);
@@ -22,4 +41,8 @@ public class CmsPath extends AbstractFsPath<CmsFileSystem, CmsFileStore> {
                return new CmsPath(getFileSystem(), getFileStore(), segments, absolute);
        }
 
+       ProvidedSession getContentSession() {
+               return getFileSystem().getContentSession();
+       }
+
 }
diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributeView.java b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentAttributeView.java
new file mode 100644 (file)
index 0000000..9bce042
--- /dev/null
@@ -0,0 +1,24 @@
+package org.argeo.cms.file.provider;
+
+import java.nio.file.attribute.FileAttributeView;
+
+import org.argeo.api.acr.Content;
+
+public class ContentAttributeView implements FileAttributeView {
+       final static String NAME = "content";
+
+       private final Content content;
+
+       public ContentAttributeView(Content content) {
+               this.content = content;
+       }
+
+       @Override
+       public String name() {
+               return NAME;
+       }
+
+       public Content getContent() {
+               return content;
+       }
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/file/provider/ContentDirectoryStream.java b/org.argeo.cms/src/org/argeo/cms/file/provider/ContentDirectoryStream.java
new file mode 100644 (file)
index 0000000..2cddf62
--- /dev/null
@@ -0,0 +1,88 @@
+package org.argeo.cms.file.provider;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Path;
+import java.util.Iterator;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.acr.DName;
+
+public class ContentDirectoryStream implements DirectoryStream<Path> {
+       private final CmsPath dir;
+       private final Filter<? super Path> filter;
+
+       private FilesAndCollectionsIterator iterator;
+
+       public ContentDirectoryStream(CmsPath dir, Filter<? super Path> filter) {
+               this.dir = dir;
+               this.filter = filter;
+       }
+
+       @Override
+       public void close() throws IOException {
+       }
+
+       @Override
+       public Iterator<Path> iterator() {
+               if (iterator == null)
+                       iterator = new FilesAndCollectionsIterator();
+               return iterator;
+       }
+
+       static boolean isFile(Content c) {
+               return !c.get(DName.getcontenttype, String.class).isEmpty();
+       }
+
+       static boolean isDirectory(Content c) {
+               return c.isContentClass(DName.collection);
+       }
+
+       class FilesAndCollectionsIterator implements Iterator<Path> {
+               private Content next;
+               private final Iterator<Content> it;
+
+               public FilesAndCollectionsIterator() {
+                       Content content = dir.getContent();
+                       if (!content.isContentClass(DName.collection))
+                               throw new IllegalStateException("Content " + content + " is not a collection");
+                       it = content.iterator();
+                       findNext();
+               }
+
+               private void findNext() {
+                       next = null;
+                       while (it.hasNext() && next != null) {
+                               Content n = it.next();
+                               if (isFile(n) || isDirectory(n)) {
+                                       if (filter != null) {
+                                               try {
+                                                       if (filter.accept(new CmsPath(dir.getFileSystem(), n)))
+                                                               next = n;
+                                               } catch (IOException e) {
+                                                       throw new UncheckedIOException("Cannot filter " + dir, e);
+                                               }
+                                       } else {
+                                               next = n;
+                                       }
+                               }
+                       }
+               }
+
+               @Override
+               public boolean hasNext() {
+                       return next != null;
+               }
+
+               @Override
+               public Path next() {
+                       if (next == null)
+                               throw new IllegalStateException("Iterator doesn't have more elements");
+                       CmsPath p = new CmsPath(dir.getFileSystem(), next);
+                       findNext();
+                       return p;
+               }
+
+       }
+}
index 265cb34a073b4443d65316f74749332d54b67695..f9a1dc36832dab593fb28d53017679f8db5f400c 100644 (file)
@@ -90,6 +90,11 @@ public class CmsDeploymentImpl implements CmsDeployment {
        }
 
        public void createHttpContext(String contextPath, HttpHandler httpHandler, CmsAuthenticator authenticator) {
+               if (!httpExpected) {
+                       if (log.isTraceEnabled())
+                               log.warn("Ignore HTTP context " + contextPath + " as we don't provide an HTTP server");
+                       return;
+               }
                HttpContext httpContext = httpServer.join().createContext(contextPath);
                // we want to set the authenticator BEFORE the handler actually becomes active
                httpContext.setAuthenticator(authenticator);
index df8363b76aead1107005e4e0995afd6e05757d06..da2e68a436ab853cf5eb1fff834a9b7ecc378514 100644 (file)
@@ -1,21 +1,20 @@
-argeo.osgi.start.2.node=\
-org.eclipse.equinox.metatype,\
-org.eclipse.equinox.cm,\
-org.eclipse.equinox.ds,\
+argeo.osgi.start.2=\
+org.apache.felix.scr,\
 org.argeo.init
 
-argeo.osgi.start.3.node=\
+argeo.osgi.start.3=\
 org.argeo.cms,\
-org.argeo.cms.jcr,\
-org.argeo.cms.ui.rcp
+org.argeo.cms.swt.rcp,\
+org.argeo.cms.ee,\
+org.argeo.cms.lib.dbus,\
 
+argeo.osgi.start.5=\
+org.argeo.app.profile.acr.fs,\
 
-# Local
-argeo.node.repo.type=h2
-org.osgi.service.http.port=7070
-#org.osgi.service.http.port.secure=7073
 
-argeo.node.useradmin.uris=os:///
+
+#argeo.node.useradmin.uris=os:///
+argeo.directory=ipa:///
 
 #argeo.node.useradmin.uris=ldap://cn=Directory%20Manager:argeoargeo@localhost:10389/dc=example,dc=com
 
@@ -31,7 +30,10 @@ log.org.argeo=DEBUG
 
 # DON'T CHANGE BELOW
 org.eclipse.equinox.http.jetty.autostart=false
-org.osgi.framework.bootdelegation=com.sun.jndi.ldap,\
+org.osgi.framework.bootdelegation=\
+sun.security.internal.spec,\
+sun.security.provider,\
+com.sun.jndi.ldap,\
 com.sun.jndi.ldap.sasl,\
 com.sun.security.jgss,\
 com.sun.jndi.dns,\
index 4f2a405d58994d8521bc2a826d9ae19df3e0a5c1..b656accf449bcc01a6c725a59eef0d6a2ae8851a 100644 (file)
@@ -7,4 +7,5 @@
    </service>
    <reference bind="setCmsContext" cardinality="1..1" interface="org.argeo.api.cms.CmsContext" name="CmsContext" policy="static"/>
    <reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.ContentRepository" name="ContentRepository" policy="static"/>
+   <reference bind="setCmsFileSystemProvider" cardinality="1..1" interface="java.nio.file.spi.FileSystemProvider" name="CmsFileSystemProvider" policy="static"/>
 </scr:component>
index add6e9edb933a6f97d556961c35af4862cf39653..d8d0f30430657a99c77e382c1f6a76d4f9e259f6 100644 (file)
@@ -1,23 +1,28 @@
 package org.argeo.cms.swt.app;
 
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.spi.FileSystemProvider;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentRepository;
-import org.argeo.api.cms.CmsContext;
 import org.argeo.api.cms.ux.CmsUi;
 import org.argeo.api.cms.ux.CmsView;
 import org.argeo.cms.AbstractCmsApp;
 import org.argeo.cms.swt.CmsSwtUi;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.swt.auth.CmsLogin;
+import org.argeo.eclipse.ui.fs.SimpleFsBrowser;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 
 public class CmsUserApp extends AbstractCmsApp {
        private ContentRepository contentRepository;
 
+       private FileSystemProvider cmsFileSystemProvider;
+
        @Override
        public Set<String> getUiNames() {
                Set<String> uiNames = new HashSet<>();
@@ -41,6 +46,12 @@ public class CmsUserApp extends AbstractCmsApp {
                        AcrContentTreeView view = new AcrContentTreeView(cmsUi, 0, rootContent);
                        view.setLayoutData(CmsSwtUtils.fillAll());
 
+               } else if ("app".equals(uiName)) {
+                       Path rootPath = cmsFileSystemProvider.getPath(URI.create("cms:///"));
+                       SimpleFsBrowser view = new SimpleFsBrowser(parent, 0);
+                       view.setInput(rootPath);
+                       view.setLayoutData(CmsSwtUtils.fillAll());
+
                }
                return cmsUi;
        }
@@ -59,4 +70,8 @@ public class CmsUserApp extends AbstractCmsApp {
                this.contentRepository = contentRepository;
        }
 
+       public void setCmsFileSystemProvider(FileSystemProvider cmsFileSystemProvider) {
+               this.cmsFileSystemProvider = cmsFileSystemProvider;
+       }
+
 }
\ No newline at end of file