X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=jcr%2Forg.argeo.cms.jcr%2Fsrc%2Forg%2Fargeo%2Fcms%2Fjcr%2Facr%2FJcrContent.java;h=dab41979498957a91a3906eb0402acfe4c85b57d;hb=279880f110272df643cee670aa976ae5ab9ec396;hp=04c5d2d8c3b2f0d32960c52d05e64bc572e70b77;hpb=8282011b0e20e80704b209ad55fa9fb132e16280;p=lgpl%2Fargeo-commons.git diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java index 04c5d2d8c..dab419794 100644 --- a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java +++ b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java @@ -1,8 +1,18 @@ package org.argeo.cms.jcr.acr; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.ArrayList; import java.util.Calendar; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ForkJoinPool; import javax.jcr.Node; import javax.jcr.NodeIterator; @@ -13,93 +23,131 @@ import javax.jcr.RepositoryException; import javax.jcr.Value; import javax.jcr.nodetype.NodeType; import javax.xml.namespace.QName; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; import org.argeo.api.acr.Content; +import org.argeo.api.acr.ContentUtils; +import org.argeo.api.acr.NamespaceUtils; import org.argeo.api.acr.spi.AbstractContent; import org.argeo.api.acr.spi.ProvidedSession; +import org.argeo.api.cms.CmsConstants; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; +/** A JCR {@link Node} accessed as {@link Content}. */ public class JcrContent extends AbstractContent { - private Node jcrNode; +// private Node jcrNode; private JcrContentProvider provider; private ProvidedSession session; - protected JcrContent(ProvidedSession session, JcrContentProvider provider, Node node) { + private String jcrWorkspace; + private String jcrPath; + + protected JcrContent(ProvidedSession session, JcrContentProvider provider, String jcrWorkspace, String jcrPath) { this.session = session; this.provider = provider; - this.jcrNode = node; + this.jcrWorkspace = jcrWorkspace; + this.jcrPath = jcrPath; } @Override public QName getName() { - return session.parsePrefixedName(Jcr.getName(jcrNode)); + String name = Jcr.getName(getJcrNode()); + if (name.equals("")) {// root + String mountPath = provider.getMountPath(); + name = ContentUtils.getParentPath(mountPath)[1]; + // name = Jcr.getWorkspaceName(getJcrNode()); + } + return NamespaceUtils.parsePrefixedName(provider, name); } + @SuppressWarnings("unchecked") @Override public Optional get(QName key, Class clss) { if (isDefaultAttrTypeRequested(clss)) { - return Optional.of((A) get(jcrNode, key.toString())); + return Optional.of((A) get(getJcrNode(), key.toString())); } - return Optional.of((A) Jcr.get(jcrNode, key.toString())); + return Optional.of((A) Jcr.get(getJcrNode(), key.toString())); } @Override public Iterator iterator() { try { - return new JcrContentIterator(jcrNode.getNodes()); + return new JcrContentIterator(getJcrNode().getNodes()); } catch (RepositoryException e) { - throw new JcrException("Cannot list children of " + jcrNode, e); + throw new JcrException("Cannot list children of " + getJcrNode(), e); } } @Override protected Iterable keys() { - return new Iterable() { - - @Override - public Iterator iterator() { - try { - PropertyIterator propertyIterator = jcrNode.getProperties(); - return new JcrKeyIterator(provider, propertyIterator); - } catch (RepositoryException e) { - throw new JcrException("Cannot retrive properties from " + jcrNode, e); - } + try { + Set keys = new HashSet<>(); + for (PropertyIterator propertyIterator = getJcrNode().getProperties(); propertyIterator.hasNext();) { + Property property = propertyIterator.nextProperty(); + // TODO convert standard names + // TODO skip technical properties + QName name = NamespaceUtils.parsePrefixedName(provider, property.getName()); + keys.add(name); } - }; + return keys; + } catch (RepositoryException e) { + throw new JcrException("Cannot list properties of " + getJcrNode(), e); + } } public Node getJcrNode() { - return jcrNode; + try { + // TODO caching? + return provider.getJcrSession(session, jcrWorkspace).getNode(jcrPath); + } catch (RepositoryException e) { + throw new JcrException("Cannot retrieve " + jcrPath + " from workspace " + jcrWorkspace, e); + } } /** Cast to a standard Java object. */ static Object get(Node node, String property) { try { - Value value = node.getProperty(property).getValue(); - switch (value.getType()) { - case PropertyType.STRING: - return value.getString(); - case PropertyType.DOUBLE: - return (Double) value.getDouble(); - case PropertyType.LONG: - return (Long) value.getLong(); - case PropertyType.BOOLEAN: - return (Boolean) value.getBoolean(); - case PropertyType.DATE: - Calendar calendar = value.getDate(); - return calendar.toInstant(); - case PropertyType.BINARY: - throw new IllegalArgumentException("Binary is not supported as an attribute"); - default: - return value.getString(); + Property p = node.getProperty(property); + if (p.isMultiple()) { + Value[] values = p.getValues(); + List lst = new ArrayList<>(); + for (Value value : values) { + lst.add(convertSingleValue(value)); + } + return lst; + } else { + Value value = node.getProperty(property).getValue(); + return convertSingleValue(value); } } catch (RepositoryException e) { throw new JcrException("Cannot cast value from " + property + " of node " + node, e); } } + static Object convertSingleValue(Value value) throws RepositoryException { + switch (value.getType()) { + case PropertyType.STRING: + return value.getString(); + case PropertyType.DOUBLE: + return (Double) value.getDouble(); + case PropertyType.LONG: + return (Long) value.getLong(); + case PropertyType.BOOLEAN: + return (Boolean) value.getBoolean(); + case PropertyType.DATE: + Calendar calendar = value.getDate(); + return calendar.toInstant(); + case PropertyType.BINARY: + throw new IllegalArgumentException("Binary is not supported as an attribute"); + default: + return value.getString(); + } + } + class JcrContentIterator implements Iterator { private final NodeIterator nodeIterator; // we keep track in order to be able to delete it @@ -116,7 +164,7 @@ public class JcrContent extends AbstractContent { @Override public Content next() { - current = new JcrContent(session, provider, nodeIterator.nextNode()); + current = new JcrContent(session, provider, jcrWorkspace, Jcr.getPath(nodeIterator.nextNode())); return current; } @@ -131,7 +179,7 @@ public class JcrContent extends AbstractContent { @Override public Content getParent() { - return new JcrContent(session, provider, Jcr.getParent(getJcrNode())); + return new JcrContent(session, provider, jcrWorkspace, Jcr.getParentPath(getJcrNode())); } @Override @@ -171,31 +219,88 @@ public class JcrContent extends AbstractContent { } - class JcrKeyIterator implements Iterator { - private final JcrContentProvider contentSession; - private final PropertyIterator propertyIterator; + /* + * ADAPTERS + */ + public A adapt(Class clss) { + if (Source.class.isAssignableFrom(clss)) { +// try { + PipedInputStream in = new PipedInputStream(); - protected JcrKeyIterator(JcrContentProvider contentSession, PropertyIterator propertyIterator) { - this.contentSession = contentSession; - this.propertyIterator = propertyIterator; - } + ForkJoinPool.commonPool().execute(() -> { + try (PipedOutputStream out = new PipedOutputStream(in)) { + provider.getJcrSession(session, jcrWorkspace).exportDocumentView(jcrPath, out, true, false); + out.flush(); + } catch (IOException | RepositoryException e) { + throw new RuntimeException("Cannot export " + jcrPath + " in workspace " + jcrWorkspace, e); + } - @Override - public boolean hasNext() { - return propertyIterator.hasNext(); - } + }); + return (A) new StreamSource(in); +// } catch (IOException e) { +// throw new RuntimeException("Cannot adapt " + JcrContent.this + " to " + clss, e); +// } + } else - @Override - public QName next() { - Property property = null; - try { - property = propertyIterator.nextProperty(); - // TODO map standard property names - return session.parsePrefixedName(property.getName()); - } catch (RepositoryException e) { - throw new JcrException("Cannot retrieve property " + property, null); + return super.adapt(clss); + } + + @Override + public C open(Class clss) throws IOException, IllegalArgumentException { + if (InputStream.class.isAssignableFrom(clss)) { + Node node = getJcrNode(); + if (Jcr.isNodeType(node, NodeType.NT_FILE)) { + try { + return (C) JcrUtils.getFileAsStream(node); + } catch (RepositoryException e) { + throw new JcrException("Cannot open " + jcrPath + " in workspace " + jcrWorkspace, e); + } } } + return super.open(clss); + } +// class JcrKeyIterator implements Iterator { +// private final PropertyIterator propertyIterator; +// +// protected JcrKeyIterator(PropertyIterator propertyIterator) { +// this.propertyIterator = propertyIterator; +// } +// +// @Override +// public boolean hasNext() { +// return propertyIterator.hasNext(); +// } +// +// @Override +// public QName next() { +// Property property = null; +// try { +// property = propertyIterator.nextProperty(); +// // TODO map standard property names +// return NamespaceUtils.parsePrefixedName(provider, property.getName()); +// } catch (RepositoryException e) { +// throw new JcrException("Cannot retrieve property " + property, null); +// } +// } +// +// } + /* + * STATIC UTLITIES + */ + public static Content nodeToContent(Node node) { + if (node == null) + return null; + try { + ProvidedSession contentSession = (ProvidedSession) node.getSession() + .getAttribute(ProvidedSession.class.getName()); + if (contentSession == null) + throw new IllegalArgumentException( + "Cannot adapt " + node + " to content, because it was not loaded from a content session"); + return contentSession.get(CmsConstants.SYS_WORKSPACE + node.getPath()); + } catch (RepositoryException e) { + throw new JcrException("Cannot adapt " + node + " to a content", e); + } } + }