X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Facr%2Fxml%2FDomContent.java;h=a4c14186ac17d299b0673e1b67ee0857db166c13;hb=3b45f571938e0eb6803084aac3f2bd298e6026ba;hp=30ecd8e82b649be7251473c204062937f5a3af8c;hpb=c0342975a37c70895c2e8f6b341d790700168d7f;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java index 30ecd8e82..a4c14186a 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/xml/DomContent.java @@ -1,25 +1,38 @@ package org.argeo.cms.acr.xml; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; import java.nio.CharBuffer; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ForkJoinPool; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; +import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import org.argeo.api.acr.Content; import org.argeo.api.acr.ContentName; +import org.argeo.api.acr.CrName; import org.argeo.api.acr.spi.ProvidedContent; import org.argeo.api.acr.spi.ProvidedSession; import org.argeo.cms.acr.AbstractContent; @@ -55,16 +68,24 @@ public class DomContent extends AbstractContent implements ProvidedContent { @Override public QName getName() { - if (element.getParentNode() == null) {// root + if (isLocalRoot()) {// root String mountPath = provider.getMountPath(); if (mountPath != null) { + if (ContentUtils.ROOT_SLASH.equals(mountPath)) { + return CrName.root.qName(); + } Content mountPoint = getSession().getMountPoint(mountPath); - return mountPoint.getName(); + QName mountPointName = mountPoint.getName(); + return mountPointName; } } return toQName(this.element); } + protected boolean isLocalRoot() { + return element.getParentNode() == null || element.getParentNode() instanceof Document; + } + protected QName toQName(Node node) { String prefix = node.getPrefix(); if (prefix == null) { @@ -112,6 +133,8 @@ public class DomContent extends AbstractContent implements ProvidedContent { for (int i = 0; i < attributes.getLength(); i++) { Attr attr = (Attr) attributes.item(i); QName key = toQName(attr); + if (key.getNamespaceURI().equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) + continue;// skip prefix mapping result.add(key); } return result; @@ -129,7 +152,7 @@ public class DomContent extends AbstractContent implements ProvidedContent { else return Optional.empty(); } else - return null; + return Optional.empty(); } @Override @@ -212,15 +235,18 @@ public class DomContent extends AbstractContent implements ProvidedContent { @Override public Content getParent() { Node parentNode = element.getParentNode(); - if (parentNode == null) { + if (isLocalRoot()) { String mountPath = provider.getMountPath(); if (mountPath == null) return null; + if (ContentUtils.ROOT_SLASH.equals(mountPath)) { + return null; + } String[] parent = ContentUtils.getParentPath(mountPath); + if (ContentUtils.EMPTY.equals(parent[0])) + return null; return getSession().get(parent[0]); } - if (parentNode instanceof Document) - return null; if (!(parentNode instanceof Element)) throw new IllegalStateException("Parent is not an element"); return new DomContent(this, (Element) parentNode); @@ -308,7 +334,7 @@ public class DomContent extends AbstractContent implements ProvidedContent { } // parentNode.replaceChild(resultNode, element); // element = (Element)resultNode; - + } catch (DOMException | TransformerException e) { throw new RuntimeException("Cannot write to element", e); } @@ -318,16 +344,74 @@ public class DomContent extends AbstractContent implements ProvidedContent { return super.write(clss); } + @SuppressWarnings("unchecked") + @Override + public C open(Class clss) throws IOException, IllegalArgumentException { + if (InputStream.class.isAssignableFrom(clss)) { + PipedOutputStream out = new PipedOutputStream(); + ForkJoinPool.commonPool().execute(() -> { + try { + Source source = new DOMSource(element); + Result result = new StreamResult(out); + provider.getTransformerFactory().newTransformer().transform(source, result); + out.flush(); + out.close(); + } catch (TransformerException | IOException e) { + throw new RuntimeException("Cannot read " + getPath(), e); + } + }); + return (C) new PipedInputStream(out); + } + return super.open(clss); + } + + @Override + public int getSiblingIndex() { + Node curr = element.getPreviousSibling(); + int count = 1; + while (curr != null) { + if (curr instanceof Element) { + if (Objects.equals(curr.getNamespaceURI(), element.getNamespaceURI()) + && Objects.equals(curr.getLocalName(), element.getLocalName())) { + count++; + } + } + curr = curr.getPreviousSibling(); + } + return count; + } + /* * TYPING */ @Override public List getContentClasses() { List res = new ArrayList<>(); - res.add(getName()); + if (isLocalRoot()) { + String mountPath = provider.getMountPath(); + if (mountPath != null) { + Content mountPoint = getSession().getMountPoint(mountPath); + res.addAll(mountPoint.getContentClasses()); + } + } else { + res.add(getName()); + } return res; } + @Override + public void addContentClasses(QName... contentClass) { + if (isLocalRoot()) { + String mountPath = provider.getMountPath(); + if (mountPath != null) { + Content mountPoint = getSession().getMountPoint(mountPath); + mountPoint.addContentClasses(contentClass); + } + } else { + super.addContentClasses(contentClass); + } + } + /* * MOUNT MANAGEMENT */