Package com.jclark.xsl.sax2

Source Code of com.jclark.xsl.sax2.XSLProcessorImpl

// $Id: XSLProcessorImpl.java 97 2005-02-28 21:18:32Z blindsey $

package com.jclark.xsl.sax2;

import com.jclark.xsl.sax.ExtensionHandlerImpl;
import com.jclark.xsl.sax.SaxFilterMaker;

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

import com.jclark.xsl.tr.*;
import com.jclark.xsl.om.*;

import javax.xml.transform.SourceLocator;

import java.util.Locale;
import java.io.IOException;
import java.net.URL;
import java.util.Hashtable;

/**
* An XSLT Processor
*/
public class XSLProcessorImpl implements XSLProcessor, Cloneable,
                                         ParameterSet
{

    private XMLProcessorEx _sourceModelBuilder;
    private XMLProcessorEx _sheetModelBuilder;

    private boolean _engineMatchesSheetLoader = false;

    private XMLReader _sheetReader;
    private XMLReader _sourceReader;

    private Sheet _sheet;
    private Engine _engine;

    private InputSource _sheetSource;

    private ResultBase _result;
    private OutputMethodHandler _outputMethodHandler;

    private ContentHandler _contentHandler;

    private DTDHandler _dtdHandler;
    private EntityResolver _resolver;
    private ErrorHandler _errorHandler;
    private Hashtable _params = new Hashtable();

    private SaxFilterMaker _xrap = null;
    private ActionDebugTarget _debugger = null;

    private Node _sourceRoot = null;


    public XSLProcessorImpl()
    {}

    public XSLProcessorImpl(Sheet sheet, Engine engine)
    {
        _sheet = sheet;
        _engine = engine;
        _engineMatchesSheetLoader = true;
    }

    /**
     * set two XMLReaders (may be the same XMLReader), #1 for
     *  parsing the XML source to transform, #2 for parsing the stylesheeet.
     */
    public void setReaders(XMLReader sourceReader, XMLReader sheetReader)
    {

        _sourceReader = sourceReader;
        _sheetReader = sheetReader;

        _sourceModelBuilder = new XMLProcessorImpl(sourceReader);
        if (_sourceReader == _sheetReader) {
            _sheetModelBuilder = _sourceModelBuilder;
        } else {
            _sheetModelBuilder = new XMLProcessorImpl(_sheetReader);
        }
        _engineMatchesSheetLoader = false; // haven't compiled the XSLT, yet
    }

    /**
     * prepare for parsing the input XML document
     */
    public void setSourceReader(XMLReader sourceReader)
    {
        _sourceReader = sourceReader;
        _sourceModelBuilder = new XMLProcessorImpl(sourceReader);
    }

    /**
     *  SAX XMLReader API
     */
    public void setDTDHandler(DTDHandler handler)
    {
        _dtdHandler = handler;
    }

    /**
     *  SAX XMLReader API
     */
    public DTDHandler getDTDHandler()
    {
        return _dtdHandler;
    }

    /**
     * SAX XMLReader API
     */
    public void setEntityResolver(EntityResolver resolver)
    {
        if (_sheetReader != null) {
            _sheetReader.setEntityResolver(resolver);
        }
        if (_sourceReader != null) {
            _sourceReader.setEntityResolver(resolver);
        }
    }

    /**
     * SAX XMLReader API
     */
    public EntityResolver getEntityResolver()
    { return _resolver; }

    /**
     * we can have either an OutputMethodHandler,
     *   or a DocumentHandler, not both
     */
    public void setOutputMethodHandler(OutputMethodHandler handler)
    {
        _outputMethodHandler = handler;
        _contentHandler = null;
    }

    /**
     * SAX 2 XMLReader API. .. return the content handler this is writing to
     * @return null in no ContentHandler was set
     */
    public ContentHandler getContentHandler()
    { return _contentHandler; }

    /**
     * SAX 2 XMLReader API.
     * we can have either an OutputMethodHandler,
     *  or a ContentHandler, not both
     */
    public void setContentHandler(ContentHandler handler)
    {
        _contentHandler = handler;
        _outputMethodHandler = null;
    }

    // FIXME
    public ContentHandler getSourceBuilder()
    {
        return null;

    }


    /**
     * SAX API
     */
    public void setErrorHandler(ErrorHandler handler)
    {
        if (_sheetReader != null) {
            _sheetReader.setErrorHandler(handler);
        }
        if (_sourceReader != null) {
            _sourceReader.setErrorHandler(handler);
        }
        if (_sheetModelBuilder != null) {
            _sheetModelBuilder.setErrorHandler(handler);
        }
        if (_sourceModelBuilder != null) {
            _sourceModelBuilder.setErrorHandler(handler);
        }
        _errorHandler = handler;
    }

    /**
     * SAX API
     * @return the error handler if one has been set, else <code>null</code>.
     */
    public ErrorHandler getErrorHandler()
    { return _errorHandler; }

    /**
     * SAX API
     */
    public void setFeature(String featureURI, boolean value)
        throws SAXNotRecognizedException, SAXNotSupportedException
    {
        // FIXME: we can do better
        throw new SAXNotSupportedException("XSLProcessor cannot set feature: " +
                                           featureURI);
    }

    /**
     * SAX API
     */
    public boolean getFeature(String featureURI)
        throws SAXNotRecognizedException, SAXNotSupportedException
    {
        // FIXME: we can do better
        throw new SAXNotSupportedException("XSLProcessor cannot get feature: " +
                                           featureURI);
    }

    /**
     * SAX API
     */
    public Object getProperty(java.lang.String name)
        throws SAXNotRecognizedException,
               SAXNotSupportedException
              
    {
        // FIXME: we can do better
        throw new SAXNotSupportedException("XSLProcessor cannot get property: " +
                                           name);
    }

    /**
     * SAX API
     */
    public void setProperty(java.lang.String name,
                            java.lang.Object value)
        throws SAXNotRecognizedException,
               SAXNotSupportedException
    {
        // FIXME: we can do better
        throw new SAXNotSupportedException("XSLProcessor cannot set property: " +
                                           name);
    }
    ////////////////////////////////////////////////////


    /**
     * load (and compile) the stylesheet
     */
    public void loadStylesheet(InputSource sheetSource)
        throws SAXException, IOException
    {
        if (!_engineMatchesSheetLoader) {
            if (_sheetModelBuilder == null) {
                throw new Error("loadStylesheet called before setParsers");
            }
            _engine = new EngineImpl(_sheetModelBuilder,
                                     new ExtensionHandlerImpl());
            _engineMatchesSheetLoader = true;
        }
        try {
            // build an object model
            phase(1);
            Node node = _sheetModelBuilder.load(sheetSource,
                                                0,
                                                _engine.getSheetLoadContext(),
                                                _engine.getNameTable());
            // "compile" it
            phase(2);
            _sheet = _engine.createSheet(node);
        }
        catch (XSLException e) {
            // TEMP
            // e.printStackTrace();

            handleXSLException(e);
        }
    }

    /**
     * sets an extension element processor for XRAP
     */
    public void setSaxExtensionFilter(String name, SaxFilterMaker xrap)
    {
        // FIXME: do this properly
        _xrap = xrap;
    }

    /**
     * sets an extension element processor for XRAP
     */
    public void setDebugger(String name, ActionDebugTarget debugger)
    {
        // FIXME: do this properly
        _debugger = debugger;
    }


    /**
     * SAX XMLReader API
     */
    public void parse(String sourceURI) throws SAXException, IOException
    {
        parse(new InputSource(sourceURI));
    }

    /**
     * load the input document into a (xslt) object model,
     *   and run the transform
     */
    public void parse(InputSource source) throws SAXException, IOException
    {
        try {
            configureResult();

            if (_sheet == null) {
                throw new SAXException("no compiled stylesheet!");
            }
            if (_engine == null) {
                throw new SAXException("no engine");
            }
            if (_sourceModelBuilder ==  null) {
                throw new SAXException("no object model builder");
            }
           
            // build a DOM of the input
            phase(3);
            Node sourceRoot = _sourceModelBuilder.load(source,
                                                   0,
                                                   _sheet.getSourceLoadContext(),
                                                   _engine.getNameTable());
           
            phase(4);
            transform(sourceRoot);
            // that's all folks
            phase(5);
        }
        catch (XSLException e) {
            handleXSLException(e);
        }
    }

    public void configureResult() {
       
        if (_outputMethodHandler != null) {
            _result = new MultiNamespaceResult(_outputMethodHandler,
                                               _errorHandler);
        } else if (_contentHandler != null) {
            _result = new MultiNamespaceResult(_contentHandler,
                                               _errorHandler);
        } else {
            // should never happen when we're using TrAX api
            _result = new MultiNamespaceResult(new DefaultHandler(),
                                               _errorHandler);
        }
    }

    public void transform(Node sourceRootthrows XSLException
    {
       
        if (_xrap != null) {
            _sheet.setSaxExtensionFilter(_xrap);
        }
        if (_debugger != null) {
            _sheet.setDebugger(_debugger);
        }
       
        // run the transform
        _sheet.process(sourceRoot, _sourceModelBuilder, this, _result);
       
    }


    public SAXTwoOMBuilder getSourceOMBuilder(String systemId)
    {
        if (_sourceModelBuilder == null) {
            return null;
        }

        return _sourceModelBuilder.getConfiguredOMBuilder(systemId,
                                                          0,
                                                          _sheet.getSourceLoadContext(),
                                                          _engine.getNameTable()
                                                          );
    }


    /**
     * rethrows an XSLException as a SAXException
     */
    void handleXSLException(XSLException e) throws SAXException, IOException
    {
        // FIXME: maybe we want to send it to the TRaX calling app, instead
        // por at least the error handler?

        String systemId = null;
        int lineNumber = -1;

        SourceLocator sl  = e.getLocator();
        if (sl != null) {
            systemId = sl.getSystemId();
            lineNumber = sl.getLineNumber();
        }

        Exception wrapped = (Exception) e.getException();
        String message = e.getMessage();
        if (systemId != null || lineNumber != -1) {
            throw new SAXParseException(message, null,
                                        systemId, lineNumber, -1, wrapped);
        }
        if (message == null) {
            if (wrapped instanceof SAXException) {
                throw (SAXException)wrapped;
            }
            if (wrapped instanceof IOException) {
                throw (IOException)wrapped;
            }
        }
        throw new SAXException(message, wrapped);
    }

    void phase(int n)
    {  /* System.out.println("XSLProcessorImpl():: phase " + n); */ }

    /**
     *
     */
    public Object clone()
    {
        try {
            XSLProcessorImpl cloned = (XSLProcessorImpl)super.clone();
            cloned._params = (Hashtable) cloned._params.clone();
            return cloned;
        }
        catch (CloneNotSupportedException e) {
            throw new Error("unexpected CloneNotSupportedException");
        }
    }

    ///////////////////////////////////////////////////////////
    //
    //  XSLT Parameters

    /**
     *
     */
    public Object getParameter(Name name)
    {
        String nameString = name.getNamespace();
        if (nameString == null) {
            nameString = name.getLocalPart();
        } else {
            nameString = (nameString
                          + OutputMethodHandler.namespaceSeparator
                          + name.getLocalPart());
        }
        return _params.get(nameString);
    }

    /**
     * recognizes names in the form "{namespace-part}local-part"
     * as used in TrAX
     */
    public void setParameter(String name, Object obj)
    {
        if (name.length() > 1 && name.charAt(0) == '{') {
            int nsend = name.indexOf('}');
            if (nsend > 0) {
                name = name.substring(1, nsend) +
                           OutputMethodHandler.namespaceSeparator
                    + name.substring(nsend + 1);

            }
        }
        _params.put(name, obj);
    }

    /**
     * recognizes names in the form "{namespace-part}local-part"
     * as used in TrAX
     */
    public Object getParameter(String name)
    {
        if (name.length() > 1 && name.charAt(0) == '{') {
            int nsend = name.indexOf('}');
            if (nsend > 0) {
                name = name.substring(1, nsend) +
                           OutputMethodHandler.namespaceSeparator
                    + name.substring(nsend + 1);

            }
        }
        return _params.get(name);
    }

    /**
     *
     */
    public void clearParameters()
    {
        _params = new Hashtable();
    }

}
TOP

Related Classes of com.jclark.xsl.sax2.XSLProcessorImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.