Source code: org/javahispano/canyamo/services/presentation/xml/HTMLTransformer.java
1 /*
2 Cañamo, portal framework
3 Copyright (c) 2002
4 Alberto Molpeceres, javaHispano (http://www.javahispano.org)
5 All rights reserved.
6 .
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
14 Neither the name of Alberto Molpeceres, javaHispano nor the names of its
15 contributors may be used to endorse or promote products derived from
16 this software without specific prior written permission.
17 .
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 package org.javahispano.canyamo.services.presentation.xml;
31
32 import javax.xml.transform.TransformerFactory;
33 import javax.xml.transform.Transformer;
34 import javax.xml.transform.Source;
35 import javax.xml.transform.Result;
36 import javax.xml.transform.Templates;
37 import javax.xml.transform.TransformerConfigurationException;
38 import javax.xml.transform.stream.StreamSource;
39 import javax.xml.transform.stream.StreamResult;
40
41 import java.io.*;
42 import java.util.*;
43
44 /**
45 * This class transforms XML files to HTML files using XSL stylesheets.
46 * It's a singleton so only one instance will be created in the virtual
47 * machine. This transformer can ouput the transformation result as
48 * files or Strings. It could be extended to support ouput as XML files
49 * as well.
50 * <P>
51 * It can take as sources for transformation any Xalan Source, i.e, URLs
52 * of xml and XML and XSL files, or representations in memory of files
53 * i.e. DOMSources and SAXSources.
54 * <P>
55 * This class supports the concept of stylesheet templates. You can use the
56 * <I>createTemplate</I> methods for storing stylesheets within the
57 * HTMLTransformer cache. These stylesheets will be reused each time
58 * so the overall performance increases.
59 *
60 * Here is a simple example of using HTMLTransformer to output a String:
61 *<P>
62 * <blockquote>
63 * <code>
64 * HTMLTransformer htmlTransformer = HTMLTransformer.newInstance();<BR>
65 * String result = htmlTransformer.transformToFile("article.xml",
66 * "article.xsl",out);<BR>
67 * </code>
68 * </blockquote>
69 *<P>
70 * If you would like to generate a file instead of using an output stream
71 *<P>
72 * <blockquote>
73 * <code>
74 * PDFTransformer pdfTransformer = PDFTransformer.newInstance();<BR>
75 * pdfTransformer.transform("article.xml","article.xsl","article.html");<BR>
76 * </code>
77 * </blockquote>
78 *
79 * @author <a href=mailto:martin@javahispano.com>Martín Pérez Mariñán</a>
80 * @created 22-09-2002
81 * @version 1.0
82 *
83 */
84 public class HTMLTransformer {
85
86 private static HTMLTransformer singleton;
87
88 /**
89 * This attribute will store the common used stylesheets to increase
90 * transformation process overall performance
91 */
92 private Map templates;
93
94 private TransformerFactory tFactory = TransformerFactory.newInstance();
95
96 private HTMLTransformer() {
97
98 templates = new HashMap();
99 }
100
101 /**
102 * HTMLTransformer will be a singleton object. This methods return
103 * the unique instance of this class and creates it if necessary
104 *
105 *@return HTMLTransformer singleton object
106 */
107 public static HTMLTransformer newInstance() {
108
109 if (singleton == null) {
110 singleton = new HTMLTransformer();
111 }
112 return singleton;
113 }
114
115 /**
116 * This method creates a template from a source stylesheet url so
117 * the styleshhet can be reused
118 * <P>
119 * Typically will be used from within a document management system
120 * to store the common stylesheets (articles, news, etc.) used to
121 * transform documents.
122 *
123 *@param source stylesheet's file url
124 *
125 *@throws TransformerException if some configuration error happens
126 */
127 public void createTemplates(String source) throws TransformerException {
128
129 if (source == null) return;
130
131 try {
132 templates.put(source, tFactory.newTemplates(
133 new StreamSource(source)));
134 } catch (TransformerConfigurationException tce) {
135 throw new TransformerException(tce);
136 }
137 }
138
139
140 /**
141 * This method creates a template from a source stylesheet so
142 * the styleshhet can be reused.
143 * <P>
144 * Typically will be used from within a document management system
145 * to store the common stylesheets (articles, news, etc.) used to
146 * transform documents.
147 *
148 *@param source stylesheet's source
149 */
150 public void createTemplates(Source source) throws TransformerException {
151
152 if (source == null) return;
153
154 try {
155 templates.put(source, tFactory.newTemplates(source));
156 } catch (TransformerConfigurationException tce) {
157 throw new TransformerException(tce);
158 }
159 }
160
161
162 /**
163 * Transforms an XML source using an XSL source to an String object.
164 * Typical source objects are StreamSource, DOMSource or SAXSource
165 *
166 *@param xmlSource XML source
167 *@param xslSource XSL source
168 *@return String transformation process result
169 *
170 *@throws TransformerException if some transformation error happens
171 */
172 public String transformToString(Source xmlSource, Source xslSource)
173 throws TransformerException {
174
175 StringWriter writer = new StringWriter();
176 Result result = new StreamResult(writer);
177 transform(xmlSource, getTransformer(xslSource), result);
178 return writer.toString();
179 }
180
181
182 /**
183 * Transforms an XML source using an XSL source to an String object.
184 *
185 *@param xmlSource XML source url
186 *@param xslSource XSL source url
187 *@return String transformation process result
188 *
189 *@throws TransformerException if some transformation error happens
190 */
191 public String transformToString(String xmlSource, String xslSource)
192 throws TransformerException {
193
194 StringWriter writer = new StringWriter();
195 Result result = new StreamResult(writer);
196 transform(new StreamSource(xmlSource),
197 getTransformer(new StreamSource(xslSource)), result);
198 return writer.toString();
199 }
200
201 /**
202 * Transforms an XML source using an XSL source and stores the result
203 * of the transformation process in the specified file.
204 * Typical source objects are StreamSource, DOMSource or SAXSource
205 *
206 *@param xmlSource XML source
207 *@param xslSource XSL source
208 *@param file File that in which will be stored the transformation's
209 * result
210 *
211 *@throws TransformerException if some transformation error happens
212 */
213 public void transformToFile(Source xmlSource, Source xslSource,
214 File file) throws TransformerException {
215
216 Result result = new StreamResult(file);
217 transform(xmlSource, getTransformer(xslSource), result);
218 }
219
220
221 /**
222 * Transforms an XML source using an XSL source and stores the result
223 * of the transformation process in the specified file.
224 *
225 *@param xmlSource XML source url
226 *@param xslSource XSL source url
227 *@param file File that in which will be stored the transformation's
228 * result
229 *
230 *@throws TransformerException if some transformation error happens
231 */
232 public void transformToFile(String xmlSource, String xslSource,
233 File file) throws TransformerException {
234
235 Result result = new StreamResult(file);
236 transform(new StreamSource(xmlSource),
237 getTransformer(xslSource), result);
238 }
239
240
241 /**
242 * Returns a transformer object. If xslSource is in the templates
243 * cache then the stored stylesheet template returns a special
244 * transformer object that can be used in multithreading environments
245 * in other case a new transformer is created ( this transformer
246 * object only can be used one time )
247 *
248 *@param xslSource stylesheet's url
249 *@return Transformer transformer object
250 *
251 *@throws TransformerException if some error happens in configuration
252 */
253 Transformer getTransformer(String xslSource)
254 throws TransformerException{
255
256 Templates tmpl = (Templates)templates.get(xslSource);
257 try {
258 if (tmpl == null) {
259 // this transformer can only be used at one time
260 return tFactory.newTransformer(new StreamSource(xslSource));
261 } else {
262 // this transformer can be reused
263 return tmpl.newTransformer();
264 }
265 } catch (TransformerConfigurationException tce) {
266 throw new TransformerException(tce);
267 }
268 }
269
270 /**
271 * Returns a transformer object. If xslSource is in the templates
272 * cache then the stored stylesheet template returns a special
273 * transformer object that can be used in multithreading environments
274 * in other case a new transformer is created ( this transformer
275 * object only can be used one time )
276 *
277 *@param xslSource stylesheet's url
278 *@return Transformer transformer object
279 *
280 *@throws TransformerException if some error happens in configuration
281 */
282 Transformer getTransformer(Source xslSource)
283 throws TransformerException{
284
285 if (xslSource == null) return null;
286
287 Templates tmpl = (Templates)templates.get(xslSource);
288 try {
289 if (tmpl == null) {
290 // this transformer can only be used at one time
291 return tFactory.newTransformer(xslSource);
292 } else {
293 // this transformer can be reused
294 return tmpl.newTransformer();
295 }
296 } catch (TransformerConfigurationException tce) {
297 throw new TransformerException(tce);
298 }
299 }
300
301
302 /**
303 * This is the more general method. Takes a source XML file, and a
304 * a source XLS stylesheet and outputs a result
305 *
306 * Source is an interface, implementations can be StreamSource,
307 * DOMSource or SAXSource. StreamSource is util for sources like
308 * URLs, files, InputStreams (etc.).
309 *
310 *@param xmlSource Source representing an XML document
311 *@param transformer Transformer that will be used to perform the
312 * transformation process
313 *@param result Result destination
314 *
315 *@return Result result of the transformation
316 */
317 Result transform(Source xmlSource, Transformer transformer,
318 Result result) throws TransformerException {
319
320 if (transformer == null) {
321 throw new TransformerException("couldn't get transformer object");
322 }
323
324 try {
325 transformer.transform(xmlSource, result);
326 return result;
327 } catch (Exception e) {
328 throw new TransformerException(e);
329 }
330 }
331
332
333 }