KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > dataxslt > StylesheetCache


1 /*
2   Copyright (C) 2003 Know Gate S.L. All rights reserved.
3                       C/O�a, 107 1�2 28050 Madrid (Spain)
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions
7   are met:
8
9   1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11
12   2. The end-user documentation included with the redistribution,
13      if any, must include the following acknowledgment:
14      "This product includes software parts from hipergate
15      (http://www.hipergate.org/)."
16      Alternately, this acknowledgment may appear in the software itself,
17      if and wherever such third-party acknowledgments normally appear.
18
19   3. The name hipergate must not be used to endorse or promote products
20      derived from this software without prior written permission.
21      Products derived from this software may not be called hipergate,
22      nor may hipergate appear in their name, without prior written
23      permission.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28
29   You should have received a copy of hipergate License with this code;
30   if not, visit http://www.hipergate.org or mail to info@hipergate.org
31 */

32
33 package com.knowgate.dataxslt;
34
35 import java.io.File JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.io.FileNotFoundException JavaDoc;
38 import java.io.InputStream JavaDoc;
39 import java.io.OutputStream JavaDoc;
40 import java.io.StringBufferInputStream JavaDoc;
41 import java.io.ByteArrayInputStream JavaDoc;
42 import java.io.ByteArrayOutputStream JavaDoc;
43 import java.io.UnsupportedEncodingException JavaDoc;
44
45 import java.util.Date JavaDoc;
46 import java.util.WeakHashMap JavaDoc;
47 import java.util.Iterator JavaDoc;
48 import java.util.Properties JavaDoc;
49 import java.util.Enumeration JavaDoc;
50
51 import javax.xml.transform.TransformerFactory JavaDoc;
52 import javax.xml.transform.Transformer JavaDoc;
53 import javax.xml.transform.Templates JavaDoc;
54 import javax.xml.transform.TransformerException JavaDoc;
55 import javax.xml.transform.TransformerConfigurationException JavaDoc;
56 import javax.xml.transform.stream.StreamSource JavaDoc;
57 import javax.xml.transform.stream.StreamResult JavaDoc;
58
59 import com.knowgate.debug.DebugFile;
60 import com.knowgate.misc.Gadgets;
61
62 /**
63  * XSL File Cache
64  * This class keeps a master copy in memory of each XSL Stylesheet file.<br>
65  * When a Transformer object is requested a copy of the master Stylesheet is
66  * done. This is faster than re-loading de XSL file from disk.<br>
67  * StylesheetCache is a WeakHashMap so cached stylesheets can be automatically
68  * garbage collected is memory runs low.
69  * @author Sergio Montoro Ten
70  * @version 1.0
71  */

72 public class StylesheetCache {
73
74   private StylesheetCache() { }
75
76   // ---------------------------------------------------------------------------
77

78   /**
79    * Get Transformer object for XSL file.
80    * StylesheetCache automatically checks file last modification date and compares
81    * it with loading date for cached objects. If file is more recent than its cached
82    * object then the disk copy is reloaded.
83    * @param sFilePath File Path
84    * @throws IOException
85    * @throws TransformerException
86    * @throws TransformerConfigurationException
87    */

88   public static synchronized Transformer JavaDoc newTransformer(String JavaDoc sFilePath)
89     throws FileNotFoundException JavaDoc, IOException JavaDoc, TransformerException JavaDoc, TransformerConfigurationException JavaDoc {
90
91     if (DebugFile.trace) {
92       DebugFile.writeln("Begin StylesheetCache.newTransformer(" + sFilePath + ")");
93       DebugFile.incIdent();
94     }
95
96     File JavaDoc oFile = new File JavaDoc(sFilePath);
97
98     if (!oFile.exists()) {
99       if (DebugFile.trace) {
100         DebugFile.writeln("File not found " + sFilePath);
101         DebugFile.decIdent();
102       }
103       throw new FileNotFoundException JavaDoc(sFilePath);
104     }
105     long lastMod = oFile.lastModified();
106
107     TransformerFactory JavaDoc oFactory;
108     Templates JavaDoc oTemplates;
109     StreamSource JavaDoc oStreamSrc;
110     SheetEntry oSheet = (SheetEntry) oCache.get(sFilePath);
111
112     if (null!=oSheet) {
113       if (DebugFile.trace) {
114         DebugFile.writeln("Cache hit: Cached stylesheet date "+new Date JavaDoc(oSheet.lastModified).toString() + " Disk file date "+new Date JavaDoc(lastMod).toString());
115       }
116       if (lastMod>oSheet.lastModified) {
117         oSheet = null;
118         oCache.remove(sFilePath);
119       }
120     } // fi (oSheet)
121

122     if (null==oSheet) {
123       if (DebugFile.trace) DebugFile.writeln("TransformerFactory.newInstance()");
124       oFactory = TransformerFactory.newInstance();
125       if (DebugFile.trace) DebugFile.writeln("new StreamSource("+sFilePath+")");
126       oStreamSrc = new StreamSource JavaDoc(sFilePath);
127       oTemplates = oFactory.newTemplates(oStreamSrc);
128       oSheet = new SheetEntry(lastMod, oTemplates);
129       oCache.put(sFilePath, oSheet);
130     }
131
132     if (DebugFile.trace) DebugFile.writeln("javax.xml.transform.Templates.newTransformer()");
133     Transformer JavaDoc oTransformer = oSheet.templates.newTransformer();
134
135     if (DebugFile.trace) {
136       DebugFile.decIdent();
137       DebugFile.writeln("End StylesheetCache.newTransformer()");
138     }
139
140     return oTransformer;
141   } // newTransformer()
142

143   // ---------------------------------------------------------------------------
144

145   /**
146    * Set parameters for a StyleSheet taken from a properties collection.
147    * This method is primarily designed for setting environment parameters.
148    * @param oXSL Transformer object.
149    * @param oProps Properties to be set as parameters. The substring "param_"
150    * will be added as a preffix to each property name passed as parameter.
151    * So if you pass a property named "workarea" it must be retrieved from XSL
152    * as &lt;xsl:param name="param_workarea"/&gt;
153    * @throws NullPointerException if oXSL is <b>null</b> or oProps is <b>null</b>
154    */

155   public static void setParameters(Transformer JavaDoc oXSL, Properties JavaDoc oProps)
156     throws NullPointerException JavaDoc {
157
158     if (DebugFile.trace) {
159       DebugFile.writeln("Begin StylesheetCache.setParameters(Transformer, Properties)");
160       if (null==oXSL) throw new NullPointerException JavaDoc("StylesheetCache.setParameters() Transformer may not be null");
161       if (null==oXSL) throw new NullPointerException JavaDoc("StylesheetCache.setParameters() Properties may not be null");
162       DebugFile.incIdent();
163     }
164
165     String JavaDoc sKey, sVal;
166     Iterator JavaDoc myIterator = oProps.keySet().iterator();
167
168     while (myIterator.hasNext())
169     {
170       sKey = (String JavaDoc) myIterator.next();
171       sVal = oProps.getProperty(sKey);
172
173       if (DebugFile.trace) {
174         DebugFile.writeln("set param_" + sKey + " = " + sVal);
175       }
176       oXSL.setParameter("param_" + sKey, sVal);
177     } // wend()
178

179     if (DebugFile.trace) {
180       DebugFile.decIdent();
181       DebugFile.writeln("End StylesheetCache.setParameters()");
182     }
183   } // setParameters
184

185   // ---------------------------------------------------------------------------
186

187   /**
188    * Perform XSLT transformation
189    * @param sStyleSheetPath File Path to XSL style sheet file
190    * @param oXMLInputStream Input Stream for XML source data
191    * @param oOutputStream Stream where output is to be written
192    * @param oProps Parameters for Transformer. The substring "param_"
193    * will be added as a preffix to each property name passed as parameter.
194    * So if you pass a property named "workarea" it must be retrieved from XSL
195    * as &lt;xsl:param name="param_workarea"/&gt;
196    * @throws NullPointerException if oProps is <b>null</b>
197    * @throws FileNotFoundException if sStyleSheetPath does not exist
198    * @throws IOException
199    * @throws TransformerException
200    * @throws TransformerConfigurationException
201    */

202   public static void transform (String JavaDoc sStyleSheetPath,
203                                 InputStream JavaDoc oXMLInputStream,
204                                 OutputStream JavaDoc oOutputStream, Properties JavaDoc oProps)
205     throws IOException JavaDoc, FileNotFoundException JavaDoc,
206            NullPointerException JavaDoc, TransformerException JavaDoc, TransformerConfigurationException JavaDoc {
207
208     long lElapsed = 0;
209
210     if (DebugFile.trace) {
211       lElapsed = System.currentTimeMillis();
212
213       DebugFile.writeln("Begin StylesheetCache.transform(" + sStyleSheetPath + ", InputStream, Properties)");
214       DebugFile.incIdent();
215     }
216
217     Transformer JavaDoc oTransformer = StylesheetCache.newTransformer(sStyleSheetPath);
218
219     if (null!=oProps) setParameters(oTransformer, oProps);
220
221     StreamSource JavaDoc oStreamSrcXML = new StreamSource JavaDoc(oXMLInputStream);
222
223     StreamResult JavaDoc oStreamResult = new StreamResult JavaDoc(oOutputStream);
224
225     if (DebugFile.trace) DebugFile.writeln("Transformer.transform(StreamSource,StreamResult)");
226
227     oTransformer.transform(oStreamSrcXML, oStreamResult);
228
229     if (DebugFile.trace) {
230       DebugFile.writeln("done in " + String.valueOf(System.currentTimeMillis()-lElapsed) + " miliseconds");
231       DebugFile.decIdent();
232       DebugFile.writeln("End StylesheetCache.transform()");
233     }
234   } // transform
235

236   // ---------------------------------------------------------------------------
237

238   /**
239    * Perform XSLT transformation
240    * @param sStyleSheetPath File Path to XSL style sheet file
241    * @param sXMLInput Input String with XML source data
242    * @param oProps Parameters for Transformer. The substring "param_"
243    * will be added as a preffix to each property name passed as parameter.
244    * So if you pass a property named "workarea" it must be retrieved from XSL
245    * as &lt;xsl:param name="param_workarea"/&gt;
246    * @return String Transformed document
247    * @throws NullPointerException if sXMLInput or oProps are <b>null</b>
248    * @throws FileNotFoundException if sStyleSheetPath does not exist
249    * @throws IOException
250    * @throws UnsupportedEncodingException
251    * @throws TransformerException
252    * @throws TransformerConfigurationException
253    * @since 3.0
254    */

255   public static String JavaDoc transform (String JavaDoc sStyleSheetPath, String JavaDoc sXMLInput, Properties JavaDoc oProps)
256     throws IOException JavaDoc, FileNotFoundException JavaDoc, UnsupportedEncodingException JavaDoc,
257            NullPointerException JavaDoc, TransformerException JavaDoc, TransformerConfigurationException JavaDoc {
258
259     if (DebugFile.trace) {
260       DebugFile.writeln("Begin StylesheetCache.transform(" + sStyleSheetPath + ", String, Properties)");
261       DebugFile.incIdent();
262     }
263
264     if (null==sXMLInput) {
265       if (DebugFile.trace) DebugFile.decIdent();
266       throw new NullPointerException JavaDoc("StylesheetCache.transform() XML input String may not be null");
267     }
268
269     // ****************************************
270
// Get character encoding of input XML data
271
String JavaDoc sEncoding;
272     int iEnc = Gadgets.indexOfIgnoreCase(sXMLInput, "encoding");
273     if (iEnc<0) {
274       sEncoding = "ISO8859_1";
275     } else {
276       int iBeg = iEnc+8;
277       int iEnd;
278       while (sXMLInput.charAt(iBeg)==' ' || sXMLInput.charAt(iBeg)=='=') iBeg++;
279       while (sXMLInput.charAt(iBeg)==' ') iBeg++;
280       if (sXMLInput.charAt(iBeg)=='"') {
281         iEnd = ++iBeg;
282         while (sXMLInput.charAt(iEnd)!='"') iEnd++;
283       } else {
284         iEnd = iBeg;
285         while (sXMLInput.charAt(iEnd)!=' ' && sXMLInput.charAt(iEnd)!='?') iEnd++;
286       } // fi
287
sEncoding = sXMLInput.substring(iBeg, iEnd);
288     } // fi
289
// ****************************************
290

291     if (DebugFile.trace) {
292       DebugFile.writeln("XML input file encoding is "+sEncoding);
293     }
294
295     ByteArrayOutputStream JavaDoc oOutputStream = new ByteArrayOutputStream JavaDoc();
296     ByteArrayInputStream JavaDoc oXMLInputStream = new ByteArrayInputStream JavaDoc(sXMLInput.getBytes(sEncoding));
297     Transformer JavaDoc oTransformer = StylesheetCache.newTransformer(sStyleSheetPath);
298     if (null!=oProps) setParameters(oTransformer, oProps);
299     StreamSource JavaDoc oStreamSrcXML = new StreamSource JavaDoc(oXMLInputStream);
300     StreamResult JavaDoc oStreamResult = new StreamResult JavaDoc(oOutputStream);
301     if (DebugFile.trace) DebugFile.writeln("Transformer.transform(StreamSource,StreamResult)");
302     oTransformer.transform(oStreamSrcXML, oStreamResult);
303     oStreamSrcXML = null;
304     oXMLInputStream.close();
305     String JavaDoc sRetVal = oOutputStream.toString(sEncoding);
306     if (DebugFile.trace) {
307       if (null==sRetVal)
308         DebugFile.writeln("Transformer.transform() returned null");
309       else
310         DebugFile.writeln("Transformer.transform() returned "+String.valueOf(sRetVal.length())+" characters");
311     }
312     oStreamResult = null;
313     oOutputStream.close();
314
315     if (DebugFile.trace) {
316       DebugFile.decIdent();
317       DebugFile.writeln("End StylesheetCache.transform()");
318     }
319     return sRetVal;
320   } // transform
321

322   // ---------------------------------------------------------------------------
323

324   static class SheetEntry {
325     long lastModified;
326     Templates JavaDoc templates;
327
328     SheetEntry (long lLastModified, Templates JavaDoc oTemplats) {
329       lastModified = lLastModified;
330       templates = oTemplats;
331     }
332   } // SheetEntry
333

334   private static WeakHashMap JavaDoc oCache = new WeakHashMap JavaDoc();
335 } // StylesheetCache
336
Free Books   Free Magazines  
Popular Tags