Improve, clarify and register namespaces
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 27 Jun 2022 10:37:40 +0000 (12:37 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 27 Jun 2022 10:37:40 +0000 (12:37 +0200)
28 files changed:
eclipse/org.argeo.cms.e4/OSGI-INF/userAdminWrapper.xml
jcr/org.argeo.cms.jcr/OSGI-INF/jcrDeployment.xml
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContentProvider.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java
org.argeo.api.acr/src/org/argeo/api/acr/CompositeString.java [deleted file]
org.argeo.api.acr/src/org/argeo/api/acr/ContentNameSupplier.java [deleted file]
org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java
org.argeo.api.acr/src/org/argeo/api/acr/CrName.java
org.argeo.api.acr/src/org/argeo/api/acr/spi/ProvidedRepository.java
org.argeo.cms/OSGI-INF/acrContentRepository.xml
org.argeo.cms/OSGI-INF/cmsContext.xml
org.argeo.cms/OSGI-INF/deployConfig.xml
org.argeo.cms/src/org/argeo/cms/acr/AbstractContent.java
org.argeo.cms/src/org/argeo/cms/acr/AbstractContentRepository.java
org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java
org.argeo.cms/src/org/argeo/cms/acr/CmsContentTypes.java
org.argeo.cms/src/org/argeo/cms/acr/MountManager.java
org.argeo.cms/src/org/argeo/cms/acr/TypesManager.java
org.argeo.cms/src/org/argeo/cms/acr/directory/HierarchyUnitContent.java
org.argeo.cms/src/org/argeo/cms/acr/fs/FsContent.java
org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-model-1.xsd [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11-modules-1.xsd [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/acr/schemas/xhtml11.xsd [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/acr/xml/ElementIterator.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/DeployedContentRepository.java
org.argeo.cms/src/org/argeo/cms/runtime/StaticCms.java
org.argeo.util/src/org/argeo/util/CompositeString.java [new file with mode: 0644]

index a267aa519f8d759aff1207ddde134fbb6cc9220d..cc7087b6e894c277368ced85b790549c0bad0c62 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="User Admin Wrapper">
    <implementation class="org.argeo.cms.e4.users.UserAdminWrapper"/>
-   <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.osgi.transaction.WorkTransaction" name="UserTransaction" policy="static"/>
+   <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.util.transaction.WorkTransaction" name="UserTransaction" policy="static"/>
    <reference bind="setUserAdmin" cardinality="1..1" interface="org.osgi.service.useradmin.UserAdmin" name="UserAdmin" policy="static"/>
    <service>
       <provide interface="org.argeo.cms.e4.users.UserAdminWrapper"/>
index 2c5a0d145cdddc8b432cef2aab2f183ff65a92fd..a94b15168f483b05ea270c817f69ac04e3ccd0e9 100644 (file)
@@ -2,5 +2,4 @@
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" name="JCR Deployment">
    <implementation class="org.argeo.cms.jcr.internal.CmsJcrDeployment"/>
    <reference bind="setCmsDeployment" cardinality="1..1" interface="org.argeo.api.cms.CmsDeployment" policy="static"/>
-   <reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.spi.ProvidedRepository" name="ProvidedRepository" policy="static"/>
 </scr:component>
index 235e27d1a922139558d8e8c42da322199340dda5..7f471c9b0d656a694482076df38872fb95de098d 100644 (file)
@@ -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<ProvidedSession, JcrSessionAdapter> sessionAdapters = Collections.synchronizedMap(new HashMap<>());
 
        public void start(Map<String, String> 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) {
index 6ba9307bee896c0e6504bb19864935bfd430cc2e..8fb61d70cb0d31ace223f9a5df9c296946478707 100644 (file)
@@ -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<JackrabbitLocalRepository> 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 (file)
index b83fe30..0000000
+++ /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<String> 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 (file)
index f7900af..0000000
+++ /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<ContentName>, 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<String> getPrefixes(String namespaceURI) {
-               Iterator<String> it = NamespaceUtils.getStandardPrefixes(namespaceURI);
-               if (it != null)
-                       return it;
-               if (namespaceURI.equals(getNamespaceURI()))
-                       return Collections.singleton(getDefaultPrefix()).iterator();
-               return Collections.emptyIterator();
-       }
-
-}
index 5d6c57dd506419ad1278da74a9a3cbe078b3b1bf..0bbf63e710142bd881c18c6815e0181b57cbe1f6 100644 (file)
@@ -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
  * <code>String<code>.
  */
-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 <T> CrAttributeType(Class<T> clss, AttributeFormatter<T> formatter) {
+       private ContentName qName;
+
+       private <T> CrAttributeType(Class<T> clss, String namespaceUri, String localName, AttributeFormatter<T> 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
 
index f8ef602dbd5b962eb2c8df739be68c211f7ce26e..1138d095d799afb792012e35b4991cfa195f00be 100644 (file)
@@ -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;
+//     }
 
 }
index 58c068996d71df0a0b0df50b7cd62821717b3c2a..7134007b99e7e09d52d057601b726797d9fe9651 100644 (file)
@@ -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);
 }
index befc95889a6f0efd196761387b77f46ee515edcd..b7a13b4d10041b5d1399831ec51a409fbb5ac298 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="true" name="ACR Content Repository">
    <implementation class="org.argeo.cms.internal.runtime.DeployedContentRepository"/>
-   <reference bind="addContentProvider" cardinality="0..n" interface="org.argeo.api.acr.spi.ContentProvider" name="ContentProvider" policy="dynamic" unbind="removeContentProvider"/>
+   <reference bind="addProvider" cardinality="0..n" interface="org.argeo.api.acr.spi.ContentProvider" name="ContentProvider" policy="dynamic" />
    <service>
       <provide interface="org.argeo.api.acr.ContentRepository"/>
       <provide interface="org.argeo.api.acr.spi.ProvidedRepository"/>
index bec00335069b71d194f7afe6b46583b23b26c729..dfcf7987ebdb675874675a2dccc7c0441b3af95a 100644 (file)
@@ -8,5 +8,4 @@
    <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
    <reference bind="setUserAdmin" cardinality="1..1" interface="org.osgi.service.useradmin.UserAdmin" name="UserAdmin" policy="static"/>
    <reference bind="setUuidFactory" cardinality="1..1" interface="org.argeo.api.uuid.UuidFactory" name="UuidFactory" policy="static"/>
-   <reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.spi.ProvidedRepository" name="ProvidedRepository" policy="static"/>
-</scr:component>
+ </scr:component>
index f82bfc32e8f5157a477525ad5302bc2830c0cc73..55755a920829d7f312d3a26f6c6796abdc28f2ba 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="true" name="Deploy Config">
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="Deploy Config">
    <implementation class="org.argeo.cms.internal.osgi.DeployConfig"/>
    <service>
       <provide interface="org.argeo.cms.internal.osgi.DeployConfig"/>
index 2703af035ee0005f2b386cc0c8dfe3fe2568e629..fd4ef4cfc2c8dddc6870c91d2df8184a4c202289 100644 (file)
@@ -94,7 +94,7 @@ public abstract class AbstractContent extends AbstractMap<QName, Object> 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();
index 2e65e7e691dee045cdb4eb940624691a61a8f8a6..8ff14169868c2d4878cef8152166aa5e60a3c549 100644 (file)
@@ -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,
index 4e1c3bcfd0846c53567c82459988564c278cb4a9..b82507d6f75025528cb4f29c69dc2b9b6637fd91 100644 (file)
@@ -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;
index 67c2063044132fd5b418416933bdf84b054ddc14..6a09a8987c873d80367480b147e6efade51f8973 100644 (file)
@@ -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);
index 3995dc30fcc84c1f32a55f435d94f6cbb0dd280f..6a6dcaacbe795ffa836f25f7738f62884f291310 100644 (file)
@@ -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");
 
        }
 
index 72bb26f209c49e5437d5eaa8895fcffc78c12d7d..6cfb2e5e9cbc2a74736c9a231e488ad99e164ac0 100644 (file)
@@ -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<QName> listTypes() {
index bf8dae72eb722df203ae8a0a13666745ee6a8844..9ded5ee7b38157fe0b3942d812937f37dfb86ac4 100644 (file)
@@ -69,7 +69,7 @@ class HierarchyUnitContent extends AbstractDirectoryContent {
        @Override
        public List<QName> getContentClasses() {
                List<QName> contentClasses = super.getContentClasses();
-               contentClasses.add(CrName.COLLECTION.get());
+               contentClasses.add(CrName.collection.qName());
                return contentClasses;
        }
 
index bbd77b2217c729ee5880d722a6dbf94804f60ae1..15917c50359a003affc0b2d853e444a483526019 100644 (file)
@@ -43,15 +43,15 @@ public class FsContent extends AbstractContent implements ProvidedContent {
        private static final Map<QName, String> POSIX_KEYS;
        static {
                BASIC_KEYS = new HashMap<>();
-               BASIC_KEYS.put(CrName.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<String> isMount = fsContent.get(CrName.MOUNT.get(), String.class);
+                                       Optional<String> 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<QName> getContentClasses() {
                List<QName> 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 (file)
index 0000000..a1c138d
--- /dev/null
@@ -0,0 +1,716 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:xh11d="http://www.w3.org/1999/xhtml/datatypes/"
+    elementFormDefault="qualified" >
+    <xs:import
+        namespace="http://www.w3.org/1999/xhtml/datatypes/"
+        schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-datatypes-1.xsd"/>
+    <xs:annotation>
+        <xs:documentation> 
+            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 $ 
+        </xs:documentation>
+        <xs:documentation source="xhtml-copyright-1.xsd"/>
+    </xs:annotation>
+    <xs:annotation>
+        <xs:documentation> 
+            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 
+        </xs:documentation>
+    </xs:annotation>
+    <xs:attributeGroup
+        name="xhtml.I18n.extra.attrib">
+        <xs:annotation>
+            <xs:documentation> Extended I18n attribute </xs:documentation>
+        </xs:annotation>
+        <xs:attributeGroup
+            ref="xhtml.dir.attrib">
+            <xs:annotation>
+                <xs:documentation> 
+                "dir" Attribute from Bi Directional Text (bdo) Module
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attributeGroup>
+        <xs:attribute name="lang" type="xh11d:LanguageCode" />
+    </xs:attributeGroup>
+    <xs:attributeGroup
+        name="xhtml.Common.extra">
+        <xs:annotation>
+            <xs:documentation> Extended Common Attributes </xs:documentation>
+        </xs:annotation>
+        <xs:attributeGroup
+            ref="xhtml.style.attrib">
+            <xs:annotation>
+                <xs:documentation> 
+                "style" attribute from Inline Style Module 
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attributeGroup>
+       <xs:attributeGroup ref="xhtml.Events.attrib">
+                       <xs:annotation>
+                               <xs:documentation> 
+                               Attributes from Events Module
+                               </xs:documentation>
+                       </xs:annotation>
+               </xs:attributeGroup>
+       </xs:attributeGroup>
+    <xs:attributeGroup
+        name="xhtml.Core.extra.attrib">
+        <xs:annotation>
+            <xs:documentation> Extend Core Attributes </xs:documentation>
+        </xs:annotation>
+    </xs:attributeGroup>
+    <xs:attributeGroup
+        name="xhtml.Global.core.extra.attrib">
+        <xs:annotation>
+            <xs:documentation> Extended Global Core Attributes </xs:documentation>
+        </xs:annotation>
+    </xs:attributeGroup>
+    <xs:attributeGroup
+        name="xhtml.Global.I18n.extra.attrib">
+        <xs:annotation>
+            <xs:documentation> Extended Global I18n attributes </xs:documentation>
+        </xs:annotation>
+    </xs:attributeGroup>
+    <xs:attributeGroup
+        name="xhtml.Global.Common.extra">
+        <xs:annotation>
+            <xs:documentation> Extended Global Common Attributes </xs:documentation>
+        </xs:annotation>
+    </xs:attributeGroup>
+    <xs:group
+        name="xhtml.Head.extra">
+        <xs:sequence/>
+    </xs:group>
+    <xs:group
+        name="xhtml.HeadOpts.mix">
+        <xs:choice>
+            <xs:element
+                name="script"
+                type="xhtml.script.type"/>
+            <xs:element
+                name="style"
+                type="xhtml.style.type"/>
+            <xs:element
+                name="meta"
+                type="xhtml.meta.type"/>
+            <xs:element
+                name="link"
+                type="xhtml.link.type"/>
+            <xs:element
+                name="object"
+                type="xhtml.object.type"/>
+            <xs:group
+                ref="xhtml.Head.extra"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.head.content">
+        <xs:sequence>
+            <xs:group
+                ref="xhtml.HeadOpts.mix"
+                minOccurs="0"
+                maxOccurs="unbounded"/>
+            <xs:choice>
+                <xs:sequence>
+                    <xs:element
+                        name="title"
+                        minOccurs="1"
+                        maxOccurs="1"
+                        type="xhtml.title.type"/>
+                    <xs:group
+                        ref="xhtml.HeadOpts.mix"
+                        minOccurs="0"
+                        maxOccurs="unbounded"/>
+                    <xs:sequence
+                        minOccurs="0">
+                        <xs:element
+                            name="base"
+                            type="xhtml.base.type"/>
+                        <xs:group
+                            ref="xhtml.HeadOpts.mix"
+                            minOccurs="0"
+                            maxOccurs="unbounded"/>
+                    </xs:sequence>
+                </xs:sequence>
+                <xs:sequence>
+                    <xs:element
+                        name="base"
+                        type="xhtml.base.type"
+                        minOccurs="1"
+                        maxOccurs="1"/>
+                    <xs:group
+                        ref="xhtml.HeadOpts.mix"
+                        minOccurs="0"
+                        maxOccurs="unbounded"/>
+                    <xs:element
+                        name="title"
+                        minOccurs="1"
+                        maxOccurs="1"
+                        type="xhtml.title.type"/>
+                    <xs:group
+                        ref="xhtml.HeadOpts.mix"
+                        minOccurs="0"
+                        maxOccurs="unbounded"/>
+                </xs:sequence>
+            </xs:choice>
+        </xs:sequence>
+    </xs:group>
+    <!--
+    ins and del are used to denote editing changes
+  -->
+    <xs:group
+        name="xhtml.Edit.class">
+        <xs:choice>
+            <xs:element
+                name="ins"
+                type="xhtml.edit.type"/>
+            <xs:element
+                name="del"
+                type="xhtml.edit.type"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    script and noscript are used to contain scripts
+    and alternative content
+  -->
+    <xs:group
+        name="xhtml.Script.class">
+        <xs:choice>
+            <xs:element
+                name="script"
+                type="xhtml.script.type"/>
+            <xs:element
+                name="noscript"
+                type="xhtml.noscript.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.Misc.extra">
+        <xs:sequence/>
+    </xs:group>
+    <!--
+    These elements are neither block nor inline, and can
+    essentially be used anywhere in the document body.
+  -->
+    <xs:group
+        name="xhtml.Misc.class">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.Edit.class"/>
+            <xs:group
+                ref="xhtml.Script.class"/>
+            <xs:group
+                ref="xhtml.Misc.extra"/>
+        </xs:choice>
+    </xs:group>
+    <!-- Inline Elements -->
+    <xs:group
+        name="xhtml.InlStruct.class">
+        <xs:choice>
+            <xs:element
+                name="br"
+                type="xhtml.br.type"/>
+            <xs:element
+                name="span"
+                type="xhtml.span.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.InlPhras.class">
+        <xs:choice>
+            <xs:element
+                name="em"
+                type="xhtml.em.type"/>
+            <xs:element
+                name="strong"
+                type="xhtml.strong.type"/>
+            <xs:element
+                name="dfn"
+                type="xhtml.dfn.type"/>
+            <xs:element
+                name="code"
+                type="xhtml.code.type"/>
+            <xs:element
+                name="samp"
+                type="xhtml.samp.type"/>
+            <xs:element
+                name="kbd"
+                type="xhtml.kbd.type"/>
+            <xs:element
+                name="var"
+                type="xhtml.var.type"/>
+            <xs:element
+                name="cite"
+                type="xhtml.cite.type"/>
+            <xs:element
+                name="abbr"
+                type="xhtml.abbr.type"/>
+            <xs:element
+                name="acronym"
+                type="xhtml.acronym.type"/>
+            <xs:element
+                name="q"
+                type="xhtml.q.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.InlPres.class">
+        <xs:choice>
+            <xs:element
+                name="tt"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="i"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="b"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="big"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="small"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="sub"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="sup"
+                type="xhtml.InlPres.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.I18n.class">
+        <xs:sequence>
+            <xs:element
+                name="bdo"
+                type="xhtml.bdo.type"/>
+        </xs:sequence>
+    </xs:group>
+    <xs:group
+        name="xhtml.Anchor.class">
+        <xs:sequence>
+            <xs:element
+                name="a"
+                type="xhtml.a.type"/>
+        </xs:sequence>
+    </xs:group>
+    <xs:group
+        name="xhtml.InlSpecial.class">
+        <xs:choice>
+            <xs:element
+                name="img"
+                type="xhtml.img.type"/>
+            <xs:element
+                name="map"
+                type="xhtml.map.type"/>
+            <xs:element
+                name="object"
+                type="xhtml.object.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.InlForm.class">
+        <xs:choice>
+            <xs:element
+                name="input"
+                type="xhtml.input.type"/>
+            <xs:element
+                name="select"
+                type="xhtml.select.type"/>
+            <xs:element
+                name="textarea"
+                type="xhtml.textarea.type"/>
+            <xs:element
+                name="label"
+                type="xhtml.label.type"/>
+            <xs:element
+                name="button"
+                type="xhtml.button.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.Inline.extra">
+        <xs:sequence/>
+    </xs:group>
+    <xs:group
+        name="xhtml.Ruby.class">
+        <xs:sequence>
+            <xs:element
+                name="ruby"
+                type="xhtml.ruby.type"/>
+        </xs:sequence>
+    </xs:group>
+    <!--
+    Inline.class includes all inline elements,
+    used as a component in mixes
+  -->
+    <xs:group
+        name="xhtml.Inline.class">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.InlStruct.class"/>
+            <xs:group
+                ref="xhtml.InlPhras.class"/>
+            <xs:group
+                ref="xhtml.InlPres.class"/>
+            <xs:group
+                ref="xhtml.I18n.class"/>
+            <xs:group
+                ref="xhtml.Anchor.class"/>
+            <xs:group
+                ref="xhtml.InlSpecial.class"/>
+            <xs:group
+                ref="xhtml.InlForm.class"/>
+            <xs:group
+                ref="xhtml.Ruby.class"/>
+            <xs:group
+                ref="xhtml.Inline.extra"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+     InlNoRuby.class includes all inline elements
+     except ruby
+  -->
+    <xs:group
+        name="xhtml.InlNoRuby.class">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.InlStruct.class"/>
+            <xs:group
+                ref="xhtml.InlPhras.class"/>
+            <xs:group
+                ref="xhtml.InlPres.class"/>
+            <xs:group
+                ref="xhtml.I18n.class"/>
+            <xs:group
+                ref="xhtml.Anchor.class"/>
+            <xs:group
+                ref="xhtml.InlSpecial.class"/>
+            <xs:group
+                ref="xhtml.InlForm.class"/>
+            <xs:group
+                ref="xhtml.Inline.extra"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    InlinePre.mix
+    Used as a component in pre model
+  -->
+    <xs:group
+        name="xhtml.InlinePre.mix">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.InlStruct.class"/>
+            <xs:group
+                ref="xhtml.InlPhras.class"/>
+            <xs:element
+                name="tt"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="i"
+                type="xhtml.InlPres.type"/>
+            <xs:element
+                name="b"
+                type="xhtml.InlPres.type"/>
+            <xs:group
+                ref="xhtml.I18n.class"/>
+            <xs:group
+                ref="xhtml.Anchor.class"/>
+            <xs:group
+                ref="xhtml.Misc.class"/>
+            <xs:element
+                name="map"
+                type="xhtml.map.type"/>
+            <xs:group
+                ref="xhtml.Inline.extra"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    InlNoAnchor.class includes all non-anchor inlines,
+    used as a component in mixes
+  -->
+    <xs:group
+        name="xhtml.InlNoAnchor.class">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.InlStruct.class"/>
+            <xs:group
+                ref="xhtml.InlPhras.class"/>
+            <xs:group
+                ref="xhtml.InlPres.class"/>
+            <xs:group
+                ref="xhtml.I18n.class"/>
+            <xs:group
+                ref="xhtml.InlSpecial.class"/>
+            <xs:group
+                ref="xhtml.InlForm.class"/>
+            <xs:group
+                ref="xhtml.Ruby.class"/>
+            <xs:group
+                ref="xhtml.Inline.extra"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    InlNoAnchor.mix includes all non-anchor inlines
+  -->
+    <xs:group
+        name="xhtml.InlNoAnchor.mix">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.InlNoAnchor.class"/>
+            <xs:group
+                ref="xhtml.Misc.class"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    Inline.mix includes all inline elements, including Misc.class
+  -->
+    <xs:group
+        name="xhtml.Inline.mix">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.Inline.class"/>
+            <xs:group
+                ref="xhtml.Misc.class"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+   InlNoRuby.mix includes all of inline.mix elements
+   except ruby
+  -->
+    <xs:group
+        name="xhtml.InlNoRuby.mix">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.InlNoRuby.class"/>
+            <xs:group
+                ref="xhtml.Misc.class"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    In the HTML 4 DTD, heading and list elements were included
+    in the block group. The Heading.class and
+    List.class groups must now be included explicitly
+    on element declarations where desired.
+  -->
+    <xs:group
+        name="xhtml.Heading.class">
+        <xs:choice>
+            <xs:element
+                name="h1"
+                type="xhtml.h1.type"/>
+            <xs:element
+                name="h2"
+                type="xhtml.h2.type"/>
+            <xs:element
+                name="h3"
+                type="xhtml.h3.type"/>
+            <xs:element
+                name="h4"
+                type="xhtml.h4.type"/>
+            <xs:element
+                name="h5"
+                type="xhtml.h5.type"/>
+            <xs:element
+                name="h6"
+                type="xhtml.h6.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.List.class">
+        <xs:choice>
+            <xs:element
+                name="ul"
+                type="xhtml.ul.type"/>
+            <xs:element
+                name="ol"
+                type="xhtml.ol.type"/>
+            <xs:element
+                name="dl"
+                type="xhtml.dl.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.Table.class">
+        <xs:choice>
+            <xs:element
+                name="table"
+                type="xhtml.table.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.Form.class">
+        <xs:choice>
+            <xs:element
+                name="form"
+                type="xhtml.form.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.Fieldset.class">
+        <xs:choice>
+            <xs:element
+                name="fieldset"
+                type="xhtml.fieldset.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.BlkStruct.class">
+        <xs:choice>
+            <xs:element
+                name="p"
+                type="xhtml.p.type"/>
+            <xs:element
+                name="div"
+                type="xhtml.div.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.BlkPhras.class">
+        <xs:choice>
+            <xs:element
+                name="pre"
+                type="xhtml.pre.type"/>
+            <xs:element
+                name="blockquote"
+                type="xhtml.blockquote.type"/>
+            <xs:element
+                name="address"
+                type="xhtml.address.type"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.BlkPres.class">
+        <xs:sequence>
+            <xs:element
+                name="hr"
+                type="xhtml.hr.type"/>
+        </xs:sequence>
+    </xs:group>
+    <xs:group
+        name="xhtml.BlkSpecial.class">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.Table.class"/>
+            <xs:group
+                ref="xhtml.Form.class"/>
+            <xs:group
+                ref="xhtml.Fieldset.class"/>
+        </xs:choice>
+    </xs:group>
+    <xs:group
+        name="xhtml.Block.extra">
+        <xs:sequence/>
+    </xs:group>
+    <!--
+    Block.class includes all block elements,
+    used as an component in mixes
+  -->
+    <xs:group
+        name="xhtml.Block.class">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.BlkStruct.class"/>
+            <xs:group
+                ref="xhtml.BlkPhras.class"/>
+            <xs:group
+                ref="xhtml.BlkPres.class"/>
+            <xs:group
+                ref="xhtml.BlkSpecial.class"/>
+            <xs:group
+                ref="xhtml.Block.extra"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+   Block.mix includes all block elements plus %Misc.class;
+  -->
+    <xs:group
+        name="xhtml.Block.mix">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.Heading.class"/>
+            <xs:group
+                ref="xhtml.List.class"/>
+            <xs:group
+                ref="xhtml.Block.class"/>
+            <xs:group
+                ref="xhtml.Misc.class"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    All Content Elements
+    Flow.mix includes all text content, block and inline
+    Note that the "any" element included here allows us
+    to add data from any other namespace, a necessity
+    for compound document creation.
+    Note however that it is not possible to add
+    to any head level element without further
+    modification. To add RDF metadata to the head
+    of a document, modify the structure module.
+  -->
+    <xs:group
+        name="xhtml.Flow.mix">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.Heading.class"/>
+            <xs:group
+                ref="xhtml.List.class"/>
+            <xs:group
+                ref="xhtml.Block.class"/>
+            <xs:group
+                ref="xhtml.Inline.class"/>
+            <xs:group
+                ref="xhtml.Misc.class"/>
+        </xs:choice>
+    </xs:group>
+    <!--
+    BlkNoForm.mix includes all non-form block elements,
+    plus Misc.class
+  -->
+    <xs:group
+        name="xhtml.BlkNoForm.mix">
+        <xs:choice>
+            <xs:group
+                ref="xhtml.Heading.class"/>
+            <xs:group
+                ref="xhtml.List.class"/>
+            <xs:group
+                ref="xhtml.BlkStruct.class"/>
+            <xs:group
+                ref="xhtml.BlkPhras.class"/>
+            <xs:group
+                ref="xhtml.BlkPres.class"/>
+            <xs:group
+                ref="xhtml.Table.class"/>
+            <xs:group
+                ref="xhtml.Block.extra"/>
+            <xs:group
+                ref="xhtml.Misc.class"/>
+        </xs:choice>
+    </xs:group>
+    <xs:element
+        name="html"
+        type="xhtml.html.type"/>
+</xs:schema>
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 (file)
index 0000000..6767067
--- /dev/null
@@ -0,0 +1,605 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+           elementFormDefault="qualified" 
+           xmlns:xh11d="http://www.w3.org/1999/xhtml/datatypes/" >
+    <xs:import namespace="http://www.w3.org/1999/xhtml/datatypes/" 
+        schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-datatypes-1.xsd" />
+
+    <xs:annotation>
+        <xs:documentation>
+      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 $
+    </xs:documentation>
+        <xs:documentation source="xhtml-copyright-1.xsd"/>
+    </xs:annotation>
+    <xs:annotation>
+        <xs:documentation>
+     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
+
+    </xs:documentation>
+    </xs:annotation>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-framework-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Schema Framework Component Modules:
+            +  notations
+            +  datatypes
+            +  common attributes
+            +  character entities
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_commonatts"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-text-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        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
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410/abstract_modules.html#s_textmodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-hypertext-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+         Hypertext module
+
+         Elements defined here:
+          * a
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410/abstract_modules.html#s_hypertextmodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.a.attlist">
+            <xs:attributeGroup ref="xhtml.a.attlist"/>
+            <xs:attributeGroup ref="xhtml.a.csim.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+              Redefinition by Client Side Image Map Module
+            </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.a.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+              Redefinition by XHTML Event Attribute Module
+            </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.a.target.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+              Target Module - A Attribute Additions
+            </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-list-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Lists module
+
+        Elements defined here:
+          * dt, dd, dl, ol, ul, li
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410/abstract_modules.html#s_listmodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-struct-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Structural module
+
+        Elements defined here:
+          * title, head, body, html
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410/abstract_modules.html#s_structuremodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.version.attrib">
+            <xs:annotation>
+                <xs:documentation>
+            Redefinition by the XHTML11 Markup (for value of version attr)
+         </xs:documentation>
+            </xs:annotation>
+            <xs:attribute name="version" type="xh11d:CDATA" fixed="-//W3C//DTD XHTML 1.1//EN"/>
+        </xs:attributeGroup>
+        <xs:attributeGroup name="xhtml.body.attlist">
+            <xs:attributeGroup ref="xhtml.body.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+              Original Body Attlist
+            </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.body.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+              Redefinition by XHTML Event Attribute Module
+            </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-edit-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Edit module
+
+        Elements defined here:
+          * ins, del
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_editmodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-bdo-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Bidirectional element module
+
+        Elements defined here:
+          * bdo
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_bdomodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-pres-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Presentational module
+
+         Elements defined here:
+           * hr, b, big, i, small,sub, sup, tt
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_presentationmodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-link-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+                Link module
+
+                Elements defined here:
+                   * link
+            </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_linkmodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.link.attlist">
+            <xs:annotation>
+                <xs:documentation>
+            Changes to XHTML Link Attlist
+          </xs:documentation>
+            </xs:annotation>
+            <xs:attributeGroup ref="xhtml.link.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Link Attributes (declared in Link Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.link.target.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                      XHTML Target Module - Attribute additions
+                     </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-meta-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Meta module
+
+        Elements defined here:
+        * meta
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_metamodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-base-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Base module
+
+        Elements defined here:
+          * base
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_basemodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.base.attlist">
+            <xs:annotation>
+                <xs:documentation>
+            Changes to XHTML base Attlist
+          </xs:documentation>
+            </xs:annotation>
+            <xs:attributeGroup ref="xhtml.base.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Base Attributes (declared in Base Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.base.target.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                XHTML Target Module - Attribute additions
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-script-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Scripting module
+
+        Elements defined here:
+          * script, noscript
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_scriptmodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-style-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Style module
+
+        Elements defined here:
+          * style
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_stylemodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-inlstyle-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Style attribute module
+
+        Attribute defined here:
+          * style
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_styleattributemodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-image-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Image module
+
+        Elements defined here:
+          * img
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_imagemodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.img.attlist">
+            <xs:attributeGroup ref="xhtml.img.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Image Attributes (in Image Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.img.csim.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Redefinition by Client Side Image Map Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.img.ssimap.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Redefinition by Server Side Image Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-csismap-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Client-side mage maps module
+
+        Elements defined here:
+          * area, map
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_imapmodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.area.attlist">
+            <xs:attributeGroup ref="xhtml.area.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Area Attributes (in CSI Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.area.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Redefinition by Events Attribute Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.area.target.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Target Module - Area Attribute Additions
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-ssismap-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+       Server-side image maps module
+
+        Attributes defined here:
+          * ismap on img
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_servermapmodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-object-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Object module
+
+        Elements defined here:
+          * object
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_objectmodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.object.attlist">
+            <xs:attributeGroup ref="xhtml.object.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Object Attlist
+              </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.object.csim.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Redefinition by Client Image Map Module
+              </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-param-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Param module
+
+        Elements defined here:
+          * param
+      </xs:documentation>
+        </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-table-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Tables module
+
+        Elements defined here:
+          * table, caption, thead, tfoot, tbody, colgroup, col, tr, th, td
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_tablemodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:redefine schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-form-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+            Forms module
+
+            Elements defined here:
+              * form, label, input, select, optgroup, option,
+              * textarea, fieldset, legend, button
+          </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_extformsmodule"/>
+        </xs:annotation>
+        <xs:attributeGroup name="xhtml.form.attlist">
+            <xs:annotation>
+                <xs:documentation>
+            Changes to XHTML Form Attlist
+          </xs:documentation>
+            </xs:annotation>
+            <xs:attributeGroup ref="xhtml.form.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Form Attributes (declared in Forms Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.form.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                XHTML Events Module - Attribute additions
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.form.target.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                      XHTML Target Module - Attribute additions
+                     </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+        <xs:attributeGroup name="xhtml.input.attlist">
+            <xs:annotation>
+                <xs:documentation>
+            Changes to XHTML Form Input Element
+          </xs:documentation>
+            </xs:annotation>
+            <xs:attributeGroup ref="xhtml.input.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Input Attributes (in Forms Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.input.csim.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Redefinition by Client Side Image Map Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.input.ssimap.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Redefinition by Server Side Image Map Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.input.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+               Redefinition by Event Attribute Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+        <xs:attributeGroup name="xhtml.label.attlist">
+            <xs:attributeGroup ref="xhtml.label.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Label Attributes (in Forms Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.label.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+               Redefinition by Event Attribute Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+        <xs:attributeGroup name="xhtml.select.attlist">
+            <xs:attributeGroup ref="xhtml.select.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Select Attributes (in Forms Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.select.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+               Redefinition by Event Attribute Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+        <xs:attributeGroup name="xhtml.textarea.attlist">
+            <xs:attributeGroup ref="xhtml.textarea.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original TextArea Attributes (in Forms Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.textarea.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+               Redefinition by Event Attribute Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+        <xs:attributeGroup name="xhtml.button.attlist">
+            <xs:attributeGroup ref="xhtml.button.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+                Original Button Attributes (in Forms Module)
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+            <xs:attributeGroup ref="xhtml.button.events.attlist">
+                <xs:annotation>
+                    <xs:documentation>
+               Redefinition by Event Attribute Module
+             </xs:documentation>
+                </xs:annotation>
+            </xs:attributeGroup>
+        </xs:attributeGroup>
+    </xs:redefine>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-ruby-1.xsd">
+      <xs:annotation>
+      <xs:documentation>
+        Ruby module
+
+        Elements defined here:
+          * ruby, rbc, rtc, rb, rt, rp
+
+        Note that either Ruby or Basic Ruby should be used but not both
+      </xs:documentation>
+      <xs:documentation source="http://www.w3.org/TR/2001/REC-ruby-20010531/#complex"/>
+      </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-events-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        XHTML Events Modules
+
+        Attributes defined here:
+          XHTML Event Types
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_intrinsiceventsmodule"/>
+        </xs:annotation>
+    </xs:include>
+    <xs:include schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml-target-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        XHTML Target Attribute Module
+
+        Attributes defined here:
+          target
+      </xs:documentation>
+            <xs:documentation source="http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_targetmodule"/>
+        </xs:annotation>
+    </xs:include>
+</xs:schema>
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 (file)
index 0000000..3416999
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://www.w3.org/1999/xhtml"
+    xmlns:xh11d="http://www.w3.org/1999/xhtml/datatypes/"
+    xmlns="http://www.w3.org/1999/xhtml"
+    elementFormDefault="qualified" >
+    <xs:annotation>
+        <xs:documentation>
+      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 $
+    </xs:documentation>
+        <xs:documentation source="xhtml-copyright-1.xsd"/>
+    </xs:annotation>
+    <xs:annotation>
+        <xs:documentation>
+      This is XHTML, a reformulation of HTML as a modular XML application
+      The Extensible HyperText Markup Language (XHTML)
+      Copyright &#169;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.
+    </xs:documentation>
+    </xs:annotation>
+    <xs:annotation>
+        <xs:documentation>
+      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
+    </xs:documentation>
+    </xs:annotation>
+    <xs:import
+        namespace="http://www.w3.org/XML/1998/namespace"
+        schemaLocation="http://www.w3.org/2001/xml.xsd">
+        <xs:annotation>
+            <xs:documentation>
+         This import brings in the XML namespace attributes
+         The XML attributes are used by various modules.
+       </xs:documentation>
+        </xs:annotation>
+    </xs:import>
+    <xs:include
+        schemaLocation="xhtml11-model-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        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
+      </xs:documentation>
+        </xs:annotation>
+    </xs:include>
+    <xs:include
+        schemaLocation="xhtml11-modules-1.xsd">
+        <xs:annotation>
+            <xs:documentation>
+        Schema that includes all modules (and redefinitions)
+        for XHTML1.1 Document Type.                
+           </xs:documentation>
+        </xs:annotation>
+    </xs:include>
+</xs:schema>
index 1206fa86a10f3759b4cdee662b963eb1d6846b77..ea1a17d7e88efd5ec67d377050db30b0909b7597 100644 (file)
@@ -52,7 +52,7 @@ class ElementIterator implements Iterator<Content> {
                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());
                }
index 10bda17fb79fbde5a579efbe383f8dddf0e99bab..2a81b6a7d11db963e7f8319f5e9761b9451dbad9 100644 (file)
@@ -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() {
index 4a4a4d9867863a4e4bf4ecf3887ba63ecdc37ab3..551062379a6047d9fbb733aee597719ca6b16d29 100644 (file)
@@ -47,13 +47,13 @@ public class DeployedContentRepository extends CmsContentRepository {
                super.stop();
        }
 
-       public void addContentProvider(ContentProvider provider, Map<String, Object> properties) {
-//             String base = LangUtils.get(properties, CmsContentRepository.ACR_MOUNT_PATH_PROPERTY);
-               addProvider(provider);
-       }
+//     public void addContentProvider(ContentProvider provider, Map<String, Object> properties) {
+////           String base = LangUtils.get(properties, CmsContentRepository.ACR_MOUNT_PATH_PROPERTY);
+//             addProvider(provider);
+//     }
 
-       public void removeContentProvider(ContentProvider provider, Map<String, Object> properties) {
-       }
+//     public void removeContentProvider(ContentProvider provider, Map<String, Object> properties) {
+//     }
 
        public void setUserManager(CmsUserManager userManager) {
                this.userManager = userManager;
index a1b8c54010b89828b9d72244a91dcdd96d39b6ad..a868e8c26ed02c9a94d9899a35c011ae19b7c1ba 100644 (file)
@@ -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 (file)
index 0000000..2f8587d
--- /dev/null
@@ -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<String> 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());
+       }
+}