View Javadoc

1   /*
2    * Copyright 2005-2012 the original author or authors.
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" 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.
15   */
16  
17  package org.springframework.xml.transform;
18  
19  import java.io.InputStream;
20  import java.io.OutputStream;
21  import java.io.Reader;
22  import java.io.Writer;
23  import javax.xml.stream.XMLEventReader;
24  import javax.xml.stream.XMLEventWriter;
25  import javax.xml.stream.XMLStreamReader;
26  import javax.xml.stream.XMLStreamWriter;
27  import javax.xml.transform.Result;
28  import javax.xml.transform.Source;
29  import javax.xml.transform.dom.DOMResult;
30  import javax.xml.transform.dom.DOMSource;
31  import javax.xml.transform.sax.SAXResult;
32  import javax.xml.transform.sax.SAXSource;
33  import javax.xml.transform.stax.StAXResult;
34  import javax.xml.transform.stax.StAXSource;
35  import javax.xml.transform.stream.StreamResult;
36  import javax.xml.transform.stream.StreamSource;
37  
38  import org.springframework.util.StringUtils;
39  import org.springframework.util.xml.StaxUtils;
40  
41  import org.w3c.dom.Document;
42  import org.w3c.dom.Node;
43  import org.xml.sax.ContentHandler;
44  import org.xml.sax.InputSource;
45  import org.xml.sax.XMLReader;
46  import org.xml.sax.ext.LexicalHandler;
47  
48  /**
49   * Convenient utility methods for dealing with TrAX.
50   *
51   * @author Arjen Poutsma
52   * @since 1.5.0
53   */
54  public abstract class TraxUtils {
55  
56      /**
57       * Returns the {@link Document} of the given {@link DOMSource}.
58       *
59       * @param source the DOM source
60       * @return the document
61       */
62      public static Document getDocument(DOMSource source) {
63          Node node = source.getNode();
64          if (node instanceof Document) {
65              return (Document) node;
66          }
67          else if (node != null) {
68              return node.getOwnerDocument();
69          }
70          else {
71              return null;
72          }
73      }
74  
75      /**
76       * Performs the given {@linkplain SourceCallback callback} operation on a {@link Source}. Supports both the JAXP 1.4
77       * {@link StAXSource} and the Spring 3.0 {@link StaxUtils#createStaxSource StaxSource}.
78       *
79       * @param source   source to look at
80       * @param callback the callback to invoke for each kind of source
81       */
82      public static void doWithSource(Source source, SourceCallback callback) throws Exception {
83          if (source instanceof DOMSource) {
84              callback.domSource(((DOMSource) source).getNode());
85              return;
86          }
87          else if (StaxUtils.isStaxSource(source)) {
88              XMLStreamReader streamReader = StaxUtils.getXMLStreamReader(source);
89              if (streamReader != null) {
90                  callback.staxSource(streamReader);
91                  return;
92              }
93              else {
94                  XMLEventReader eventReader = StaxUtils.getXMLEventReader(source);
95                  if (eventReader != null) {
96                      callback.staxSource(eventReader);
97                      return;
98                  }
99              }
100         }
101         else if (source instanceof SAXSource) {
102             SAXSource saxSource = (SAXSource) source;
103             callback.saxSource(saxSource.getXMLReader(), saxSource.getInputSource());
104             return;
105         }
106         else if (source instanceof StreamSource) {
107             StreamSource streamSource = (StreamSource) source;
108             if (streamSource.getInputStream() != null) {
109                 callback.streamSource(streamSource.getInputStream());
110                 return;
111             }
112             else if (streamSource.getReader() != null) {
113                 callback.streamSource(streamSource.getReader());
114                 return;
115             }
116         }
117         if (StringUtils.hasLength(source.getSystemId())) {
118             String systemId = source.getSystemId();
119             callback.source(systemId);
120         }
121         else {
122             throw new IllegalArgumentException("Unknown Source type: " + source.getClass());
123         }
124     }
125 
126     /**
127      * Performs the given {@linkplain org.springframework.xml.transform.TraxUtils.ResultCallback callback} operation on a {@link javax.xml.transform.Result}. Supports both the JAXP 1.4
128      * {@link javax.xml.transform.stax.StAXResult} and the Spring 3.0 {@link org.springframework.util.xml.StaxUtils#createStaxResult StaxSource}.
129      *
130      * @param result   result to look at
131      * @param callback the callback to invoke for each kind of result
132      */
133     public static void doWithResult(Result result, ResultCallback callback) throws Exception {
134         if (result instanceof DOMResult) {
135             callback.domResult(((DOMResult) result).getNode());
136             return;
137         }
138         else if (StaxUtils.isStaxResult(result)) {
139             XMLStreamWriter streamWriter = StaxUtils.getXMLStreamWriter(result);
140             if (streamWriter != null) {
141                 callback.staxResult(streamWriter);
142                 return;
143             }
144             else {
145                 XMLEventWriter eventWriter = StaxUtils.getXMLEventWriter(result);
146                 if (eventWriter != null) {
147                     callback.staxResult(eventWriter);
148                     return;
149                 }
150             }
151         }
152         else if (result instanceof SAXResult) {
153             SAXResult saxSource = (SAXResult) result;
154             callback.saxResult(saxSource.getHandler(), saxSource.getLexicalHandler());
155             return;
156         }
157         else if (result instanceof StreamResult) {
158             StreamResult streamSource = (StreamResult) result;
159             if (streamSource.getOutputStream() != null) {
160                 callback.streamResult(streamSource.getOutputStream());
161                 return;
162             }
163             else if (streamSource.getWriter() != null) {
164                 callback.streamResult(streamSource.getWriter());
165                 return;
166             }
167         }
168         if (StringUtils.hasLength(result.getSystemId())) {
169             String systemId = result.getSystemId();
170             callback.result(systemId);
171         }
172         else {
173             throw new IllegalArgumentException("Unknown Result type: " + result.getClass());
174         }
175     }
176 
177     /**
178      * Callback interface invoked on each sort of {@link Source}.
179      *
180      * @see TraxUtils#doWithSource(Source, SourceCallback)
181      */
182     public interface SourceCallback {
183 
184         /**
185          * Perform an operation on the node contained in a {@link DOMSource}.
186          *
187          * @param node the node
188          */
189         void domSource(Node node) throws Exception;
190 
191         /**
192          * Perform an operation on the {@code XMLReader} and {@code InputSource} contained in a {@link SAXSource}.
193          *
194          * @param reader      the reader, can be {@code null}
195          * @param inputSource the input source, can be {@code null}
196          */
197         void saxSource(XMLReader reader, InputSource inputSource) throws Exception;
198 
199         /**
200          * Perform an operation on the {@code XMLEventReader} contained in a JAXP 1.4 {@link StAXSource} or Spring
201          * {@link StaxUtils#createStaxSource StaxSource}.
202          *
203          * @param eventReader the reader
204          */
205         void staxSource(XMLEventReader eventReader) throws Exception;
206 
207         /**
208          * Perform an operation on the {@code XMLStreamReader} contained in a JAXP 1.4 {@link StAXSource} or Spring
209          * {@link StaxUtils#createStaxSource StaxSource}.
210          *
211          * @param streamReader the reader
212          */
213         void staxSource(XMLStreamReader streamReader) throws Exception;
214 
215         /**
216          * Perform an operation on the {@code InputStream} contained in a {@link StreamSource}.
217          *
218          * @param inputStream the input stream
219          */
220         void streamSource(InputStream inputStream) throws Exception;
221 
222         /**
223          * Perform an operation on the {@code Reader} contained in a {@link StreamSource}.
224          *
225          * @param reader the reader
226          */
227         void streamSource(Reader reader) throws Exception;
228 
229         /**
230          * Perform an operation on the system identifier contained in any {@link Source}.
231          *
232          * @param systemId the system identifier
233          */
234         void source(String systemId) throws Exception;
235 
236 
237     }
238 
239     /**
240      * Callback interface invoked on each sort of {@link Result}.
241      *
242      * @see TraxUtils#doWithResult(Result, ResultCallback)
243      */
244     public interface ResultCallback {
245 
246         /**
247          * Perform an operation on the node contained in a {@link DOMResult}.
248          *
249          * @param node the node
250          */
251         void domResult(Node node) throws Exception;
252 
253         /**
254          * Perform an operation on the {@code ContentHandler} and {@code LexicalHandler} contained in a {@link
255          * SAXResult}.
256          *
257          * @param contentHandler the content handler
258          * @param lexicalHandler the lexicalHandler, can be {@code null}
259          */
260         void saxResult(ContentHandler contentHandler, LexicalHandler lexicalHandler) throws Exception;
261 
262         /**
263          * Perform an operation on the {@code XMLEventWriter} contained in a JAXP 1.4 {@link StAXResult} or Spring
264          * {@link StaxUtils#createStaxResult StaxResult}.
265          *
266          * @param eventWriter the writer
267          */
268         void staxResult(XMLEventWriter eventWriter) throws Exception;
269 
270         /**
271          * Perform an operation on the {@code XMLStreamWriter} contained in a JAXP 1.4 {@link StAXResult} or Spring
272          * {@link StaxUtils#createStaxResult StaxResult}.
273          *
274          * @param streamWriter the writer
275          */
276         void staxResult(XMLStreamWriter streamWriter) throws Exception;
277 
278         /**
279          * Perform an operation on the {@code OutputStream} contained in a {@link StreamResult}.
280          *
281          * @param outputStream the output stream
282          */
283         void streamResult(OutputStream outputStream) throws Exception;
284 
285         /**
286          * Perform an operation on the {@code Writer} contained in a {@link StreamResult}.
287          *
288          * @param writer the writer
289          */
290         void streamResult(Writer writer) throws Exception;
291 
292         /**
293          * Perform an operation on the system identifier contained in any {@link Result}.
294          *
295          * @param systemId the system identifier
296          */
297         void result(String systemId) throws Exception;
298 
299     }
300 
301 
302 }