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 }