View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.eclipse.ui.jcr.util;
17  
18  import java.io.InputStream;
19  
20  import javax.jcr.Node;
21  import javax.jcr.Property;
22  import javax.jcr.RepositoryException;
23  import javax.jcr.nodetype.NodeType;
24  
25  import org.apache.commons.io.IOUtils;
26  import org.argeo.eclipse.ui.EclipseUiException;
27  import org.argeo.eclipse.ui.FileProvider;
28  
29  /**
30   * Implements a FileProvider for UI purposes. Note that it might not be very
31   * reliable as long as we have not fixed login and multi repository issues that
32   * will be addressed in the next version.
33   * 
34   * NOTE: id used here is the real id of the JCR Node, not the JCR Path
35   * 
36   * Relies on common approach for JCR file handling implementation.
37   * 
38   */
39  @SuppressWarnings("deprecation")
40  public class JcrFileProvider implements FileProvider {
41  
42  	// private Object[] rootNodes;
43  	private Node refNode;
44  
45  	/**
46  	 * Must be set in order for the provider to be able to get current session
47  	 * and thus have the ability to get the file node corresponding to a given
48  	 * file ID
49  	 * 
50  	 * @param refNode
51  	 */
52  	public void setReferenceNode(Node refNode) {
53  		// FIXME : this introduces some concurrency ISSUES.
54  		this.refNode = refNode;
55  	}
56  
57  	public byte[] getByteArrayFileFromId(String fileId) {
58  		InputStream fis = null;
59  		byte[] ba = null;
60  		Node child = getFileNodeFromId(fileId);
61  		try {
62  			fis = (InputStream) child.getProperty(Property.JCR_DATA).getBinary().getStream();
63  			ba = IOUtils.toByteArray(fis);
64  
65  		} catch (Exception e) {
66  			throw new EclipseUiException("Stream error while opening file", e);
67  		} finally {
68  			IOUtils.closeQuietly(fis);
69  		}
70  		return ba;
71  	}
72  
73  	public InputStream getInputStreamFromFileId(String fileId) {
74  		try {
75  			InputStream fis = null;
76  
77  			Node child = getFileNodeFromId(fileId);
78  			fis = (InputStream) child.getProperty(Property.JCR_DATA).getBinary().getStream();
79  			return fis;
80  		} catch (RepositoryException re) {
81  			throw new EclipseUiException("Cannot get stream from file node for Id " + fileId, re);
82  		}
83  	}
84  
85  	/**
86  	 * Throws an exception if the node is not found in the current repository (a
87  	 * bit like a FileNotFoundException)
88  	 * 
89  	 * @param fileId
90  	 * @return Returns the child node of the nt:file node. It is the child node
91  	 *         that have the jcr:data property where actual file is stored.
92  	 *         never null
93  	 */
94  	private Node getFileNodeFromId(String fileId) {
95  		try {
96  			Node result = refNode.getSession().getNodeByIdentifier(fileId);
97  
98  			// rootNodes: for (int j = 0; j < rootNodes.length; j++) {
99  			// // in case we have a classic JCR Node
100 			// if (rootNodes[j] instanceof Node) {
101 			// Node curNode = (Node) rootNodes[j];
102 			// if (result != null)
103 			// break rootNodes;
104 			// } // Case of a repository Node
105 			// else if (rootNodes[j] instanceof RepositoryNode) {
106 			// Object[] nodes = ((RepositoryNode) rootNodes[j])
107 			// .getChildren();
108 			// for (int i = 0; i < nodes.length; i++) {
109 			// Node node = (Node) nodes[i];
110 			// result = node.getSession().getNodeByIdentifier(fileId);
111 			// if (result != null)
112 			// break rootNodes;
113 			// }
114 			// }
115 			// }
116 
117 			// Sanity checks
118 			if (result == null)
119 				throw new EclipseUiException("File node not found for ID" + fileId);
120 
121 			Node child = null;
122 
123 			boolean isValid = true;
124 			if (!result.isNodeType(NodeType.NT_FILE))
125 				// useless: mandatory child node
126 				// || !result.hasNode(Property.JCR_CONTENT))
127 				isValid = false;
128 			else {
129 				child = result.getNode(Property.JCR_CONTENT);
130 				if (!(child.isNodeType(NodeType.NT_RESOURCE) || child.hasProperty(Property.JCR_DATA)))
131 					isValid = false;
132 			}
133 
134 			if (!isValid)
135 				throw new EclipseUiException("ERROR: In the current implemented model, '" + NodeType.NT_FILE
136 						+ "' file node must have a child node named jcr:content "
137 						+ "that has a BINARY Property named jcr:data " + "where the actual data is stored");
138 			return child;
139 
140 		} catch (RepositoryException re) {
141 			throw new EclipseUiException("Erreur while getting file node of ID " + fileId, re);
142 		}
143 	}
144 }