Make ACR implementation more robust.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / xml / DomContent.java
index b4931220b2b8077979ab172f0ee5de53915fba6f..ac863403deed8138a298cb25a0efd5ce098c7d0a 100644 (file)
@@ -25,6 +25,7 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
 
+/** Content persisted as a DOM element. */
 public class DomContent extends AbstractContent implements ProvidedContent {
 
        private final ProvidedSession session;
@@ -128,12 +129,31 @@ public class DomContent extends AbstractContent implements ProvidedContent {
                Object previous = get(key);
                String namespaceUriOrNull = XMLConstants.NULL_NS_URI.equals(key.getNamespaceURI()) ? null
                                : key.getNamespaceURI();
+               String prefixToUse = registerPrefixIfNeeded(key);
                element.setAttributeNS(namespaceUriOrNull,
-                               namespaceUriOrNull == null ? key.getLocalPart() : key.getPrefix() + ":" + key.getLocalPart(),
+                               namespaceUriOrNull == null ? key.getLocalPart() : prefixToUse + ":" + key.getLocalPart(),
                                value.toString());
                return previous;
        }
 
+       protected String registerPrefixIfNeeded(QName name) {
+               String namespaceUriOrNull = XMLConstants.NULL_NS_URI.equals(name.getNamespaceURI()) ? null
+                               : name.getNamespaceURI();
+               String prefixToUse;
+               if (namespaceUriOrNull != null) {
+                       String registeredPrefix = provider.getPrefix(namespaceUriOrNull);
+                       if (registeredPrefix != null) {
+                               prefixToUse = registeredPrefix;
+                       } else {
+                               provider.registerPrefix(name.getPrefix(), namespaceUriOrNull);
+                               prefixToUse = name.getPrefix();
+                       }
+               } else {
+                       prefixToUse = null;
+               }
+               return prefixToUse;
+       }
+
        @Override
        public boolean hasText() {
 //             return element instanceof Text;
@@ -204,8 +224,9 @@ public class DomContent extends AbstractContent implements ProvidedContent {
                Document document = this.element.getOwnerDocument();
                String namespaceUriOrNull = XMLConstants.NULL_NS_URI.equals(name.getNamespaceURI()) ? null
                                : name.getNamespaceURI();
+               String prefixToUse = registerPrefixIfNeeded(name);
                Element child = document.createElementNS(namespaceUriOrNull,
-                               namespaceUriOrNull == null ? name.getLocalPart() : name.getPrefix() + ":" + name.getLocalPart());
+                               namespaceUriOrNull == null ? name.getLocalPart() : prefixToUse + ":" + name.getLocalPart());
                element.appendChild(child);
                return new DomContent(this, child);
        }
@@ -226,6 +247,7 @@ public class DomContent extends AbstractContent implements ProvidedContent {
 
        }
 
+       @SuppressWarnings("unchecked")
        @Override
        public <A> A adapt(Class<A> clss) throws IllegalArgumentException {
                if (CharBuffer.class.isAssignableFrom(clss)) {
@@ -236,6 +258,7 @@ public class DomContent extends AbstractContent implements ProvidedContent {
                return super.adapt(clss);
        }
 
+       @SuppressWarnings("unchecked")
        public <A> CompletableFuture<A> write(Class<A> clss) {
                if (String.class.isAssignableFrom(clss)) {
                        CompletableFuture<String> res = new CompletableFuture<>();