1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package nl.hippo.client.webdav.method;
17
18 import java.io.BufferedReader;
19 import java.io.BufferedWriter;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.InputStreamReader;
23 import java.io.OutputStreamWriter;
24 import java.io.Reader;
25 import java.io.UnsupportedEncodingException;
26
27 import nl.hippo.client.api.ClientException;
28 import nl.hippo.client.api.content.DocumentPath;
29 import nl.hippo.client.api.content.RawResponse;
30 import nl.hippo.client.api.service.WebdavService;
31 import nl.hippo.client.webdav.WebdavLogger;
32 import nl.hippo.client.webdav.WebdavResponse;
33 import nl.hippo.client.webdav.binding.content.DocumentFactory;
34 import nl.hippo.client.webdav.caching.WebdavCacheHandler;
35
36 import org.xmlpull.v1.XmlPullParser;
37 import org.xmlpull.v1.XmlPullParserException;
38 import org.xmlpull.v1.XmlPullParserFactory;
39 import org.xmlpull.v1.XmlSerializer;
40
41 public class ContentIncluder {
42
43 private final static String DOCUMENT_ELEMENT = "document";
44 private final static String CONTENT_ELEMENT = "content";
45 private final static String URI_ATTRIBUTE = "uri";
46
47 private XmlPullParserFactory factory;
48 private WebdavService webdavService;
49 private WebdavCacheHandler cacheHandler;
50
51 public ContentIncluder(WebdavService webdavService, WebdavCacheHandler cacheHandler) {
52 this.webdavService = webdavService;
53 this.cacheHandler = cacheHandler;
54 try {
55 this.factory = XmlPullParserFactory.newInstance();
56 this.factory.setNamespaceAware(false);
57 } catch (XmlPullParserException e) {
58 WebdavLogger.log.error("Error while initializing xpp pull parser factory: " + e.getMessage());
59 }
60 }
61
62 public WebdavResponse includeContent(WebdavResponse searchResult) throws ClientException {
63 if (searchResult == null) {
64 throw new IllegalArgumentException("searchResult may not be null");
65 }
66 WebdavResponse result = (WebdavResponse)searchResult;
67 try {
68 ByteArrayOutputStream bytes = new ByteArrayOutputStream();
69 XmlSerializer serializer = factory.newSerializer();
70 serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " ");
71 serializer.setOutput(new BufferedWriter(new OutputStreamWriter(bytes)));
72
73 searchResult = searchResult.transform(DocumentFactory.xslt, cacheHandler);
74 serialize(searchResult, serializer, true);
75 result = new WebdavResponse(searchResult.getResponseCode(), bytes.toByteArray(), searchResult.getRequest());
76
77 } catch (UnsupportedEncodingException e) {
78 throw new ClientException("Error merging content into searchResult", e);
79 } catch (XmlPullParserException e) {
80 throw new ClientException("Error merging content into searchResult", e);
81 } catch (IllegalArgumentException e) {
82 throw new ClientException("Error merging content into searchResult", e);
83 } catch (IllegalStateException e) {
84 throw new ClientException("Error merging content into searchResult", e);
85 } catch (IOException e) {
86 throw new ClientException("Error merging content into searchResult", e);
87 }
88 return result;
89 }
90
91 private void serialize(RawResponse response, XmlSerializer serializer, boolean toplevel) throws ClientException,
92 XmlPullParserException, IOException {
93
94 Reader in = new BufferedReader(new InputStreamReader(response.getResponseAsStream()));
95 XmlPullParser parser = factory.newPullParser();
96 parser.setInput(in);
97
98 parser.nextToken();
99 writeToken(parser, serializer, XmlPullParser.START_DOCUMENT, toplevel);
100 while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
101 writeToken(parser, serializer, parser.getEventType(), toplevel);
102 parser.nextToken();
103 }
104 writeToken(parser, serializer, XmlPullParser.END_DOCUMENT, toplevel);
105 }
106
107 private void writeToken(XmlPullParser parser, XmlSerializer serializer, int eventType, boolean toplevel)
108 throws XmlPullParserException, IOException, ClientException {
109
110 switch (eventType) {
111
112 case XmlPullParser.START_DOCUMENT:
113 if (toplevel) {
114 serializer.startDocument(parser.getInputEncoding(), null);
115 }
116 break;
117
118 case XmlPullParser.END_DOCUMENT:
119 if (toplevel) {
120 serializer.endDocument();
121 }
122 break;
123
124 case XmlPullParser.START_TAG:
125 String uri = "";
126 serializer.startTag(parser.getNamespace(), parser.getName());
127 for (int i = 0; i < parser.getAttributeCount(); i++) {
128 String name = parser.getAttributeName(i);
129 String value = parser.getAttributeValue(i);
130 if (name.equals(URI_ATTRIBUTE)) {
131 uri = value;
132 }
133 serializer.attribute(parser.getAttributeNamespace(i), name, value);
134 }
135 if (toplevel && parser.getName().equals(DOCUMENT_ELEMENT)) {
136 serializer.startTag(parser.getNamespace(), CONTENT_ELEMENT);
137 DocumentPath path = webdavService.getBasePath().createAbsolutePath(uri);
138 RawResponse response = webdavService.fetchContent(path);
139 serialize(response, serializer, false);
140 serializer.endTag(parser.getNamespace(), CONTENT_ELEMENT);
141 }
142 break;
143
144 case XmlPullParser.END_TAG:
145 serializer.endTag(parser.getNamespace(), parser.getName());
146 break;
147
148 case XmlPullParser.IGNORABLE_WHITESPACE:
149 serializer.ignorableWhitespace(parser.getText());
150 break;
151
152 case XmlPullParser.TEXT:
153 serializer.text(parser.getText());
154 break;
155
156 case XmlPullParser.ENTITY_REF:
157 serializer.entityRef(parser.getName());
158 break;
159
160 case XmlPullParser.CDSECT:
161
162 serializer.text(parser.getText());
163 break;
164
165 case XmlPullParser.PROCESSING_INSTRUCTION:
166 serializer.processingInstruction(parser.getText());
167 break;
168
169 case XmlPullParser.COMMENT:
170 serializer.comment(parser.getText());
171 break;
172
173 case XmlPullParser.DOCDECL:
174 serializer.docdecl(parser.getText());
175 break;
176 }
177 }
178
179 }