added XMLDocument, XMLSchema, and XSLTransformation classes.
[utils] / support / general / src / main / java / org / wamblee / xml / XSLTransformation.java
1 /*
2  * Copyright 2005-2011 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 package org.wamblee.xml;
17
18 import java.io.IOException;
19 import java.io.OutputStream;
20 import java.net.MalformedURLException;
21 import java.net.URI;
22
23 import javax.xml.transform.OutputKeys;
24 import javax.xml.transform.Result;
25 import javax.xml.transform.Source;
26 import javax.xml.transform.Transformer;
27 import javax.xml.transform.TransformerConfigurationException;
28 import javax.xml.transform.TransformerException;
29 import javax.xml.transform.TransformerFactory;
30 import javax.xml.transform.TransformerFactoryConfigurationError;
31 import javax.xml.transform.URIResolver;
32 import javax.xml.transform.dom.DOMResult;
33 import javax.xml.transform.dom.DOMSource;
34 import javax.xml.transform.stream.StreamResult;
35 import javax.xml.transform.stream.StreamSource;
36
37 import org.w3c.dom.Document;
38
39 /**
40  * Represents an XSL Transformation.
41  * @author Erik Brakkee
42  *
43  */
44 public class XSLTransformation implements XMLProcessor, XMLTextProcessor {
45
46     private TransformerFactory factory;
47     private Transformer transformer;
48     private String systemId; 
49
50     /**
51      * Identity transform.
52      */
53     public XSLTransformation() throws XMLException {
54         factory = TransformerFactory.newInstance();
55         try {
56             transformer = factory.newTransformer();
57             systemId = "identityTransform";
58         } catch (TransformerConfigurationException e) {
59             throw new XMLException(e.getMessage(), e);
60         }
61     }
62
63     public XSLTransformation(URI aUri) throws XMLException {
64         try {
65             factory = TransformerFactory.newInstance();
66             Source source = new StreamSource(aUri.toURL().openStream());
67             source.setSystemId(aUri.toString());
68             systemId = aUri.toString();
69             transformer = factory.newTransformer(source);
70         } catch (MalformedURLException e) {
71             throw new XMLException(e.getMessage(), e);
72         } catch (TransformerConfigurationException e) {
73             throw new XMLException(e.getMessage(), e);
74         } catch (TransformerFactoryConfigurationError e) {
75             throw new XMLException(e.getMessage(), e);
76         } catch (IOException e) {
77             throw new XMLException(e.getMessage(), e);
78         }
79
80     }
81
82     public XSLTransformation(String aSystemId, URIResolver aResolver)
83         throws XMLException {
84         try {
85             factory = TransformerFactory.newInstance();
86             factory.setURIResolver(aResolver);
87             Source source = aResolver.resolve(aSystemId, null);
88             source.setSystemId(aSystemId);
89             systemId = aSystemId;
90             transformer = factory.newTransformer(source);
91         } catch (TransformerConfigurationException e) {
92             throw new XMLException(e.getMessage(), e);
93         } catch (TransformerFactoryConfigurationError e) {
94             throw new XMLException(e.getMessage(), e);
95         } catch (TransformerException e) { 
96             throw new XMLException(e.getMessage(), e);
97         }
98     }
99     
100     /**
101      * Configure the transformation to do pretty-printing. 
102      */
103     public XSLTransformation setPrettyPrint(boolean aPrettyPrint) { 
104         transformer.setOutputProperty(OutputKeys.INDENT, aPrettyPrint ? "yes": "no");
105         return this; 
106     }
107     
108   
109     public XSLTransformation transformation(URI aUri) throws XMLException {
110         return new XSLTransformation(aUri);
111     }
112
113     public XSLTransformation transformation(String aSystemId, URIResolver aResolver)
114         throws XMLException {
115         return new XSLTransformation(aSystemId, aResolver);
116     }
117
118     @Override
119     public DOMSource process(DOMSource aDocument) throws XMLException {
120         DOMResult result = new DOMResult();
121         try {
122             transform(aDocument, result);
123         } catch (IOException e) {
124             throw new XMLException(e.getMessage(), e);
125         } catch (TransformerException e) {
126             throw new XMLException(e.getMessage(), e);
127         }
128         Document docraw = (Document)result.getNode();
129         DOMSource resultSource = new DOMSource(docraw); 
130         resultSource.setSystemId(aDocument.getSystemId() + "/transformed(" + systemId + ")");
131         return resultSource;
132     }
133
134     @Override
135     public void write(DOMSource aDocument, OutputStream aStream) throws XMLException {
136         StreamResult result = new StreamResult(aStream);
137         try {
138             transform(aDocument, result);
139         } catch (IOException e) {
140             throw new XMLException(e.getMessage(), e);
141         } catch (TransformerException e) {
142             throw new XMLException(e.getMessage(), e);
143         }
144     }
145
146     /**
147      * Transforms a document using XSLT.
148      * 
149      * @param aSource
150      *            Document to transform.
151      * @param aResult
152      *            Result of the transformation.
153      * 
154      * @throws IOException
155      *             In case of problems reading resources.
156      * @throws TransformerException
157      *             In case transformation fails.
158      */
159     private void transform(Source aSource, Result aResult) throws IOException,
160         TransformerException {
161         try {
162             transformer.transform(aSource, aResult);
163         } catch (TransformerConfigurationException e) {
164             throw new TransformerException(
165                 "Configuration problem of XSLT transformation", e);
166         }
167     }
168 }