- /*
- * Copyright 2001-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * $Id: TemplatesHandlerImpl.java,v 1.25 2004/02/16 22:57:21 minchau Exp $
- */
-
- package com.sun.org.apache.xalan.internal.xsltc.trax;
-
- import javax.xml.transform.Source;
- import javax.xml.transform.Templates;
- import javax.xml.transform.TransformerException;
- import javax.xml.transform.URIResolver;
- import javax.xml.transform.sax.TemplatesHandler;
-
- import com.sun.org.apache.xalan.internal.xsltc.compiler.CompilerException;
- import com.sun.org.apache.xalan.internal.xsltc.compiler.Parser;
- import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader;
- import com.sun.org.apache.xalan.internal.xsltc.compiler.Stylesheet;
- import com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode;
- import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
- import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
-
- import org.xml.sax.ContentHandler;
- import org.xml.sax.InputSource;
- import org.xml.sax.Locator;
- import org.xml.sax.SAXException;
- import org.xml.sax.Attributes;
-
- import java.util.Vector;
-
- /**
- * Implementation of a JAXP1.1 TemplatesHandler
- * @author Morten Jorgensen
- * @author Santiago Pericas-Geertsen
- */
- public class TemplatesHandlerImpl
- implements ContentHandler, TemplatesHandler, SourceLoader
- {
- /**
- * System ID for this stylesheet.
- */
- private String _systemId;
-
- /**
- * Number of spaces to add for output indentation.
- */
- private int _indentNumber;
-
- /**
- * This URIResolver is passed to all Transformers.
- */
- private URIResolver _uriResolver = null;
-
- /**
- * A reference to the transformer factory that this templates
- * object belongs to.
- */
- private TransformerFactoryImpl _tfactory = null;
-
- /**
- * A reference to XSLTC's parser object.
- */
- private Parser _parser = null;
-
- /**
- * The created Templates object.
- */
- private TemplatesImpl _templates = null;
-
- /**
- * Default constructor
- */
- protected TemplatesHandlerImpl(int indentNumber,
- TransformerFactoryImpl tfactory)
- {
- _indentNumber = indentNumber;
- _tfactory = tfactory;
-
- // Instantiate XSLTC and get reference to parser object
- _parser = new XSLTC().getParser();
- }
-
- /**
- * Implements javax.xml.transform.sax.TemplatesHandler.getSystemId()
- * Get the base ID (URI or system ID) from where relative URLs will be
- * resolved.
- * @return The systemID that was set with setSystemId(String id)
- */
- public String getSystemId() {
- return _systemId;
- }
-
- /**
- * Implements javax.xml.transform.sax.TemplatesHandler.setSystemId()
- * Get the base ID (URI or system ID) from where relative URLs will be
- * resolved.
- * @param id Base URI for this stylesheet
- */
- public void setSystemId(String id) {
- _systemId = id;
- }
-
- /**
- * Store URIResolver needed for Transformers.
- */
- public void setURIResolver(URIResolver resolver) {
- _uriResolver = resolver;
- }
-
- /**
- * Implements javax.xml.transform.sax.TemplatesHandler.getTemplates()
- * When a TemplatesHandler object is used as a ContentHandler or
- * DocumentHandler for the parsing of transformation instructions, it
- * creates a Templates object, which the caller can get once the SAX
- * events have been completed.
- * @return The Templates object that was created during the SAX event
- * process, or null if no Templates object has been created.
- */
- public Templates getTemplates() {
- return _templates;
- }
-
- /**
- * This method implements XSLTC's SourceLoader interface. It is used to
- * glue a TrAX URIResolver to the XSLTC compiler's Input and Import classes.
- *
- * @param href The URI of the document to load
- * @param context The URI of the currently loaded document
- * @param xsltc The compiler that resuests the document
- * @return An InputSource with the loaded document
- */
- public InputSource loadSource(String href, String context, XSLTC xsltc) {
- try {
- // A _uriResolver must be set if this method is called
- final Source source = _uriResolver.resolve(href, context);
- if (source != null) {
- return Util.getInputSource(xsltc, source);
- }
- }
- catch (TransformerException e) {
- // Falls through
- }
- return null;
- }
-
- // -- ContentHandler --------------------------------------------------
-
- /**
- * Re-initialize parser and forward SAX2 event.
- */
- public void startDocument() {
- XSLTC xsltc = _parser.getXSLTC();
- xsltc.init(); // calls _parser.init()
- xsltc.setOutputType(XSLTC.BYTEARRAY_OUTPUT);
- _parser.startDocument();
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void endDocument() throws SAXException {
- _parser.endDocument();
-
- // create the templates
- try {
- XSLTC xsltc = _parser.getXSLTC();
-
- // Set the translet class name if not already set
- String transletName = null;
- if (_systemId != null) {
- transletName = Util.baseName(_systemId);
- }
- else {
- transletName = (String)_tfactory.getAttribute("translet-name");
- }
- xsltc.setClassName(transletName);
-
- // Get java-legal class name from XSLTC module
- transletName = xsltc.getClassName();
-
- Stylesheet stylesheet = null;
- SyntaxTreeNode root = _parser.getDocumentRoot();
-
- // Compile the translet - this is where the work is done!
- if (!_parser.errorsFound() && root != null) {
- // Create a Stylesheet element from the root node
- stylesheet = _parser.makeStylesheet(root);
- stylesheet.setSystemId(_systemId);
- stylesheet.setParentStylesheet(null);
-
- // Set a document loader (for xsl:include/import) if defined
- if (_uriResolver != null) {
- stylesheet.setSourceLoader(this);
- }
-
- _parser.setCurrentStylesheet(stylesheet);
-
- // Set it as top-level in the XSLTC object
- xsltc.setStylesheet(stylesheet);
-
- // Create AST under the Stylesheet element
- _parser.createAST(stylesheet);
- }
-
- // Generate the bytecodes and output the translet class(es)
- if (!_parser.errorsFound() && stylesheet != null) {
- stylesheet.setMultiDocument(xsltc.isMultiDocument());
- stylesheet.setHasIdCall(xsltc.hasIdCall());
-
- // Class synchronization is needed for BCEL
- synchronized (xsltc.getClass()) {
- stylesheet.translate();
- }
- }
-
- if (!_parser.errorsFound()) {
- // Check that the transformation went well before returning
- final byte[][] bytecodes = xsltc.getBytecodes();
- if (bytecodes != null) {
- _templates =
- new TemplatesImpl(xsltc.getBytecodes(), transletName,
- _parser.getOutputProperties(), _indentNumber, _tfactory);
-
- // Set URIResolver on templates object
- if (_uriResolver != null) {
- _templates.setURIResolver(_uriResolver);
- }
- }
- }
- else {
- StringBuffer errorMessage = new StringBuffer();
- Vector errors = _parser.getErrors();
- final int count = errors.size();
- for (int i = 0; i < count; i++) {
- if (errorMessage.length() > 0)
- errorMessage.append('\n');
- errorMessage.append(errors.elementAt(i).toString());
- }
- throw new SAXException(ErrorMsg.JAXP_COMPILE_ERR, new TransformerException(errorMessage.toString()));
- }
- }
- catch (CompilerException e) {
- throw new SAXException(ErrorMsg.JAXP_COMPILE_ERR, e);
- }
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void startPrefixMapping(String prefix, String uri) {
- _parser.startPrefixMapping(prefix, uri);
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void endPrefixMapping(String prefix) {
- _parser.endPrefixMapping(prefix);
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void startElement(String uri, String localname, String qname,
- Attributes attributes) throws SAXException
- {
- _parser.startElement(uri, localname, qname, attributes);
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void endElement(String uri, String localname, String qname) {
- _parser.endElement(uri, localname, qname);
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void characters(char[] ch, int start, int length) {
- _parser.characters(ch, start, length);
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void processingInstruction(String name, String value) {
- _parser.processingInstruction(name, value);
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void ignorableWhitespace(char[] ch, int start, int length) {
- _parser.ignorableWhitespace(ch, start, length);
- }
-
- /**
- * Just forward SAX2 event to parser object.
- */
- public void skippedEntity(String name) {
- _parser.skippedEntity(name);
- }
-
- /**
- * Set internal system Id and forward SAX2 event to parser object.
- */
- public void setDocumentLocator(Locator locator) {
- setSystemId(locator.getSystemId());
- _parser.setDocumentLocator(locator);
- }
- }
-
-