You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-dev@jakarta.apache.org by cm...@apache.org on 2002/11/28 21:06:08 UTC

cvs commit: jakarta-cactus/framework/src/java/share/org/apache/cactus/server/runner XMLTransformer.java ServletTestRunner.java

cmlenz      2002/11/28 12:06:08

  Modified:    framework/src/java/share/org/apache/cactus/server/runner
                        ServletTestRunner.java
  Added:       framework/src/java/share/org/apache/cactus/server/runner
                        XMLTransformer.java
  Log:
  Adding support for server-side XSLT transformations to the
  ServletTestRunner. This code currently uses reflection to avoid a direct
  dependancy on the TraX APIs at runtime. It is assumed that the TraX APIs
  will be available at compile time, as they are bundled with Ant.
  
  To enable the server-side transformations, an XSLT processor needs to be
  on the test web-apps classpath (JDK1.4 will do, too). Second, a new
  initialization parameter named 'xsl-stylesheet' needs to be added to the
  servlets definition in web.xml. Third, the HTTP request parameter
  'transform' needs to be present in the request to the servlet, regardless
  of the parameters value.
  
  I'll need to document this stuff and probably do some polishing. Would be
  cool to get some feedback on whether this works for people.
  
  Revision  Changes    Path
  1.8       +113 -11   jakarta-cactus/framework/src/java/share/org/apache/cactus/server/runner/ServletTestRunner.java
  
  Index: ServletTestRunner.java
  ===================================================================
  RCS file: /home/cvs/jakarta-cactus/framework/src/java/share/org/apache/cactus/server/runner/ServletTestRunner.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ServletTestRunner.java	26 Sep 2002 16:43:33 -0000	1.7
  +++ ServletTestRunner.java	28 Nov 2002 20:06:07 -0000	1.8
  @@ -56,10 +56,17 @@
    */
   package org.apache.cactus.server.runner;
   
  +import java.io.InputStream;
   import java.io.IOException;
  +import java.io.Reader;
   import java.io.PrintWriter;
  +import java.io.StringReader;
  +import java.io.Writer;
  +import java.lang.reflect.Constructor;
  +import java.lang.reflect.Method;
   
   import javax.servlet.ServletException;
  +import javax.servlet.UnavailableException;
   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
  @@ -71,8 +78,15 @@
   
   /**
    * Helper servlet to start a JUnit Test Runner in a webapp.
  - *
  + * 
  + * <p>
  + *   This class currently does a couple of reflection tricks to avoid a direct 
  + *   dependancy on the TraX API (<code>javax.xml.transform.*</code>),
  + *   encapsulated in the {@link XMLTransformer} class.
  + * </p>
  + * 
    * @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
  + * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
    *
    * @version $Id$
    */
  @@ -84,6 +98,13 @@
       private static final String HTTP_SUITE_PARAM = "suite";
   
       /**
  +     * HTTP parameter that determines whether the XML test results should be 
  +     * transformed using the XSLT stylesheet specified as initialization 
  +     * parameter.
  +     */
  +    private static final String HTTP_TRANSFORM_PARAM = "transform";
  +
  +    /**
        * HTTP parameter containing name of the XSL stylesheet to put in the
        * returned XML test result. It will only work if the browser supports
        * this feature (IE does, I don't know about others).
  @@ -91,6 +112,59 @@
       private static final String HTTP_XSL_PARAM = "xsl";
   
       /**
  +     * Name of the servlet initialization parameter that contains the path to
  +     * the XSLT stylesheet for transforming the XML report into HTML.
  +     */
  +    private static final String XSL_STYLESHEET_PARAM = "xsl-stylesheet";
  +
  +    /**
  +     * The XML transformer. Avoid direct dependancy by using reflection.
  +     */
  +    private Object transformer = null;
  +
  +    /**
  +     * Called by the container when the servlet is initialized.
  +     * 
  +     * @throws ServletException If an initialization parameter contains an
  +     *         illegal value
  +     */
  +    public void init() throws ServletException
  +    {
  +        String xslStylesheetParam = getInitParameter(XSL_STYLESHEET_PARAM);
  +        if (xslStylesheetParam != null)
  +        {
  +            InputStream xslStylesheet =
  +                getServletContext().getResourceAsStream(xslStylesheetParam);
  +            if (xslStylesheet != null)
  +            {
  +                try
  +                {
  +                    Class transformerClass =
  +                        Class.forName(
  +                            "org.apache.cactus.server.runner.XMLTransformer");
  +                    Constructor transformerCtor =
  +                        transformerClass.getConstructor(
  +                            new Class[] {InputStream.class});
  +                    transformer =
  +                        transformerCtor.newInstance(
  +                            new Object[] {xslStylesheet});
  +                }
  +                catch (Throwable t)
  +                {
  +                    log("Could not instantiate XMLTransformer - will not "
  +                        + "perform server-side XSLT transformations", t);
  +                }
  +            }
  +            else
  +            {
  +                throw new UnavailableException(
  +                    "The initialization parameter 'xsl-stylesheet' does not "
  +                    + "refer to an existing resource");
  +            }
  +        }
  +    }
  +
  +    /**
        * Starts the test suite passed as a HTTP parameter
        *
        * @param theRequest the incoming HTTP client request
  @@ -113,10 +187,6 @@
                   + HTTP_SUITE_PARAM + "] in request");
           }
   
  -        // Get the XSL stylesheet parameter if any
  -        String xslParam = theRequest.getParameter(HTTP_XSL_PARAM);
  -
  -
           // Set up default Cactus System properties so that there is no need
           // to have a cactus.properties file in WEB-INF/classes
           System.setProperty(BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY, 
  @@ -124,14 +194,46 @@
               + theRequest.getServerPort()
               + theRequest.getContextPath());
   
  -        // Run the tests
  -        String xml = run(suiteClassName, xslParam);
  +        // Get the XSL stylesheet parameter if any
  +        String xslParam = theRequest.getParameter(HTTP_XSL_PARAM);
   
  -        theResponse.setContentType("text/xml");
  +        // Get the transform parameter if any
  +        String transformParam = theRequest.getParameter(HTTP_TRANSFORM_PARAM);
   
  -        PrintWriter pw = theResponse.getWriter();
  +        // Run the tests
  +        String xml = run(suiteClassName, xslParam);
   
  -        pw.println(xml);
  +        // Check if we should do the transformation server side
  +        if ((transformParam != null) && (transformer != null))
  +        {
  +            // Transform server side
  +            try
  +            {
  +                Method getContentTypeMethod =
  +                    transformer.getClass().getMethod(
  +                        "getContentType", new Class[0]);
  +                theResponse.setContentType((String)
  +                    getContentTypeMethod.invoke(transformer, new Object[0]));
  +                PrintWriter out = theResponse.getWriter();
  +                Method transformMethod =
  +                    transformer.getClass().getMethod(
  +                        "transform", new Class[] {Reader.class,Writer.class});
  +                transformMethod.invoke(transformer,
  +                    new Object[] {new StringReader(xml), out});
  +            }
  +            catch (Exception e)
  +            {
  +                throw new ServletException(
  +                    "Problem applying the XSLT transformation", e);
  +            }
  +        }
  +        else
  +        {
  +            // Transform client side (or not at all)
  +            theResponse.setContentType("text/xml");
  +            PrintWriter pw = theResponse.getWriter();
  +            pw.println(xml);
  +        }
       }
   
       /**
  
  
  
  1.1                  jakarta-cactus/framework/src/java/share/org/apache/cactus/server/runner/XMLTransformer.java
  
  Index: XMLTransformer.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2002 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Cactus" and "Apache Software
   *    Foundation" 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"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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.cactus.server.runner;
  
  import java.io.InputStream;
  import java.io.Reader;
  import java.io.Writer;
  
  import javax.xml.transform.Source;
  import javax.xml.transform.Templates;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerConfigurationException;
  import javax.xml.transform.TransformerException;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.stream.StreamResult;
  import javax.xml.transform.stream.StreamSource;
  
  /**
   * Helper class that handles the transformation of the XML test results to
   * some output format determined by a stylesheet.
   * 
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   *
   * @version $Id: XMLTransformer.java,v 1.1 2002/11/28 20:06:07 cmlenz Exp $
   */
  public class XMLTransformer
  {
      // Constants ---------------------------------------------------------------
  
      /**
       * Mime type of HTML content.
       */
      private static final String HTML_MIME_TYPE = "text/html";
  
      /**
       * XSLT output method for HTML.
       */
      private static final String HTML_OUTPUT_METHOD = "html";
  
      /**
       * Mime type of plain text content.
       */
      private static final String TEXT_MIME_TYPE = "text/plain";
  
      /**
       * XSLT output method for plain text.
       */
      private static final String TEXT_OUTPUT_METHOD = "text";
  
      /**
       * Mime type of XML content.
       */
      private static final String XML_MIME_TYPE = "text/xml";
  
      /**
       * XSLT output method for XML content.
       */
      private static final String XML_OUTPUT_METHOD = "xml";
  
      /**
       * Name of the XSLT output method property.
       */
      private static final String XSL_OUTPUT_PROPERTY_METHOD = "method";
  
      // Instance Variables ------------------------------------------------------
  
      /**
       * The XSLT templates to use for transforming the XML report into HTML.
       */
      private Templates templates = null;
  
      /**
       * The MIME type of the content we'll be sending to the client. This
       * defaults to "text/html", but depends on the provided XSLT stylesheet.
       */
      private String contentType = XML_MIME_TYPE;
  
      // Constructors ------------------------------------------------------------
  
      /**
       * Constructor.
       * 
       * @param theStylesheet The input stream for the stylesheet to use for the 
       *        transformations
       */
      public XMLTransformer(InputStream theStylesheet)
          throws TransformerConfigurationException
      {
          // Setup the transformation templates
          // NOTE: Because this is done at initialization time for 
          // better performance and simplicity, changes to the
          // stylesheet will only go live after the web-app is
          // restarted
          TransformerFactory transformerFactory =
              TransformerFactory.newInstance();
          Source source = new StreamSource(theStylesheet);
          templates =
              transformerFactory.newTemplates(source);
          // Find out which content type is produced by the
          // stylesheet (valid values per XSLT 1.0 are 'xml', 'html'
          // and 'text')
          String outputMethod =
              templates.getOutputProperties().getProperty(
                  XSL_OUTPUT_PROPERTY_METHOD);
          if (HTML_OUTPUT_METHOD.equals(outputMethod))
          {
              contentType = HTML_MIME_TYPE;
          }
          else if (TEXT_OUTPUT_METHOD.equals(outputMethod))
          {
              contentType = TEXT_MIME_TYPE;
          }
          else if (XML_OUTPUT_METHOD.equals(outputMethod))
          {
              contentType = XML_MIME_TYPE;
          }
      }
  
      // Public Methods ----------------------------------------------------------
  
      /**
       * Returns the content type that will be produced by the XSLT stylesheet 
       * after transformation.
       * 
       * @return The content type
       */
      public String getContentType()
      {
          return contentType;
      }
  
      /**
       * Performs the actual transformation.
       * 
       * @param theXml The XML source to transform
       * @param theWriter The writer to which the transformation result should be 
       *        written.
       */
      public void transform(Reader theXml, Writer theWriter)
          throws TransformerException
      {
          Transformer transformer = templates.newTransformer();
          transformer.transform(new StreamSource(theXml),
              new StreamResult(theWriter));
      }
  
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>