1 package org.apache.turbine.services.xslt;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.io.File;
58 import java.io.Reader;
59 import java.io.StringWriter;
60 import java.io.Writer;
61 import java.util.Hashtable;
62 import javax.xml.transform.Result;
63 import javax.xml.transform.Source;
64 import javax.xml.transform.Templates;
65 import javax.xml.transform.Transformer;
66 import javax.xml.transform.TransformerFactory;
67 import javax.xml.transform.dom.DOMSource;
68 import javax.xml.transform.stream.StreamResult;
69 import javax.xml.transform.stream.StreamSource;
70 import org.apache.turbine.services.TurbineBaseService;
71 import org.apache.turbine.services.TurbineServices;
72 import org.apache.turbine.services.resources.TurbineResources;
73 import org.apache.turbine.services.servlet.TurbineServlet;
74
75 /***
76 * Implementation of the Turbine XSLT Service. It transforms xml with a given
77 * xsl file. XSL stylesheets are compiled and cached (if the property in
78 * TurbineResources.properties is set) to improve speeds.
79 *
80 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
81 * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
82 */
83 public class TurbineXSLTService
84 extends TurbineBaseService
85 implements XSLTService
86
87 {
88 /***
89 * Property to control the caching of StyleSheetRoots.
90 */
91 protected boolean caching = false;
92
93 /***
94 * Path to style sheets used for tranforming well-formed
95 * XML documents. The path is relative to the webapp context.
96 */
97 protected String path;
98
99 /***
100 * Cache of compiled StyleSheetRoots.
101 */
102 protected Hashtable cache = new Hashtable();
103
104 /***
105 * Factory for producing templates and null transformers
106 */
107 private static TransformerFactory tfactory;
108
109 /***
110 * Initialize the TurbineXSLT Service. Load the path to search for
111 * xsl files and initiates the cache.
112 */
113 public void init()
114 {
115 if (getInit())
116 {
117 return;
118 }
119
120 path = TurbineResources.getString (
121 TurbineServices.SERVICE_PREFIX +
122 XSLTService.SERVICE_NAME + ".path");
123
124 path = TurbineServlet.getRealPath (path);
125
126 if (!path.endsWith("/") && !path.endsWith ("//"))
127 {
128 path = path + File.separator;
129 }
130
131 caching = TurbineResources.getBoolean (
132 TurbineServices.SERVICE_PREFIX +
133 XSLTService.SERVICE_NAME + ".cache");
134
135
136 tfactory = TransformerFactory.newInstance();
137
138 setInit(true);
139 }
140
141 /***
142 * Get a valid and existing filename from a template name.
143 * The extension is removed and replaced with .xsl. If this
144 * file does not exist the method attempts to find default.xsl.
145 * If it fails to find default.xsl it returns null.
146 */
147 protected String getFileName(String templateName)
148 {
149 // First we chop of the existing extension
150 int colon = templateName.lastIndexOf (".");
151 if (colon > 0)
152 {
153 templateName = templateName.substring(0, colon);
154 }
155
156 // Now we try to find the file ...
157 File f = new File (path+templateName + ".xsl");
158 if (f.exists())
159 {
160 return path+templateName+".xsl";
161 }
162 else
163 {
164 // ... or the default file
165 f = new File(path + "default.xsl");
166 if (f.exists())
167 {
168 return path + "default.xsl";
169 }
170 else
171 {
172 return null;
173 }
174 }
175 }
176
177 /***
178 * Compile Templates from an input file.
179 */
180 protected Templates compileTemplates(String source) throws Exception
181 {
182 StreamSource xslin = new StreamSource(new File(source));
183 Templates root = tfactory.newTemplates(xslin);
184 return root;
185 }
186
187 /***
188 * Retrieves Templates. If caching is switched on the
189 * first attempt is to load the Templates from the cache.
190 * If caching is switched of or if the Stylesheet is not found
191 * in the cache a new StyleSheetRoot is compiled from an input
192 * file.
193 * <p>
194 * This method is synchronized on the xsl cache so that a thread
195 * does not attempt to load a StyleSheetRoot from the cache while
196 * it is still being compiled.
197 */
198 protected Templates getTemplates(String xslName) throws Exception
199 {
200 synchronized (cache)
201 {
202 if (caching && cache.containsKey (xslName))
203 {
204 return (Templates) cache.get(xslName);
205 }
206
207 String fn = getFileName(xslName);
208
209 if (fn == null) return null;
210
211 Templates sr = compileTemplates(fn);
212
213 if (caching)
214 {
215 cache.put(xslName,sr);
216 }
217
218 return sr;
219 }
220
221 }
222
223 protected void transform(String xslName, Source xmlin, Result xmlout)
224 throws Exception
225 {
226 Templates sr = getTemplates(xslName);
227 Transformer transformer;
228
229
230 // If there is no stylesheet we just echo the xml
231 if (sr == null)
232 {
233 transformer = tfactory.newTransformer();
234 }
235 else
236 {
237 transformer = sr.newTransformer();
238 }
239
240 transformer.transform(xmlin, xmlout);
241 }
242
243
244 /***
245 * Execute an xslt
246 */
247 public void transform(String xslName, Reader in, Writer out)
248 throws Exception
249 {
250 Source xmlin = new StreamSource(in);
251 Result xmlout = new StreamResult(out);
252
253 transform(xslName,xmlin,xmlout);
254 }
255
256 /***
257 * Execute an xslt
258 */
259 public String transform(String xslName, Reader in) throws Exception
260 {
261 StringWriter sw = new StringWriter();
262 transform(xslName,in,sw);
263 return sw.toString();
264 }
265
266
267 /***
268 * Execute an xslt
269 */
270 public void transform(String xslName, org.w3c.dom.Node in, Writer out)
271 throws Exception
272 {
273 Source xmlin = new DOMSource(in);
274 Result xmlout = new StreamResult(out);
275
276 transform(xslName,xmlin,xmlout);
277 }
278
279 /***
280 * Execute an xslt
281 */
282 public String transform(String xslName, org.w3c.dom.Node in)
283 throws Exception
284 {
285 StringWriter sw = new StringWriter();
286 transform(xslName,in,sw);
287 return sw.toString();
288 }
289
290 }
This page was automatically generated by Maven