]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org/argeo/jcr/JcrResourceAdapter.java
Prepare next development cycle
[lgpl/argeo-commons.git] / org / argeo / jcr / JcrResourceAdapter.java
1 /*
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
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
17 package org.argeo.jcr;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.ArrayList;
22 import java.util.Calendar;
23 import java.util.List;
24
25 import javax.activation.MimetypesFileTypeMap;
26 import javax.jcr.Node;
27 import javax.jcr.Property;
28 import javax.jcr.RepositoryException;
29 import javax.jcr.Session;
30 import javax.jcr.version.Version;
31 import javax.jcr.version.VersionHistory;
32 import javax.jcr.version.VersionIterator;
33
34 import org.apache.commons.io.FilenameUtils;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.argeo.ArgeoException;
38 import org.springframework.core.io.Resource;
39
40 public class JcrResourceAdapter {
41 private final static Log log = LogFactory.getLog(JcrResourceAdapter.class);
42
43 private Session session;
44
45 private Boolean versioning = true;
46 private String defaultEncoding = "UTF-8";
47
48 // private String restoreBase = "/.restore";
49
50 public JcrResourceAdapter() {
51 }
52
53 public JcrResourceAdapter(Session session) {
54 this.session = session;
55 }
56
57 public void mkdirs(String path) {
58 JcrUtils.mkdirs(session(), path, "nt:folder", versioning);
59 }
60
61 public void create(String path, Resource file, String mimeType) {
62 try {
63 create(path, file.getInputStream(), mimeType);
64 } catch (IOException e) {
65 throw new ArgeoException("Cannot read " + file, e);
66 }
67 }
68
69 public void create(String path, InputStream in, String mimeType) {
70 try {
71 if (session().itemExists(path)) {
72 throw new ArgeoException("Node " + path + " already exists.");
73 }
74
75 int index = path.lastIndexOf('/');
76 String parentPath = path.substring(0, index);
77 if (parentPath.equals(""))
78 parentPath = "/";
79 String fileName = path.substring(index + 1);
80 if (!session().itemExists(parentPath))
81 throw new ArgeoException("Parent folder of node " + path
82 + " does not exist: " + parentPath);
83
84 Node folderNode = (Node) session().getItem(parentPath);
85 Node fileNode = folderNode.addNode(fileName, "nt:file");
86
87 Node contentNode = fileNode.addNode("jcr:content", "nt:resource");
88 if (mimeType != null)
89 contentNode.setProperty("jcr:mimeType", mimeType);
90 contentNode.setProperty("jcr:encoding", defaultEncoding);
91 contentNode.setProperty("jcr:data", in);
92 Calendar lastModified = Calendar.getInstance();
93 // lastModified.setTimeInMillis(file.lastModified());
94 contentNode.setProperty("jcr:lastModified", lastModified);
95 // resNode.addMixin("mix:referenceable");
96
97 if (versioning)
98 fileNode.addMixin("mix:versionable");
99
100 session().save();
101
102 if (versioning)
103 fileNode.checkin();
104
105 if (log.isDebugEnabled())
106 log.debug("Created " + path);
107 } catch (Exception e) {
108 throw new ArgeoException("Cannot create node for " + path, e);
109 }
110
111 }
112
113 public void update(String path, Resource file) {
114 try {
115 update(path, file.getInputStream());
116 } catch (IOException e) {
117 throw new ArgeoException("Cannot read " + file, e);
118 }
119 }
120
121 public void update(String path, InputStream in) {
122 try {
123
124 if (!session().itemExists(path)) {
125 String type = new MimetypesFileTypeMap()
126 .getContentType(FilenameUtils.getName(path));
127 create(path, in, type);
128 return;
129 }
130
131 Node fileNode = (Node) session().getItem(path);
132 Node contentNode = fileNode.getNode("jcr:content");
133 if (versioning)
134 fileNode.checkout();
135 contentNode.setProperty("jcr:data", in);
136 Calendar lastModified = Calendar.getInstance();
137 // lastModified.setTimeInMillis(file.lastModified());
138 contentNode.setProperty("jcr:lastModified", lastModified);
139
140 session().save();
141 if (versioning)
142 fileNode.checkin();
143
144 if (log.isDebugEnabled())
145 log.debug("Updated " + path);
146 } catch (Exception e) {
147 throw new ArgeoException("Cannot update node " + path, e);
148 }
149 }
150
151 public List<Calendar> listVersions(String path) {
152 if (!versioning)
153 throw new ArgeoException("Versioning is not activated");
154
155 try {
156 List<Calendar> versions = new ArrayList<Calendar>();
157 Node fileNode = (Node) session().getItem(path);
158 VersionHistory history = fileNode.getVersionHistory();
159 for (VersionIterator it = history.getAllVersions(); it.hasNext();) {
160 Version version = (Version) it.next();
161 versions.add(version.getCreated());
162 if (log.isTraceEnabled()) {
163 log.debug(version);
164 // debug(version);
165 }
166 }
167 return versions;
168 } catch (Exception e) {
169 throw new ArgeoException("Cannot list version of node " + path, e);
170 }
171 }
172
173 public InputStream retrieve(String path) {
174 try {
175 Node node = (Node) session().getItem(path + "/jcr:content");
176 Property property = node.getProperty("jcr:data");
177 return property.getStream();
178 } catch (Exception e) {
179 throw new ArgeoException("Cannot retrieve " + path, e);
180 }
181 }
182
183 public synchronized InputStream retrieve(String path, Integer revision) {
184 if (!versioning)
185 throw new ArgeoException("Versioning is not activated");
186
187 try {
188 Node fileNode = (Node) session().getItem(path);
189 VersionHistory history = fileNode.getVersionHistory();
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("jcr:content").getProperty(
216 "jcr:data").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 }