Clarify implementation-specific APIs
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / CmsContentRepository.java
index 092876d397fc2bccc37622502b0fa45ceaf37ce0..3b47c1630aa4f63a41a30d0909d2ace7b13350de 100644 (file)
@@ -1,97 +1,35 @@
 package org.argeo.cms.acr;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 
-import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentSession;
-import org.argeo.api.acr.CrName;
-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.cms.CmsAuth;
-import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsSession;
-import org.argeo.cms.acr.xml.DomContentProvider;
-import org.argeo.cms.acr.xml.DomUtils;
-import org.argeo.cms.auth.CurrentUser;
+import org.argeo.api.cms.CmsState;
+import org.argeo.api.cms.DataAdminPrincipal;
+import org.argeo.api.uuid.UuidFactory;
+import org.argeo.cms.CurrentUser;
 import org.argeo.cms.internal.runtime.CmsContextImpl;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
+import org.argeo.cms.util.CurrentSubject;
 
 /**
- * Base implementation of a {@link ProvidedRepository} integrated with a CMS.
+ * Multi-session {@link ProvidedRepository}, integrated with a CMS.
  */
-public class CmsContentRepository implements ProvidedRepository {
-       private final static CmsLog log = CmsLog.getLog(CmsContentRepository.class);
-
-       private final MountManager mountManager;
-       private final TypesManager typesManager;
-
-       private CmsContentSession systemSession;
+public class CmsContentRepository extends AbstractContentRepository {
+       public final static String RUN_BASE = "/run";
+       public final static String DIRECTORY_BASE = "/directory";
 
        private Map<CmsSession, CmsContentSession> userSessions = Collections.synchronizedMap(new HashMap<>());
 
-       // utilities
-       private TransformerFactory transformerFactory = TransformerFactory.newInstance();
-
-       public final static String ACR_MOUNT_PATH_PROPERTY = "acr.mount.path";
-
-       public CmsContentRepository() {
-               // types
-               typesManager = new TypesManager();
-               typesManager.init();
-               Set<QName> types = typesManager.listTypes();
-               for (QName type : types) {
-                       log.debug(type);
-               }
-
-               systemSession = newSystemSession();
-
-               // mounts
-               mountManager = new MountManager(systemSession);
-
-       }
-
-       protected CmsContentSession newSystemSession() {
-               LoginContext loginContext;
-               try {
-                       loginContext = new LoginContext(CmsAuth.DATA_ADMIN.getLoginContextName());
-                       loginContext.login();
-               } catch (LoginException e1) {
-                       throw new RuntimeException("Could not login as data admin", e1);
-               } finally {
-               }
-               return new CmsContentSession(this, loginContext.getSubject(), Locale.getDefault());
-       }
-
-       public void start() {
-       }
-
-       public void stop() {
-
-       }
+       private CmsState cmsState;
+       private UuidFactory uuidFactory;
 
        /*
         * REPOSITORY
@@ -104,11 +42,19 @@ public class CmsContentRepository implements ProvidedRepository {
 
        @Override
        public ContentSession get(Locale locale) {
-               // Subject subject = Subject.getSubject(AccessController.getContext());
+               if (!CmsSession.hasCmsSession(CurrentSubject.current())) {
+                       if (DataAdminPrincipal.isDataAdmin(CurrentSubject.current())) {
+                               // TODO open multiple data admin sessions?
+                               return getSystemSession();
+                       }
+                       throw new IllegalStateException("Caller must be authenticated");
+               }
+
                CmsSession cmsSession = CurrentUser.getCmsSession();
                CmsContentSession contentSession = userSessions.get(cmsSession);
                if (contentSession == null) {
-                       final CmsContentSession newContentSession = new CmsContentSession(this, cmsSession.getSubject(), locale);
+                       final CmsContentSession newContentSession = new CmsContentSession(this, cmsSession.getUuid(),
+                                       cmsSession.getSubject(), locale, uuidFactory);
                        cmsSession.addOnCloseCallback((c) -> {
                                newContentSession.close();
                                userSessions.remove(cmsSession);
@@ -118,126 +64,30 @@ public class CmsContentRepository implements ProvidedRepository {
                return contentSession;
        }
 
-       public void addProvider(ContentProvider provider) {
-               mountManager.addStructuralContentProvider(provider);
-       }
-
-       public void registerTypes(String prefix, String namespaceURI, String schemaSystemId) {
-               typesManager.registerTypes(prefix, namespaceURI, schemaSystemId);
-       }
-
-       /*
-        * FACTORIES
-        */
-       public void initRootContentProvider(Path path) {
-               try {
-//                     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-//                     factory.setNamespaceAware(true);
-//                     factory.setXIncludeAware(true);
-//                     factory.setSchema(contentTypesManager.getSchema());
-//
-                       DocumentBuilder dBuilder = typesManager.newDocumentBuilder();
-
-                       Document document;
-//                     if (path != null && Files.exists(path)) {
-//                             InputSource inputSource = new InputSource(path.toAbsolutePath().toUri().toString());
-//                             inputSource.setEncoding(StandardCharsets.UTF_8.name());
-//                             // TODO public id as well?
-//                             document = dBuilder.parse(inputSource);
-//                     } else {
-                       document = dBuilder.newDocument();
-                       Element root = document.createElementNS(CrName.CR_NAMESPACE_URI, CrName.ROOT.get().toPrefixedString());
-
-                       for (String prefix : typesManager.getPrefixes().keySet()) {
-//                             root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix,
-//                                             contentTypesManager.getPrefixes().get(prefix));
-                               DomUtils.addNamespace(root, prefix, typesManager.getPrefixes().get(prefix));
-                       }
-
-                       document.appendChild(root);
-
-                       // write it
-                       if (path != null) {
-                               try (OutputStream out = Files.newOutputStream(path)) {
-                                       writeDom(document, out);
-                               }
-                       }
-//                     }
-
-                       String mountPath = "/";
-                       DomContentProvider contentProvider = new DomContentProvider(mountPath, document);
-                       addProvider(contentProvider);
-               } catch (DOMException | IOException e) {
-                       throw new IllegalStateException("Cannot init ACR root " + path, e);
-               }
-
-       }
-
-       public void writeDom(Document document, OutputStream out) throws IOException {
+       @Override
+       protected CmsContentSession newSystemSession() {
+               LoginContext loginContext;
                try {
-                       Transformer transformer = transformerFactory.newTransformer();
-                       transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
-                       transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-
-                       DOMSource source = new DOMSource(document);
-                       typesManager.validate(source);
-                       StreamResult result = new StreamResult(out);
-                       transformer.transform(source, result);
-               } catch (TransformerException e) {
-                       throw new IOException("Cannot write dom", e);
+                       loginContext = new LoginContext(CmsAuth.DATA_ADMIN.getLoginContextName());
+                       loginContext.login();
+               } catch (LoginException e1) {
+                       throw new RuntimeException("Could not login as data admin", e1);
+               } finally {
                }
+               return new CmsContentSession(this, getCmsState().getUuid(), loginContext.getSubject(), Locale.getDefault(),
+                               uuidFactory);
        }
 
-       /*
-        * MOUNT MANAGEMENT
-        */
-
-       @Override
-       public ContentProvider getMountContentProvider(Content mountPoint, boolean initialize, QName... types) {
-               String mountPath = mountPoint.getPath();
-               // TODO check consistency with types
-
-               return mountManager.getOrAddMountedProvider(mountPath, (path) -> {
-                       DocumentBuilder dBuilder = typesManager.newDocumentBuilder();
-                       Document document;
-                       if (initialize) {
-                               QName firstType = types[0];
-                               document = dBuilder.newDocument();
-                               String prefix = ((ProvidedContent) mountPoint).getSession().getPrefix(firstType.getNamespaceURI());
-                               Element root = document.createElementNS(firstType.getNamespaceURI(),
-                                               prefix + ":" + firstType.getLocalPart());
-                               DomUtils.addNamespace(root, prefix, firstType.getNamespaceURI());
-                               document.appendChild(root);
-                       } else {
-                               try (InputStream in = mountPoint.open(InputStream.class)) {
-                                       document = dBuilder.parse(in);
-                                       // TODO check consistency with types
-                               } catch (IOException | SAXException e) {
-                                       throw new IllegalStateException("Cannot load mount from " + mountPoint, e);
-                               }
-                       }
-                       DomContentProvider contentProvider = new DomContentProvider(path, document);
-                       return contentProvider;
-               });
-       }
-
-       @Override
-       public boolean shouldMount(QName... types) {
-               if (types.length == 0)
-                       return false;
-               QName firstType = types[0];
-               Set<QName> registeredTypes = typesManager.listTypes();
-               if (registeredTypes.contains(firstType))
-                       return true;
-               return false;
+       protected CmsState getCmsState() {
+               return cmsState;
        }
 
-       MountManager getMountManager() {
-               return mountManager;
+       public void setCmsState(CmsState cmsState) {
+               this.cmsState = cmsState;
        }
 
-       TypesManager getTypesManager() {
-               return typesManager;
+       public void setUuidFactory(UuidFactory uuidFactory) {
+               this.uuidFactory = uuidFactory;
        }
 
 }