curcuru     01/08/08 06:29:18

  Added:       test/java/src/org/apache/qetest/xsl ExtensionTestlet.java
                        TestableExtension.java
  Log:
  ExtensionTestlet is like StylesheetTestlet but also calls validation from 
Java-based extensions;
  TestableExtension is a base class that Java extensions extend to provide 
validation
  
  Revision  Changes    Path
  1.1                  
xml-xalan/test/java/src/org/apache/qetest/xsl/ExtensionTestlet.java
  
  Index: ExtensionTestlet.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 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 "Xalan" 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 [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    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 and was
   * originally based on software copyright (c) 2000, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   *
   * ExtensionTestlet.java
   *
   */
  package org.apache.qetest.xsl;
  
  import org.apache.qetest.CheckService;
  import org.apache.qetest.Datalet;
  import org.apache.qetest.Logger;
  import org.apache.qetest.QetestUtils;
  import org.apache.qetest.TestletImpl;
  import org.apache.qetest.xsl.StylesheetDatalet;
  import org.apache.qetest.xsl.XHTFileCheckService;
  import org.apache.qetest.xslwrapper.TransformWrapper;
  import org.apache.qetest.xslwrapper.TransformWrapperFactory;
  
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.PrintWriter;
  import java.io.StringWriter;
  import java.lang.reflect.Method;
  import java.util.Hashtable;
  
  /**
   * Testlet for testing xsl stylesheet extensions.  
   *
   * This class provides the testing algorithim used for verifying 
   * Xalan-specific extensions, primarily by transforming stylesheets 
   * that use extensions and optionally by allowing any Java-based 
   * extension classes to verify themselves and log out info.
   *
   * @author [EMAIL PROTECTED]
   * @version $Id: ExtensionTestlet.java,v 1.1 2001/08/08 13:29:18 curcuru Exp $
   */
  public class ExtensionTestlet extends TestletImpl
  {
      // Initialize our classname for TestletImpl's main() method
      static { thisClassName = "org.apache.qetest.xsl.ExtensionTestlet"; }
  
      // Initialize our defaultDatalet
      { defaultDatalet = (Datalet)new StylesheetDatalet(); }
  
      /** Convenience constant: Property key for Java classnames.  */
      public static final String JAVA_CLASS_NAME = "java.class.name";
  
      /** Convenience constant: Property key for TestableExtension objects.  */
      public static final String TESTABLE_EXTENSION = "testable.extension";
  
      /**
       * Accesor method for a brief description of this test.  
       * @return String describing what this ExtensionTestlet does.
       */
      public String getDescription()
      {
          return "ExtensionTestlet";
      }
  
  
      /**
       * Run this ExtensionTestlet: execute it's test and return.
       *
       * @param Datalet to use as data point for the test.
       */
      public void execute(Datalet d)
        {
          // Common: ensure cast to StylesheetDatalet
          StylesheetDatalet datalet = null;
          try
          {
              datalet = (StylesheetDatalet)d;
          }
          catch (ClassCastException e)
          {
              logger.checkErr("Datalet provided is not a StylesheetDatalet; 
cannot continue with " + d);
              return;
          }
  
          // Common: generic pre-logging
          logger.logMsg(Logger.STATUSMSG, "About to test: " 
                        + (null == datalet.inputName
                           ? datalet.xmlName
                           : datalet.inputName));
  
          // Continue if our Datalet is OK, and after we've performed 
          //  any other pre-transform steps...
          if (preCheck(datalet))
          {
              // ... then just perform a transform ...
              if (doTransform(datalet))
              {
                  // ... and if that's OK, then do verification
                  postCheck(datalet);
              }
          }
        }
  
  
      /**
       * Perform any pre-transform validation or logging.  
       * This optionally does deleteOutFile, then attempts to load 
       * a matching TestableExtension class that matches the datalet's 
       * stylesheet.  If one is found, we call preCheck on that too.
       * 
       * @param d datalet to use for testing
       */
      protected boolean preCheck(StylesheetDatalet datalet)
      {
          //@todo validate our Datalet - ensure it has valid 
          //  and/or existing files available.
          
          // Cleanup outName only if asked to - delete the file on disk
          // Optimization: this takes extra time and often is not 
          //  needed, so only do this if the option is set
          if 
("true".equalsIgnoreCase(datalet.options.getProperty("deleteOutFile")))
          {
              try
              {
                  boolean btmp = (new File(datalet.outputName)).delete();
                  logger.logMsg(Logger.TRACEMSG, "Deleting OutFile of::" + 
datalet.outputName
                                       + " status: " + btmp);
              }
              catch (SecurityException se)
              {
                  logger.logMsg(Logger.WARNINGMSG, "Deleting OutFile of::" + 
datalet.outputName
                                         + " threw: " + se.toString());
                  // But continue anyways...
              }
          }
  
          // See if we have a Java-based extension class
          // Side effect: fills in datalet.options
          findExtensionClass(datalet);
  
          // If found, ask the class to validate
          Class extensionClazz = (Class)datalet.options.get(TESTABLE_EXTENSION);
          if (null != extensionClazz)
          {
              return invokeMethodOn(extensionClazz, "preCheck", datalet);
          }
          else
          {
              logger.logMsg(Logger.TRACEMSG, "No extension class found");
              return true; // This currently isn't fatal; you can 
                           //  still run these tests
          }
      }
  
  
      /**
       * Perform just the transformation itself.  
       * This is generic to most testlets and was just copied from 
       * the body of StylesheetTestlet.
       * 
       * Accesses our class member logger.
       * @param d datalet to use for testing
       */
      protected boolean doTransform(StylesheetDatalet datalet)
      {
          // Just perform the transform and log it; don't verify yet
          TransformWrapper transformWrapper = null;
          try
          {
              transformWrapper = 
TransformWrapperFactory.newWrapper(datalet.flavor);
              // Set our datalet's options as options in the wrapper
              transformWrapper.newProcessor(datalet.options);
          }
          catch (Throwable t)
          {
              logger.logThrowable(Logger.ERRORMSG, t, getDescription() + " 
newWrapper/newProcessor threw");
              logger.checkErr(getDescription() + " newWrapper/newProcessor 
threw: " + t.toString());
              return false;
          }
  
          // Transform our supplied input file
          try
          {
              logger.logMsg(Logger.TRACEMSG, "executing with: inputName=" + 
datalet.inputName
                            + " xmlName=" + datalet.xmlName + " outputName=" + 
datalet.outputName
                            + " goldName=" + datalet.goldName + " flavor="  + 
datalet.flavor);
  
              // Simply have the wrapper do all the transforming
              //  or processing for us - we handle either normal .xsl 
              //  stylesheet tests or just .xml embedded tests
              long retVal = 0L;
              if (null == datalet.inputName)
              {
                  // presume it's an embedded test
                  long [] times = 
transformWrapper.transformEmbedded(datalet.xmlName, datalet.outputName);
                  retVal = times[TransformWrapper.IDX_OVERALL];
              }
              else
              {
                  // presume it's a normal stylesheet test
                  long[] times = transformWrapper.transform(datalet.xmlName, 
datalet.inputName, datalet.outputName);
                  retVal = times[TransformWrapper.IDX_OVERALL];
              }
              return true;
          }
          catch (Throwable t)
          {
              // Put the logThrowable first, so it appears before 
              //  the Fail record, and gets color-coded
              logger.logThrowable(Logger.ERRORMSG, t, getDescription() + " " + 
datalet.getDescription());
              logger.checkFail(getDescription() + " " + 
datalet.getDescription() 
                               + " threw: " + t.toString());
              return false;
          }
      }
  
  
      /**
       * Perform any post-transform validation or logging.  
       * 
       * Accesses our class member logger.
       * @param d datalet to use for testing
       */
      protected boolean postCheck(StylesheetDatalet datalet)
      {
          // If we have an associated extension class, call postCheck
          // If found, ask the class to validate
          Class extensionClazz = (Class)datalet.options.get(TESTABLE_EXTENSION);
          if (null != extensionClazz)
          {
              return invokeMethodOn(extensionClazz, "postCheck", datalet);
          }
          else
          {
              // Simply validate the output files ourselves, as normal
              CheckService fileChecker = 
(CheckService)datalet.options.get("fileCheckerImpl");
              // Supply default value
              if (null == fileChecker)
                  fileChecker = new XHTFileCheckService();
              if (Logger.PASS_RESULT
                  != fileChecker.check(logger,
                                       new File(datalet.outputName), 
                                       new File(datalet.goldName), 
                                       "Extension test of " + 
datalet.getDescription())
                 )
              {
                  // Log a custom element with all the file refs first
                  // Closely related to viewResults.xsl select='fileref"
                  //@todo check that these links are valid when base 
                  //  paths are either relative or absolute!
                  Hashtable attrs = new Hashtable();
                  attrs.put("idref", (new File(datalet.inputName)).getName());
                  attrs.put("inputName", datalet.inputName);
                  attrs.put("xmlName", datalet.xmlName);
                  attrs.put("outputName", datalet.outputName);
                  attrs.put("goldName", datalet.goldName);
                  logger.logElement(Logger.STATUSMSG, "fileref", attrs, 
"Extension test file references");
              }
              
              return true; // This currently isn't fatal; you can 
                           //  still run these tests
          }
      }
  
  
      /**
       * Worker method: Try to find a matching .class file for this .xsl.  
       * 
       * Accesses our class member logger.
       * @param d datalet to use for testing
       */
      protected void findExtensionClass(StylesheetDatalet datalet)
      {
          // Find the basename of the stylesheet
          String classname = null;
          if (null != datalet.inputName)
          {
              classname = datalet.inputName.substring(0, 
datalet.inputName.indexOf(".xsl"));
          }
          else
          {
              classname = datalet.xmlName.substring(0, 
datalet.xmlName.indexOf(".xml"));
          }
          
          // Also rip off any pathing info if it's found
          classname = classname.substring(classname.lastIndexOf(File.separator) 
+ 1);
              
          try
          {
              //@todo future work: since these Java extensions are all 
              //  packageless, figure out a better way to reduce name 
              //  collisions - perhaps allow as org.apache.qetest.something
              Class extensionClazz = Class.forName(classname);
              logger.logMsg(Logger.TRACEMSG, "findExtensionClass found for " 
                      + classname + " which is " + extensionClazz.getName());
  
              // Ensure the class is a TestableExtension
              if 
((TestableExtension.class).isAssignableFrom((Class)extensionClazz))
              {
                  // Store info about class in datalet
                  datalet.options.put(JAVA_CLASS_NAME, 
extensionClazz.getName());
                  datalet.options.put(TESTABLE_EXTENSION, extensionClazz);
              }
              else
              {
                  logger.logMsg(Logger.STATUSMSG, "findExtensionClass was not a 
TestableExtension, was: " + extensionClazz);
              }
          } 
          catch (Exception e)
          {
              logger.logMsg(Logger.INFOMSG, "findExtensionClass not found for " 
+ classname);
          }
      }
  
  
      /**
       * Worker method: Call a method on this extension.  
       * Only works for preCheck/postCheck, since they have the 
       * proper method signatures.
       * 
       * Accesses our class member logger.
       * @param extensionClazz Class that's assumed to be a TestableExtension
       * @param methodName method to invoke
       * @param datalet to pass to method
       */
      protected boolean invokeMethodOn(Class extensionClazz, 
              String methodName, StylesheetDatalet datalet)
      {
          try
          {
              Class[] parameterTypes = new Class[2];
              parameterTypes[0] = Logger.class;
              parameterTypes[1] = StylesheetDatalet.class;
              Method method = extensionClazz.getMethod(methodName, 
parameterTypes);
      
              // Call static method to perform pre-transform validation
              // Pass on the datalet's options in case it uses them
              Object[] parameters = new Object[2];
              parameters[0] = logger;
              parameters[1] = datalet;
              Object returnValue = method.invoke(null, parameters);
              // If the method returned something, return that ..
              if ((null != returnValue)
                  && (returnValue instanceof Boolean))
              {
                  return ((Boolean)returnValue).booleanValue();
              }
              else
              {
                  // .. otherwise just return true by default
                  return true;
              }
          }
          catch (Exception e)
          {
              logger.logThrowable(Logger.WARNINGMSG, e, "invokeMethodOn(" + 
methodName + ") threw");
              logger.checkErr("invokeMethodOn(" + methodName + ") threw: " + 
e.toString());
              return false;
          }
      }
  
  }  // end of class ExtensionTestlet
  
  
  
  
  1.1                  
xml-xalan/test/java/src/org/apache/qetest/xsl/TestableExtension.java
  
  Index: TestableExtension.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 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 "Xalan" 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 [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    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 and was
   * originally based on software copyright (c) 2000, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   *
   * TestableExtension.java
   *
   */
  package org.apache.qetest.xsl;
  import org.apache.qetest.Logger;
  import org.apache.qetest.CheckService;
  import org.apache.qetest.xsl.StylesheetDatalet;
  
  
  /**
   * Simple base class defining test hooks for Java extensions.  
   *
   * Currently provides generic but limited verification for 
   * basic extensions in the context of being called from standard 
   * transformations.  I would have preferred an interface, but then 
   * methods couldn't be static, which makes validation simpler 
   * since the test doesn't have to try to grab the same instance of 
   * an extension that the transformer used.
   *
   * @author [EMAIL PROTECTED]
   * @version $Id: TestableExtension.java,v 1.1 2001/08/08 13:29:18 curcuru Exp 
$
   */
  public class TestableExtension
  {
      /** 
       * Perform and log any pre-transformation info.  
       *
       * The extension should log out to the logger brief info 
       * about what the extension does.  It may also use items in 
       * the datalet to perform additional validation (like ensuring 
       * that counters are zeroed, etc.).
       *
       * TestableExtensions should validate any output files needed in 
       * their postCheck method; ExtensionTestlets simply rely on this 
       * method to both validate the internal actions of the extension 
       * as well as any output files, as needed.
       *
       * This should only return false if some horrendous error with 
       * the extension appears to have occoured; it will likely prevent 
       * any callers from completing the test.
       * 
       * @return true if OK; false if any fatal error occoured
       * @param logger Logger to dump any info to
       * @param datalet Datalet of current stylesheet test
       */
      public static boolean preCheck(Logger logger, StylesheetDatalet datalet) 
      {
          /* Must be overridden */
          return false;
      }
      
  
      /** 
       * Perform and log any post-transformation info.  
       * 
       * The extension should validate that it's extension was 
       * properly called.  It should also validate any output files
       * specified in the datalet, etc.  It may also 
       * validate against extension-specific data in the options 
       * (like validating that some extension call was hit a 
       * certain number of times or the like).
       * 
       * @param logger Logger to dump any info to
       * @param datalet Datalet of current stylesheet test
       */
      public static void postCheck(Logger logger, StylesheetDatalet datalet)
      {
          /* Must be overridden */
          return;
      }
  
  
      /**
       * Description of what this extension does.  
       * @return String description of extension
       */
      public static String getDescription()
      {
          return "Must be overridden";
      }
  
  }  // end of class TestableExtension
  
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to