Use WebDav names
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 16 Sep 2022 05:43:53 +0000 (07:43 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 16 Sep 2022 05:43:53 +0000 (07:43 +0200)
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java
org.argeo.api.acr/src/org/argeo/api/acr/CrName.java
org.argeo.api.acr/src/org/argeo/api/acr/DName.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java
org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java
org.argeo.cms/src/org/argeo/cms/acr/directory/HierarchyUnitContent.java
org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java
org.argeo.cms/src/org/argeo/cms/dav/DavXmlElement.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java

index 558086b5558f291dc47653d94730a82a1d57d920..25e54b302678b602c334cd22f7bb3ce78e9a8b7a 100644 (file)
@@ -31,6 +31,7 @@ import javax.xml.transform.dom.DOMSource;
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentName;
 import org.argeo.api.acr.CrName;
+import org.argeo.api.acr.DName;
 import org.argeo.api.acr.NamespaceUtils;
 import org.argeo.api.acr.spi.ProvidedContent;
 import org.argeo.api.acr.spi.ProvidedSession;
@@ -64,13 +65,13 @@ public class JcrContentUtils {
                                                file.write(InputStream.class).complete(in);
                                        }
                                } else if (node.isNodeType(NodeType.NT_FOLDER)) {
-                                       Content subCol = collection.add(name, CrName.collection.qName());
+                                       Content subCol = collection.add(name, DName.collection.qName());
                                        copyFiles(node, subCol, additionalCollectionTypes);
                                } else {
                                        List<QName> contentClasses = typesAsContentClasses(node, jcrNamespaceContext);
                                        for (String collectionType : additionalCollectionTypes) {
                                                if (node.isNodeType(collectionType)) {
-                                                       contentClasses.add(CrName.collection.qName());
+                                                       contentClasses.add(DName.collection.qName());
                                                        Content subCol = collection.add(name,
                                                                        contentClasses.toArray(new QName[contentClasses.size()]));
                                                        setAttributes(node, subCol, jcrNamespaceContext);
index 3fe3462b97fc6f7b1b0459e242efc14a9135c874..f618335077eadbcd093273cb584ed1d9520449fc 100644 (file)
@@ -6,24 +6,24 @@ public enum CrName implements QNamed {
        /*
         * TYPES
         */
-       collection, // a collection type
+//     collection, // a collection type
 
        /*
         * ATTRIBUTES
         */
        uuid, // the UUID of a content
        mount, // a mount point
-       cc, // content class
+//     cc, // content class
 
        /*
         * ATTRIBUTES FROM FILE SEMANTICS
         */
-       creationTime, //
-       lastModifiedTime, //
-       size, //
+//     creationTime, //
+//     lastModifiedTime, //
+//     size, //
        fileKey, //
-       owner, //
-       group, //
+//     owner, //
+//     group, //
        permissions, //
 
        /*
diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/DName.java b/org.argeo.api.acr/src/org/argeo/api/acr/DName.java
new file mode 100644 (file)
index 0000000..162ae91
--- /dev/null
@@ -0,0 +1,45 @@
+package org.argeo.api.acr;
+
+/**
+ * Name for core concepts with the same semantics as defined in the WebDav
+ * standard and extensions.
+ * 
+ * @see http://www.webdav.org/specs/rfc4918.html
+ * @see http://www.webdav.org/specs/rfc3744.html
+ */
+public enum DName implements QNamed
+
+{
+       // RFC4918 (WebDav) properties used as CR attr
+       creationdate, //
+       displayname, //
+       getcontentlanguage, //
+       getcontentlength, //
+       getcontenttype, //
+       getetag, //
+       getlastmodified, //
+       resourcetype, //
+
+       // RFC4918 (WebDav) value used as CR class
+       collection, //
+
+       // RFC3744 (ACL) properties uase as CR attr
+       owner, //
+       group, //
+       //
+       ;
+
+       public final static String WEBDAV_NAMESPACE_URI = "DAV:";
+       public final static String WEBDAV_DEFAULT_PREFIX = "D";
+
+       @Override
+       public String getNamespace() {
+               return WEBDAV_NAMESPACE_URI;
+       }
+
+       @Override
+       public String getDefaultPrefix() {
+               return WEBDAV_DEFAULT_PREFIX;
+       }
+
+}
index ba7dfa32d59f7244bef7e417f39c66105c216545..34d683605ac4e81240be687a04e4371f7e325d79 100644 (file)
@@ -13,6 +13,7 @@ import javax.security.auth.Subject;
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentSession;
 import org.argeo.api.acr.CrName;
+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;
@@ -180,7 +181,7 @@ class CmsContentSession implements ProvidedSession {
                        else {
                                Content runDir = get(CmsContentRepository.RUN_BASE);
                                // TODO deal with no run dir available?
-                               sessionRunDir = runDir.add(uuid.toString(), CrName.collection.qName());
+                               sessionRunDir = runDir.add(uuid.toString(),DName.collection.qName());
                        }
                }
                return sessionRunDir;
index e1fbcb1a9f440157b818a5c12dc8cf264be75c11..48b047c295359434450bface9438b986e83aea9b 100644 (file)
@@ -14,6 +14,7 @@ import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentRepository;
 import org.argeo.api.acr.ContentSession;
 import org.argeo.api.acr.CrName;
+import org.argeo.api.acr.DName;
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.cms.CmsUserManager;
 import org.argeo.osgi.useradmin.UserDirectory;
@@ -135,7 +136,7 @@ public class ContentUtils {
        public static Content createCollections(ContentSession session, String path) {
                if (session.exists(path)) {
                        Content content = session.get(path);
-                       if (!content.isContentClass(CrName.collection.qName())) {
+                       if (!content.isContentClass(DName.collection.qName())) {
                                throw new IllegalStateException("Content " + path + " already exists, but is not a collection");
                        } else {
                                return content;
@@ -143,7 +144,7 @@ public class ContentUtils {
                } else {
                        String[] parentPath = getParentPath(path);
                        Content parent = createCollections(session, parentPath[0]);
-                       Content content = parent.add(parentPath[1], CrName.collection.qName());
+                       Content content = parent.add(parentPath[1], DName.collection.qName());
                        return content;
                }
        }
index 9ded5ee7b38157fe0b3942d812937f37dfb86ac4..1e4aad77328a7805df4732e51935eafc71e5a047 100644 (file)
@@ -11,6 +11,7 @@ import javax.xml.namespace.QName;
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentName;
 import org.argeo.api.acr.CrName;
+import org.argeo.api.acr.DName;
 import org.argeo.api.acr.spi.ProvidedSession;
 import org.argeo.osgi.useradmin.UserDirectory;
 import org.argeo.util.directory.Directory;
@@ -69,7 +70,7 @@ class HierarchyUnitContent extends AbstractDirectoryContent {
        @Override
        public List<QName> getContentClasses() {
                List<QName> contentClasses = super.getContentClasses();
-               contentClasses.add(CrName.collection.qName());
+               contentClasses.add(DName.collection.qName());
                return contentClasses;
        }
 
index f0c7338579c5f67f319c5122c06a2cebc072948e..2d30cedec3b8f936ae395e175fd8ec539d4cd7c2 100644 (file)
@@ -36,6 +36,7 @@ import org.argeo.api.acr.ContentName;
 import org.argeo.api.acr.ContentResourceException;
 import org.argeo.api.acr.CrAttributeType;
 import org.argeo.api.acr.CrName;
+import org.argeo.api.acr.DName;
 import org.argeo.api.acr.NamespaceUtils;
 import org.argeo.api.acr.spi.ContentProvider;
 import org.argeo.api.acr.spi.ProvidedContent;
@@ -55,14 +56,15 @@ public class FsContent extends AbstractContent implements ProvidedContent {
        private static final Map<QName, String> POSIX_KEYS;
        static {
                BASIC_KEYS = new HashMap<>();
-               BASIC_KEYS.put(CrName.creationTime.qName(), "basic:creationTime");
-               BASIC_KEYS.put(CrName.lastModifiedTime.qName(), "basic:lastModifiedTime");
-               BASIC_KEYS.put(CrName.size.qName(), "basic:size");
+               BASIC_KEYS.put(DName.creationdate.qName(), "basic:creationTime");
+               BASIC_KEYS.put(DName.getlastmodified.qName(), "basic:lastModifiedTime");
+               BASIC_KEYS.put(DName.getcontentlength.qName(), "basic:size");
+
                BASIC_KEYS.put(CrName.fileKey.qName(), "basic:fileKey");
 
                POSIX_KEYS = new HashMap<>(BASIC_KEYS);
-               POSIX_KEYS.put(CrName.owner.qName(), "owner:owner");
-               POSIX_KEYS.put(CrName.group.qName(), "posix:group");
+               POSIX_KEYS.put(DName.owner.qName(), "owner:owner");
+               POSIX_KEYS.put(DName.group.qName(), "posix:group");
                POSIX_KEYS.put(CrName.permissions.qName(), "posix:permissions");
        }
 
@@ -284,7 +286,7 @@ public class FsContent extends AbstractContent implements ProvidedContent {
                FsContent fsContent;
                try {
                        Path newPath = path.resolve(NamespaceUtils.toPrefixedName(provider, name));
-                       if (ContentName.contains(classes, CrName.collection.qName()))
+                       if (ContentName.contains(classes, DName.collection.qName()))
                                Files.createDirectory(newPath);
                        else
                                Files.createFile(newPath);
@@ -360,13 +362,13 @@ public class FsContent extends AbstractContent implements ProvidedContent {
        @Override
        public List<QName> getContentClasses() {
                List<QName> res = new ArrayList<>();
-               List<String> value = getMultiple(CrName.cc.qName(), String.class);
+               List<String> value = getMultiple(DName.resourcetype.qName(), String.class);
                for (String s : value) {
                        QName name = NamespaceUtils.parsePrefixedName(provider, s);
                        res.add(name);
                }
                if (Files.isDirectory(path))
-                       res.add(CrName.collection.qName());
+                       res.add(DName.collection.qName());
                return res;
        }
 
@@ -374,14 +376,14 @@ public class FsContent extends AbstractContent implements ProvidedContent {
        public void addContentClasses(QName... contentClass) {
                List<String> toWrite = new ArrayList<>();
                for (QName cc : getContentClasses()) {
-                       if (cc.equals(CrName.collection.qName()))
+                       if (cc.equals(DName.collection.qName()))
                                continue; // skip
                        toWrite.add(NamespaceUtils.toPrefixedName(provider, cc));
                }
                for (QName cc : contentClass) {
                        toWrite.add(NamespaceUtils.toPrefixedName(provider, cc));
                }
-               put(CrName.cc.qName(), toWrite);
+               put(DName.resourcetype.qName(), toWrite);
        }
 
        /*
@@ -398,7 +400,7 @@ public class FsContent extends AbstractContent implements ProvidedContent {
         */
        @SuppressWarnings("unchecked")
        public <A> CompletableFuture<A> write(Class<A> clss) {
-               if (isContentClass(CrName.collection.qName())) {
+               if (isContentClass(DName.collection.qName())) {
                        throw new IllegalStateException("Cannot directly write to a collection");
                }
                if (InputStream.class.isAssignableFrom(clss)) {
index a3929a02beb18be796f55fac30b037d511311cc1..452a24f446201daf9fa8b4ca55fbee7f1470990a 100644 (file)
@@ -10,6 +10,7 @@ public enum DavXmlElement implements QNamed {
        response, //
        multistatus, //
        href, //
+       /** MUST be the same as DName.collection */
        collection, //
        prop, //
        resourcetype, //
index 92da1b0c298ed3524087cf308ff0703ddc3af173..11fc1a3667140ea5b444947cd83dab98112f1642 100644 (file)
@@ -15,7 +15,7 @@ import javax.xml.namespace.QName;
 
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentSession;
-import org.argeo.api.acr.CrName;
+import org.argeo.api.acr.DName;
 import org.argeo.api.acr.spi.ProvidedRepository;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.acr.ContentUtils;
@@ -95,7 +95,7 @@ public class CmsAcrHttpHandler implements HttpHandler {
                DavResponse davResponse = new DavResponse();
                String href = CmsConstants.PATH_API_ACR + content.getPath();
                davResponse.setHref(href);
-               if (content.hasContentClass(CrName.collection))
+               if (content.hasContentClass(DName.collection))
                        davResponse.setCollection(true);
                if (davPropfind.isAllprop()) {
                        for (Map.Entry<QName, Object> entry : content.entrySet()) {
@@ -124,7 +124,7 @@ public class CmsAcrHttpHandler implements HttpHandler {
                consumer.accept(davResponse);
 
                // recurse only on collections
-               if (content.hasContentClass(CrName.collection)) {
+               if (content.hasContentClass(DName.collection)) {
                        if (davPropfind.getDepth() == DavDepth.DEPTH_INFINITY
                                        || (davPropfind.getDepth() == DavDepth.DEPTH_1 && currentDepth == 0)) {
                                for (Content child : content) {
@@ -136,7 +136,7 @@ public class CmsAcrHttpHandler implements HttpHandler {
 
        protected void processMapEntry(DavResponse davResponse, QName key, Object value) {
                // ignore content classes
-               if (CrName.cc.qName().equals(key))
+               if (DName.resourcetype.qName().equals(key))
                        return;
                String str;
                if (value instanceof Collection) {
@@ -157,7 +157,7 @@ public class CmsAcrHttpHandler implements HttpHandler {
                ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(),
                                new RemoteAuthHttpExchange(exchange));
                Content content = session.get(ContentUtils.ROOT_SLASH + relativePath);
-               Optional<Long> size = content.get(CrName.size, Long.class);
+               Optional<Long> size = content.get(DName.getcontentlength, Long.class);
                try (InputStream in = content.open(InputStream.class)) {
                        exchange.sendResponseHeaders(HttpResponseStatus.OK.getCode(), size.orElse(0l));
                        StreamUtils.copy(in, exchange.getResponseBody());