+ Fix a bug on file download for the generic JCR view
authorBruno Sinou <bsinou@argeo.org>
Fri, 1 Apr 2011 13:25:49 +0000 (13:25 +0000)
committerBruno Sinou <bsinou@argeo.org>
Fri, 1 Apr 2011 13:25:49 +0000 (13:25 +0000)
+ Introduce a file provider that depends on a single session and retrieves node with the path as ID

git-svn-id: https://svn.argeo.org/commons/trunk@4420 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/browser/NodeContentProvider.java
eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/utils/JcrFileProvider.java
eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/utils/SingleSessionFileProvider.java [new file with mode: 0644]
eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/views/GenericJcrBrowser.java

index 6a3967de6dd0dc43509f5bf8bfd2687a46c75774..3e5bc1d8dd0fe0b1d879bc7e62d02caf43671cfe 100644 (file)
@@ -29,6 +29,7 @@ public class NodeContentProvider implements ITreeContentProvider {
                this.repositoryRegister = repositoryRegister;
        }
 
+       /** Sends back the first level of the Tree. Independent from inputElement that can be null*/
        public Object[] getElements(Object inputElement) {
                List<Object> objs = new ArrayList<Object>();
                if (userSession != null)
index 6cf4d29c58ba058d0b5a6181de67eeab2d8cda33..16b7b1445bc87438f9ca0de6998089d52e92ce9f 100644 (file)
@@ -1,24 +1,30 @@
 package org.argeo.eclipse.ui.jcr.utils;
 
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.io.IOUtils;
 import org.argeo.ArgeoException;
 import org.argeo.eclipse.ui.jcr.browser.RepositoryNode;
-import org.argeo.eclipse.ui.jcr.browser.WorkspaceNode;
 import org.argeo.eclipse.ui.specific.FileProvider;
+import org.argeo.jcr.RepositoryRegister;
 
 /**
  * Implements a FileProvider for UI purposes. Note that it might not be very
  * reliable as long as we have not fixed login & multi repository issues that
  * will be addressed in the next version.
  * 
- * We are also very dependant of the repository architecture for file nodes. We
- * assume the content of the file is stored in a nt:resource child node of the
- * nt:file in the jcr:data property
+ * 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.
  * 
  * @author bsinou
  * 
@@ -26,15 +32,33 @@ import org.argeo.eclipse.ui.specific.FileProvider;
 
 public class JcrFileProvider implements FileProvider {
 
-       private RepositoryNode repositoryNode;
+       private Object[] rootNodes;
 
        /**
         * Must be set in order for the provider to be able to search the repository
+        * Provided object might be either JCR Nodes or UI RepositoryNode for the
+        * time being.
         * 
         * @param repositoryNode
         */
-       public void setRepositoryNode(RepositoryNode repositoryNode) {
-               this.repositoryNode = repositoryNode;
+       public void setRootNodes(Object[] rootNodes) {
+               List<Object> tmpNodes = new ArrayList<Object>();
+               for (int i = 0; i < rootNodes.length; i++) {
+                       Object obj = rootNodes[i];
+                       if (obj instanceof Node) {
+                               tmpNodes.add(obj);
+                       } else if (obj instanceof RepositoryRegister) {
+                               RepositoryRegister repositoryRegister = (RepositoryRegister) obj;
+                               Map<String, Repository> repositories = repositoryRegister
+                                               .getRepositories();
+                               for (String name : repositories.keySet()) {
+                                       tmpNodes.add(new RepositoryNode(name, repositories
+                                                       .get(name)));
+                               }
+
+                       }
+               }
+               this.rootNodes = tmpNodes.toArray();
        }
 
        public byte[] getByteArrayFileFromId(String fileId) {
@@ -42,8 +66,8 @@ public class JcrFileProvider implements FileProvider {
                byte[] ba = null;
                Node child = getFileNodeFromId(fileId);
                try {
-                       fis = (InputStream) child.getProperty("jcr:data").getBinary()
-                                       .getStream();
+                       fis = (InputStream) child.getProperty(Property.JCR_DATA)
+                                       .getBinary().getStream();
                        ba = IOUtils.toByteArray(fis);
 
                } catch (Exception e) {
@@ -59,8 +83,8 @@ public class JcrFileProvider implements FileProvider {
                        InputStream fis = null;
 
                        Node child = getFileNodeFromId(fileId);
-                       fis = (InputStream) child.getProperty("jcr:data").getBinary()
-                                       .getStream();
+                       fis = (InputStream) child.getProperty(Property.JCR_DATA)
+                                       .getBinary().getStream();
                        return fis;
                } catch (RepositoryException re) {
                        throw new ArgeoException("Cannot get stream from file node for Id "
@@ -78,34 +102,51 @@ public class JcrFileProvider implements FileProvider {
         *         never null
         */
        private Node getFileNodeFromId(String fileId) {
-               Object[] nodes = repositoryNode.getChildren();
                try {
                        Node result = null;
 
-                       repos: for (int i = 0; i < nodes.length; i++) {
-                               WorkspaceNode wNode = (WorkspaceNode) nodes[i];
-                               result = wNode.getSession().getNodeByIdentifier(fileId);
-
-                               if (result == null)
-                                       continue repos;
-
-                               // Ensure that the node have the correct type.
-                               if (!result.isNodeType("nt:file"))
-                                       throw new ArgeoException(
-                                                       "Cannot open file children Node that are not of 'nt:resource' type.");
+                       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];
+                                       result = curNode.getSession().getNodeByIdentifier(fileId);
+                                       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;
+                                       }
+                               }
+                       }
 
-                               Node child = result.getNodes().nextNode();
-                               if (child == null || !child.isNodeType("nt:resource"))
-                                       throw new ArgeoException(
-                                                       "ERROR: IN the current implemented model, nt:file file node must have one and only one child of the nt:ressource, where actual data is stored");
+                       // Sanity checks
+                       if (result == null)
+                               throw new ArgeoException("File node not found for ID" + fileId);
+
+                       // Ensure that the node have the correct type.
+                       if (!result.isNodeType(NodeType.NT_FILE))
+                               throw new ArgeoException(
+                                               "Cannot open file children Node that are not of '"
+                                                               + NodeType.NT_RESOURCE + "' type.");
+
+                       // Get the usefull part of the Node
+                       Node child = result.getNodes().nextNode();
+                       if (child == null || !child.isNodeType(NodeType.NT_RESOURCE))
+                               throw new ArgeoException(
+                                               "ERROR: IN the current implemented model, '"
+                                                               + NodeType.NT_FILE
+                                                               + "' file node must have one and only one child of the nt:ressource, where actual data is stored");
+                       return child;
 
-                               return child;
-                       }
                } catch (RepositoryException re) {
                        throw new ArgeoException("Erreur while getting file node of ID "
                                        + fileId, re);
                }
-
-               throw new ArgeoException("File node not found for ID" + fileId);
        }
 }
diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/utils/SingleSessionFileProvider.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/utils/SingleSessionFileProvider.java
new file mode 100644 (file)
index 0000000..4499f67
--- /dev/null
@@ -0,0 +1,101 @@
+package org.argeo.eclipse.ui.jcr.utils;
+
+import java.io.InputStream;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.specific.FileProvider;
+
+/**
+ * Implements a FileProvider for UI purposes. Unlike the
+ * <code> JcrFileProvider </code>, it relies on a single session and manages
+ * nodes with path only.
+ * 
+ * Note that considered id is the JCR path
+ * 
+ * Relies on common approach for JCR file handling implementation.
+ * 
+ * @author bsinou
+ * 
+ */
+
+public class SingleSessionFileProvider implements FileProvider {
+
+       private Session session;
+
+       public SingleSessionFileProvider(Session session) {
+               this.session = session;
+       }
+
+       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 ArgeoException("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 ArgeoException("Cannot get stream from file node for Id "
+                                       + fileId, re);
+               }
+       }
+
+       /**
+        * 
+        * @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 = null;
+                       result = session.getNode(fileId);
+
+                       // Sanity checks
+                       if (result == null)
+                               throw new ArgeoException("File node not found for ID" + fileId);
+
+                       // Ensure that the node have the correct type.
+                       if (!result.isNodeType(NodeType.NT_FILE))
+                               throw new ArgeoException(
+                                               "Cannot open file children Node that are not of "
+                                                               + NodeType.NT_RESOURCE + " type.");
+
+                       Node child = result.getNodes().nextNode();
+                       if (child == null || !child.isNodeType(NodeType.NT_RESOURCE))
+                               throw new ArgeoException(
+                                               "ERROR: IN the current implemented model, "
+                                                               + NodeType.NT_FILE
+                                                               + "  file node must have one and only one child of the nt:ressource, where actual data is stored");
+                       return child;
+               } catch (RepositoryException re) {
+                       throw new ArgeoException("Erreur while getting file node of ID "
+                                       + fileId, re);
+               }
+       }
+}
index a9eba799aeb78974663af2ead5806b02b9012ac6..e369c6c8a3e5dc0c76f98aff2a73840c56be176d 100644 (file)
@@ -8,6 +8,7 @@ import javax.jcr.PropertyType;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -49,6 +50,7 @@ public class GenericJcrBrowser extends ViewPart {
        private Session session;
 
        private TreeViewer nodesViewer;
+       private NodeContentProvider nodeContentProvider;
        private TableViewer propertiesViewer;
 
        private RepositoryRegister repositoryRegister;
@@ -93,8 +95,9 @@ public class GenericJcrBrowser extends ViewPart {
                                        throw new ArgeoException("Cannot login to node repository");
                                }
                }
-               nodesViewer.setContentProvider(new NodeContentProvider(nodeSession,
-                               repositoryRegister));
+               nodeContentProvider = new NodeContentProvider(nodeSession,
+                               repositoryRegister);
+               nodesViewer.setContentProvider(nodeContentProvider);
                nodesViewer.setLabelProvider(new NodeLabelProvider());
                nodesViewer
                                .addSelectionChangedListener(new ISelectionChangedListener() {
@@ -119,12 +122,7 @@ public class GenericJcrBrowser extends ViewPart {
                                if (obj instanceof RepositoryNode) {
                                        RepositoryNode rpNode = (RepositoryNode) obj;
                                        rpNode.login();
-                                       // For the file provider to be able to browse the various
-                                       // repository.
-                                       // TODO : enhanced that.
-                                       jfp.setRepositoryNode(rpNode);
                                        nodesViewer.refresh(obj);
-
                                } else if (obj instanceof WorkspaceNode) {
                                        ((WorkspaceNode) obj).login();
                                        nodesViewer.refresh(obj);
@@ -133,9 +131,16 @@ public class GenericJcrBrowser extends ViewPart {
 
                                        // double clic on a file node triggers its opening
                                        try {
-                                               if (node.isNodeType("nt:file")) {
+                                               if (node.isNodeType(NodeType.NT_FILE)) {
                                                        String name = node.getName();
                                                        String id = node.getIdentifier();
+                                                       // For the file provider to be able to browse the
+                                                       // various
+                                                       // repository.
+                                                       // TODO : enhanced that.
+                                                       jfp.setRootNodes((Object[]) nodeContentProvider
+                                                                       .getElements(null));
+
                                                        fh.openFile(name, id);
                                                }
                                        } catch (RepositoryException re) {