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
.server
.jcr
.mvc
;
19 import javax
.jcr
.Node
;
20 import javax
.jcr
.NodeIterator
;
21 import javax
.jcr
.RepositoryException
;
22 import javax
.servlet
.http
.HttpServletRequest
;
23 import javax
.servlet
.http
.HttpServletResponse
;
24 import javax
.xml
.parsers
.DocumentBuilderFactory
;
25 import javax
.xml
.transform
.Transformer
;
26 import javax
.xml
.transform
.TransformerFactory
;
27 import javax
.xml
.transform
.dom
.DOMSource
;
28 import javax
.xml
.transform
.stream
.StreamResult
;
30 import org
.argeo
.ArgeoException
;
31 import org
.argeo
.server
.ServerSerializer
;
32 import org
.springframework
.xml
.dom
.DomContentHandler
;
33 import org
.w3c
.dom
.Document
;
34 import org
.w3c
.dom
.Element
;
35 import org
.w3c
.dom
.NodeList
;
36 import org
.xml
.sax
.SAXException
;
38 public class JcrXmlServerSerializer
implements ServerSerializer
{
39 private String contentTypeCharset
= "UTF-8";
41 private final DocumentBuilderFactory documentBuilderFactory
= DocumentBuilderFactory
43 private final TransformerFactory transformerFactory
= TransformerFactory
46 public void serialize(Object obj
, HttpServletRequest request
,
47 HttpServletResponse response
) {
48 if (!(obj
instanceof Node
))
49 throw new ArgeoException("Only " + Node
.class + " is supported");
51 String noRecurseStr
= request
.getParameter("noRecurse");
52 boolean noRecurse
= noRecurseStr
!= null && noRecurseStr
.equals("true");
54 String depthStr
= request
.getParameter("depth");
55 String downloadStr
= request
.getParameter("download");
57 Node node
= (Node
) obj
;
60 String contentType
= "text/xml;charset=" + contentTypeCharset
;
62 if (downloadStr
!= null && downloadStr
.equals("true")) {
63 String fileName
= node
.getName().replace(':', '_') + ".xml";
64 contentType
= contentType
+ ";name=\"" + fileName
+ "\"";
65 response
.setHeader("Content-Disposition",
66 "attachment; filename=\"" + fileName
+ "\"");
67 response
.setHeader("Expires", "0");
69 .setHeader("Cache-Control", "no-cache, must-revalidate");
70 response
.setHeader("Pragma", "no-cache");
73 response
.setContentType(contentType
);
74 if (depthStr
== null) {
75 node
.getSession().exportDocumentView(node
.getPath(),
76 response
.getOutputStream(), true, noRecurse
);
78 int depth
= Integer
.parseInt(depthStr
);
79 Document document
= documentBuilderFactory
.newDocumentBuilder()
81 serializeLevelToDom(node
, document
, 0, depth
);
82 Transformer transformer
= transformerFactory
.newTransformer();
83 transformer
.transform(new DOMSource(document
),
84 new StreamResult(response
.getOutputStream()));
86 } catch (Exception e
) {
87 throw new ArgeoException("Cannot serialize " + node
, e
);
91 protected void serializeLevelToDom(Node currentJcrNode
,
92 org
.w3c
.dom
.Node currentDomNode
, int currentDepth
, int targetDepth
)
93 throws RepositoryException
, SAXException
{
94 DomContentHandler domContentHandler
= new DomContentHandler(
96 currentJcrNode
.getSession().exportDocumentView(
97 currentJcrNode
.getPath(), domContentHandler
, true, true);
99 if (currentDepth
== targetDepth
)
103 NodeIterator nit
= currentJcrNode
.getNodes();
104 while (nit
.hasNext()) {
105 Node nextJcrNode
= nit
.nextNode();
106 org
.w3c
.dom
.Node nextDomNode
;
107 if (currentDomNode
instanceof Document
)
108 nextDomNode
= ((Document
) currentDomNode
).getDocumentElement();
110 String name
= currentJcrNode
.getName();
111 NodeList nodeList
= ((Element
) currentDomNode
)
112 .getElementsByTagName(name
);
113 if (nodeList
.getLength() < 1)
114 throw new ArgeoException("No elment named " + name
115 + " under " + currentDomNode
);
116 // we know it is the last one added
117 nextDomNode
= nodeList
.item(nodeList
.getLength() - 1);
120 serializeLevelToDom(nextJcrNode
, nextDomNode
, currentDepth
+ 1,
125 public void setContentTypeCharset(String contentTypeCharset
) {
126 this.contentTypeCharset
= contentTypeCharset
;