1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.xml.util;
12
13 import org.mule.RequestContext;
14 import org.mule.api.transport.OutputHandler;
15 import org.mule.module.xml.stax.DelegateXMLStreamReader;
16 import org.mule.module.xml.stax.StaxSource;
17 import org.mule.module.xml.transformer.DelayedResult;
18 import org.mule.module.xml.transformer.XmlToDomDocument;
19 import org.mule.util.IOUtils;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.StringReader;
26
27 import javax.xml.stream.XMLStreamConstants;
28 import javax.xml.stream.XMLStreamException;
29 import javax.xml.stream.XMLStreamReader;
30 import javax.xml.stream.XMLStreamWriter;
31 import javax.xml.transform.Source;
32 import javax.xml.transform.Transformer;
33 import javax.xml.transform.TransformerConfigurationException;
34 import javax.xml.transform.TransformerFactory;
35 import javax.xml.transform.TransformerFactoryConfigurationError;
36 import javax.xml.transform.dom.DOMResult;
37 import javax.xml.transform.dom.DOMSource;
38 import javax.xml.transform.sax.SAXSource;
39 import javax.xml.transform.stream.StreamSource;
40
41 import org.apache.commons.io.output.ByteArrayOutputStream;
42 import org.apache.commons.lang.StringUtils;
43 import org.dom4j.DocumentException;
44 import org.dom4j.io.DOMReader;
45 import org.dom4j.io.DocumentSource;
46 import org.w3c.dom.Document;
47 import org.xml.sax.InputSource;
48
49
50
51
52 public class XMLUtils extends org.mule.util.XMLUtils
53 {
54 public static final String TRANSFORMER_FACTORY_JDK5 = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
55
56
57 public static final String APACHE_XML_FEATURES_VALIDATION_SCHEMA = "http://apache.org/xml/features/validation/schema";
58 public static final String APACHE_XML_FEATURES_VALIDATION_SCHEMA_FULL_CHECKING = "http://apache.org/xml/features/validation/schema-full-checking";
59
60
61 public static final String JAXP_PROPERTIES_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
62
63
64
65 public static final String JAXP_PROPERTIES_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
66 public static final String JAXP_PROPERTIES_SCHEMA_LANGUAGE_VALUE = "http://www.w3.org/2001/XMLSchema";
67
68
69
70
71 public static String toXml(Document dom)
72 {
73 return new DOMReader().read(dom).asXML();
74 }
75
76
77
78
79
80
81 public static Transformer getTransformer() throws TransformerConfigurationException
82 {
83 TransformerFactory tf;
84 try
85 {
86 tf = TransformerFactory.newInstance();
87 }
88 catch (TransformerFactoryConfigurationError e)
89 {
90 System.setProperty("javax.xml.transform.TransformerFactory", TRANSFORMER_FACTORY_JDK5);
91 tf = TransformerFactory.newInstance();
92 }
93 if (tf != null)
94 {
95 return tf.newTransformer();
96 }
97 else
98 {
99 throw new TransformerConfigurationException("Unable to instantiate a TransformerFactory");
100 }
101 }
102
103 public static org.dom4j.Document toDocument(Object obj) throws Exception
104 {
105 return toDocument(obj, null);
106 }
107
108
109
110
111
112
113 public static org.dom4j.Document toDocument(Object obj, String externalSchemaLocation) throws Exception
114 {
115 org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();
116 if (externalSchemaLocation != null)
117 {
118 reader.setValidation(true);
119 reader.setFeature(APACHE_XML_FEATURES_VALIDATION_SCHEMA, true);
120 reader.setFeature(APACHE_XML_FEATURES_VALIDATION_SCHEMA_FULL_CHECKING, true);
121
122 InputStream xsdAsStream = IOUtils.getResourceAsStream(externalSchemaLocation, XMLUtils.class);
123 if (xsdAsStream == null)
124 {
125 throw new IllegalArgumentException("Couldn't find schema at " + externalSchemaLocation);
126 }
127
128
129
130 reader.setProperty(JAXP_PROPERTIES_SCHEMA_LANGUAGE, JAXP_PROPERTIES_SCHEMA_LANGUAGE_VALUE);
131
132
133 reader.setProperty(JAXP_PROPERTIES_SCHEMA_SOURCE, xsdAsStream);
134 }
135
136 if (obj instanceof org.dom4j.Document)
137 {
138 return (org.dom4j.Document) obj;
139 }
140 else if (obj instanceof org.w3c.dom.Document)
141 {
142 org.dom4j.io.DOMReader domReader = new org.dom4j.io.DOMReader();
143 return domReader.read((org.w3c.dom.Document) obj);
144 }
145 else if (obj instanceof org.xml.sax.InputSource)
146 {
147 return reader.read((org.xml.sax.InputSource) obj);
148 }
149 else if (obj instanceof javax.xml.transform.Source || obj instanceof javax.xml.stream.XMLStreamReader)
150 {
151
152 XmlToDomDocument tr = new XmlToDomDocument();
153 tr.setReturnClass(org.dom4j.Document.class);
154 return (org.dom4j.Document) tr.transform(obj);
155 }
156 else if (obj instanceof java.io.InputStream)
157 {
158 return reader.read((java.io.InputStream) obj);
159 }
160 else if (obj instanceof String)
161 {
162 return reader.read(new StringReader((String) obj));
163 }
164 else if (obj instanceof byte[])
165 {
166
167 return reader.read(new StringReader(new String((byte[]) obj)));
168 }
169 else if (obj instanceof File)
170 {
171 return reader.read((File) obj);
172 }
173 else
174 {
175 return null;
176 }
177 }
178
179
180
181
182
183 public static javax.xml.stream.XMLStreamReader toXMLStreamReader(javax.xml.stream.XMLInputFactory factory, Object obj) throws XMLStreamException
184 {
185 if (obj instanceof javax.xml.stream.XMLStreamReader)
186 {
187 return (javax.xml.stream.XMLStreamReader) obj;
188 }
189 else if (obj instanceof org.mule.module.xml.stax.StaxSource)
190 {
191 return ((org.mule.module.xml.stax.StaxSource) obj).getXMLStreamReader();
192 }
193 else if (obj instanceof javax.xml.transform.Source)
194 {
195 return factory.createXMLStreamReader((javax.xml.transform.Source) obj);
196 }
197 else if (obj instanceof org.xml.sax.InputSource)
198 {
199 return factory.createXMLStreamReader(((org.xml.sax.InputSource) obj).getByteStream());
200 }
201 else if (obj instanceof org.w3c.dom.Document)
202 {
203 return factory.createXMLStreamReader(new javax.xml.transform.dom.DOMSource((org.w3c.dom.Document) obj));
204 }
205 else if (obj instanceof org.dom4j.Document)
206 {
207 return factory.createXMLStreamReader(new org.dom4j.io.DocumentSource((org.dom4j.Document) obj));
208 }
209 else if (obj instanceof java.io.InputStream)
210 {
211 final InputStream is = (java.io.InputStream) obj;
212
213 XMLStreamReader xsr = factory.createXMLStreamReader(is);
214 return new DelegateXMLStreamReader(xsr) {
215
216 public void close() throws XMLStreamException
217 {
218 super.close();
219
220 try
221 {
222 is.close();
223 }
224 catch (IOException e)
225 {
226 throw new XMLStreamException(e);
227 }
228 }
229
230 };
231 }
232 else if (obj instanceof String)
233 {
234 return factory.createXMLStreamReader(new StringReader((String) obj));
235 }
236 else if (obj instanceof byte[])
237 {
238
239 return factory.createXMLStreamReader(new ByteArrayInputStream((byte[]) obj));
240 }
241 else
242 {
243 return null;
244 }
245 }
246
247
248
249
250 public static javax.xml.transform.Source toXmlSource(javax.xml.stream.XMLInputFactory xmlInputFactory, boolean useStaxSource, Object src) throws Exception
251 {
252 if (src instanceof javax.xml.transform.Source)
253 {
254 return (Source) src;
255 }
256 else if (src instanceof byte[])
257 {
258 ByteArrayInputStream stream = new ByteArrayInputStream((byte[]) src);
259 return toStreamSource(xmlInputFactory, useStaxSource, stream);
260 }
261 else if (src instanceof InputStream)
262 {
263 return toStreamSource(xmlInputFactory, useStaxSource, (InputStream) src);
264 }
265 else if (src instanceof String)
266 {
267 if (useStaxSource)
268 {
269 return new StaxSource(xmlInputFactory.createXMLStreamReader(new StringReader((String) src)));
270 }
271 else
272 {
273 return new StreamSource(new StringReader((String) src));
274 }
275 }
276 else if (src instanceof org.dom4j.Document)
277 {
278 return new DocumentSource((org.dom4j.Document) src);
279 }
280 else if (src instanceof org.xml.sax.InputSource)
281 {
282 return new SAXSource((InputSource) src);
283 }
284
285 else if (src instanceof XMLStreamReader)
286 {
287 XMLStreamReader xsr = (XMLStreamReader) src;
288
289
290 if (!xsr.isStartElement() &&
291 xsr.getEventType() != XMLStreamConstants.START_DOCUMENT)
292 {
293 xsr.nextTag();
294 }
295
296 return new StaxSource((XMLStreamReader) src);
297 }
298 else if (src instanceof org.w3c.dom.Document || src instanceof org.w3c.dom.Element)
299 {
300 return new DOMSource((org.w3c.dom.Node) src);
301 }
302 else if (src instanceof DelayedResult)
303 {
304 DelayedResult result = ((DelayedResult) src);
305 DOMResult domResult = new DOMResult();
306 result.write(domResult);
307 return new DOMSource(domResult.getNode());
308 }
309 else if (src instanceof OutputHandler)
310 {
311 OutputHandler handler = ((OutputHandler) src);
312 ByteArrayOutputStream output = new ByteArrayOutputStream();
313
314 handler.write(RequestContext.getEvent(), output);
315
316 return toStreamSource(xmlInputFactory, useStaxSource, new ByteArrayInputStream(output.toByteArray()));
317 }
318 else
319 {
320 return null;
321 }
322 }
323
324 public static javax.xml.transform.Source toStreamSource(javax.xml.stream.XMLInputFactory xmlInputFactory, boolean useStaxSource, InputStream stream) throws XMLStreamException
325 {
326 if (useStaxSource)
327 {
328 return new org.mule.module.xml.stax.StaxSource(xmlInputFactory.createXMLStreamReader(stream));
329 }
330 else
331 {
332 return new javax.xml.transform.stream.StreamSource(stream);
333 }
334 }
335
336
337
338
339
340
341
342
343
344
345
346 public static void copy(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
347 copy(reader, writer, false);
348 }
349 public static void copy(XMLStreamReader reader, XMLStreamWriter writer,
350 boolean fragment) throws XMLStreamException {
351
352 int read = 0;
353 int event = reader.getEventType();
354
355 while (reader.hasNext()) {
356 switch (event) {
357 case XMLStreamConstants.START_ELEMENT:
358 read++;
359 writeStartElement(reader, writer);
360 break;
361 case XMLStreamConstants.END_ELEMENT:
362 writer.writeEndElement();
363 read--;
364 if (read <= 0 && !fragment) {
365 return;
366 }
367 break;
368 case XMLStreamConstants.CHARACTERS:
369 writer.writeCharacters(reader.getText());
370 break;
371 case XMLStreamConstants.START_DOCUMENT:
372 case XMLStreamConstants.END_DOCUMENT:
373 case XMLStreamConstants.ATTRIBUTE:
374 case XMLStreamConstants.NAMESPACE:
375 break;
376 default:
377 break;
378 }
379 event = reader.next();
380 }
381 }
382
383 private static void writeStartElement(XMLStreamReader reader, XMLStreamWriter writer)
384 throws XMLStreamException {
385 String local = reader.getLocalName();
386 String uri = reader.getNamespaceURI();
387 String prefix = reader.getPrefix();
388 if (prefix == null) {
389 prefix = "";
390 }
391
392
393
394 boolean writeElementNS = false;
395 if (uri != null) {
396 String boundPrefix = writer.getPrefix(uri);
397 if (boundPrefix == null || !prefix.equals(boundPrefix)) {
398 writeElementNS = true;
399 }
400 }
401
402
403 if (uri != null) {
404 if (prefix.length() == 0 && StringUtils.isEmpty(uri)) {
405 writer.writeStartElement(local);
406 writer.setDefaultNamespace(uri);
407
408 } else {
409 writer.writeStartElement(prefix, local, uri);
410 writer.setPrefix(prefix, uri);
411 }
412 } else {
413 writer.writeStartElement(local);
414 }
415
416
417 for (int i = 0; i < reader.getNamespaceCount(); i++) {
418 String nsURI = reader.getNamespaceURI(i);
419 String nsPrefix = reader.getNamespacePrefix(i);
420 if (nsPrefix == null) {
421 nsPrefix = "";
422 }
423
424 if (nsPrefix.length() == 0) {
425 writer.writeDefaultNamespace(nsURI);
426 } else {
427 writer.writeNamespace(nsPrefix, nsURI);
428 }
429
430 if (nsURI.equals(uri) && nsPrefix.equals(prefix)) {
431 writeElementNS = false;
432 }
433 }
434
435
436
437
438 if (writeElementNS) {
439 if (prefix == null || prefix.length() == 0) {
440 writer.writeDefaultNamespace(uri);
441 } else {
442 writer.writeNamespace(prefix, uri);
443 }
444 }
445
446
447 for (int i = 0; i < reader.getAttributeCount(); i++) {
448 String ns = reader.getAttributeNamespace(i);
449 String nsPrefix = reader.getAttributePrefix(i);
450 if (ns == null || ns.length() == 0) {
451 writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i));
452 } else if (nsPrefix == null || nsPrefix.length() == 0) {
453 writer.writeAttribute(reader.getAttributeNamespace(i), reader.getAttributeLocalName(i),
454 reader.getAttributeValue(i));
455 } else {
456 writer.writeAttribute(reader.getAttributePrefix(i), reader.getAttributeNamespace(i), reader
457 .getAttributeLocalName(i), reader.getAttributeValue(i));
458 }
459
460 }
461 }
462 }