View Javadoc

1   /*
2    * Copyright 2008 Hippo
3    *
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
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" 
12   * BASIS, 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.
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             //Output CDATA sections as (escaped) text
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 }