]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrResourceAdapter.java
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org
.argeo
.jcr
;
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
;
25 import javax
.jcr
.Node
;
26 import javax
.jcr
.Property
;
27 import javax
.jcr
.RepositoryException
;
28 import javax
.jcr
.Session
;
29 import javax
.jcr
.version
.Version
;
30 import javax
.jcr
.version
.VersionHistory
;
31 import javax
.jcr
.version
.VersionIterator
;
33 import org
.apache
.commons
.logging
.Log
;
34 import org
.apache
.commons
.logging
.LogFactory
;
35 import org
.argeo
.ArgeoException
;
36 import org
.springframework
.core
.io
.Resource
;
39 * Bridge Spring resources and JCR folder / files semantics (nt:folder /
40 * nt:file), supporting versioning as well.
42 public class JcrResourceAdapter
{
43 private final static Log log
= LogFactory
.getLog(JcrResourceAdapter
.class);
45 private Session session
;
47 private Boolean versioning
= true;
48 private String defaultEncoding
= "UTF-8";
50 // private String restoreBase = "/.restore";
52 public JcrResourceAdapter() {
55 public JcrResourceAdapter(Session session
) {
56 this.session
= session
;
59 public void mkdirs(String path
) {
60 JcrUtils
.mkdirs(session(), path
, "nt:folder", "nt:folder", versioning
);
63 public void create(String path
, Resource file
, String mimeType
) {
65 create(path
, file
.getInputStream(), mimeType
);
66 } catch (IOException e
) {
67 throw new ArgeoException("Cannot read " + file
, e
);
71 public void create(String path
, InputStream in
, String mimeType
) {
73 if (session().itemExists(path
)) {
74 throw new ArgeoException("Node " + path
+ " already exists.");
77 int index
= path
.lastIndexOf('/');
78 String parentPath
= path
.substring(0, index
);
79 if (parentPath
.equals(""))
81 String fileName
= path
.substring(index
+ 1);
82 if (!session().itemExists(parentPath
))
83 throw new ArgeoException("Parent folder of node " + path
84 + " does not exist: " + parentPath
);
86 Node folderNode
= (Node
) session().getItem(parentPath
);
87 Node fileNode
= folderNode
.addNode(fileName
, "nt:file");
89 Node contentNode
= fileNode
.addNode("jcr:content", "nt:resource");
91 contentNode
.setProperty("jcr:mimeType", mimeType
);
92 contentNode
.setProperty("jcr:encoding", defaultEncoding
);
93 contentNode
.setProperty("jcr:data", in
);
94 Calendar lastModified
= Calendar
.getInstance();
95 // lastModified.setTimeInMillis(file.lastModified());
96 contentNode
.setProperty("jcr:lastModified", lastModified
);
97 // resNode.addMixin("mix:referenceable");
100 fileNode
.addMixin("mix:versionable");
107 if (log
.isDebugEnabled())
108 log
.debug("Created " + path
);
109 } catch (Exception e
) {
110 throw new ArgeoException("Cannot create node for " + path
, e
);
115 public void update(String path
, Resource file
) {
117 update(path
, file
.getInputStream());
118 } catch (IOException e
) {
119 throw new ArgeoException("Cannot read " + file
, e
);
123 public void update(String path
, InputStream in
) {
126 if (!session().itemExists(path
)) {
128 // FIXME: using javax.activation leads to conflict between Java
129 // 1.5 and 1.6 (since javax.activation was included in Java 1.6)
130 // String type = new MimetypesFileTypeMap()
131 // .getContentType(FilenameUtils.getName(path));
132 create(path
, in
, type
);
136 Node fileNode
= (Node
) session().getItem(path
);
137 Node contentNode
= fileNode
.getNode("jcr:content");
140 contentNode
.setProperty("jcr:data", in
);
141 Calendar lastModified
= Calendar
.getInstance();
142 // lastModified.setTimeInMillis(file.lastModified());
143 contentNode
.setProperty("jcr:lastModified", lastModified
);
149 if (log
.isDebugEnabled())
150 log
.debug("Updated " + path
);
151 } catch (Exception e
) {
152 throw new ArgeoException("Cannot update node " + path
, e
);
156 public List
<Calendar
> listVersions(String path
) {
158 throw new ArgeoException("Versioning is not activated");
161 List
<Calendar
> versions
= new ArrayList
<Calendar
>();
162 Node fileNode
= (Node
) session().getItem(path
);
163 VersionHistory history
= fileNode
.getVersionHistory();
164 for (VersionIterator it
= history
.getAllVersions(); it
.hasNext();) {
165 Version version
= (Version
) it
.next();
166 versions
.add(version
.getCreated());
167 if (log
.isTraceEnabled()) {
173 } catch (Exception e
) {
174 throw new ArgeoException("Cannot list version of node " + path
, e
);
178 public InputStream
retrieve(String path
) {
180 Node node
= (Node
) session().getItem(path
+ "/jcr:content");
181 Property property
= node
.getProperty("jcr:data");
182 return property
.getStream();
183 } catch (Exception e
) {
184 throw new ArgeoException("Cannot retrieve " + path
, e
);
188 public synchronized InputStream
retrieve(String path
, Integer revision
) {
190 throw new ArgeoException("Versioning is not activated");
193 Node fileNode
= (Node
) session().getItem(path
);
194 VersionHistory history
= fileNode
.getVersionHistory();
196 Version version
= null;
197 for (VersionIterator it
= history
.getAllVersions(); it
.hasNext();) {
198 version
= (Version
) it
.next();
199 if (count
== revision
+ 1) {
200 InputStream in
= fromVersion(version
);
201 if (log
.isDebugEnabled())
202 log
.debug("Retrieved " + path
+ " at revision "
208 } catch (Exception e
) {
209 throw new ArgeoException("Cannot retrieve version " + revision
213 throw new ArgeoException("Version " + revision
214 + " does not exist for node " + path
);
217 protected InputStream
fromVersion(Version version
)
218 throws RepositoryException
{
219 Node frozenNode
= version
.getNode("jcr:frozenNode");
220 InputStream in
= frozenNode
.getNode("jcr:content")
221 .getProperty("jcr:data").getStream();
225 protected Session
session() {
229 public void setVersioning(Boolean versioning
) {
230 this.versioning
= versioning
;
233 public void setDefaultEncoding(String defaultEncoding
) {
234 this.defaultEncoding
= defaultEncoding
;
237 protected String
fill(Integer number
) {
239 String str
= number
.toString();
240 for (int i
= str
.length(); i
< size
; i
++) {
246 public void setSession(Session session
) {
247 this.session
= session
;