]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.server.jcr/src/org/argeo/jcr/JcrResourceAdapter.java
Adapt to package names changes in Spring Security
[lgpl/argeo-commons.git] / org.argeo.server.jcr / src / org / argeo / jcr / JcrResourceAdapter.java
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.jcr;
17
18 import java.io.InputStream;
19 import java.util.ArrayList;
20 import java.util.Calendar;
21 import java.util.List;
22
23 import javax.jcr.Binary;
24 import javax.jcr.Node;
25 import javax.jcr.Property;
26 import javax.jcr.RepositoryException;
27 import javax.jcr.Session;
28 import javax.jcr.nodetype.NodeType;
29 import javax.jcr.version.Version;
30 import javax.jcr.version.VersionHistory;
31 import javax.jcr.version.VersionIterator;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.argeo.ArgeoException;
36
37 /**
38 * Bridge Spring resources and JCR folder / files semantics (nt:folder /
39 * nt:file), supporting versioning as well.
40 */
41 public class JcrResourceAdapter {
42 private final static Log log = LogFactory.getLog(JcrResourceAdapter.class);
43
44 private Session session;
45
46 private Boolean versioning = true;
47 private String defaultEncoding = "UTF-8";
48
49 // private String restoreBase = "/.restore";
50
51 public JcrResourceAdapter() {
52 }
53
54 public JcrResourceAdapter(Session session) {
55 this.session = session;
56 }
57
58 public void mkdirs(String path) {
59 JcrUtils.mkdirs(session(), path, NodeType.NT_FOLDER,
60 NodeType.NT_FOLDER, versioning);
61 }
62
63 public void create(String path, InputStream in, String mimeType) {
64 try {
65 if (session().itemExists(path)) {
66 throw new ArgeoException("Node " + path + " already exists.");
67 }
68
69 int index = path.lastIndexOf('/');
70 String parentPath = path.substring(0, index);
71 if (parentPath.equals(""))
72 parentPath = "/";
73 String fileName = path.substring(index + 1);
74 if (!session().itemExists(parentPath))
75 throw new ArgeoException("Parent folder of node " + path
76 + " does not exist: " + parentPath);
77
78 Node folderNode = (Node) session().getItem(parentPath);
79 Node fileNode = folderNode.addNode(fileName, "nt:file");
80
81 Node contentNode = fileNode.addNode(Property.JCR_CONTENT,
82 "nt:resource");
83 if (mimeType != null)
84 contentNode.setProperty(Property.JCR_MIMETYPE, mimeType);
85 contentNode.setProperty(Property.JCR_ENCODING, defaultEncoding);
86 Binary binary = session().getValueFactory().createBinary(in);
87 contentNode.setProperty(Property.JCR_DATA, binary);
88 JcrUtils.closeQuietly(binary);
89 Calendar lastModified = Calendar.getInstance();
90 // lastModified.setTimeInMillis(file.lastModified());
91 contentNode.setProperty(Property.JCR_LAST_MODIFIED, lastModified);
92 // resNode.addMixin("mix:referenceable");
93
94 if (versioning)
95 fileNode.addMixin("mix:versionable");
96
97 session().save();
98
99 if (versioning)
100 session().getWorkspace().getVersionManager()
101 .checkin(fileNode.getPath());
102
103 if (log.isDebugEnabled())
104 log.debug("Created " + path);
105 } catch (Exception e) {
106 throw new ArgeoException("Cannot create node for " + path, e);
107 }
108
109 }
110
111 public void update(String path, InputStream in) {
112 try {
113
114 if (!session().itemExists(path)) {
115 String type = null;
116 // FIXME: using javax.activation leads to conflict between Java
117 // 1.5 and 1.6 (since javax.activation was included in Java 1.6)
118 // String type = new MimetypesFileTypeMap()
119 // .getContentType(FilenameUtils.getName(path));
120 create(path, in, type);
121 return;
122 }
123
124 Node fileNode = (Node) session().getItem(path);
125 Node contentNode = fileNode.getNode(Property.JCR_CONTENT);
126 if (versioning)
127 session().getWorkspace().getVersionManager()
128 .checkout(fileNode.getPath());
129 Binary binary = session().getValueFactory().createBinary(in);
130 contentNode.setProperty(Property.JCR_DATA, binary);
131 JcrUtils.closeQuietly(binary);
132 Calendar lastModified = Calendar.getInstance();
133 // lastModified.setTimeInMillis(file.lastModified());
134 contentNode.setProperty(Property.JCR_LAST_MODIFIED, lastModified);
135
136 session().save();
137 if (versioning)
138 session().getWorkspace().getVersionManager()
139 .checkin(fileNode.getPath());
140
141 if (log.isDebugEnabled())
142 log.debug("Updated " + path);
143 } catch (Exception e) {
144 throw new ArgeoException("Cannot update node " + path, e);
145 }
146 }
147
148 public List<Calendar> listVersions(String path) {
149 if (!versioning)
150 throw new ArgeoException("Versioning is not activated");
151
152 try {
153 List<Calendar> versions = new ArrayList<Calendar>();
154 Node fileNode = (Node) session().getItem(path);
155 VersionHistory history = session().getWorkspace()
156 .getVersionManager().getVersionHistory(fileNode.getPath());
157 for (VersionIterator it = history.getAllVersions(); it.hasNext();) {
158 Version version = (Version) it.next();
159 versions.add(version.getCreated());
160 if (log.isTraceEnabled()) {
161 log.debug(version);
162 // debug(version);
163 }
164 }
165 return versions;
166 } catch (Exception e) {
167 throw new ArgeoException("Cannot list version of node " + path, e);
168 }
169 }
170
171 public InputStream retrieve(String path) {
172 try {
173 Node node = (Node) session().getItem(
174 path + "/" + Property.JCR_CONTENT);
175 Property property = node.getProperty(Property.JCR_DATA);
176 return property.getBinary().getStream();
177 } catch (Exception e) {
178 throw new ArgeoException("Cannot retrieve " + path, e);
179 }
180 }
181
182 public synchronized InputStream retrieve(String path, Integer revision) {
183 if (!versioning)
184 throw new ArgeoException("Versioning is not activated");
185
186 try {
187 Node fileNode = (Node) session().getItem(path);
188 VersionHistory history = session().getWorkspace()
189 .getVersionManager().getVersionHistory(fileNode.getPath());
190 int count = 0;
191 Version version = null;
192 for (VersionIterator it = history.getAllVersions(); it.hasNext();) {
193 version = (Version) it.next();
194 if (count == revision + 1) {
195 InputStream in = fromVersion(version);
196 if (log.isDebugEnabled())
197 log.debug("Retrieved " + path + " at revision "
198 + revision);
199 return in;
200 }
201 count++;
202 }
203 } catch (Exception e) {
204 throw new ArgeoException("Cannot retrieve version " + revision
205 + " of " + path, e);
206 }
207
208 throw new ArgeoException("Version " + revision
209 + " does not exist for node " + path);
210 }
211
212 protected InputStream fromVersion(Version version)
213 throws RepositoryException {
214 Node frozenNode = version.getNode("jcr:frozenNode");
215 InputStream in = frozenNode.getNode(Property.JCR_CONTENT)
216 .getProperty(Property.JCR_DATA).getBinary().getStream();
217 return in;
218 }
219
220 protected Session session() {
221 return session;
222 }
223
224 public void setVersioning(Boolean versioning) {
225 this.versioning = versioning;
226 }
227
228 public void setDefaultEncoding(String defaultEncoding) {
229 this.defaultEncoding = defaultEncoding;
230 }
231
232 protected String fill(Integer number) {
233 int size = 4;
234 String str = number.toString();
235 for (int i = str.length(); i < size; i++) {
236 str = "0" + str;
237 }
238 return str;
239 }
240
241 public void setSession(Session session) {
242 this.session = session;
243 }
244
245 }