]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/integration/JcrServlet.java
1 package org
.argeo
.cms
.integration
;
3 import java
.io
.IOException
;
4 import java
.net
.URLDecoder
;
5 import java
.nio
.charset
.StandardCharsets
;
8 import javax
.jcr
.NodeIterator
;
9 import javax
.jcr
.Property
;
10 import javax
.jcr
.PropertyIterator
;
11 import javax
.jcr
.PropertyType
;
12 import javax
.jcr
.Repository
;
13 import javax
.jcr
.RepositoryException
;
14 import javax
.jcr
.Session
;
15 import javax
.jcr
.Value
;
16 import javax
.servlet
.ServletException
;
17 import javax
.servlet
.http
.HttpServlet
;
18 import javax
.servlet
.http
.HttpServletRequest
;
19 import javax
.servlet
.http
.HttpServletResponse
;
21 import org
.apache
.commons
.logging
.Log
;
22 import org
.apache
.commons
.logging
.LogFactory
;
23 import org
.apache
.jackrabbit
.api
.JackrabbitNode
;
24 import org
.apache
.jackrabbit
.api
.JackrabbitValue
;
25 import org
.argeo
.jcr
.JcrUtils
;
27 import com
.google
.gson
.Gson
;
28 import com
.google
.gson
.GsonBuilder
;
29 import com
.google
.gson
.stream
.JsonWriter
;
31 /** Canonical access to a JCR repository via web services. */
32 public class JcrServlet
extends HttpServlet
{
33 private static final long serialVersionUID
= 6536175260540484539L;
35 private final static String PARAM_VERBOSE
= "verbose";
36 private final static String PARAM_DEPTH
= "depth";
37 private final static String PARAM_PRETTY
= "pretty";
39 private final static Log log
= LogFactory
.getLog(JcrServlet
.class);
41 private Repository repository
;
42 private Integer maxDepth
= 8;
44 private Gson gson
= new GsonBuilder().setPrettyPrinting().create();
47 protected void doGet(HttpServletRequest req
, HttpServletResponse resp
) throws ServletException
, IOException
{
48 String path
= req
.getPathInfo();
49 if (log
.isTraceEnabled())
50 log
.trace("Data service: " + path
);
51 path
= URLDecoder
.decode(path
, StandardCharsets
.UTF_8
.name());
52 String
[] pathTokens
= path
.split("/");
53 // TODO make it more robust
55 String domain
= pathTokens
[1];
56 String dataWorkspace
= "vje_" + domain
;
57 String jcrPath
= path
.substring(domain
.length() + 1);
59 boolean verbose
= req
.getParameter(PARAM_VERBOSE
) != null && !req
.getParameter(PARAM_VERBOSE
).equals("false");
61 if (req
.getParameter(PARAM_DEPTH
) != null) {
62 depth
= Integer
.parseInt(req
.getParameter(PARAM_DEPTH
));
64 throw new RuntimeException("Depth " + depth
+ " is higher than maximum " + maxDepth
);
66 String urlBase
= null;
67 if (req
.getParameter("html") != null)
68 urlBase
= req
.getServletPath() + '/' + domain
;
69 boolean pretty
= req
.getParameter(PARAM_PRETTY
) != null;
71 resp
.setContentType("application/json");
72 Session session
= null;
75 session
= openJcrSession(req
, resp
, repository
, dataWorkspace
);
76 if (!session
.itemExists(jcrPath
))
77 throw new RuntimeException("JCR node " + jcrPath
+ " does not exist");
78 Node node
= session
.getNode(jcrPath
);
80 JsonWriter jsonWriter
;
82 jsonWriter
= new GsonBuilder().setPrettyPrinting().create().newJsonWriter(resp
.getWriter());
84 jsonWriter
= gson
.newJsonWriter(resp
.getWriter());
85 jsonWriter
.beginObject();
86 writeNodeProperties(node
, jsonWriter
, verbose
, urlBase
);
87 writeNodeChildren(node
, jsonWriter
, depth
, verbose
, urlBase
);
88 jsonWriter
.endObject();
90 } catch (RepositoryException e
) {
92 throw new RuntimeException("Cannot process JCR node " + jcrPath
, e
);
94 JcrUtils
.logoutQuietly(session
);
98 protected Session
openJcrSession(HttpServletRequest req
, HttpServletResponse resp
, Repository repository
,
99 String workspace
) throws RepositoryException
{
100 return repository
.login();
103 protected void writeNodeProperties(Node node
, JsonWriter jsonWriter
, boolean verbose
, String urlBase
)
104 throws RepositoryException
, IOException
{
105 String jcrPath
= node
.getPath();
106 jsonWriter
.name("jcr:name");
107 jsonWriter
.value(node
.getName());
108 jsonWriter
.name("jcr:path");
109 jsonWriter
.value(jcrPath
);
111 PropertyIterator pit
= node
.getProperties();
112 properties
: while (pit
.hasNext()) {
113 Property property
= pit
.nextProperty();
115 if (property
.getName().equals("jcr:primaryType") || property
.getName().equals("jcr:mixinTypes")
116 || property
.getName().equals("jcr:created") || property
.getName().equals("jcr:createdBy")
117 || property
.getName().equals("jcr:lastModified")
118 || property
.getName().equals("jcr:lastModifiedBy")) {
119 continue properties
;// skip
123 if (property
.getType() == PropertyType
.BINARY
) {
124 if (!(node
instanceof JackrabbitNode
)) {
125 continue properties
;// skip
129 if (!property
.isMultiple()) {
130 jsonWriter
.name(property
.getName());
131 writePropertyValue(property
.getType(), property
.getValue(), jsonWriter
);
133 jsonWriter
.name(property
.getName());
134 jsonWriter
.beginArray();
135 Value
[] values
= property
.getValues();
136 for (Value value
: values
) {
137 writePropertyValue(property
.getType(), value
, jsonWriter
);
139 jsonWriter
.endArray();
145 jsonWriter
.name("jcr:identifier");
146 jsonWriter
.value(node
.getIdentifier());
148 if (urlBase
!= null) {// TODO make it browsable
149 jsonWriter
.name("url");
150 String url
= urlBase
+ jcrPath
;
151 jsonWriter
.value("<a href='" + url
+ "?html=true'>" + url
+ "</a>");
155 protected void writePropertyValue(int type
, Value value
, JsonWriter jsonWriter
)
156 throws RepositoryException
, IOException
{
157 if (type
== PropertyType
.DOUBLE
)
158 jsonWriter
.value(value
.getDouble());
159 else if (type
== PropertyType
.LONG
)
160 jsonWriter
.value(value
.getLong());
161 else if (type
== PropertyType
.BINARY
) {
162 if (value
instanceof JackrabbitValue
) {
163 String contentIdentity
= ((JackrabbitValue
) value
).getContentIdentity();
164 jsonWriter
.value("SHA256:" + contentIdentity
);
167 jsonWriter
.value(value
.getString());
170 protected void writeNodeChildren(Node node
, JsonWriter jsonWriter
, int depth
, boolean verbose
, String urlBase
)
171 throws RepositoryException
, IOException
{
172 if (!node
.hasNodes())
176 NodeIterator nit
= node
.getNodes();
177 jsonWriter
.name("jcr:nodes");
178 jsonWriter
.beginArray();
179 while (nit
.hasNext()) {
180 Node child
= nit
.nextNode();
181 jsonWriter
.beginObject();
182 writeNodeProperties(child
, jsonWriter
, verbose
, urlBase
);
183 writeNodeChildren(child
, jsonWriter
, depth
- 1, verbose
, urlBase
);
184 jsonWriter
.endObject();
186 jsonWriter
.endArray();
189 public void setRepository(Repository repository
) {
190 this.repository
= repository
;
193 public void setMaxDepth(Integer maxDepth
) {
194 this.maxDepth
= maxDepth
;