KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > trax > TemplatesHandlerImpl


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
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 /*
17  * $Id: TemplatesHandlerImpl.java,v 1.25 2004/02/16 22:57:21 minchau Exp $
18  */

19
20 package org.apache.xalan.xsltc.trax;
21
22 import javax.xml.transform.Source JavaDoc;
23 import javax.xml.transform.Templates JavaDoc;
24 import javax.xml.transform.TransformerException JavaDoc;
25 import javax.xml.transform.URIResolver JavaDoc;
26 import javax.xml.transform.sax.TemplatesHandler JavaDoc;
27
28 import org.apache.xalan.xsltc.compiler.CompilerException;
29 import org.apache.xalan.xsltc.compiler.Parser;
30 import org.apache.xalan.xsltc.compiler.SourceLoader;
31 import org.apache.xalan.xsltc.compiler.Stylesheet;
32 import org.apache.xalan.xsltc.compiler.SyntaxTreeNode;
33 import org.apache.xalan.xsltc.compiler.XSLTC;
34 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
35
36 import org.xml.sax.ContentHandler JavaDoc;
37 import org.xml.sax.InputSource JavaDoc;
38 import org.xml.sax.Locator JavaDoc;
39 import org.xml.sax.SAXException JavaDoc;
40 import org.xml.sax.Attributes JavaDoc;
41
42 import java.util.Vector JavaDoc;
43
44 /**
45  * Implementation of a JAXP1.1 TemplatesHandler
46  * @author Morten Jorgensen
47  * @author Santiago Pericas-Geertsen
48  */

49 public class TemplatesHandlerImpl
50     implements ContentHandler JavaDoc, TemplatesHandler JavaDoc, SourceLoader
51 {
52     /**
53      * System ID for this stylesheet.
54      */

55     private String JavaDoc _systemId;
56
57     /**
58      * Number of spaces to add for output indentation.
59      */

60     private int _indentNumber;
61
62     /**
63      * This URIResolver is passed to all Transformers.
64      */

65     private URIResolver JavaDoc _uriResolver = null;
66
67     /**
68      * A reference to the transformer factory that this templates
69      * object belongs to.
70      */

71     private TransformerFactoryImpl _tfactory = null;
72
73     /**
74      * A reference to XSLTC's parser object.
75      */

76     private Parser _parser = null;
77
78     /**
79      * The created Templates object.
80      */

81     private TemplatesImpl _templates = null;
82
83     /**
84      * Default constructor
85      */

86     protected TemplatesHandlerImpl(int indentNumber,
87     TransformerFactoryImpl tfactory)
88     {
89     _indentNumber = indentNumber;
90     _tfactory = tfactory;
91
92         // Instantiate XSLTC and get reference to parser object
93
_parser = new XSLTC().getParser();
94     }
95
96     /**
97      * Implements javax.xml.transform.sax.TemplatesHandler.getSystemId()
98      * Get the base ID (URI or system ID) from where relative URLs will be
99      * resolved.
100      * @return The systemID that was set with setSystemId(String id)
101      */

102     public String JavaDoc getSystemId() {
103     return _systemId;
104     }
105
106     /**
107      * Implements javax.xml.transform.sax.TemplatesHandler.setSystemId()
108      * Get the base ID (URI or system ID) from where relative URLs will be
109      * resolved.
110      * @param id Base URI for this stylesheet
111      */

112     public void setSystemId(String JavaDoc id) {
113     _systemId = id;
114     }
115
116     /**
117      * Store URIResolver needed for Transformers.
118      */

119     public void setURIResolver(URIResolver JavaDoc resolver) {
120     _uriResolver = resolver;
121     }
122
123     /**
124      * Implements javax.xml.transform.sax.TemplatesHandler.getTemplates()
125      * When a TemplatesHandler object is used as a ContentHandler or
126      * DocumentHandler for the parsing of transformation instructions, it
127      * creates a Templates object, which the caller can get once the SAX
128      * events have been completed.
129      * @return The Templates object that was created during the SAX event
130      * process, or null if no Templates object has been created.
131      */

132     public Templates JavaDoc getTemplates() {
133         return _templates;
134     }
135
136     /**
137      * This method implements XSLTC's SourceLoader interface. It is used to
138      * glue a TrAX URIResolver to the XSLTC compiler's Input and Import classes.
139      *
140      * @param href The URI of the document to load
141      * @param context The URI of the currently loaded document
142      * @param xsltc The compiler that resuests the document
143      * @return An InputSource with the loaded document
144      */

145     public InputSource JavaDoc loadSource(String JavaDoc href, String JavaDoc context, XSLTC xsltc) {
146     try {
147         // A _uriResolver must be set if this method is called
148
final Source JavaDoc source = _uriResolver.resolve(href, context);
149         if (source != null) {
150         return Util.getInputSource(xsltc, source);
151         }
152     }
153     catch (TransformerException JavaDoc e) {
154         // Falls through
155
}
156     return null;
157     }
158
159     // -- ContentHandler --------------------------------------------------
160

161     /**
162      * Re-initialize parser and forward SAX2 event.
163      */

164     public void startDocument() {
165         XSLTC xsltc = _parser.getXSLTC();
166         xsltc.init(); // calls _parser.init()
167
xsltc.setOutputType(XSLTC.BYTEARRAY_OUTPUT);
168         _parser.startDocument();
169     }
170
171     /**
172      * Just forward SAX2 event to parser object.
173      */

174     public void endDocument() throws SAXException JavaDoc {
175         _parser.endDocument();
176
177         // create the templates
178
try {
179             XSLTC xsltc = _parser.getXSLTC();
180
181             // Set the translet class name if not already set
182
String JavaDoc transletName = null;
183             if (_systemId != null) {
184                 transletName = Util.baseName(_systemId);
185             }
186             else {
187                 transletName = (String JavaDoc)_tfactory.getAttribute("translet-name");
188             }
189             xsltc.setClassName(transletName);
190
191             // Get java-legal class name from XSLTC module
192
transletName = xsltc.getClassName();
193
194             Stylesheet stylesheet = null;
195             SyntaxTreeNode root = _parser.getDocumentRoot();
196
197             // Compile the translet - this is where the work is done!
198
if (!_parser.errorsFound() && root != null) {
199                 // Create a Stylesheet element from the root node
200
stylesheet = _parser.makeStylesheet(root);
201                 stylesheet.setSystemId(_systemId);
202                 stylesheet.setParentStylesheet(null);
203
204                 // Set a document loader (for xsl:include/import) if defined
205
if (_uriResolver != null) {
206                     stylesheet.setSourceLoader(this);
207                 }
208
209                 _parser.setCurrentStylesheet(stylesheet);
210
211                 // Set it as top-level in the XSLTC object
212
xsltc.setStylesheet(stylesheet);
213
214                 // Create AST under the Stylesheet element
215
_parser.createAST(stylesheet);
216             }
217
218             // Generate the bytecodes and output the translet class(es)
219
if (!_parser.errorsFound() && stylesheet != null) {
220                 stylesheet.setMultiDocument(xsltc.isMultiDocument());
221                 stylesheet.setHasIdCall(xsltc.hasIdCall());
222
223                 // Class synchronization is needed for BCEL
224
synchronized (xsltc.getClass()) {
225                     stylesheet.translate();
226                 }
227             }
228
229             if (!_parser.errorsFound()) {
230                 // Check that the transformation went well before returning
231
final byte[][] bytecodes = xsltc.getBytecodes();
232                 if (bytecodes != null) {
233                     _templates =
234                     new TemplatesImpl(xsltc.getBytecodes(), transletName,
235                         _parser.getOutputProperties(), _indentNumber, _tfactory);
236
237                     // Set URIResolver on templates object
238
if (_uriResolver != null) {
239                         _templates.setURIResolver(_uriResolver);
240                     }
241                 }
242             }
243             else {
244                 StringBuffer JavaDoc errorMessage = new StringBuffer JavaDoc();
245                 Vector JavaDoc errors = _parser.getErrors();
246                 final int count = errors.size();
247                 for (int i = 0; i < count; i++) {
248                     if (errorMessage.length() > 0)
249                         errorMessage.append('\n');
250                     errorMessage.append(errors.elementAt(i).toString());
251                 }
252                 throw new SAXException JavaDoc(ErrorMsg.JAXP_COMPILE_ERR, new TransformerException JavaDoc(errorMessage.toString()));
253             }
254         }
255         catch (CompilerException e) {
256             throw new SAXException JavaDoc(ErrorMsg.JAXP_COMPILE_ERR, e);
257         }
258     }
259
260     /**
261      * Just forward SAX2 event to parser object.
262      */

263     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri) {
264         _parser.startPrefixMapping(prefix, uri);
265     }
266
267     /**
268      * Just forward SAX2 event to parser object.
269      */

270     public void endPrefixMapping(String JavaDoc prefix) {
271         _parser.endPrefixMapping(prefix);
272     }
273
274     /**
275      * Just forward SAX2 event to parser object.
276      */

277     public void startElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname,
278         Attributes JavaDoc attributes) throws SAXException JavaDoc
279     {
280         _parser.startElement(uri, localname, qname, attributes);
281     }
282
283     /**
284      * Just forward SAX2 event to parser object.
285      */

286     public void endElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname) {
287         _parser.endElement(uri, localname, qname);
288     }
289
290     /**
291      * Just forward SAX2 event to parser object.
292      */

293     public void characters(char[] ch, int start, int length) {
294         _parser.characters(ch, start, length);
295     }
296
297     /**
298      * Just forward SAX2 event to parser object.
299      */

300     public void processingInstruction(String JavaDoc name, String JavaDoc value) {
301         _parser.processingInstruction(name, value);
302     }
303
304     /**
305      * Just forward SAX2 event to parser object.
306      */

307     public void ignorableWhitespace(char[] ch, int start, int length) {
308         _parser.ignorableWhitespace(ch, start, length);
309     }
310
311     /**
312      * Just forward SAX2 event to parser object.
313      */

314     public void skippedEntity(String JavaDoc name) {
315         _parser.skippedEntity(name);
316     }
317
318     /**
319      * Set internal system Id and forward SAX2 event to parser object.
320      */

321     public void setDocumentLocator(Locator JavaDoc locator) {
322         setSystemId(locator.getSystemId());
323         _parser.setDocumentLocator(locator);
324     }
325 }
326
327
328
Popular Tags