From: Mathieu Baudier Date: Sun, 10 Mar 2024 12:15:11 +0000 (+0100) Subject: Clarify ACR API X-Git-Tag: v2.3.28~11 X-Git-Url: http://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=c7b612ca9bd7df43b0bec37c8abcae846587c978 Clarify ACR API --- diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/Content.java b/org.argeo.api.acr/src/org/argeo/api/acr/Content.java index d6af2fe3d..c69e76a19 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/Content.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/Content.java @@ -4,7 +4,6 @@ import static org.argeo.api.acr.NamespaceUtils.unqualified; import java.io.Closeable; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -17,74 +16,17 @@ import javax.xml.namespace.QName; * whose nodes are named. */ public interface Content extends QualifiedData { - /** The base of a repository path. */ - String ROOT_PATH = "/"; + /** The path separator: '/' */ + char PATH_SEPARATOR = '/'; - QName getName(); + /** The base of a repository path. */ + String ROOT_PATH = Character.toString(PATH_SEPARATOR); String getPath(); - Content getParent(); - - /* - * ATTRIBUTES OPERATIONS - */ - - Optional get(QName key, Class clss); - - Class getType(QName key); - - boolean isMultiple(QName key); - - List getMultiple(QName key, Class clss); - - /* - * ATTRIBUTES OPERATION HELPERS - */ - default boolean containsKey(QNamed key) { - return containsKey(key.qName()); - } - - default Optional get(QNamed key, Class clss) { - return get(key.qName(), clss); - } - - default Object get(QNamed key) { - return get(key.qName()); - } - - default Object put(QNamed key, Object value) { - return put(key.qName(), value); - } - - default Object remove(QNamed key) { - return remove(key.qName()); - } - - // TODO do we really need the helpers below? - - default Object get(String key) { - return get(unqualified(key)); - } - - default Object put(String key, Object value) { - return put(unqualified(key), value); - } - - default Object remove(String key) { - return remove(unqualified(key)); - } - - @SuppressWarnings("unchecked") - default List getMultiple(QName key) { - Class type; - try { - type = (Class) getType(key); - } catch (ClassCastException e) { - throw new IllegalArgumentException("Requested type is not the default type"); - } - List res = getMultiple(key, type); - return res; + /** MUST be {@link Content#PATH_SEPARATOR}. */ + default char getPathSeparator() { + return PATH_SEPARATOR; } /* @@ -165,21 +107,9 @@ public interface Content extends QualifiedData { return res; } - /* - * SIBLINGS - */ - - default int getSiblingIndex() { - return 1; - } - /* * DEFAULT METHODS */ - default A adapt(Class clss) { - throw new UnsupportedOperationException("Cannot adapt content " + this + " to " + clss.getName()); - } - default C open(Class clss) throws IOException { throw new UnsupportedOperationException("Cannot open content " + this + " as " + clss.getName()); } @@ -191,19 +121,6 @@ public interface Content extends QualifiedData { /* * CHILDREN */ - - default boolean hasChild(QName name) { - for (Content child : this) { - if (child.getName().equals(name)) - return true; - } - return false; - } - - default boolean hasChild(QNamed name) { - return hasChild(name.qName()); - } - default Content anyOrAddChild(QName name, QName... classes) { Content child = anyChild(name); if (child != null) @@ -215,92 +132,10 @@ public interface Content extends QualifiedData { return anyOrAddChild(unqualified(name), classes); } - /** Any child with this name, or null if there is none */ - default Content anyChild(QName name) { - for (Content child : this) { - if (child.getName().equals(name)) - return child; - } - return null; - } - - default List children(QName name) { - List res = new ArrayList<>(); - for (Content child : this) { - if (child.getName().equals(name)) - res.add(child); - } - return res; - } - - default List children(QNamed name) { - return children(name.qName()); - } - - default Optional soleChild(QNamed name) { - return soleChild(name.qName()); - } - - default Optional soleChild(QName name) { - List res = children(name); - if (res.isEmpty()) - return Optional.empty(); - if (res.size() > 1) - throw new IllegalStateException(this + " has multiple children with name " + name); - return Optional.of(res.get(0)); - } - default Content soleOrAddChild(QName name, QName... classes) { return soleChild(name).orElseGet(() -> this.add(name, classes)); } - default Content child(QName name) { - return soleChild(name).orElseThrow(); - } - - default Content child(QNamed name) { - return child(name.qName()); - } - - /* - * ATTR AS STRING - */ - /** - * Convenience method returning an attribute as a {@link String}. - * - * @param key the attribute name - * @return the attribute value as a {@link String} or null. - * - * @see Object#toString() - */ - default String attr(QName key) { - return get(key, String.class).orElse(null); - } - - /** - * Convenience method returning an attribute as a {@link String}. - * - * @param key the attribute name - * @return the attribute value as a {@link String} or null. - * - * @see Object#toString() - */ - default String attr(QNamed key) { - return attr(key.qName()); - } - - /** - * Convenience method returning an attribute as a {@link String}. - * - * @param key the attribute name - * @return the attribute value as a {@link String} or null. - * - * @see Object#toString() - */ - default String attr(String key) { - return attr(unqualified(key)); - } - /* * CONTEXT */ diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/QualifiedData.java b/org.argeo.api.acr/src/org/argeo/api/acr/QualifiedData.java index 89ab665df..b2c7bbb90 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/QualifiedData.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/QualifiedData.java @@ -1,8 +1,187 @@ package org.argeo.api.acr; +import static org.argeo.api.acr.NamespaceUtils.unqualified; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + import javax.xml.namespace.QName; /** A {@link StructuredData} whose attributes have qualified keys. */ public interface QualifiedData> extends StructuredData { + QName getName(); + + CHILD getParent(); + + /* + * ATTRIBUTES OPERATIONS + */ + + Optional get(QName key, Class clss); + + Class getType(QName key); + + boolean isMultiple(QName key); + + List getMultiple(QName key, Class clss); + + /* + * PATH + */ + char getPathSeparator(); + + /* + * ATTRIBUTES OPERATION HELPERS + */ + default boolean containsKey(QNamed key) { + return containsKey(key.qName()); + } + + default Optional get(QNamed key, Class clss) { + return get(key.qName(), clss); + } + + default Object get(QNamed key) { + return get(key.qName()); + } + + default Object put(QNamed key, Object value) { + return put(key.qName(), value); + } + + default Object remove(QNamed key) { + return remove(key.qName()); + } + + // TODO do we really need the helpers below? + + default Object get(String key) { + return get(unqualified(key)); + } + + default Object put(String key, Object value) { + return put(unqualified(key), value); + } + + default Object remove(String key) { + return remove(unqualified(key)); + } + + @SuppressWarnings("unchecked") + default List getMultiple(QName key) { + Class type; + try { + type = (Class) getType(key); + } catch (ClassCastException e) { + throw new IllegalArgumentException("Requested type is not the default type"); + } + List res = getMultiple(key, type); + return res; + } + + /* + * CHILDREN + */ + + default boolean hasChild(QName name) { + for (CHILD child : this) { + if (child.getName().equals(name)) + return true; + } + return false; + } + + default boolean hasChild(QNamed name) { + return hasChild(name.qName()); + } + + /** Any child with this name, or null if there is none */ + default CHILD anyChild(QName name) { + for (CHILD child : this) { + if (child.getName().equals(name)) + return child; + } + return null; + } + + default List children(QName name) { + List res = new ArrayList<>(); + for (CHILD child : this) { + if (child.getName().equals(name)) + res.add(child); + } + return res; + } + + default List children(QNamed name) { + return children(name.qName()); + } + + default Optional soleChild(QNamed name) { + return soleChild(name.qName()); + } + + default Optional soleChild(QName name) { + List res = children(name); + if (res.isEmpty()) + return Optional.empty(); + if (res.size() > 1) + throw new IllegalStateException(this + " has multiple children with name " + name); + return Optional.of(res.get(0)); + } + + default CHILD child(QName name) { + return soleChild(name).orElseThrow(); + } + + default CHILD child(QNamed name) { + return child(name.qName()); + } + + /* + * ATTR AS STRING + */ + /** + * Convenience method returning an attribute as a {@link String}. + * + * @param key the attribute name + * @return the attribute value as a {@link String} or null. + * + * @see Object#toString() + */ + default String attr(QName key) { + return get(key, String.class).orElse(null); + } + + /** + * Convenience method returning an attribute as a {@link String}. + * + * @param key the attribute name + * @return the attribute value as a {@link String} or null. + * + * @see Object#toString() + */ + default String attr(QNamed key) { + return attr(key.qName()); + } + + /** + * Convenience method returning an attribute as a {@link String}. + * + * @param key the attribute name + * @return the attribute value as a {@link String} or null. + * + * @see Object#toString() + */ + default String attr(String key) { + return attr(unqualified(key)); + } + /* + * SIBLINGS + */ + default int getSiblingIndex() { + return 1; + } } diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/RuntimeNamespaceContext.java b/org.argeo.api.acr/src/org/argeo/api/acr/RuntimeNamespaceContext.java index dc4749338..871275a48 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/RuntimeNamespaceContext.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/RuntimeNamespaceContext.java @@ -23,6 +23,8 @@ public class RuntimeNamespaceContext implements NamespaceContext { public final static String XSD_DEFAULT_PREFIX = "xs"; public final static String XSD_INSTANCE_DEFAULT_PREFIX = "xsi"; + private final static RuntimeNamespaceContext INSTANCE = new RuntimeNamespaceContext(); + private NavigableMap prefixes = new TreeMap<>(); private NavigableMap namespaces = new TreeMap<>(); @@ -58,7 +60,6 @@ public class RuntimeNamespaceContext implements NamespaceContext { /* * STATIC */ - private final static RuntimeNamespaceContext INSTANCE = new RuntimeNamespaceContext(); static { // Standard @@ -66,6 +67,7 @@ public class RuntimeNamespaceContext implements NamespaceContext { register(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE); // Common + // FIXME shouldn't it be registered externally? register(XMLConstants.W3C_XML_SCHEMA_NS_URI, XSD_DEFAULT_PREFIX); register(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XSD_INSTANCE_DEFAULT_PREFIX); diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/StructuredData.java b/org.argeo.api.acr/src/org/argeo/api/acr/StructuredData.java index 4e38cf62d..770823222 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/StructuredData.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/StructuredData.java @@ -4,5 +4,10 @@ import java.util.Map; /** A hierarchical structure of unnamed mappings. */ public interface StructuredData extends Map, Iterable { - + /* + * DEFAULT METHODS + */ + default A adapt(Class clss) { + throw new UnsupportedOperationException("Cannot adapt content " + this + " to " + clss.getName()); + } } diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedContent.java b/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedContent.java index f1e5aaaa8..5e7182236 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedContent.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedContent.java @@ -41,10 +41,10 @@ public interface ProvidedContent extends Content { @Override default Optional getContent(String path) { String absolutePath; - if (path.startsWith(Content.ROOT_PATH)) {// absolute + if (path.startsWith(ROOT_PATH)) {// absolute absolutePath = path; } else {// relative - absolutePath = getPath() + '/' + path; + absolutePath = getPath() + PATH_SEPARATOR + path; } return getSession().exists(absolutePath) ? Optional.of(getSession().get(absolutePath)) : Optional.empty(); } diff --git a/org.argeo.cms.ux/src/org/argeo/cms/ux/acr/ContentCmsEditable.java b/org.argeo.cms.ux/src/org/argeo/cms/ux/acr/ContentCmsEditable.java index 7278c2857..870211f76 100644 --- a/org.argeo.cms.ux/src/org/argeo/cms/ux/acr/ContentCmsEditable.java +++ b/org.argeo.cms.ux/src/org/argeo/cms/ux/acr/ContentCmsEditable.java @@ -5,7 +5,7 @@ import org.argeo.api.acr.spi.ContentProvider; import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.acr.spi.ProvidedSession; import org.argeo.api.cms.ux.CmsEditable; -import org.argeo.cms.acr.ContentUtils; +import org.argeo.cms.acr.CmsContent; import org.argeo.cms.ux.AbstractCmsEditable; /** {@link CmsEditable} semantics for a {@link Content}. */ @@ -22,7 +22,7 @@ public class ContentCmsEditable extends AbstractCmsEditable { canEdit = providedContent.canEdit(); session = providedContent.getSession(); provider = providedContent.getProvider(); - relativePath = ContentUtils.relativize(provider.getMountPath(), content.getPath()); + relativePath = CmsContent.relativize(provider.getMountPath(), content.getPath()); } @Override diff --git a/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java b/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java index 1acdcc380..7eb4138ab 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java @@ -21,7 +21,7 @@ import org.argeo.api.acr.spi.ProvidedSession; import org.argeo.cms.util.LangUtils; /** Partial reference implementation of a {@link ProvidedContent}. */ -public abstract class AbstractContent extends AbstractMap implements ProvidedContent { +public abstract class AbstractContent extends AbstractMap implements CmsContent { private final ProvidedSession session; // cache @@ -96,7 +96,7 @@ public abstract class AbstractContent extends AbstractMap impleme if (CrName.root.qName().equals(name)) continue ancestors; - path.append('/'); + path.append(PATH_SEPARATOR); path.append(NamespaceUtils.toPrefixedName(name)); int siblingIndex = c.getSiblingIndex(); if (siblingIndex != 1) diff --git a/org.argeo.cms/src/org/argeo/cms/acr/CmsContent.java b/org.argeo.cms/src/org/argeo/cms/acr/CmsContent.java new file mode 100644 index 000000000..184b2ce35 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/acr/CmsContent.java @@ -0,0 +1,53 @@ +package org.argeo.cms.acr; + +import java.util.Objects; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.spi.ProvidedContent; + +/** A content within a CMS system. */ +public interface CmsContent extends ProvidedContent { + + /** + * Split a path (with {@link Content#PATH_SEPARATOR} separator) in an array of + * length 2, the first part being the parent path (which could be either + * absolute or relative), the second one being the last segment, (guaranteed to + * be without a '/'). + */ + static String[] getParentPath(String path) { + if (path == null) + throw new IllegalArgumentException("Path cannot be null"); + if (path.length() == 0) + throw new IllegalArgumentException("Path cannot be empty"); + ContentUtils.checkDoubleSlash(path); + int parentIndex = path.lastIndexOf(PATH_SEPARATOR); + if (parentIndex == path.length() - 1) {// trailing '/' + path = path.substring(0, path.length() - 1); + parentIndex = path.lastIndexOf(PATH_SEPARATOR); + } + + if (parentIndex == -1) // no '/' + return new String[] { "", path }; + + return new String[] { parentIndex != 0 ? path.substring(0, parentIndex) : ContentUtils.PATH_SEPARATOR_STRING, + path.substring(parentIndex + 1) }; + } + + /** + * Constructs a relative path between a base path and a given path. + * + * @throws IllegalArgumentException if the base path is not an ancestor of the + * path + */ + static String relativize(String basePath, String path) throws IllegalArgumentException { + Objects.requireNonNull(basePath); + Objects.requireNonNull(path); + if (!path.startsWith(basePath)) + throw new IllegalArgumentException(basePath + " is not an ancestor of " + path); + String relativePath = path.substring(basePath.length()); + if (relativePath.length() > 0 && relativePath.charAt(0) == PATH_SEPARATOR) + relativePath = relativePath.substring(1); + return relativePath; + } + +} 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 c782256e2..04a6fea6c 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java @@ -74,7 +74,7 @@ class CmsContentSession implements ProvidedSession, UuidIdentified { throw new IllegalArgumentException(path + " is not an absolute path"); ContentProvider contentProvider = contentRepository.getMountManager().findContentProvider(path); String mountPath = contentProvider.getMountPath(); - String relativePath = ContentUtils.relativize(mountPath, path); + String relativePath = CmsContent.relativize(mountPath, path); ProvidedContent content = contentProvider.get(CmsContentSession.this, relativePath); return content; } @@ -85,7 +85,7 @@ class CmsContentSession implements ProvidedSession, UuidIdentified { throw new IllegalArgumentException(path + " is not an absolute path"); ContentProvider contentProvider = contentRepository.getMountManager().findContentProvider(path); String mountPath = contentProvider.getMountPath(); - String relativePath = ContentUtils.relativize(mountPath, path); + String relativePath = CmsContent.relativize(mountPath, path); return contentProvider.exists(this, relativePath); } @@ -113,7 +113,7 @@ class CmsContentSession implements ProvidedSession, UuidIdentified { */ @Override public Content getMountPoint(String path) { - String[] parent = ContentUtils.getParentPath(path); + String[] parent = CmsContent.getParentPath(path); ProvidedContent mountParent = (ProvidedContent) get(parent[0]); // Content mountPoint = mountParent.getProvider().get(CmsContentSession.this, null, path); return mountParent.getMountPoint(parent[1]); 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 b3f814547..5676e5c10 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java @@ -1,11 +1,12 @@ package org.argeo.cms.acr; +import static org.argeo.api.acr.Content.PATH_SEPARATOR; + import java.io.PrintStream; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.StringJoiner; import java.util.StringTokenizer; import java.util.function.BiConsumer; @@ -30,6 +31,10 @@ import org.argeo.cms.util.CurrentSubject; /** Utilities and routines around {@link Content}. */ public class ContentUtils { + // Optimisations + static final String PATH_SEPARATOR_STRING = Character.toString(PATH_SEPARATOR); + private static final String DOUBLE_PATH_SEPARATOR = PATH_SEPARATOR_STRING + PATH_SEPARATOR_STRING; + public static void traverse(Content content, BiConsumer doIt) { traverse(content, doIt, (Integer) null); } @@ -75,61 +80,33 @@ public class ContentUtils { // return t instanceof String; // } - public static final char SLASH = '/'; - public static final String SLASH_STRING = Character.toString(SLASH); - public static final String EMPTY = ""; - - /** - * Split a path (with '/' separator) in an array of length 2, the first part - * being the parent path (which could be either absolute or relative), the - * second one being the last segment, (guaranteed to be without a '/'). - */ - public static String[] getParentPath(String path) { - if (path == null) - throw new IllegalArgumentException("Path cannot be null"); - if (path.length() == 0) - throw new IllegalArgumentException("Path cannot be empty"); - checkDoubleSlash(path); - int parentIndex = path.lastIndexOf(SLASH); - if (parentIndex == path.length() - 1) {// trailing '/' - path = path.substring(0, path.length() - 1); - parentIndex = path.lastIndexOf(SLASH); - } - - if (parentIndex == -1) // no '/' - return new String[] { EMPTY, path }; - - return new String[] { parentIndex != 0 ? path.substring(0, parentIndex) : "" + SLASH, - path.substring(parentIndex + 1) }; - } - public static String toPath(List segments) { // TODO checks - StringJoiner sj = new StringJoiner("/"); + StringJoiner sj = new StringJoiner(PATH_SEPARATOR_STRING); segments.forEach((s) -> sj.add(s)); return sj.toString(); } - public static List toPathSegments(String path) { + static List toPathSegments(String path) { List res = new ArrayList<>(); - if (EMPTY.equals(path) || Content.ROOT_PATH.equals(path)) + if ("".equals(path) || Content.ROOT_PATH.equals(path)) return res; collectPathSegments(path, res); return res; } - private static void collectPathSegments(String path, List segments) { - String[] parent = getParentPath(path); - if (EMPTY.equals(parent[1])) // root + static void collectPathSegments(String path, List segments) { + String[] parent = CmsContent.getParentPath(path); + if ("".equals(parent[1])) // root return; segments.add(0, parent[1]); - if (EMPTY.equals(parent[0])) // end + if ("".equals(parent[0])) // end return; collectPathSegments(parent[0], segments); } - public static void checkDoubleSlash(String path) { - if (path.contains(SLASH + "" + SLASH)) + static void checkDoubleSlash(String path) { + if (path.contains(DOUBLE_PATH_SEPARATOR)) throw new IllegalArgumentException("Path " + path + " contains //"); } @@ -156,7 +133,7 @@ public class ContentUtils { public static Content hierarchyUnitToContent(ContentSession contentSession, HierarchyUnit hierarchyUnit) { CmsDirectory directory = hierarchyUnit.getDirectory(); - StringJoiner relativePath = new StringJoiner(SLASH_STRING); + StringJoiner relativePath = new StringJoiner(PATH_SEPARATOR_STRING); buildHierarchyUnitPath(hierarchyUnit, relativePath); String path = directoryPath(directory) + relativePath.toString(); Content content = contentSession.get(path); @@ -165,7 +142,7 @@ public class ContentUtils { /** The path to this {@link CmsDirectory}. Ends with a /. */ private static String directoryPath(CmsDirectory directory) { - return CmsContentRepository.DIRECTORY_BASE + SLASH + directory.getName() + SLASH; + return CmsContentRepository.DIRECTORY_BASE + PATH_SEPARATOR + directory.getName() + PATH_SEPARATOR; } /** Recursively build a relative path of a {@link HierarchyUnit}. */ @@ -189,7 +166,7 @@ public class ContentUtils { return content; } } else { - String[] parentPath = getParentPath(path); + String[] parentPath = CmsContent.getParentPath(path); Content parent = createCollections(session, parentPath[0]); Content content = parent.add(parentPath[1], DName.collection.qName()); return content; @@ -219,23 +196,6 @@ public class ContentUtils { return CurrentSubject.callAs(cmsSession.getSubject(), () -> contentRepository.get()); } - /** - * Constructs a relative path between a base path and a given path. - * - * @throws IllegalArgumentException if the base path is not an ancestor of the - * path - */ - public static String relativize(String basePath, String path) throws IllegalArgumentException { - Objects.requireNonNull(basePath); - Objects.requireNonNull(path); - if (!path.startsWith(basePath)) - throw new IllegalArgumentException(basePath + " is not an ancestor of " + path); - String relativePath = path.substring(basePath.length()); - if (relativePath.length() > 0 && relativePath.charAt(0) == '/') - relativePath = relativePath.substring(1); - return relativePath; - } - /** A path in the node repository */ public static String getDataPath(Content node) { // TODO make it more configurable? diff --git a/org.argeo.cms/src/org/argeo/cms/acr/MountManager.java b/org.argeo.cms/src/org/argeo/cms/acr/MountManager.java index 90d621b76..39b2038fb 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/MountManager.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/MountManager.java @@ -28,7 +28,7 @@ class MountManager { partitions.put(mountPath, contentProvider); if ("/".equals(mountPath))// root return; - String[] parentPath = ContentUtils.getParentPath(mountPath); + String[] parentPath = CmsContent.getParentPath(mountPath); Content parent = systemSession.get(parentPath[0]); Content mount = parent.add(parentPath[1]); mount.put(CrName.mount.qName(), "true"); @@ -57,7 +57,7 @@ class MountManager { String mountPath = floorEntry.getKey(); if (!path.startsWith(mountPath)) { // FIXME make it more robust and find when there is no content provider - String[] parent = ContentUtils.getParentPath(path); + String[] parent = CmsContent.getParentPath(path); return findContentProvider(parent[0]); // throw new IllegalArgumentException("Path " + path + " doesn't have a content // provider"); diff --git a/org.argeo.cms/src/org/argeo/cms/acr/dav/DavContent.java b/org.argeo.cms/src/org/argeo/cms/acr/dav/DavContent.java index 96e6eeaf3..b5915406e 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/dav/DavContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/dav/DavContent.java @@ -15,7 +15,7 @@ import org.argeo.api.acr.NamespaceUtils; import org.argeo.api.acr.spi.ContentProvider; import org.argeo.api.acr.spi.ProvidedSession; import org.argeo.cms.acr.AbstractContent; -import org.argeo.cms.acr.ContentUtils; +import org.argeo.cms.acr.CmsContent; import org.argeo.cms.dav.DavResponse; import org.argeo.cms.http.HttpStatus; @@ -41,7 +41,7 @@ public class DavContent extends AbstractContent { @Override public QName getName() { - String fileName = ContentUtils.getParentPath(uri.getPath())[1]; + String fileName = CmsContent.getParentPath(uri.getPath())[1]; ContentName name = NamespaceUtils.parsePrefixedName(provider, fileName); return name; } @@ -49,7 +49,7 @@ public class DavContent extends AbstractContent { @Override public Content getParent() { try { - String parentPath = ContentUtils.getParentPath(uri.getPath())[0]; + String parentPath = CmsContent.getParentPath(uri.getPath())[0]; URI parentUri = new URI(uri.getScheme(), uri.getHost(), parentPath, null); return provider.getDavContent(getSession(), parentUri); } catch (URISyntaxException e) { 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 13b19aabb..de21d32a6 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 @@ -42,7 +42,7 @@ import org.argeo.api.acr.spi.ContentProvider; import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.acr.spi.ProvidedSession; import org.argeo.cms.acr.AbstractContent; -import org.argeo.cms.acr.ContentUtils; +import org.argeo.cms.acr.CmsContent; import org.argeo.cms.util.FsUtils; /** Content persisted as a filesystem {@link Path}. */ @@ -332,7 +332,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { String mountPath = provider.getMountPath(); if (mountPath == null || mountPath.equals("/")) return null; - String[] parent = ContentUtils.getParentPath(mountPath); + String[] parent = CmsContent.getParentPath(mountPath); return getSession().get(parent[0]); } return new FsContent(this, path.getParent()); diff --git a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java index 0686be7cb..1d7511491 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java @@ -34,7 +34,7 @@ import org.argeo.api.acr.CrName; import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.acr.spi.ProvidedSession; import org.argeo.cms.acr.AbstractContent; -import org.argeo.cms.acr.ContentUtils; +import org.argeo.cms.acr.CmsContent; import org.w3c.dom.Attr; import org.w3c.dom.DOMException; import org.w3c.dom.Document; @@ -239,8 +239,8 @@ public class DomContent extends AbstractContent implements ProvidedContent { if (Content.ROOT_PATH.equals(mountPath)) { return null; } - String[] parent = ContentUtils.getParentPath(mountPath); - if (ContentUtils.EMPTY.equals(parent[0])) + String[] parent = CmsContent.getParentPath(mountPath); + if ("".equals(parent[0])) return null; return getSession().get(parent[0]); } diff --git a/org.argeo.cms/src/org/argeo/cms/http/server/StaticHttpHandler.java b/org.argeo.cms/src/org/argeo/cms/http/server/StaticHttpHandler.java index 49cc242c7..8c5ccb048 100644 --- a/org.argeo.cms/src/org/argeo/cms/http/server/StaticHttpHandler.java +++ b/org.argeo.cms/src/org/argeo/cms/http/server/StaticHttpHandler.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.NavigableMap; import java.util.TreeMap; -import org.argeo.cms.acr.ContentUtils; +import org.argeo.cms.acr.CmsContent; import org.argeo.cms.http.HttpHeader; import org.argeo.cms.http.HttpStatus; import org.argeo.cms.util.StreamUtils; @@ -66,7 +66,7 @@ public class StaticHttpHandler implements HttpHandler { String mountPath = entry.getKey(); if (!path.startsWith(mountPath)) { // FIXME make it more robust and find when there is no content provider - String[] parent = ContentUtils.getParentPath(path); + String[] parent = CmsContent.getParentPath(path); return findBind(parent[0]); } return entry;