Package org.apache.jetspeed.util

Source Code of org.apache.jetspeed.util.SimpleTransform

/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
*     "Apache Jetspeed" must not be used to endorse or promote products
*    derived from this software without prior written permission. For
*    written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache" or
*    "Apache Jetspeed", nor may "Apache" appear in their name, without
*    prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.jetspeed.util;

//java stuff
import java.io.*;
import java.util.*;

//Trax support
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Templates;
//import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import javax.xml.transform.sax.TransformerHandler;             

//xpath objects
import org.apache.xpath.objects.XString;

//SAX Suport
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.InputSource;

//DOM Support
import org.w3c.dom.*;

//turbine support
import org.apache.turbine.util.*;

//Jetspeed stuff
import org.apache.jetspeed.cache.disk.*;
import org.apache.jetspeed.xml.JetspeedXMLEntityResolver;




/**
* Provides a very simple mechanism to transform a document using XSLT using
* one XML document and another XSL document.  This implementation uses the TRAX API.
* It can be used with any TRAX transformer.   This can be used for very
* simple XML -> XSL processing to reduce the complexity and possibility of a
* runtime failure.
*
* @author <a href="mailto:burton@apache.org">Kevin A. Burton</a>
* @author <a href="mailto:sgala@apache.org">Santiago Gala</a>
* @version $Id: SimpleTransform.java,v 1.20 2003/03/04 00:05:15 sgala Exp $
*/
public class SimpleTransform
{

    //FIXME: This code should go into the Turbine XSLTservice.
    //Also, it is a temporary hack, as it should be configurable,
    // and done later.
    static
    {
        try
        {
            if( System.getProperty( "org.xml.sax.driver" ) == null )
            {
                System.setProperty( "org.xml.sax.driver",
                                    "org.apache.xerces.parsers.SAXParser" );
            }
        }
        catch (Throwable t)
        {
            //be very cautious here. We are in class initialization.
            t.printStackTrace();
        }
    }
   
    /**
     * Given a a DOM and a URL to a stylesheet,
     * transform the original document.
     */
    public static String transform( Document doc,
                                    String stylesheet_url)
        throws SAXException
    {
        return transform( doc, stylesheet_url, null );
    }

   
    /**
     * Given a a DOM and a URL to a stylesheet,
     * transform the original document,
     * passing parameters to the stylesheet
     */
    public static String transform( Document doc,
                                    String stylesheet_url,
                                    Map params)
        throws SAXException
    {

        // Instantiate a TransformerFactory.
        TransformerFactory tFactory = TransformerFactory.newInstance();
        // Determine whether the TransformerFactory supports the use of SAXSource
        // and SAXResult
        if (!tFactory.getFeature(SAXTransformerFactory.FEATURE) )
        {
            Log.error( "SimpleTransform: nobody told you that we need a SAX Transformer?" );
            throw new SAXException( "Invalid SAX Tranformer" );
        }
        try
        {
            // Cast the TransformerFactory.
            SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory);
            // Create a ContentHandler to handle parsing of the stylesheet.
            TemplatesHandler templatesHandler = saxTFactory.newTemplatesHandler();

            // Create an XMLReader and set its ContentHandler.
            XMLReader reader = XMLReaderFactory.createXMLReader();
            reader.setContentHandler(templatesHandler);
            // Set it to solve Entities through Jetspeed URL Manager
            reader.setEntityResolver( new JetspeedXMLEntityResolver() );
   
            // Parse the stylesheet.                      
            final InputSource xstyle = new InputSource( JetspeedDiskCache.getInstance()
                                                        .getEntry( stylesheet_url ).getReader() );
            xstyle.setSystemId( stylesheet_url );
            reader.parse( xstyle );

            //Get the Templates object from the ContentHandler.
            Templates templates = templatesHandler.getTemplates();
            // Create a ContentHandler to handle parsing of the XML source. 
            TransformerHandler handler
                = saxTFactory.newTransformerHandler(templates);
       
            // Reset the XMLReader's ContentHandler.
            reader.setContentHandler(handler)

            // Set the ContentHandler to also function as a LexicalHandler, which
            // includes "lexical" events (e.g., comments and CDATA).
            try
            {
                reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
            }
            catch( org.xml.sax.SAXNotRecognizedException e ) {}

            final Transformer processor = handler.getTransformer();

            if( params != null ) {
                Iterator keys = params.keySet().iterator();
                while( keys.hasNext() )
                {
                    String name  = (String) keys.next();
                    String value = (String) params.get(name);
                    processor.setParameter(name,
                                           value ); //FIXME: maybe we need to quote again...
                    // was processor.createXString( value)
                }
            }
       
            StringWriter pw = new StringWriter();
       
            // Have the XSLTProcessor processor object transform "foo.xml" to
            // System.out, using the XSLT instructions found in "foo.xsl".
            processor.transform( new DOMSource( doc ),
                                 new StreamResult( pw ) );
                     
            try
            {

                pw.flush();
                pw.close();
           
            }
            catch (IOException e)
            {
                //should never really happen
                Log.error( e );
            }
            return pw.toString();
        }
        catch (Exception e)
        {
            Log.error( "Invalid SAX Transformer: " , e );
            throw new SAXException( "problem in SAX transform: " + e.toString() );
        }   
    }
   
    /**
     * Given a URL to an XML file and a URL to a stylesheet, transform the
     * original document.
     */
    public static String transform( String url,
                                    String stylesheet_url )
        throws SAXException
    {

        return transform( url, stylesheet_url, null );
   
    }
   
    /**
     * Given a URL to an XML file and a URL to a stylesheet, transform the
     * original document.
     */
    public static String transform( String url,
                                    String stylesheet_url,
                                    Map params )
        throws SAXException
    {

        //bring these URLs local if they happen to be remote

        InputSource in;
        InputSource style;
        try
        {
            in = new InputSource( JetspeedDiskCache.getInstance().getEntry( url ).getReader() );
            style = new InputSource( JetspeedDiskCache.getInstance().getEntry( stylesheet_url ).getReader() );
        }
        catch (IOException e)
        {
            Log.error( e );
            //at this point we can just use the original url and stylesheet_url so this shouldn't be a problem
            in = new InputSource( url );
            style = new InputSource( stylesheet_url );
        }

        Log.info( "SimpleTransform:  transforming url: " +
                  url +
                  " with stylesheet: " +
                  stylesheet_url );

        in.setSystemId( url );
        style.setSystemId( stylesheet_url );

        return transform( in,
                          style,
                          params );
   
    }
   
    /**
     * Used internally to handle doing XSLT transformations directly.
     */
    public static String transform( InputSource content,
                                    InputSource stylesheet,
                                    Map params)
        throws SAXException
    {

        // Instantiate a TransformerFactory.
        TransformerFactory tFactory = TransformerFactory.newInstance();
        // Determine whether the TransformerFactory supports the use of SAXSource
        // and SAXResult
        if (!tFactory.getFeature(SAXTransformerFactory.FEATURE) )
        {
            Log.error( "SimpleTransform: nobody told you that we need a SAX Transformer?" );
            throw new SAXException( "Invalid SAX Tranformer" );
        }
        try
        {
            // Cast the TransformerFactory.
            SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory);
            // Create a ContentHandler to handle parsing of the stylesheet.
            TemplatesHandler templatesHandler = saxTFactory.newTemplatesHandler();

            // Create an XMLReader and set its ContentHandler.
            XMLReader reader = XMLReaderFactory.createXMLReader();
            reader.setContentHandler(templatesHandler);
   
            // Parse the stylesheet.                      
            reader.parse( stylesheet );

            //Get the Templates object from the ContentHandler.
            Templates templates = templatesHandler.getTemplates();
            // Create a ContentHandler to handle parsing of the XML source. 
            TransformerHandler handler
                = saxTFactory.newTransformerHandler(templates);
       
            // Reset the XMLReader's ContentHandler.
            reader.setContentHandler(handler)

            // Set the ContentHandler to also function as a LexicalHandler, which
            // includes "lexical" events (e.g., comments and CDATA).
            try
            {
                reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
            }
            catch( org.xml.sax.SAXNotRecognizedException e ) {}
           
            final Transformer processor = handler.getTransformer();

       
            if( params != null )
            {
                Iterator keys = params.keySet().iterator();
                while( keys.hasNext() )
                {
                    String name  = (String) keys.next();
                    String value = (String) params.get(name);
                    processor.setParameter(name,
                                           new XString( value )
                         /*FIXME: was processor.createXString( value) */ );
                }
            }

            StringWriter pw = new StringWriter();
       
            // Have the XSLTProcessor processor object transform "foo.xml" to
            // System.out, using the XSLT instructions found in "foo.xsl".
            processor.transform( new SAXSource( content ),
                                 new StreamResult( pw ) );
                     
            try
            {
                pw.flush();
                pw.close();
            }
            catch (IOException e)
            {
                //should never really happen
                Log.error( e );
            }
            return pw.toString();
        }
        catch (Exception e)
        {
            Log.error( "Invalid SAX Transformer: " , e);
            throw new SAXException( "problem in SAX transform: " + e.toString() );
        }   
    }

    /**
     * Perform a event based parsing of the given content_url,
     * process it with the XSLT stylesheet stylesheet_url, using the params
     * parameters, and return a Reader that will do the transformation dynamically.
     *
     * @param content_url The url of the xml document
     * @param stylesheet_url The url of the stylesheet
     * @param params A Map containing stylesheet parameters
     * @return a Reader on the transformed document
     *
     */
    public static Reader SAXTransform( String content_url,
                                       String stylesheet_url,
                                       Map params) throws IOException
    {

        // Instantiate a TransformerFactory.
        TransformerFactory tFactory = TransformerFactory.newInstance();
        // Determine whether the TransformerFactory supports the use of SAXSource
        // and SAXResult
        if (!tFactory.getFeature(SAXTransformerFactory.FEATURE) )
        {
            Log.error( "SimpleTransform: nobody told you that we need a SAX Transformer?" );
            throw new IOException( "Invalid SAX Tranformer" );
        }
        try
        {
            // Cast the TransformerFactory.
            SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory);
            // Create a ContentHandler to handle parsing of the stylesheet.
            TemplatesHandler templatesHandler = saxTFactory.newTemplatesHandler();

            // Create an XMLReader and set its ContentHandler.
            XMLReader reader = XMLReaderFactory.createXMLReader();
            reader.setContentHandler(templatesHandler);
            // Set it to solve Entities through Jetspeed URL Manager
            reader.setEntityResolver( new JetspeedXMLEntityResolver() );

            // Parse the stylesheet.                      
            InputSource style = new InputSource( JetspeedDiskCache.getInstance()
                                                 .getEntry( stylesheet_url ).getReader() );
            style.setSystemId( stylesheet_url );
            final InputSource xstyle = style;

            reader.parse( xstyle );

            //Get the Templates object from the ContentHandler.
            Templates templates = templatesHandler.getTemplates();
            // Create a ContentHandler to handle parsing of the XML source. 
            TransformerHandler handler
                = saxTFactory.newTransformerHandler(templates);
       
            // Reset the XMLReader's ContentHandler.
            reader.setContentHandler(handler)

            // Set the ContentHandler to also function as a LexicalHandler, which
            // includes "lexical" events (e.g., comments and CDATA).
            try
            {
                reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
            }
            catch( org.xml.sax.SAXNotRecognizedException e ) {}

            final Transformer processor = handler.getTransformer();

            //Set the parameters (if any)
            if( params != null )
            {
                Iterator keys = params.keySet().iterator();
                while( keys.hasNext() )
                {
                    String name  = (String) keys.next();
                    String value = (String) params.get(name);
                    //FIXME: maybe we need to quote again...
                    // was processor.createXString( value)
                    processor.setParameter(name,
                                           new XString( value ) );
                }
            }

            PipedInputStream pis = new PipedInputStream();
            PipedOutputStream pos = new PipedOutputStream( pis );
            try
            {

                final Writer pw = new OutputStreamWriter( pos, "utf-8" );
                InputSource is = new InputSource( JetspeedDiskCache.getInstance()
                                                  .getEntry( content_url ).getReader() );
                is.setSystemId( content_url );

                final SAXSource xinput = new SAXSource( is );
                //Perform the transformation on a new thread, using
                // PipedStreams
                Thread t = new Thread( new Runnable()
                    {
                        public void run()
                        {
                            // Have the processor object transform
                            // "foo.xml" to
                            // System.out, using the XSLT instructions
                            //found in "foo.xsl".
                            Log.debug("Starting SAX thread...");
                            try
                            {
                                processor.transform( xinput,
                                                     new StreamResult( pw ) );
                                pw.close();
                                Log.debug("...ending SAX thread.");
                            }
                            catch( Exception se)
                            {
                                Log.debug("Error in SAXTransform");
                                Log.debug( se.toString(), se );
                            }
                        }
                    } );
                t.start();
            }
            catch (java.io.UnsupportedEncodingException uee)
            {
                Log.debug("Need utf-8 encoding to SAXTransform");
            }
            return new InputStreamReader ( pis, "utf-8" );
        }
        catch (Exception e)
        {
            Log.error( "Invalid SAX Transformer:" , e);
            throw new IOException( "problem in SAX transform: " + e.toString() );
        }   
    }

}
TOP

Related Classes of org.apache.jetspeed.util.SimpleTransform

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.