package org.argeo.cms.acr.xml;
import java.nio.CharBuffer;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentName;
import org.argeo.cms.acr.AbstractContent;
import org.argeo.cms.acr.ContentUtils;
import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/** Content persisted as a DOM element. */
public class DomContent extends AbstractContent implements ProvidedContent {
- private final ProvidedSession session;
private final DomContentProvider provider;
private final Element element;
private Boolean hasText = null;
public DomContent(ProvidedSession session, DomContentProvider contentProvider, Element element) {
- this.session = session;
+ super(session);
this.provider = contentProvider;
this.element = element;
}
if (element.getParentNode() == null) {// root
String mountPath = provider.getMountPath();
if (mountPath != null) {
- Content mountPoint = session.getMountPoint(mountPath);
+ Content mountPoint = getSession().getMountPoint(mountPath);
return mountPoint.getName();
}
}
@Override
public Iterator<Content> iterator() {
NodeList nodeList = element.getChildNodes();
- return new ElementIterator(this, session, provider, nodeList);
+ return new ElementIterator(this, getSession(), provider, nodeList);
}
@Override
if (mountPath == null)
return null;
String[] parent = ContentUtils.getParentPath(mountPath);
- return session.get(parent[0]);
+ return getSession().get(parent[0]);
}
if (parentNode instanceof Document)
return null;
String textContent = element.getTextContent();
CharBuffer buf = CharBuffer.wrap(textContent);
return (A) buf;
+ } else if (Source.class.isAssignableFrom(clss)) {
+ DOMSource source = new DOMSource(element);
+ return (A) source;
}
return super.adapt(clss);
}
if (String.class.isAssignableFrom(clss)) {
CompletableFuture<String> res = new CompletableFuture<>();
res.thenAccept((s) -> {
- session.notifyModification(this);
+ getSession().notifyModification(this);
element.setTextContent(s);
});
return (CompletableFuture<A>) res;
+ } else if (Source.class.isAssignableFrom(clss)) {
+ CompletableFuture<Source> res = new CompletableFuture<>();
+ res.thenAccept((source) -> {
+ try {
+ Transformer transformer = provider.getTransformerFactory().newTransformer();
+ DocumentFragment documentFragment = element.getOwnerDocument().createDocumentFragment();
+ DOMResult result = new DOMResult(documentFragment);
+ transformer.transform(source, result);
+ // Node parentNode = element.getParentNode();
+ Element resultElement = (Element) documentFragment.getFirstChild();
+ QName resultName = toQName(resultElement);
+ if (!resultName.equals(getName()))
+ throw new IllegalArgumentException(resultName + "+ is not compatible with " + getName());
+
+ // attributes
+ NamedNodeMap attrs = resultElement.getAttributes();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ Attr attr2 = (Attr) element.getOwnerDocument().importNode(attrs.item(i), true);
+ element.getAttributes().setNamedItem(attr2);
+ }
+
+ // Move all the children
+ while (element.hasChildNodes()) {
+ element.removeChild(element.getFirstChild());
+ }
+ while (resultElement.hasChildNodes()) {
+ element.appendChild(resultElement.getFirstChild());
+ }
+// parentNode.replaceChild(resultNode, element);
+// element = (Element)resultNode;
+
+ } catch (DOMException | TransformerException e) {
+ throw new RuntimeException("Cannot write to element", e);
+ }
+ });
+ return (CompletableFuture<A>) res;
}
return super.write(clss);
}
+ /*
+ * TYPING
+ */
+ @Override
+ public List<QName> getContentClasses() {
+ List<QName> res = new ArrayList<>();
+ res.add(getName());
+ return res;
+ }
+
/*
* MOUNT MANAGEMENT
*/
return new DomContent(this, childElement);
}
- public ProvidedSession getSession() {
- return session;
- }
-
+ @Override
public DomContentProvider getProvider() {
return provider;
}