From 6832a0807e45e70c23b22598874807a3a9373475 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Fri, 16 Sep 2022 07:43:53 +0200 Subject: [PATCH] Use WebDav names --- .../argeo/cms/jcr/acr/JcrContentUtils.java | 5 ++- .../src/org/argeo/api/acr/CrName.java | 14 +++--- .../src/org/argeo/api/acr/DName.java | 45 +++++++++++++++++++ .../org/argeo/cms/acr/CmsContentSession.java | 3 +- .../src/org/argeo/cms/acr/ContentUtils.java | 5 ++- .../acr/directory/HierarchyUnitContent.java | 3 +- .../src/org/argeo/cms/acr/fs/FsContent.java | 24 +++++----- .../src/org/argeo/cms/dav/DavXmlElement.java | 1 + .../internal/runtime/CmsAcrHttpHandler.java | 10 ++--- 9 files changed, 81 insertions(+), 29 deletions(-) create mode 100644 org.argeo.api.acr/src/org/argeo/api/acr/DName.java diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java index 558086b55..25e54b302 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentUtils.java @@ -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 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); diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/CrName.java b/org.argeo.api.acr/src/org/argeo/api/acr/CrName.java index 3fe3462b9..f61833507 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/CrName.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/CrName.java @@ -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 index 000000000..162ae919f --- /dev/null +++ b/org.argeo.api.acr/src/org/argeo/api/acr/DName.java @@ -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; + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java index ba7dfa32d..34d683605 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java @@ -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; diff --git a/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java b/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java index e1fbcb1a9..48b047c29 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java @@ -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; } } diff --git a/org.argeo.cms/src/org/argeo/cms/acr/directory/HierarchyUnitContent.java b/org.argeo.cms/src/org/argeo/cms/acr/directory/HierarchyUnitContent.java index 9ded5ee7b..1e4aad773 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/directory/HierarchyUnitContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/directory/HierarchyUnitContent.java @@ -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 getContentClasses() { List contentClasses = super.getContentClasses(); - contentClasses.add(CrName.collection.qName()); + contentClasses.add(DName.collection.qName()); return contentClasses; } diff --git a/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java b/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java index f0c733857..2d30cedec 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java @@ -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 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 getContentClasses() { List res = new ArrayList<>(); - List value = getMultiple(CrName.cc.qName(), String.class); + List 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 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 CompletableFuture write(Class 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)) { diff --git a/org.argeo.cms/src/org/argeo/cms/dav/DavXmlElement.java b/org.argeo.cms/src/org/argeo/cms/dav/DavXmlElement.java index a3929a02b..452a24f44 100644 --- a/org.argeo.cms/src/org/argeo/cms/dav/DavXmlElement.java +++ b/org.argeo.cms/src/org/argeo/cms/dav/DavXmlElement.java @@ -10,6 +10,7 @@ public enum DavXmlElement implements QNamed { response, // multistatus, // href, // + /** MUST be the same as DName.collection */ collection, // prop, // resourcetype, // diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java index 92da1b0c2..11fc1a366 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java @@ -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 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 size = content.get(CrName.size, Long.class); + Optional 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()); -- 2.30.2