From: Mathieu Baudier Date: Mon, 27 Jun 2022 10:37:40 +0000 (+0200) Subject: Improve, clarify and register namespaces X-Git-Tag: v2.3.10~156 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=7e464c3cedfa41ece64811fb55ddc9ce740a1050;p=lgpl%2Fargeo-commons.git Improve, clarify and register namespaces --- diff --git a/eclipse/org.argeo.cms.e4/OSGI-INF/userAdminWrapper.xml b/eclipse/org.argeo.cms.e4/OSGI-INF/userAdminWrapper.xml index a267aa519..cc7087b6e 100644 --- a/eclipse/org.argeo.cms.e4/OSGI-INF/userAdminWrapper.xml +++ b/eclipse/org.argeo.cms.e4/OSGI-INF/userAdminWrapper.xml @@ -1,7 +1,7 @@ - + diff --git a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml index 2c5a0d145..a94b15168 100644 --- a/jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml +++ b/jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml @@ -2,5 +2,4 @@ - diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java index 235e27d1a..7f471c9b0 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java @@ -16,7 +16,6 @@ import org.argeo.api.acr.Content; 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.CmsContentRepository; import org.argeo.cms.acr.ContentUtils; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jcr.JcrException; @@ -24,6 +23,8 @@ import org.argeo.jcr.JcrUtils; /** A JCR workspace accessed as an {@link ContentProvider}. */ public class JcrContentProvider implements ContentProvider, NamespaceContext { + public final static String ACR_MOUNT_PATH_PROPERTY = "acr.mount.path"; + private Repository jcrRepository; private Session adminSession; @@ -32,7 +33,7 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { private Map sessionAdapters = Collections.synchronizedMap(new HashMap<>()); public void start(Map properties) { - mountPath = properties.get(CmsContentRepository.ACR_MOUNT_PATH_PROPERTY); + mountPath = properties.get(ACR_MOUNT_PATH_PROPERTY); if ("/".equals(mountPath)) throw new IllegalArgumentException("JCR content provider cannot be root /"); Objects.requireNonNull(mountPath); @@ -40,7 +41,8 @@ public class JcrContentProvider implements ContentProvider, NamespaceContext { } public void stop() { - JcrUtils.logoutQuietly(adminSession); + if (adminSession.isLive()) + JcrUtils.logoutQuietly(adminSession); } public void setJcrRepository(Repository jcrRepository) { diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java index 6ba9307be..8fb61d70c 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java @@ -37,6 +37,7 @@ import org.argeo.api.cms.CmsLog; import org.argeo.cms.ArgeoNames; import org.argeo.cms.internal.jcr.JcrInitUtils; import org.argeo.cms.jcr.CmsJcrUtils; +import org.argeo.cms.jcr.acr.JcrContentProvider; import org.argeo.cms.jcr.internal.servlet.CmsRemotingServlet; import org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet; import org.argeo.cms.jcr.internal.servlet.JcrHttpUtils; @@ -75,8 +76,6 @@ public class CmsJcrDeployment { private boolean nodeAvailable = false; CmsDeployment cmsDeployment; - private ProvidedRepository contentRepository; - public void start() { dataModels = new DataModels(bc); @@ -88,12 +87,13 @@ public class CmsJcrDeployment { JcrInitUtils.addToDeployment(cmsDeployment); - contentRepository.registerTypes(NamespaceRegistry.PREFIX_JCR, NamespaceRegistry.NAMESPACE_JCR, null); - contentRepository.registerTypes(NamespaceRegistry.PREFIX_MIX, NamespaceRegistry.NAMESPACE_MIX, null); - contentRepository.registerTypes(NamespaceRegistry.PREFIX_NT, NamespaceRegistry.NAMESPACE_NT, null); - // Jackrabbit - // see https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html - contentRepository.registerTypes("rep", "internal", null); +// contentRepository.registerTypes(NamespaceRegistry.PREFIX_JCR, NamespaceRegistry.NAMESPACE_JCR, null); +// contentRepository.registerTypes(NamespaceRegistry.PREFIX_MIX, NamespaceRegistry.NAMESPACE_MIX, null); +// contentRepository.registerTypes(NamespaceRegistry.PREFIX_NT, NamespaceRegistry.NAMESPACE_NT, null); +// // Jackrabbit +// // see +// // https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html +// contentRepository.registerTypes("rep", "internal", null); } @@ -101,6 +101,7 @@ public class CmsJcrDeployment { // if (nodeHttp != null) // nodeHttp.destroy(); + try { for (ServiceReference sr : bc .getServiceReferences(JackrabbitLocalRepository.class, null)) { @@ -116,10 +117,6 @@ public class CmsJcrDeployment { this.cmsDeployment = cmsDeployment; } - public void setContentRepository(ProvidedRepository contentRepository) { - this.contentRepository = contentRepository; - } - /** * Checks whether the deployment is available according to expectations, and * mark it as available. diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/CompositeString.java b/org.argeo.api.acr/src/org/argeo/api/acr/CompositeString.java deleted file mode 100644 index b83fe301e..000000000 --- a/org.argeo.api.acr/src/org/argeo/api/acr/CompositeString.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.argeo.api.acr; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.StringTokenizer; - -/** A name that can be expressed with various conventions. */ -public class CompositeString { - public final static Character UNDERSCORE = Character.valueOf('_'); - public final static Character SPACE = Character.valueOf(' '); - public final static Character DASH = Character.valueOf('-'); - - private final String[] parts; - - // optimisation - private final int hashCode; - - public CompositeString(String str) { - Objects.requireNonNull(str, "String cannot be null"); - if ("".equals(str.trim())) - throw new IllegalArgumentException("String cannot be empty"); - if (!str.equals(str.trim())) - throw new IllegalArgumentException("String must be trimmed"); - this.parts = toParts(str); - hashCode = hashCode(this.parts); - } - - public String toString(char separator, boolean upperCase) { - StringBuilder sb = null; - for (String part : parts) { - if (sb == null) { - sb = new StringBuilder(); - } else { - sb.append(separator); - } - sb.append(upperCase ? part.toUpperCase() : part); - } - return sb.toString(); - } - - public String toStringCaml(boolean firstCharUpperCase) { - StringBuilder sb = null; - for (String part : parts) { - if (sb == null) {// first - sb = new StringBuilder(); - sb.append(firstCharUpperCase ? Character.toUpperCase(part.charAt(0)) : part.charAt(0)); - } else { - sb.append(Character.toUpperCase(part.charAt(0))); - } - - if (part.length() > 1) - sb.append(part.substring(1)); - } - return sb.toString(); - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof CompositeString)) - return false; - - CompositeString other = (CompositeString) obj; - return Arrays.equals(parts, other.parts); - } - - @Override - public String toString() { - return toString(DASH, false); - } - - public static String[] toParts(String str) { - Character separator = null; - if (str.indexOf(UNDERSCORE) >= 0) { - checkNo(str, SPACE); - checkNo(str, DASH); - separator = UNDERSCORE; - } else if (str.indexOf(DASH) >= 0) { - checkNo(str, SPACE); - checkNo(str, UNDERSCORE); - separator = DASH; - } else if (str.indexOf(SPACE) >= 0) { - checkNo(str, DASH); - checkNo(str, UNDERSCORE); - separator = SPACE; - } - - List res = new ArrayList<>(); - if (separator != null) { - StringTokenizer st = new StringTokenizer(str, separator.toString()); - while (st.hasMoreTokens()) { - res.add(st.nextToken().toLowerCase()); - } - } else { - // single - String strLowerCase = str.toLowerCase(); - if (str.toUpperCase().equals(str) || strLowerCase.equals(str)) - return new String[] { strLowerCase }; - - // CAML - StringBuilder current = null; - for (char c : str.toCharArray()) { - if (Character.isUpperCase(c)) { - if (current != null) - res.add(current.toString()); - current = new StringBuilder(); - } - if (current == null)// first char is lower case - current = new StringBuilder(); - current.append(Character.toLowerCase(c)); - } - res.add(current.toString()); - } - return res.toArray(new String[res.size()]); - } - - private static void checkNo(String str, Character c) { - if (str.indexOf(c) >= 0) { - throw new IllegalArgumentException("Only one kind of sperator is allowed"); - } - } - - private static int hashCode(String[] parts) { - int hashCode = 0; - for (String part : parts) { - hashCode = hashCode + part.hashCode(); - } - return hashCode; - } - - static boolean smokeTests() { - CompositeString plainName = new CompositeString("NAME"); - assert "name".equals(plainName.toString()); - assert "NAME".equals(plainName.toString(UNDERSCORE, true)); - assert "name".equals(plainName.toString(UNDERSCORE, false)); - assert "name".equals(plainName.toStringCaml(false)); - assert "Name".equals(plainName.toStringCaml(true)); - - CompositeString camlName = new CompositeString("myComplexName"); - - assert new CompositeString("my-complex-name").equals(camlName); - assert new CompositeString("MY_COMPLEX_NAME").equals(camlName); - assert new CompositeString("My complex Name").equals(camlName); - assert new CompositeString("MyComplexName").equals(camlName); - - assert "my-complex-name".equals(camlName.toString()); - assert "MY_COMPLEX_NAME".equals(camlName.toString(UNDERSCORE, true)); - assert "my_complex_name".equals(camlName.toString(UNDERSCORE, false)); - assert "myComplexName".equals(camlName.toStringCaml(false)); - assert "MyComplexName".equals(camlName.toStringCaml(true)); - - return CompositeString.class.desiredAssertionStatus(); - } - - public static void main(String[] args) { - System.out.println(smokeTests()); - } -} diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/ContentNameSupplier.java b/org.argeo.api.acr/src/org/argeo/api/acr/ContentNameSupplier.java deleted file mode 100644 index f7900afd3..000000000 --- a/org.argeo.api.acr/src/org/argeo/api/acr/ContentNameSupplier.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.argeo.api.acr; - -import java.util.Collections; -import java.util.Iterator; -import java.util.function.Supplier; - -import javax.xml.XMLConstants; -import javax.xml.namespace.NamespaceContext; - -public interface ContentNameSupplier extends Supplier, NamespaceContext { - String name(); - - String getNamespaceURI(); - - String getDefaultPrefix(); - - @Override - default ContentName get() { - return toContentName(); - } - - default ContentName toContentName() { - CompositeString cs = new CompositeString(name()); - String camlName = cs.toStringCaml(false); - return new ContentName(getNamespaceURI(), camlName, this); - } - -// default String getNamespaceURI() { -// return XMLConstants.NULL_NS_URI; -// } -// -// default String getDefaultPrefix() { -// return XMLConstants.DEFAULT_NS_PREFIX; -// } - -// static ContentName toContentName(String namespaceURI, String localName, String prefix) { -// CompositeString cs = new CompositeString(localName); -// String camlName = cs.toStringCaml(false); -// return new ContentName(namespaceURI, camlName, this); -// } - - /* - * NAMESPACE CONTEXT - */ - - @Override - default String getNamespaceURI(String prefix) { - String namespaceURI = NamespaceUtils.getStandardNamespaceURI(prefix); - if (namespaceURI != null) - return namespaceURI; - if (prefix.equals(getDefaultPrefix())) - return getNamespaceURI(); - return XMLConstants.NULL_NS_URI; - } - - @Override - default String getPrefix(String namespaceURI) { - String prefix = NamespaceUtils.getStandardPrefix(namespaceURI); - if (prefix != null) - return prefix; - if (namespaceURI.equals(getNamespaceURI())) - return getDefaultPrefix(); - return null; - } - - @Override - default Iterator getPrefixes(String namespaceURI) { - Iterator it = NamespaceUtils.getStandardPrefixes(namespaceURI); - if (it != null) - return it; - if (namespaceURI.equals(getNamespaceURI())) - return Collections.singleton(getDefaultPrefix()).iterator(); - return Collections.emptyIterator(); - } - -} diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java b/org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java index 5d6c57dd5..0bbf63e71 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java @@ -1,5 +1,7 @@ package org.argeo.api.acr; +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; + import java.net.URI; import java.net.URISyntaxException; import java.time.Instant; @@ -9,32 +11,44 @@ import java.util.Base64; import java.util.List; import java.util.UUID; -import javax.xml.XMLConstants; +import javax.xml.namespace.QName; /** * Minimal standard attribute types that MUST be supported. All related classes * belong to java.base and can be implicitly derived form a given * String. */ -public enum CrAttributeType implements ContentNameSupplier { - BOOLEAN(Boolean.class, new BooleanFormatter()), // - INTEGER(Integer.class, new IntegerFormatter()), // - LONG(Long.class, new LongFormatter()), // - DOUBLE(Double.class, new DoubleFormatter()), // +public enum CrAttributeType { + BOOLEAN(Boolean.class, W3C_XML_SCHEMA_NS_URI, "boolean", new BooleanFormatter()), // + INTEGER(Integer.class, W3C_XML_SCHEMA_NS_URI, "integer", new IntegerFormatter()), // + LONG(Long.class, W3C_XML_SCHEMA_NS_URI, "long", new LongFormatter()), // + DOUBLE(Double.class, W3C_XML_SCHEMA_NS_URI, "double", new DoubleFormatter()), // // we do not support short and float, like recent additions to Java // (e.g. optional primitives) - DATE_TIME(Instant.class, new InstantFormatter()), // - UUID(UUID.class, new UuidFormatter()), // - ANY_URI(URI.class, new UriFormatter()), // - STRING(String.class, new StringFormatter()), // + DATE_TIME(Instant.class, W3C_XML_SCHEMA_NS_URI, "dateTime", new InstantFormatter()), // + UUID(UUID.class, CrName.CR_NAMESPACE_URI, "uuid", new UuidFormatter()), // + ANY_URI(URI.class, W3C_XML_SCHEMA_NS_URI, "anyUri", new UriFormatter()), // + STRING(String.class, W3C_XML_SCHEMA_NS_URI, "string", new StringFormatter()), // ; private final Class clss; private final AttributeFormatter formatter; - private CrAttributeType(Class clss, AttributeFormatter formatter) { + private ContentName qName; + + private CrAttributeType(Class clss, String namespaceUri, String localName, AttributeFormatter formatter) { this.clss = clss; this.formatter = formatter; + + qName = new ContentName(namespaceUri, localName, RuntimeNamespaceContext.getNamespaceContext()); + } + + public QName getqName() { + return qName; + } + + public void setqName(ContentName qName) { + this.qName = qName; } public Class getClss() { @@ -45,21 +59,21 @@ public enum CrAttributeType implements ContentNameSupplier { return formatter; } - @Override - public String getDefaultPrefix() { - if (equals(UUID)) - return CrName.CR_DEFAULT_PREFIX; - else - return "xs"; - } - - @Override - public String getNamespaceURI() { - if (equals(UUID)) - return CrName.CR_NAMESPACE_URI; - else - return XMLConstants.W3C_XML_SCHEMA_NS_URI; - } +// @Override +// public String getDefaultPrefix() { +// if (equals(UUID)) +// return CrName.CR_DEFAULT_PREFIX; +// else +// return "xs"; +// } +// +// @Override +// public String getNamespaceURI() { +// if (equals(UUID)) +// return CrName.CR_NAMESPACE_URI; +// else +// return XMLConstants.W3C_XML_SCHEMA_NS_URI; +// } /** Default parsing procedure from a String to an object. */ public static Object parse(String str) { @@ -112,7 +126,7 @@ public enum CrAttributeType implements ContentNameSupplier { } catch (IllegalArgumentException e) { // silent } - + // TODO support QName as a type? It would require a NamespaceContext // see https://www.oreilly.com/library/view/xml-schema/0596002521/re91.html 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 f8ef602db..1138d095d 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 @@ -1,34 +1,36 @@ package org.argeo.api.acr; +import javax.xml.namespace.QName; + /** Standard names. */ -public enum CrName implements ContentNameSupplier { +public enum CrName { /* * TYPES */ - COLLECTION, // a collection type + collection, // a collection type /* * ATTRIBUTES */ - UUID, // the UUID of a content - MOUNT, + uuid, // the UUID of a content + mount, /* * ATTRIBUTES FROM FILE SEMANTICS */ - CREATION_TIME, // - LAST_MODIFIED_TIME, // - SIZE, // - FILE_KEY, // - OWNER, // - GROUP, // - PERMISSIONS, // + creationTime, // + lastModifiedTime, // + size, // + fileKey, // + owner, // + group, // + permissions, // /* * CONTENT NAMES */ - ROOT, + root, // ; @@ -46,22 +48,21 @@ public enum CrName implements ContentNameSupplier { private final ContentName value; CrName() { - value = toContentName(); + value = new ContentName(CR_NAMESPACE_URI, name(), RuntimeNamespaceContext.getNamespaceContext()); } - @Override - public ContentName get() { + public QName qName() { return value; } - @Override - public String getNamespaceURI() { - return CR_NAMESPACE_URI; - } - - @Override - public String getDefaultPrefix() { - return CR_DEFAULT_PREFIX; - } +// @Override +// public String getNamespaceURI() { +// return CR_NAMESPACE_URI; +// } +// +// @Override +// public String getDefaultPrefix() { +// return CR_DEFAULT_PREFIX; +// } } diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedRepository.java b/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedRepository.java index 58c068996..7134007b9 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedRepository.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedRepository.java @@ -12,4 +12,6 @@ public interface ProvidedRepository extends ContentRepository { ContentProvider getMountContentProvider(Content mountPoint, boolean initialize, QName... types); boolean shouldMount(QName... types); + + void addProvider(ContentProvider provider); } diff --git a/org.argeo.cms/OSGI-INF/acrContentRepository.xml b/org.argeo.cms/OSGI-INF/acrContentRepository.xml index befc95889..b7a13b4d1 100644 --- a/org.argeo.cms/OSGI-INF/acrContentRepository.xml +++ b/org.argeo.cms/OSGI-INF/acrContentRepository.xml @@ -1,7 +1,7 @@ - + diff --git a/org.argeo.cms/OSGI-INF/cmsContext.xml b/org.argeo.cms/OSGI-INF/cmsContext.xml index bec003350..dfcf7987e 100644 --- a/org.argeo.cms/OSGI-INF/cmsContext.xml +++ b/org.argeo.cms/OSGI-INF/cmsContext.xml @@ -8,5 +8,4 @@ - - + diff --git a/org.argeo.cms/OSGI-INF/deployConfig.xml b/org.argeo.cms/OSGI-INF/deployConfig.xml index f82bfc32e..55755a920 100644 --- a/org.argeo.cms/OSGI-INF/deployConfig.xml +++ b/org.argeo.cms/OSGI-INF/deployConfig.xml @@ -1,5 +1,5 @@ - + 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 2703af035..fd4ef4cfc 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java @@ -94,7 +94,7 @@ public abstract class AbstractContent extends AbstractMap impleme for (Content c : ancestors) { QName name = c.getName(); // FIXME - if (!CrName.ROOT.get().equals(name)) + if (!CrName.root.qName().equals(name)) path.append('/').append(name); } return path.toString(); diff --git a/org.argeo.cms/src/org/argeo/cms/acr/AbstractContentRepository.java b/org.argeo.cms/src/org/argeo/cms/acr/AbstractContentRepository.java index 2e65e7e69..8ff141698 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/AbstractContentRepository.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/AbstractContentRepository.java @@ -19,6 +19,7 @@ import javax.xml.transform.stream.StreamResult; import org.argeo.api.acr.Content; import org.argeo.api.acr.CrName; +import org.argeo.api.acr.NamespaceUtils; import org.argeo.api.acr.RuntimeNamespaceContext; import org.argeo.api.acr.spi.ContentProvider; import org.argeo.api.acr.spi.ProvidedContent; @@ -48,7 +49,7 @@ public abstract class AbstractContentRepository implements ProvidedRepository { /** Should be used only to copy source and results. */ private TransformerFactory identityTransformerFactory = TransformerFactory.newInstance(); - public final static String ACR_MOUNT_PATH_PROPERTY = "acr.mount.path"; +// public final static String ACR_MOUNT_PATH_PROPERTY = "acr.mount.path"; public AbstractContentRepository() { // types @@ -78,7 +79,7 @@ public abstract class AbstractContentRepository implements ProvidedRepository { /* * REPOSITORY */ - + @Override public void addProvider(ContentProvider provider) { if (mountManager == null) providersToAdd.add(provider); @@ -110,7 +111,8 @@ public abstract class AbstractContentRepository implements ProvidedRepository { // document = dBuilder.parse(inputSource); // } else { document = dBuilder.newDocument(); - Element root = document.createElementNS(CrName.CR_NAMESPACE_URI, CrName.ROOT.get().toPrefixedString()); + Element root = document.createElementNS(CrName.CR_NAMESPACE_URI, + NamespaceUtils.toPrefixedName(CrName.root.qName())); for (String prefix : RuntimeNamespaceContext.getPrefixes().keySet()) { // root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE + ":" + 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 4e1c3bcfd..b82507d6f 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java @@ -170,7 +170,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.get()); + sessionRunDir = runDir.add(uuid.toString(), CrName.collection.qName()); } } return sessionRunDir; diff --git a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentTypes.java b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentTypes.java index 67c206304..6a09a8987 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/CmsContentTypes.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/CmsContentTypes.java @@ -7,8 +7,17 @@ import java.util.Objects; import org.argeo.api.acr.CrName; public enum CmsContentTypes { + // + // ARGEO + // CR_2(CrName.CR_DEFAULT_PREFIX, CrName.CR_NAMESPACE_URI, "cr.xsd", null), // + SLC("slc", "http://www.argeo.org/ns/slc", null, null), + // + ARGEO_LEGACY("argeo", "http://www.argeo.org/ns/argeo", null, null), + // + // EXTERNAL + // XSD_2001("xs", "http://www.w3.org/2001/XMLSchema", "XMLSchema.xsd", "http://www.w3.org/2001/XMLSchema.xsd"), // XML_1998("xml", "http://www.w3.org/XML/1998/namespace", "xml.xsd", "http://www.w3.org/2001/xml.xsd"), @@ -21,6 +30,8 @@ public enum CmsContentTypes { SVG_1_1("svg", "http://www.w3.org/2000/svg", "SVG.xsd", "https://raw.githubusercontent.com/oreillymedia/HTMLBook/master/schema/svg/SVG.xsd"), // + XHTML_1_1("h", "http://www.w3.org/1999/xhtml", "xhtml11.xsd", "https://www.w3.org/MarkUp/SCHEMA/xhtml11.xsd"), + // DOCBOOK_5_0_1("dbk", "http://docbook.org/ns/docbook", "docbook.xsd", "http://docbook.org/xml/5.0.1/xsd/docbook.xsd"), // @@ -33,6 +44,22 @@ public enum CmsContentTypes { DSML_v2("dsml", "urn:oasis:names:tc:DSML:2:0:core", "DSMLv2.xsd", "https://www.oasis-open.org/committees/dsml/docs/DSMLv2.xsd"), // + // JCR (to be moved elsewhere) + // + JCR("jcr", "http://www.jcp.org/jcr/1.0", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + JCR_MIX("mix", "http://www.jcp.org/jcr/mix/1.0", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + JCR_NT("nt", "http://www.jcp.org/jcr/nt/1.0", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + JACKRABBIT("rep", "internal", null, + "https://jackrabbit.apache.org/archive/wiki/JCR/NamespaceRegistry_115513459.html"), + // + JCRX("jcrx", "http://www.argeo.org/ns/jcrx", null, null), + // ; private final static String RESOURCE_BASE = "/org/argeo/cms/acr/schemas/"; @@ -47,8 +74,10 @@ public enum CmsContentTypes { this.defaultPrefix = defaultPrefix; Objects.requireNonNull(namespace); this.namespace = namespace; - resource = getClass().getResource(RESOURCE_BASE + resourceFileName); - Objects.requireNonNull(resource); + if (resourceFileName != null) { + resource = getClass().getResource(RESOURCE_BASE + resourceFileName); + Objects.requireNonNull(resource); + } if (publicUrl != null) try { this.publicUrl = new URL(publicUrl); 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 3995dc30f..6a6dcaacb 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/MountManager.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/MountManager.java @@ -31,7 +31,7 @@ class MountManager { String[] parentPath = ContentUtils.getParentPath(mountPath); Content parent = systemSession.get(parentPath[0]); Content mount = parent.add(parentPath[1]); - mount.put(CrName.MOUNT.get(), "true"); + mount.put(CrName.mount.qName(), "true"); } diff --git a/org.argeo.cms/src/org/argeo/cms/acr/TypesManager.java b/org.argeo.cms/src/org/argeo/cms/acr/TypesManager.java index 72bb26f20..6cfb2e5e9 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/TypesManager.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/TypesManager.java @@ -77,35 +77,29 @@ class TypesManager { } - public synchronized void init() { -// prefixes.put(CrName.CR_DEFAULT_PREFIX, CrName.CR_NAMESPACE_URI); -// prefixes.put("basic", CrName.CR_NAMESPACE_URI); -// prefixes.put("owner", CrName.CR_NAMESPACE_URI); -// prefixes.put("posix", CrName.CR_NAMESPACE_URI); - + public void init() { for (CmsContentTypes cs : CmsContentTypes.values()) { - StreamSource source = new StreamSource(cs.getResource().toExternalForm()); - sources.add(source); -// if (prefixes.containsKey(cs.getDefaultPrefix())) -// throw new IllegalStateException("Prefix " + cs.getDefaultPrefix() + " is already mapped with " -// + prefixes.get(cs.getDefaultPrefix())); -// prefixes.put(cs.getDefaultPrefix(), cs.getNamespace()); + if (cs.getResource() != null) { + StreamSource source = new StreamSource(cs.getResource().toExternalForm()); + sources.add(source); + } RuntimeNamespaceContext.register(cs.getNamespace(), cs.getDefaultPrefix()); } reload(); } - public synchronized void registerTypes(String defaultPrefix, String namespace, String xsdSystemId) { + public void registerTypes(String defaultPrefix, String namespace, String xsdSystemId) { // if (prefixes.containsKey(defaultPrefix)) // throw new IllegalStateException( // "Prefix " + defaultPrefix + " is already mapped with " + prefixes.get(defaultPrefix)); // prefixes.put(defaultPrefix, namespace); RuntimeNamespaceContext.register(namespace, defaultPrefix); - if (xsdSystemId != null) + if (xsdSystemId != null) { sources.add(new StreamSource(xsdSystemId)); - reload(); + reload(); + } } public Set listTypes() { 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 bf8dae72e..9ded5ee7b 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 @@ -69,7 +69,7 @@ class HierarchyUnitContent extends AbstractDirectoryContent { @Override public List getContentClasses() { List contentClasses = super.getContentClasses(); - contentClasses.add(CrName.COLLECTION.get()); + contentClasses.add(CrName.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 bbd77b221..15917c503 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 @@ -43,15 +43,15 @@ public class FsContent extends AbstractContent implements ProvidedContent { private static final Map POSIX_KEYS; static { BASIC_KEYS = new HashMap<>(); - BASIC_KEYS.put(CrName.CREATION_TIME.get(), "basic:creationTime"); - BASIC_KEYS.put(CrName.LAST_MODIFIED_TIME.get(), "basic:lastModifiedTime"); - BASIC_KEYS.put(CrName.SIZE.get(), "basic:size"); - BASIC_KEYS.put(CrName.FILE_KEY.get(), "basic:fileKey"); + 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(CrName.fileKey.qName(), "basic:fileKey"); POSIX_KEYS = new HashMap<>(BASIC_KEYS); - POSIX_KEYS.put(CrName.OWNER.get(), "owner:owner"); - POSIX_KEYS.put(CrName.GROUP.get(), "posix:group"); - POSIX_KEYS.put(CrName.PERMISSIONS.get(), "posix:permissions"); + POSIX_KEYS.put(CrName.owner.qName(), "owner:owner"); + POSIX_KEYS.put(CrName.group.qName(), "posix:group"); + POSIX_KEYS.put(CrName.permissions.qName(), "posix:permissions"); } private final FsContentProvider provider; @@ -71,7 +71,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { Content mountPoint = session.getMountPoint(mountPath); this.name = mountPoint.getName(); } else { - this.name = CrName.ROOT.get(); + this.name = CrName.root.qName(); } } else { @@ -209,7 +209,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { try { return Files.list(path).map((p) -> { FsContent fsContent = new FsContent(this, p); - Optional isMount = fsContent.get(CrName.MOUNT.get(), String.class); + Optional isMount = fsContent.get(CrName.mount.qName(), String.class); if (isMount.orElse("false").equals("true")) { QName[] classes = null; ContentProvider contentProvider = getSession().getRepository() @@ -233,7 +233,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.get())) + if (ContentName.contains(classes, CrName.collection.qName())) Files.createDirectory(newPath); else Files.createFile(newPath); @@ -250,7 +250,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { ContentProvider contentProvider = getSession().getRepository().getMountContentProvider(fsContent, true, classes); Content mountedContent = contentProvider.get(getSession(), ""); - fsContent.put(CrName.MOUNT.get(), "true"); + fsContent.put(CrName.mount.qName(), "true"); return mountedContent; } else { @@ -308,7 +308,7 @@ public class FsContent extends AbstractContent implements ProvidedContent { public List getContentClasses() { List res = new ArrayList<>(); if (Files.isDirectory(path)) - res.add(CrName.COLLECTION.get()); + res.add(CrName.collection.qName()); // TODO add other types return res; } diff --git a/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-model-1.xsd b/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-model-1.xsd new file mode 100644 index 000000000..a1c138d84 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-model-1.xsd @@ -0,0 +1,716 @@ + + + + + + This is the XML Schema module of common content models for XHTML11 + + $Id: xhtml11-model-1.xsd,v 1.9 2009/02/03 15:14:49 ahby Exp $ + + + + + + XHTML Document Model + This module describes the groupings of elements/attributes + that make up common content models for XHTML elements. + XHTML has following basic content models: + xhtml.Inline.mix; character-level elements + xhtml.Block.mix; block-like elements, e.g., paragraphs and lists + xhtml.Flow.mix; any block or inline elements + xhtml.HeadOpts.mix; Head Elements + xhtml.InlinePre.mix; Special class for pre content model + xhtml.InlineNoAnchor.mix; Content model for Anchor + + Any groups declared in this module may be used to create + element content models, but the above are considered 'global' + (insofar as that term applies here). XHTML has the + following Attribute Groups + xhtml.Core.extra.attrib + xhtml.I18n.extra.attrib + xhtml.Common.extra + + The above attribute Groups are considered Global + + + + + Extended I18n attribute + + + + + "dir" Attribute from Bi Directional Text (bdo) Module + + + + + + + + Extended Common Attributes + + + + + "style" attribute from Inline Style Module + + + + + + + Attributes from Events Module + + + + + + + Extend Core Attributes + + + + + Extended Global Core Attributes + + + + + Extended Global I18n attributes + + + + + Extended Global Common Attributes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-modules-1.xsd b/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-modules-1.xsd new file mode 100644 index 000000000..676706760 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-modules-1.xsd @@ -0,0 +1,605 @@ + + + + + + + This schema includes all modules for XHTML1.1 Document Type. + $Id: xhtml11-modules-1.xsd,v 1.10 2009/02/03 15:14:49 ahby Exp $ + + + + + + This schema includes all modules (and redefinitions) + for XHTML1.1 Document Type. + XHTML1.1 Document Type includes the following Modules + + XHTML Core modules (Required for XHTML Family Conformance) + + text + + hypertext + + lists + + structure + + Other XHTML modules + + Edit + + Bdo + + Presentational + + Link + + Meta + + Base + + Scripting + + Style + + Image + + Applet + + Object + + Param (Applet/Object modules require Param Module) + + Tables + + Target + + Forms + + Client side image maps + + Server side image maps + + + + + + + Schema Framework Component Modules: + + notations + + datatypes + + common attributes + + character entities + + + + + + + + Text module + + The Text module includes declarations for all core + text container elements and their attributes. + + + block phrasal + + block structural + + inline phrasal + + inline structural + + Elements defined here: + * address, blockquote, pre, h1, h2, h3, h4, h5, h6 + * div, p + * abbr, acronym, cite, code, dfn, em, kbd, q, samp, strong, var + * br, span + + + + + + + + Hypertext module + + Elements defined here: + * a + + + + + + + + + Redefinition by Client Side Image Map Module + + + + + + + Redefinition by XHTML Event Attribute Module + + + + + + + Target Module - A Attribute Additions + + + + + + + + + Lists module + + Elements defined here: + * dt, dd, dl, ol, ul, li + + + + + + + + Structural module + + Elements defined here: + * title, head, body, html + + + + + + + Redefinition by the XHTML11 Markup (for value of version attr) + + + + + + + + + Original Body Attlist + + + + + + + Redefinition by XHTML Event Attribute Module + + + + + + + + + Edit module + + Elements defined here: + * ins, del + + + + + + + + Bidirectional element module + + Elements defined here: + * bdo + + + + + + + + Presentational module + + Elements defined here: + * hr, b, big, i, small,sub, sup, tt + + + + + + + + Link module + + Elements defined here: + * link + + + + + + + Changes to XHTML Link Attlist + + + + + + Original Link Attributes (declared in Link Module) + + + + + + + XHTML Target Module - Attribute additions + + + + + + + + + Meta module + + Elements defined here: + * meta + + + + + + + + Base module + + Elements defined here: + * base + + + + + + + Changes to XHTML base Attlist + + + + + + Original Base Attributes (declared in Base Module) + + + + + + + XHTML Target Module - Attribute additions + + + + + + + + + Scripting module + + Elements defined here: + * script, noscript + + + + + + + + Style module + + Elements defined here: + * style + + + + + + + + Style attribute module + + Attribute defined here: + * style + + + + + + + + Image module + + Elements defined here: + * img + + + + + + + + Original Image Attributes (in Image Module) + + + + + + + Redefinition by Client Side Image Map Module + + + + + + + Redefinition by Server Side Image Module + + + + + + + + + Client-side mage maps module + + Elements defined here: + * area, map + + + + + + + + Original Area Attributes (in CSI Module) + + + + + + + Redefinition by Events Attribute Module + + + + + + + Target Module - Area Attribute Additions + + + + + + + + + Server-side image maps module + + Attributes defined here: + * ismap on img + + + + + + + + Object module + + Elements defined here: + * object + + + + + + + + Original Object Attlist + + + + + + + Redefinition by Client Image Map Module + + + + + + + + + Param module + + Elements defined here: + * param + + + + + + + Tables module + + Elements defined here: + * table, caption, thead, tfoot, tbody, colgroup, col, tr, th, td + + + + + + + + Forms module + + Elements defined here: + * form, label, input, select, optgroup, option, + * textarea, fieldset, legend, button + + + + + + + Changes to XHTML Form Attlist + + + + + + Original Form Attributes (declared in Forms Module) + + + + + + + XHTML Events Module - Attribute additions + + + + + + + XHTML Target Module - Attribute additions + + + + + + + + Changes to XHTML Form Input Element + + + + + + Original Input Attributes (in Forms Module) + + + + + + + Redefinition by Client Side Image Map Module + + + + + + + Redefinition by Server Side Image Map Module + + + + + + + Redefinition by Event Attribute Module + + + + + + + + + Original Label Attributes (in Forms Module) + + + + + + + Redefinition by Event Attribute Module + + + + + + + + + Original Select Attributes (in Forms Module) + + + + + + + Redefinition by Event Attribute Module + + + + + + + + + Original TextArea Attributes (in Forms Module) + + + + + + + Redefinition by Event Attribute Module + + + + + + + + + Original Button Attributes (in Forms Module) + + + + + + + Redefinition by Event Attribute Module + + + + + + + + + Ruby module + + Elements defined here: + * ruby, rbc, rtc, rb, rt, rp + + Note that either Ruby or Basic Ruby should be used but not both + + + + + + + + XHTML Events Modules + + Attributes defined here: + XHTML Event Types + + + + + + + + XHTML Target Attribute Module + + Attributes defined here: + target + + + + + diff --git a/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11.xsd b/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11.xsd new file mode 100644 index 000000000..341699935 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11.xsd @@ -0,0 +1,104 @@ + + + + + This is the XML Schema driver for XHTML 1.1. + Please use this namespace for XHTML elements: + + "http://www.w3.org/1999/xhtml" + + $Id: xhtml11.xsd,v 1.7 2009/02/03 15:14:49 ahby Exp $ + + + + + + This is XHTML, a reformulation of HTML as a modular XML application + The Extensible HyperText Markup Language (XHTML) + Copyright ©1998-2007 World Wide Web Consortium + (Massachusetts Institute of Technology, European Research Consortium + for Informatics and Mathematics, Keio University). + All Rights Reserved. + + Permission to use, copy, modify and distribute the XHTML Schema + modules and their accompanying xs:documentation for any purpose + and without fee is hereby granted in perpetuity, provided that the above + copyright notice and this paragraph appear in all copies. + The copyright holders make no representation about the suitability of + these XML Schema modules for any purpose. + + They are provided "as is" without expressed or implied warranty. + + + + + This is the Schema Driver file for XHTML1.1 + Document Type + + This schema + + imports external schemas (xml.xsd) + + refedines (and include)s schema modules for XHTML1.1 Document Type. + + includes Schema for Named content model for the + XHTML1.1 Document Type + + XHTML1.1 Document Type includes the following Modules + XHTML Core modules (Required for XHTML Family Conformance) + + text + + hypertext + + lists + + structure + Other XHTML modules + + Edit + + Bdo + + Presentational + + Link + + Meta + + Base + + Scripting + + Style + + Image + + Applet + + Object + + Param (Applet/Object modules require Param Module) + + Tables + + Forms + + Client side image maps + + Server side image maps + + Ruby + + + + + + This import brings in the XML namespace attributes + The XML attributes are used by various modules. + + + + + + + Document Model module for the XHTML1.1 Document Type. + This schema file defines all named models used by XHTML + Modularization Framework for XHTML1.1 Document Type + + + + + + + Schema that includes all modules (and redefinitions) + for XHTML1.1 Document Type. + + + + diff --git a/org.argeo.cms/src/org/argeo/cms/acr/xml/ElementIterator.java b/org.argeo.cms/src/org/argeo/cms/acr/xml/ElementIterator.java index 1206fa86a..ea1a17d7e 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/xml/ElementIterator.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/xml/ElementIterator.java @@ -52,7 +52,7 @@ class ElementIterator implements Iterator { if (nextElement == null) throw new NoSuchElementException(); Content result; - String isMount = nextElement.getAttributeNS(CrName.CR_NAMESPACE_URI, CrName.MOUNT.get().getLocalPart()); + String isMount = nextElement.getAttributeNS(CrName.CR_NAMESPACE_URI, CrName.mount.qName().getLocalPart()); if (isMount.equals("true")) { result = session.get(parent.getPath() + '/' + nextElement.getTagName()); } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java index 10bda17fb..2a81b6a7d 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java @@ -39,7 +39,7 @@ public class CmsContextImpl implements CmsContext { private CmsDeployment cmsDeployment; private UserAdmin userAdmin; private UuidFactory uuidFactory; - private ProvidedRepository contentRepository; +// private ProvidedRepository contentRepository; // i18n private Locale defaultLocale; @@ -165,13 +165,13 @@ public class CmsContextImpl implements CmsContext { this.uuidFactory = uuidFactory; } - public ProvidedRepository getContentRepository() { - return contentRepository; - } - - public void setContentRepository(ProvidedRepository contentRepository) { - this.contentRepository = contentRepository; - } +// public ProvidedRepository getContentRepository() { +// return contentRepository; +// } +// +// public void setContentRepository(ProvidedRepository contentRepository) { +// this.contentRepository = contentRepository; +// } @Override public Locale getDefaultLocale() { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/DeployedContentRepository.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/DeployedContentRepository.java index 4a4a4d986..551062379 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/DeployedContentRepository.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/DeployedContentRepository.java @@ -47,13 +47,13 @@ public class DeployedContentRepository extends CmsContentRepository { super.stop(); } - public void addContentProvider(ContentProvider provider, Map properties) { -// String base = LangUtils.get(properties, CmsContentRepository.ACR_MOUNT_PATH_PROPERTY); - addProvider(provider); - } +// public void addContentProvider(ContentProvider provider, Map properties) { +//// String base = LangUtils.get(properties, CmsContentRepository.ACR_MOUNT_PATH_PROPERTY); +// addProvider(provider); +// } - public void removeContentProvider(ContentProvider provider, Map properties) { - } +// public void removeContentProvider(ContentProvider provider, Map properties) { +// } public void setUserManager(CmsUserManager userManager) { this.userManager = userManager; diff --git a/org.argeo.cms/src/org/argeo/cms/runtime/StaticCms.java b/org.argeo.cms/src/org/argeo/cms/runtime/StaticCms.java index a1b8c5401..a868e8c26 100644 --- a/org.argeo.cms/src/org/argeo/cms/runtime/StaticCms.java +++ b/org.argeo.cms/src/org/argeo/cms/runtime/StaticCms.java @@ -126,8 +126,8 @@ public class StaticCms { .addDependency(cmsDeploymentC.getType(CmsDeployment.class), cmsContext::setCmsDeployment, null) // .addDependency(userAdminC.getType(UserAdmin.class), cmsContext::setUserAdmin, null) // .addDependency(uuidFactoryC.getType(UuidFactory.class), cmsContext::setUuidFactory, null) // - .addDependency(contentRepositoryC.getType(ProvidedRepository.class), cmsContext::setContentRepository, - null) // +// .addDependency(contentRepositoryC.getType(ProvidedRepository.class), cmsContext::setContentRepository, +// null) // .build(register); assert cmsContextC.get() == cmsContext; diff --git a/org.argeo.util/src/org/argeo/util/CompositeString.java b/org.argeo.util/src/org/argeo/util/CompositeString.java new file mode 100644 index 000000000..2f8587dec --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/CompositeString.java @@ -0,0 +1,164 @@ +package org.argeo.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.StringTokenizer; + +/** A name that can be expressed with various conventions. */ +public class CompositeString { + public final static Character UNDERSCORE = Character.valueOf('_'); + public final static Character SPACE = Character.valueOf(' '); + public final static Character DASH = Character.valueOf('-'); + + private final String[] parts; + + // optimisation + private final int hashCode; + + public CompositeString(String str) { + Objects.requireNonNull(str, "String cannot be null"); + if ("".equals(str.trim())) + throw new IllegalArgumentException("String cannot be empty"); + if (!str.equals(str.trim())) + throw new IllegalArgumentException("String must be trimmed"); + this.parts = toParts(str); + hashCode = hashCode(this.parts); + } + + public String toString(char separator, boolean upperCase) { + StringBuilder sb = null; + for (String part : parts) { + if (sb == null) { + sb = new StringBuilder(); + } else { + sb.append(separator); + } + sb.append(upperCase ? part.toUpperCase() : part); + } + return sb.toString(); + } + + public String toStringCaml(boolean firstCharUpperCase) { + StringBuilder sb = null; + for (String part : parts) { + if (sb == null) {// first + sb = new StringBuilder(); + sb.append(firstCharUpperCase ? Character.toUpperCase(part.charAt(0)) : part.charAt(0)); + } else { + sb.append(Character.toUpperCase(part.charAt(0))); + } + + if (part.length() > 1) + sb.append(part.substring(1)); + } + return sb.toString(); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof CompositeString)) + return false; + + CompositeString other = (CompositeString) obj; + return Arrays.equals(parts, other.parts); + } + + @Override + public String toString() { + return toString(DASH, false); + } + + public static String[] toParts(String str) { + Character separator = null; + if (str.indexOf(UNDERSCORE) >= 0) { + checkNo(str, SPACE); + checkNo(str, DASH); + separator = UNDERSCORE; + } else if (str.indexOf(DASH) >= 0) { + checkNo(str, SPACE); + checkNo(str, UNDERSCORE); + separator = DASH; + } else if (str.indexOf(SPACE) >= 0) { + checkNo(str, DASH); + checkNo(str, UNDERSCORE); + separator = SPACE; + } + + List res = new ArrayList<>(); + if (separator != null) { + StringTokenizer st = new StringTokenizer(str, separator.toString()); + while (st.hasMoreTokens()) { + res.add(st.nextToken().toLowerCase()); + } + } else { + // single + String strLowerCase = str.toLowerCase(); + if (str.toUpperCase().equals(str) || strLowerCase.equals(str)) + return new String[] { strLowerCase }; + + // CAML + StringBuilder current = null; + for (char c : str.toCharArray()) { + if (Character.isUpperCase(c)) { + if (current != null) + res.add(current.toString()); + current = new StringBuilder(); + } + if (current == null)// first char is lower case + current = new StringBuilder(); + current.append(Character.toLowerCase(c)); + } + res.add(current.toString()); + } + return res.toArray(new String[res.size()]); + } + + private static void checkNo(String str, Character c) { + if (str.indexOf(c) >= 0) { + throw new IllegalArgumentException("Only one kind of sperator is allowed"); + } + } + + private static int hashCode(String[] parts) { + int hashCode = 0; + for (String part : parts) { + hashCode = hashCode + part.hashCode(); + } + return hashCode; + } + + static boolean smokeTests() { + CompositeString plainName = new CompositeString("NAME"); + assert "name".equals(plainName.toString()); + assert "NAME".equals(plainName.toString(UNDERSCORE, true)); + assert "name".equals(plainName.toString(UNDERSCORE, false)); + assert "name".equals(plainName.toStringCaml(false)); + assert "Name".equals(plainName.toStringCaml(true)); + + CompositeString camlName = new CompositeString("myComplexName"); + + assert new CompositeString("my-complex-name").equals(camlName); + assert new CompositeString("MY_COMPLEX_NAME").equals(camlName); + assert new CompositeString("My complex Name").equals(camlName); + assert new CompositeString("MyComplexName").equals(camlName); + + assert "my-complex-name".equals(camlName.toString()); + assert "MY_COMPLEX_NAME".equals(camlName.toString(UNDERSCORE, true)); + assert "my_complex_name".equals(camlName.toString(UNDERSCORE, false)); + assert "myComplexName".equals(camlName.toStringCaml(false)); + assert "MyComplexName".equals(camlName.toStringCaml(true)); + + return CompositeString.class.desiredAssertionStatus(); + } + + public static void main(String[] args) { + System.out.println(smokeTests()); + } +}