Package org.apache.bsf.engines.xslt

Source Code of org.apache.bsf.engines.xslt.XSLTEngine

/*
* Copyright 2004,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.
*/

package org.apache.bsf.engines.xslt;

import java.io.File;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.util.Vector;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;

import org.apache.bsf.BSFDeclaredBean;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
import org.apache.bsf.util.BSFEngineImpl;
import org.apache.bsf.util.BSFFunctions;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Node;

/**
* Xerces XSLT interface to BSF. Requires Xalan and Xerces from Apache.
*
* This integration uses the BSF registry to pass in any src document
* and stylesheet base URI that the user may wish to set.
*
* @author   Sanjiva Weerawarana
* @author   Sam Ruby
*
* Re-implemented for the Xalan 2 codebase
*
* @author   Victor J. Orlikowski
*/
public class XSLTEngine extends BSFEngineImpl {
    TransformerFactory tFactory;
    Transformer transformer;
   
    Log logger = LogFactory.getLog(this.getClass().getName());

    /**
     * call the named method of the given object.
     */
    public Object call (Object object, String method, Object[] args)
        throws BSFException {
  throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE,
                                "BSF:XSLTEngine can't call methods");
    }

    /**
     * Declare a bean by setting it as a parameter
     */
    public void declareBean (BSFDeclaredBean bean) throws BSFException {
        transformer.setParameter (bean.name, new XObject (bean.bean));
    }

    /**
     * Evaluate an expression. In this case, an expression is assumed
     * to be a stylesheet of the template style (see the XSLT spec).
     */
    public Object eval (String source, int lineNo, int columnNo,
                        Object oscript) throws BSFException {
  // get the style base URI (the place from where Xerces XSLT will
  // look for imported/included files and referenced docs): if a
  // bean named "xslt:styleBaseURI" is registered, then cvt it
  // to a string and use that. Otherwise use ".", which means the
  // base is the directory where the process is running from
  Object sbObj = mgr.lookupBean ("xslt:styleBaseURI");
  String styleBaseURI = (sbObj == null) ? "." : sbObj.toString ();

  // Locate the stylesheet.
  StreamSource styleSource;

        styleSource =
            new StreamSource(new StringReader(oscript.toString ()));
        styleSource.setSystemId(styleBaseURI);

        try {
            transformer = tFactory.newTransformer(styleSource);
        } catch (Exception e) {
          logger.error("Exception from Xerces XSLT:", e);
            throw new BSFException (BSFException.REASON_EXECUTION_ERROR,
                                    "Exception from Xerces XSLT: " + e, e);
        }

  // get the src to work on: if a bean named "xslt:src" is registered
  // and its a Node, then use it as the source. If its not a Node, then
  // if its a URL parse it, if not treat it as a file and make a URL and
  // parse it and go. If no xslt:src is found, use an empty document
  // (stylesheet is treated as a literal result element stylesheet)
  Object srcObj = mgr.lookupBean ("xslt:src");
  Object xis = null;
  if (srcObj != null) {
            if (srcObj instanceof Node) {
    xis = new DOMSource((Node)srcObj);
            } else {
    try {
                    String mesg = "as anything";
                    if (srcObj instanceof Reader) {
      xis = new StreamSource ((Reader) srcObj);
      mesg = "as a Reader";
                    } else if (srcObj instanceof File) {
                        xis = new StreamSource ((File) srcObj);
                        mesg = "as a file";
                    } else {
                        String srcObjstr=srcObj.toString();
                        xis = new StreamSource (new StringReader(srcObjstr));
                        if (srcObj instanceof URL) {
                            mesg = "as a URL";
                        } else {
                            ((StreamSource) xis).setPublicId (srcObjstr);
                            mesg = "as an XML string";
                        }
                    }

                    if (xis == null) {
      throw new Exception ("Unable to get input from '" +
                                             srcObj + "' " + mesg);
                    }
    } catch (Exception e) {
                    throw new BSFException (BSFException.REASON_EXECUTION_ERROR,
                                            "BSF:XSLTEngine: unable to get " +
                                            "input from '" + srcObj + "' as XML", e);
    }
            }
  } else {
            // create an empty document - real src must come into the
            // stylesheet using "doc(...)" [see XSLT spec] or the stylesheet
            // must be of literal result element type
            xis = new StreamSource();
  }
 
  // set all declared beans as parameters.
  for (int i = 0; i < declaredBeans.size (); i++) {
            BSFDeclaredBean b = (BSFDeclaredBean) declaredBeans.elementAt (i);
            transformer.setParameter (b.name, new XObject (b.bean));
  }

  // declare a "bsf" parameter which is the BSF handle so that
  // the script can do BSF stuff if it wants to
  transformer.setParameter ("bsf",
                                  new XObject (new BSFFunctions (mgr, this)));

  // do it
  try {
            DOMResult result = new DOMResult();
            transformer.transform ((StreamSource) xis, result);
            return new XSLTResultNode (result.getNode());
  } catch (Exception e) {
            throw new BSFException (BSFException.REASON_EXECUTION_ERROR,
                                    "exception while eval'ing XSLT script" + e, e);
  }
    }

    /**
     * Initialize the engine.
     */
    public void initialize (BSFManager mgr, String lang,
                            Vector declaredBeans) throws BSFException {
  super.initialize (mgr, lang, declaredBeans);

        tFactory = TransformerFactory.newInstance();
    }

    /**
     * Undeclare a bean by setting he parameter represeting it to null
     */
    public void undeclareBean (BSFDeclaredBean bean) throws BSFException {
        // Cannot clear only one parameter in Xalan 2, so we set it to null
        if ((transformer.getParameter (bean.name)) != null) {
            transformer.setParameter (bean.name, null);
        }
    }
}
TOP

Related Classes of org.apache.bsf.engines.xslt.XSLTEngine

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.