Code clean up
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / CmsContentSession.java
index 318080509b02ab624e3bf18c3feb124a7f8817db..73adc7012860c99503bacf683488d6b0c2fb0235 100644 (file)
@@ -1,47 +1,57 @@
 package org.argeo.cms.acr;
 
-import java.util.Iterator;
+import java.util.HashSet;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
-import java.util.TreeSet;
+import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
 import java.util.function.Consumer;
-import java.util.stream.Collectors;
 
 import javax.security.auth.Subject;
 
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentSession;
-import org.argeo.api.acr.NamespaceUtils;
+import org.argeo.api.acr.DName;
 import org.argeo.api.acr.spi.ContentProvider;
 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.uuid.UuidFactory;
 import org.argeo.cms.acr.xml.DomContentProvider;
 
 /** Implements {@link ProvidedSession}. */
 class CmsContentSession implements ProvidedSession {
-       final private CmsContentRepository contentRepository;
+       final private AbstractContentRepository contentRepository;
 
+       private final UUID uuid;
        private Subject subject;
        private Locale locale;
 
+       private UuidFactory uuidFactory;
+
        private CompletableFuture<ProvidedSession> closed = new CompletableFuture<>();
 
        private CompletableFuture<ContentSession> edition;
 
-       private Set<ContentProvider> modifiedProviders = new TreeSet<>();
+       private Set<ContentProvider> modifiedProviders = new HashSet<>();
+
+       private Content sessionRunDir;
 
-       public CmsContentSession(CmsContentRepository contentRepository, Subject subject, Locale locale) {
+       public CmsContentSession(AbstractContentRepository contentRepository, UUID uuid, Subject subject, Locale locale,
+                       UuidFactory uuidFactory) {
                this.contentRepository = contentRepository;
                this.subject = subject;
                this.locale = locale;
+               this.uuid = uuid;
+               this.uuidFactory = uuidFactory;
        }
 
        public void close() {
                closed.complete(this);
+
+               if (sessionRunDir != null)
+                       sessionRunDir.remove();
        }
 
        @Override
@@ -51,13 +61,30 @@ class CmsContentSession implements ProvidedSession {
 
        @Override
        public Content get(String path) {
+               if (!path.startsWith(ContentUtils.ROOT_SLASH))
+                       throw new IllegalArgumentException(path + " is not an absolute path");
+               ContentProvider contentProvider = contentRepository.getMountManager().findContentProvider(path);
+               String mountPath = contentProvider.getMountPath();
+               String relativePath = extractRelativePath(mountPath, path);
+               ProvidedContent content = contentProvider.get(CmsContentSession.this, relativePath);
+               return content;
+       }
+
+       @Override
+       public boolean exists(String path) {
+               if (!path.startsWith(ContentUtils.ROOT_SLASH))
+                       throw new IllegalArgumentException(path + " is not an absolute path");
                ContentProvider contentProvider = contentRepository.getMountManager().findContentProvider(path);
                String mountPath = contentProvider.getMountPath();
+               String relativePath = extractRelativePath(mountPath, path);
+               return contentProvider.exists(this, relativePath);
+       }
+
+       private String extractRelativePath(String mountPath, String path) {
                String relativePath = path.substring(mountPath.length());
                if (relativePath.length() > 0 && relativePath.charAt(0) == '/')
                        relativePath = relativePath.substring(1);
-               ProvidedContent content = contentProvider.get(CmsContentSession.this, mountPath, relativePath);
-               return content;
+               return relativePath;
        }
 
        @Override
@@ -75,6 +102,10 @@ class CmsContentSession implements ProvidedSession {
                return contentRepository;
        }
 
+       public UuidFactory getUuidFactory() {
+               return uuidFactory;
+       }
+
        /*
         * MOUNT MANAGEMENT
         */
@@ -87,34 +118,24 @@ class CmsContentSession implements ProvidedSession {
        }
 
        /*
-        * NAMESPACE CONTEXT
+        * EDITION
         */
-
-       @Override
-       public String getNamespaceURI(String prefix) {
-               return NamespaceUtils.getNamespaceURI((p) -> contentRepository.getTypesManager().getPrefixes().get(p), prefix);
-       }
-
-       @Override
-       public Iterator<String> getPrefixes(String namespaceURI) {
-               return NamespaceUtils.getPrefixes((ns) -> contentRepository.getTypesManager().getPrefixes().entrySet().stream()
-                               .filter(e -> e.getValue().equals(ns)).map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet()),
-                               namespaceURI);
-       }
-
        @Override
        public CompletionStage<ContentSession> edit(Consumer<ContentSession> work) {
                edition = CompletableFuture.supplyAsync(() -> {
                        work.accept(this);
                        return this;
                }).thenApply((s) -> {
-                       // TODO optimise
-                       for (ContentProvider provider : modifiedProviders) {
-                               if (provider instanceof DomContentProvider) {
-                                       ((DomContentProvider) provider).persist(s);
+                       synchronized (CmsContentSession.this) {
+                               // TODO optimise
+                               for (ContentProvider provider : modifiedProviders) {
+                                       if (provider instanceof DomContentProvider) {
+                                               ((DomContentProvider) provider).persist(s);
+                                       }
                                }
+                               modifiedProviders.clear();
+                               return s;
                        }
-                       return s;
                });
                return edition.minimalCompletionStage();
        }
@@ -125,11 +146,31 @@ class CmsContentSession implements ProvidedSession {
        }
 
        @Override
-       public void notifyModification(ProvidedContent content) {
+       public synchronized void notifyModification(ProvidedContent content) {
                ContentProvider contentProvider = content.getProvider();
                modifiedProviders.add(contentProvider);
        }
 
+       @Override
+       public UUID getUuid() {
+               return uuid;
+       }
+
+       @Override
+       public Content getSessionRunDir() {
+               if (sessionRunDir == null) {
+                       String runDirPath = CmsContentRepository.RUN_BASE + '/' + uuid.toString();
+                       if (exists(runDirPath))
+                               sessionRunDir = get(runDirPath);
+                       else {
+                               Content runDir = get(CmsContentRepository.RUN_BASE);
+                               // TODO deal with no run dir available?
+                               sessionRunDir = runDir.add(uuid.toString(), DName.collection.qName());
+                       }
+               }
+               return sessionRunDir;
+       }
+
 //             @Override
 //             public String findNamespace(String prefix) {
 //                     return prefixes.get(prefix);