KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > PreparedStylesheet


1 package net.sf.saxon;
2 //import net.sf.saxon.dom.NodeOverNodeInfo;
3
import net.sf.saxon.event.CommentStripper;
4 import net.sf.saxon.event.PipelineConfiguration;
5 import net.sf.saxon.event.Sender;
6 import net.sf.saxon.event.StartTagBuffer;
7 import net.sf.saxon.instruct.Executable;
8 import net.sf.saxon.om.NamePool;
9 import net.sf.saxon.om.Validation;
10 import net.sf.saxon.style.*;
11 import net.sf.saxon.trans.StaticError;
12 import net.sf.saxon.trans.XPathException;
13 import net.sf.saxon.tree.DocumentImpl;
14 import net.sf.saxon.tree.TreeBuilder;
15 import org.xml.sax.XMLReader JavaDoc;
16
17 import javax.xml.transform.*;
18 import java.io.FileInputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.ObjectInputStream JavaDoc;
21 import java.io.Serializable JavaDoc;
22 import java.math.BigDecimal JavaDoc;
23 import java.util.Properties JavaDoc;
24
25 /**
26  * This <B>PreparedStylesheet</B> class represents a Stylesheet that has been
27  * prepared for execution (or "compiled").
28  */

29
30 public class PreparedStylesheet implements Templates, Serializable JavaDoc {
31
32     private Executable executable;
33     private transient Configuration config;
34     private NamePool targetNamePool; // the namepool used when the stylesheet was compiled,
35
// saved here so it can be used again when the stylesheet is run
36
private transient StyleNodeFactory nodeFactory;
37     private int errorCount = 0;
38
39     /**
40      * Constructor: deliberately protected
41      *
42      * @param config The Configuration set up by the TransformerFactory
43      */

44
45     protected PreparedStylesheet(Configuration config) {
46         this.config = config;
47     }
48
49     /**
50      * Make a Transformer from this Templates object.
51      *
52      * @return the new Transformer (always a Controller)
53      * @see net.sf.saxon.Controller
54      */

55
56     public Transformer newTransformer() {
57         Controller c = new Controller(config, executable);
58         c.setPreparedStylesheet(this);
59         return c;
60     }
61
62     public void setConfiguration(Configuration config) {
63         this.config = config;
64     }
65
66     public Configuration getConfiguration() {
67         return config;
68     }
69
70     /**
71      * Set the name pool
72      */

73
74     public void setTargetNamePool(NamePool pool) {
75         targetNamePool = pool;
76     }
77
78     /**
79      * Get the name pool in use. This is the namepool used for names that need to be accessible
80      * at runtime, notably the names used in XPath expressions in the stylesheet.
81      *
82      * @return the name pool in use
83      */

84
85     public NamePool getTargetNamePool() {
86         if (targetNamePool==null) {
87             return config.getNamePool();
88         } else {
89             return targetNamePool;
90         }
91     }
92
93     /**
94      * Get the StyleNodeFactory in use. The StyleNodeFactory determines which subclass of StyleElement
95      * to use for each element node in the stylesheet tree.
96      *
97      * @return the StyleNodeFactory
98      */

99
100     public StyleNodeFactory getStyleNodeFactory() {
101         return nodeFactory;
102     }
103
104     /**
105      * Prepare a stylesheet from a Source document
106      *
107      * @param styleSource the source document containing the stylesheet
108      * @exception TransformerConfigurationException if compilation of the
109      * stylesheet fails for any reason
110      */

111
112     protected void prepare(Source styleSource) throws TransformerConfigurationException {
113         nodeFactory = new StyleNodeFactory(config);
114         DocumentImpl doc;
115         try {
116             doc = loadStylesheetModule(styleSource, config, config.getNamePool(), nodeFactory);
117             setStylesheetDocument(doc, nodeFactory);
118         } catch (XPathException e) {
119             if (!e.hasBeenReported()) {
120                 try {
121                     config.getErrorListener().fatalError(e);
122                 } catch (TransformerException e1) {
123                     //
124
}
125             }
126             if (errorCount==0) {
127                 errorCount++;
128             }
129         }
130
131         if (errorCount > 0) {
132             throw new TransformerConfigurationException(
133                             "Failed to compile stylesheet. " +
134                             errorCount +
135                             (errorCount==1 ? " error " : " errors ") +
136                             "detected.");
137         }
138     }
139
140     /**
141      * Build the tree representation of a stylesheet module
142      *
143      * @param styleSource the source of the module
144      * @param config the Configuration of the transformation factory
145      * @param localNamePool the namepool used during compilation
146      * @param nodeFactory the StyleNodeFactory used for creating
147      * element nodes in the tree
148      * @exception XPathException if XML parsing or tree
149      * construction fails
150      * @return the root Document node of the tree containing the stylesheet
151      * module
152      */

153     public static DocumentImpl loadStylesheetModule(
154                                     Source styleSource,
155                                     Configuration config,
156                                     NamePool localNamePool,
157                                     StyleNodeFactory nodeFactory)
158     throws XPathException {
159
160         TreeBuilder styleBuilder = new TreeBuilder();
161         PipelineConfiguration pipe = config.makePipelineConfiguration();
162         styleBuilder.setPipelineConfiguration(pipe);
163         styleBuilder.setSystemId(styleSource.getSystemId());
164         styleBuilder.setNodeFactory(nodeFactory);
165         styleBuilder.setLineNumbering(true);
166
167         StartTagBuffer startTagBuffer = new StartTagBuffer();
168
169         UseWhenFilter useWhenFilter = new UseWhenFilter(startTagBuffer);
170         useWhenFilter.setUnderlyingReceiver(styleBuilder);
171
172         startTagBuffer.setUnderlyingReceiver(useWhenFilter);
173
174         StylesheetStripper styleStripper = new StylesheetStripper();
175         styleStripper.setStylesheetRules(localNamePool);
176         styleStripper.setUnderlyingReceiver(startTagBuffer);
177
178         CommentStripper commentStripper = new CommentStripper();
179         commentStripper.setUnderlyingReceiver(styleStripper);
180
181         // build the stylesheet document
182

183         DocumentImpl doc;
184
185         Sender sender = new Sender(pipe);
186         AugmentedSource aug = AugmentedSource.makeAugmentedSource(styleSource);
187         aug.setSchemaValidationMode(Validation.STRIP);
188         if (aug.getXMLReader() == null) {
189             XMLReader JavaDoc styleParser = config.getStyleParser();
190             aug.setXMLReader(styleParser);
191             sender.send(aug, commentStripper);
192             config.reuseStyleParser(styleParser);
193         } else {
194             sender.send(aug, commentStripper);
195         }
196         doc = (DocumentImpl)styleBuilder.getCurrentRoot();
197
198         return doc;
199
200     }
201
202     /**
203      * Load a PreparedStylesheet from a compiled stylesheet stored in a file.
204      * @param config The Configuration. <b>This method changes the NamePool used by this configuration
205      * to be the NamePool that was stored with the compiled stylesheet. The method must therefore not
206      * be used in a multi-threaded environment where the Configuration (and NamePool) are shared between
207      * multiple concurrent transformations.</b>
208      * @param fileName The name of the file containing the compiled stylesheet (which is just the Java serialization
209      * of a PreparedStylesheet object).
210      * @return the PreparedStylesheet, which can be used in JAXP interfaces as the Templates object
211      */

212
213     public static PreparedStylesheet loadCompiledStylesheet(Configuration config, String JavaDoc fileName)
214             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
215         ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc(new FileInputStream JavaDoc(fileName));
216         PreparedStylesheet sheet = (PreparedStylesheet)ois.readObject();
217         ois.close();
218         NamePool compiledNamePool = sheet.getTargetNamePool();
219         sheet.setConfiguration(config);
220         sheet.getExecutable().setConfiguration(config);
221         config.setNamePool(compiledNamePool);
222         NamePool.setDefaultNamePool(compiledNamePool);
223         return sheet;
224     }
225
226     /**
227      * Create a PreparedStylesheet from a supplied DocumentInfo
228      * Note: the document must have been built using the StyleNodeFactory
229      *
230      * @param doc the document containing the stylesheet module
231      * @param snFactory the StyleNodeFactory used to build the tree
232      * @exception XPathException if the document supplied
233      * is not a stylesheet
234      */

235
236     protected void setStylesheetDocument(DocumentImpl doc, StyleNodeFactory snFactory)
237     throws XPathException {
238
239         DocumentImpl styleDoc = doc;
240         nodeFactory = snFactory;
241
242         // If top-level node is a literal result element, stitch it into a skeleton stylesheet
243

244         StyleElement topnode = (StyleElement)styleDoc.getDocumentElement();
245         if (topnode instanceof LiteralResultElement) {
246             styleDoc = ((LiteralResultElement)topnode).makeStylesheet(this, snFactory);
247         }
248
249         if (!(styleDoc.getDocumentElement() instanceof XSLStylesheet)) {
250             throw new StaticError(
251                         "Outermost element of stylesheet is not xsl:stylesheet or xsl:transform or literal result element");
252         }
253
254         XSLStylesheet top = (XSLStylesheet)styleDoc.getDocumentElement();
255         if (config.isVersionWarning() && top.getVersion().equals(BigDecimal.valueOf(1))) {
256             try {
257                 config.getErrorListener().warning(
258                         new TransformerException("Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor")
259                 );
260             } catch (TransformerException e) {
261                 throw StaticError.makeStaticError(e);
262             }
263         }
264
265         // Preprocess the stylesheet, performing validation and preparing template definitions
266

267         top.setPreparedStylesheet(this);
268         try {
269             top.preprocess();
270         } catch (XPathException e) {
271             Throwable JavaDoc e2 = e.getException();
272             if (e2 instanceof XPathException && !((XPathException)e2).hasBeenReported()) {
273                 // this happens with some fundamental errors e.g. an xsl:stylesheet element in the wrong place
274
try {
275                     config.getErrorListener().fatalError((XPathException)e2);
276                 } catch (TransformerException e1) {
277                     //
278
}
279             }
280             throw e;
281         }
282
283         // Compile the stylesheet, retaining the resulting executable
284

285         executable = top.compileStylesheet();
286     }
287
288     /**
289      * Get the associated executable
290      *
291      * @return the Executable for this stylesheet
292      */

293
294     public Executable getExecutable() {
295         return executable;
296     }
297
298     /**
299      * Get the properties for xsl:output. JAXP method. The object returned will
300      * be a clone of the internal values, and thus it can be mutated
301      * without mutating the Templates object, and then handed in to
302      * the process method.
303      * <p>In Saxon, the properties object is a new, empty, Properties object that is
304      * backed by the live properties to supply default values for missing properties.
305      * This means that the property values must be read using the getProperty() method.
306      * Calling the get() method on the underlying Hashtable will return null.</p>
307      * <p>In Saxon 8.x, this method gets the output properties for the unnamed output
308      * format in the stylesheet.</p>
309      *
310      * @see javax.xml.transform.Transformer#setOutputProperties
311      * @return A Properties object reflecting the output properties defined
312      * for the default (unnamed) output format in the stylesheet. It may
313      * be mutated and supplied to the setOutputProperties() method of the
314      * Transformer, without affecting other transformations that use the
315      * same stylesheet.
316      */

317
318
319     public Properties JavaDoc getOutputProperties() {
320         Properties JavaDoc details = executable.getDefaultOutputProperties();
321         return new Properties JavaDoc(details);
322     }
323
324     /**
325      * Report a compile time error. This calls the errorListener to output details
326      * of the error, and increments an error count.
327      *
328      * @param err the exception containing details of the error
329      * @exception TransformerException if the ErrorListener decides that the
330      * error should be reported
331      */

332
333     public void reportError(TransformerException err) throws TransformerException {
334         errorCount++;
335         config.getErrorListener().fatalError(err);
336     }
337
338     /**
339      * Get the number of errors reported so far
340      *
341      * @return the number of errors reported
342      */

343
344     public int getErrorCount() {
345         return errorCount;
346     }
347
348     /**
349      * Report a compile time warning. This calls the errorListener to output details
350      * of the warning.
351      *
352      * @param err an exception holding details of the warning condition to be
353      * reported
354      */

355
356     public void reportWarning(TransformerException err) {
357         try {
358             config.getErrorListener().warning(err);
359         } catch (TransformerException err2) {}
360     }
361
362 }
363
364 //
365
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
366
// you may not use this file except in compliance with the License. You may obtain a copy of the
367
// License at http://www.mozilla.org/MPL/
368
//
369
// Software distributed under the License is distributed on an "AS IS" basis,
370
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
371
// See the License for the specific language governing rights and limitations under the License.
372
//
373
// The Original Code is: all this file.
374
//
375
// The Initial Developer of the Original Code is Michael H. Kay.
376
//
377
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
378
//
379
// Contributor(s): none.
380
//
381
Popular Tags