--- /dev/null
+package org.argeo.eclipse.ui.jcr.util;
+
+import java.io.InputStream;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.argeo.eclipse.ui.FileProvider;
+
+/**
+ * Implements a FileProvider for UI purposes. Note that it might not be very
+ * reliable as long as we have not fixed login and multi repository issues that
+ * will be addressed in the next version.
+ *
+ * NOTE: id used here is the real id of the JCR Node, not the JCR Path
+ *
+ * Relies on common approach for JCR file handling implementation.
+ *
+ */
+@SuppressWarnings("deprecation")
+public class JcrFileProvider implements FileProvider {
+
+ // private Object[] rootNodes;
+ private Node refNode;
+
+ /**
+ * Must be set in order for the provider to be able to get current session
+ * and thus have the ability to get the file node corresponding to a given
+ * file ID
+ *
+ * @param refNode
+ */
+ public void setReferenceNode(Node refNode) {
+ // FIXME : this introduces some concurrency ISSUES.
+ this.refNode = refNode;
+ }
+
+ public byte[] getByteArrayFileFromId(String fileId) {
+ InputStream fis = null;
+ byte[] ba = null;
+ Node child = getFileNodeFromId(fileId);
+ try {
+ fis = (InputStream) child.getProperty(Property.JCR_DATA).getBinary().getStream();
+ ba = IOUtils.toByteArray(fis);
+
+ } catch (Exception e) {
+ throw new EclipseUiException("Stream error while opening file", e);
+ } finally {
+ IOUtils.closeQuietly(fis);
+ }
+ return ba;
+ }
+
+ public InputStream getInputStreamFromFileId(String fileId) {
+ try {
+ InputStream fis = null;
+
+ Node child = getFileNodeFromId(fileId);
+ fis = (InputStream) child.getProperty(Property.JCR_DATA).getBinary().getStream();
+ return fis;
+ } catch (RepositoryException re) {
+ throw new EclipseUiException("Cannot get stream from file node for Id " + fileId, re);
+ }
+ }
+
+ /**
+ * Throws an exception if the node is not found in the current repository (a
+ * bit like a FileNotFoundException)
+ *
+ * @param fileId
+ * @return Returns the child node of the nt:file node. It is the child node
+ * that have the jcr:data property where actual file is stored.
+ * never null
+ */
+ private Node getFileNodeFromId(String fileId) {
+ try {
+ Node result = refNode.getSession().getNodeByIdentifier(fileId);
+
+ // rootNodes: for (int j = 0; j < rootNodes.length; j++) {
+ // // in case we have a classic JCR Node
+ // if (rootNodes[j] instanceof Node) {
+ // Node curNode = (Node) rootNodes[j];
+ // if (result != null)
+ // break rootNodes;
+ // } // Case of a repository Node
+ // else if (rootNodes[j] instanceof RepositoryNode) {
+ // Object[] nodes = ((RepositoryNode) rootNodes[j])
+ // .getChildren();
+ // for (int i = 0; i < nodes.length; i++) {
+ // Node node = (Node) nodes[i];
+ // result = node.getSession().getNodeByIdentifier(fileId);
+ // if (result != null)
+ // break rootNodes;
+ // }
+ // }
+ // }
+
+ // Sanity checks
+ if (result == null)
+ throw new EclipseUiException("File node not found for ID" + fileId);
+
+ Node child = null;
+
+ boolean isValid = true;
+ if (!result.isNodeType(NodeType.NT_FILE))
+ // useless: mandatory child node
+ // || !result.hasNode(Property.JCR_CONTENT))
+ isValid = false;
+ else {
+ child = result.getNode(Property.JCR_CONTENT);
+ if (!(child.isNodeType(NodeType.NT_RESOURCE) || child.hasProperty(Property.JCR_DATA)))
+ isValid = false;
+ }
+
+ if (!isValid)
+ throw new EclipseUiException("ERROR: In the current implemented model, '" + NodeType.NT_FILE
+ + "' file node must have a child node named jcr:content "
+ + "that has a BINARY Property named jcr:data " + "where the actual data is stored");
+ return child;
+
+ } catch (RepositoryException re) {
+ throw new EclipseUiException("Erreur while getting file node of ID " + fileId, re);
+ }
+ }
+}