]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/jcr/mvc/JcrXmlServerSerializer.java
Prepare next development cycle
[lgpl/argeo-commons.git] / server / jcr / mvc / JcrXmlServerSerializer.java
1 package org.argeo.server.jcr.mvc;
2
3 import javax.jcr.Node;
4 import javax.jcr.NodeIterator;
5 import javax.jcr.RepositoryException;
6 import javax.servlet.http.HttpServletRequest;
7 import javax.servlet.http.HttpServletResponse;
8 import javax.xml.parsers.DocumentBuilderFactory;
9 import javax.xml.transform.Transformer;
10 import javax.xml.transform.TransformerFactory;
11 import javax.xml.transform.dom.DOMSource;
12 import javax.xml.transform.stream.StreamResult;
13
14 import org.argeo.ArgeoException;
15 import org.argeo.server.ServerSerializer;
16 import org.springframework.xml.dom.DomContentHandler;
17 import org.w3c.dom.Document;
18 import org.w3c.dom.Element;
19 import org.w3c.dom.NodeList;
20 import org.xml.sax.SAXException;
21
22 public class JcrXmlServerSerializer implements ServerSerializer {
23 private String contentTypeCharset = "UTF-8";
24
25 private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
26 .newInstance();
27 private final TransformerFactory transformerFactory = TransformerFactory
28 .newInstance();
29
30 public void serialize(Object obj, HttpServletRequest request,
31 HttpServletResponse response) {
32 if (!(obj instanceof Node))
33 throw new ArgeoException("Only " + Node.class + " is supported");
34
35 String noRecurseStr = request.getParameter("noRecurse");
36 boolean noRecurse = noRecurseStr != null && noRecurseStr.equals("true");
37
38 String depthStr = request.getParameter("depth");
39 String downloadStr = request.getParameter("download");
40
41 Node node = (Node) obj;
42
43 try {
44 String contentType = "text/xml;charset=" + contentTypeCharset;
45 // download case
46 if (downloadStr != null && downloadStr.equals("true")) {
47 String fileName = node.getName().replace(':', '_') + ".xml";
48 contentType = contentType + ";name=\"" + fileName + "\"";
49 response.setHeader("Content-Disposition",
50 "attachment; filename=\"" + fileName + "\"");
51 response.setHeader("Expires", "0");
52 response
53 .setHeader("Cache-Control", "no-cache, must-revalidate");
54 response.setHeader("Pragma", "no-cache");
55 }
56
57 response.setContentType(contentType);
58 if (depthStr == null) {
59 node.getSession().exportDocumentView(node.getPath(),
60 response.getOutputStream(), true, noRecurse);
61 } else {
62 int depth = Integer.parseInt(depthStr);
63 Document document = documentBuilderFactory.newDocumentBuilder()
64 .newDocument();
65 serializeLevelToDom(node, document, 0, depth);
66 Transformer transformer = transformerFactory.newTransformer();
67 transformer.transform(new DOMSource(document),
68 new StreamResult(response.getOutputStream()));
69 }
70 } catch (Exception e) {
71 throw new ArgeoException("Cannot serialize " + node, e);
72 }
73 }
74
75 protected void serializeLevelToDom(Node currentJcrNode,
76 org.w3c.dom.Node currentDomNode, int currentDepth, int targetDepth)
77 throws RepositoryException, SAXException {
78 DomContentHandler domContentHandler = new DomContentHandler(
79 currentDomNode);
80 currentJcrNode.getSession().exportDocumentView(
81 currentJcrNode.getPath(), domContentHandler, true, true);
82
83 if (currentDepth == targetDepth)
84 return;
85
86 // TODO: filter
87 NodeIterator nit = currentJcrNode.getNodes();
88 while (nit.hasNext()) {
89 Node nextJcrNode = nit.nextNode();
90 org.w3c.dom.Node nextDomNode;
91 if (currentDomNode instanceof Document)
92 nextDomNode = ((Document) currentDomNode).getDocumentElement();
93 else {
94 String name = currentJcrNode.getName();
95 NodeList nodeList = ((Element) currentDomNode)
96 .getElementsByTagName(name);
97 if (nodeList.getLength() < 1)
98 throw new ArgeoException("No elment named " + name
99 + " under " + currentDomNode);
100 // we know it is the last one added
101 nextDomNode = nodeList.item(nodeList.getLength() - 1);
102 }
103 // recursive call
104 serializeLevelToDom(nextJcrNode, nextDomNode, currentDepth + 1,
105 targetDepth);
106 }
107 }
108
109 public void setContentTypeCharset(String contentTypeCharset) {
110 this.contentTypeCharset = contentTypeCharset;
111 }
112
113 }