curcuru     01/07/09 10:03:25

  Added:       test/java/src/org/apache/qetest/xalanj2
                        TransformStateDatalet.java TransformStateTest.java
                        TransformStateTestlet.java
  Log:
  New tests for TransformState; only partly validated so far
  
  Revision  Changes    Path
  1.1                  
xml-xalan/test/java/src/org/apache/qetest/xalanj2/TransformStateDatalet.java
  
  Index: TransformStateDatalet.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/>.
   */
  
  /*
   *
   * TransformStateDatalet.java
   *
   */
  package org.apache.qetest.xalanj2;
  
  import org.apache.qetest.Datalet;
  
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.StringTokenizer;
  
  /**
   * Datalet for holding ExpectedTransformState objects.
   *
   * @author [EMAIL PROTECTED]
   * @version $Id: TransformStateDatalet.java,v 1.1 2001/07/09 17:03:21 curcuru 
Exp $
   */
  public class TransformStateDatalet implements Datalet
  {
      //// Items associated with the normal test
      /** URL of the stylesheet; default:.../identity.xsl.  */
      public String inputName = "tests/api/trax/identity.xsl";
  
      /** URL of the xml document; default:.../identity.xml.  */
      public String xmlName = "tests/api/trax/identity.xml";
  
      /** URL to put output into; default:TransformStateDatalet.out.  */
      public String outputName = "TransformStateDatalet.out";
  
      /** URL of the a gold file or data; default:.../identity.out.  */
      public String goldName = "tests/api-gold/trax/identity.out";
  
      /** 
       * A Hashtable of ExpectedTransformState objects to validate.  
       * Users should put ExpectedTransformState objects in here with 
       * some sort of hashKey that they want to use.
       */
  /***********************************************
  // Comment out validation using ExpectedObjects since they hang 28-Jun-01 -sc
      public Hashtable expectedTransformStates = new Hashtable();
  // Comment out validation using ExpectedObjects since they hang 28-Jun-01 -sc
  ***********************************************/
  
      /** 
       * Cheap-o hash of items to validate for column 99.  
       * Temporary use until we solve problem in TransformStateTestlet:
       * "Comment out validation using ExpectedObjects since they hang 
28-Jun-01 -sc".
       */
      public Hashtable validate99 = new Hashtable();
  
  
      /** Description of what this Datalet tests.  */
      protected String description = "TransformStateDatalet: String inputName, 
String xmlName, String outputName, String goldName, String flavor; plus second 
Templates object";
  
  
      /**
       * No argument constructor is a no-op.  
       */
      public TransformStateDatalet() { /* no-op */ }
  
  
      /**
       * Initialize this datalet from a string, perhaps from 
       * a command line.  
       * We will parse the command line with whitespace and fill
       * in our member variables in order:
       * <pre>inputName, xmlName, outputName, goldName, flavor</pre>, 
       * if there are too few tokens, remaining variables will default.
       */
      public TransformStateDatalet(String args)
      {
          load(args);
      }
  
  
      /**
       * Accesor method for a brief description of this Datalet.  
       *
       * @return String describing the specific set of data 
       * this Datalet contains (can often be used as the description
       * of any check() calls made from the Testlet).
       */
      public String getDescription()
      {
          return description;
      }
  
  
      /**
       * Accesor method for a brief description of this Datalet.  
       *
       * @param s description to use for this Datalet.
       */
      public void setDescription(String s)
      {
          description = s;
      }
  
  
      /**
       * Load fields of this Datalet from a Hashtable.  
       * Caller must provide data for all of our fields.
       * //@todo NOT FULLY IMPLEMENTED!.
       * 
       * @param Hashtable to load
       */
      public void load(Hashtable h)
      {
          if (null == h)
              return; //@todo should this have a return val or exception?
  
          inputName = (String)h.get("inputName");
          xmlName = (String)h.get("xmlName");
          outputName = (String)h.get("outputName");
          goldName = (String)h.get("goldName");
      }
  
  
      /**
       * Load fields of this Datalet from a Properties.  
       * Caller must provide data for all of our fields.
       * //@todo NOT FULLY IMPLEMENTED!.
       * 
       * @param Hashtable to load
       */
      public void load(Properties p)
      {
          if (null == p)
              return; //@todo should this have a return val or exception?
  
          inputName = (String)p.getProperty("inputName");
          xmlName = (String)p.getProperty("xmlName");
          outputName = (String)p.getProperty("outputName");
          goldName = (String)p.getProperty("goldName");
      }
      /**
       * Load fields of this Datalet from a String.  
       * NOT IMPLEMENTED! No easy way to load the Templates from string.  
       * 
       * @param s String to load
       */
      public void load(String s)
      {
          throw new RuntimeException("TransformStateDatalet.load(String) not 
implemented!");
      }
      /**
       * Load fields of this Datalet from a String[].  
       * NOT IMPLEMENTED! No easy way to load the Templates from string.  
       * 
       * @param s String array to load
       */
      public void load(String[] s)
      {
          throw new RuntimeException("TransformStateDatalet.load(String[]) not 
implemented!");
      }
  }  // end of class TransformStateDatalet
  
  
  
  
  1.1                  
xml-xalan/test/java/src/org/apache/qetest/xalanj2/TransformStateTest.java
  
  Index: TransformStateTest.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/>.
   */
  
  /*
   *
   * TransformStateTest.java
   *
   */
  package org.apache.qetest.xalanj2;
  
  // Support for test reporting and harness classes
  import org.apache.qetest.*;
  import org.apache.qetest.xsl.*;
  
  // Import all relevant TRAX packages
  import javax.xml.transform.*;
  import javax.xml.transform.dom.*;
  
  // Needed SAX, DOM, JAXP classes
  
  // java classes
  import java.io.File;
  import java.util.Properties;
  import java.util.Vector;
  
  //-------------------------------------------------------------------------
  
  /**
   * Basic functionality testing of TransformState interface.
   * This is basically just a test driver class for an explicit 
   * list of TransformStateTestlet/Datalets.  In the future we 
   * should enable better data-driven testing by being able to 
   * read in a list of TransformStateDatalets somehow.
   * 
   * @author [EMAIL PROTECTED]
   * @version $Id: TransformStateTest.java,v 1.1 2001/07/09 17:03:22 curcuru 
Exp $
   */
  public class TransformStateTest extends XSLProcessorTestBase
  {
  
      /** Subdirectory under test\tests\api for our xsl/xml files.  */
      public static final String X2J_SUBDIR = "xalanj2";
  
  
      /** Just initialize test name, comment, numTestCases. */
      public TransformStateTest()
      {
          numTestCases = 1;  // REPLACE_num
          testName = "TransformStateTest";
          testComment = "Basic functionality testing of TransformState 
interface";
      }
  
  
      /**
       * Initialize this test - create output dir.  
       *
       * @param p Properties to initialize from (if needed)
       * @return false if we should abort the test; true otherwise
       */
      public boolean doTestFileInit(Properties p)
      {
          // NOTE: 'reporter' variable is already initialized at this point
  
          // Used for all tests; just dump files in trax subdir
          File outSubDir = new File(outputDir + File.separator + X2J_SUBDIR);
          if (!outSubDir.mkdirs())
              reporter.logWarningMsg("Could not create output dir: " + 
outSubDir);
  
          return true;
      }
  
  
      /**
       * Use a TransformStateTestlet to test some datalets.
       *
       * @return false if we should abort the test; true otherwise
       */
      public boolean testCase1()
      {
          // Use a 'fake' testCase1 to initialize everything
          reporter.testCaseInit("Use a TransformStateTestlet to test some 
datalets");
          reporter.logWarningMsg("Note: limited validation: only certain events 
checked.");
  
          // First arg is list of files; currently unused
          // Note: several method signatures are copied from 
          //  StylesheetTestletDriver for future growth
          Vector datalets = buildDatalets(null, 
                                          new File(inputDir + File.separator + 
X2J_SUBDIR), 
                                          new File(outputDir + File.separator + 
X2J_SUBDIR), 
                                          new File(goldDir + File.separator + 
X2J_SUBDIR));
  
          // Validate datalets
          if ((null == datalets) || (0 == datalets.size()))
          {
              // No datalets to test, report it as an error
              reporter.checkErr("Testlet or datalets are null/blank, nothing to 
test!");
              return true;
          }
          else
          {
              reporter.checkPass("Found " + datalets.size() + " datalets to 
test...");
          }
  
          // Now just go through the list and process each set
          int numDatalets = 0;
          numDatalets = datalets.size();
          reporter.logInfoMsg("processFileList-equivalent() with " + numDatalets
                              + " potential tests");
          // Close out our 'fake' initialization testCase1
          reporter.testCaseClose();
          // Iterate over every datalet and test it
          for (int ctr = 0; ctr < numDatalets; ctr++)
          {
              try
              {
                  reporter.testCaseInit("Testing datalet(" + ctr + ") 
validation size=" 
                          + 
((TransformStateDatalet)datalets.elementAt(ctr)).validate99.size());
                  // Create a Testlet to execute a test with this 
                  //  next datalet - the Testlet will log all info 
                  //  about the test, including calling check*()
                  
getTestlet().execute((TransformStateDatalet)datalets.elementAt(ctr));
              } 
              catch (Throwable t)
              {
                  // Log any exceptions as fails and keep going
                  //@todo improve the below to output more useful info
                  reporter.checkFail("Datalet num " + ctr + " threw: " + 
t.toString());
                  reporter.logThrowable(Logger.ERRORMSG, t, "Datalet threw");
              }
              reporter.testCaseClose();
          }  // of while...
  
          return true;
      }
  
  
      /**
       * Transform a vector of individual test names into a Vector 
       * of filled-in datalets to be tested
       *
       * This currently is hard-coded to return a static Vector
       * of Datalets that are simply constructed here.
       * In the future we should add a way to read them in from disk.
       * 
       * @param files Vector of local path\filenames to be tested
       * This is currently ignored
       * @param testLocation File denoting directory where all 
       * .xml/.xsl tests are found
       * @param outLocation File denoting directory where all 
       * output files should be put
       * @param goldLocation File denoting directory where all 
       * gold files are found
       * @return Vector of StylesheetDatalets that are fully filled in,
       * i.e. outputName, goldName, etc are filled in respectively 
       * to inputName
       */
      public Vector buildDatalets(Vector files, File testLocation, 
                                  File outLocation, File goldLocation)
      {
          Vector v = new Vector();
          
  /***********************************************
  // Comment out validation using ExpectedObjects since they hang 28-Jun-01 -sc
          // A simple datalet for identity transform
          TransformStateDatalet d = new TransformStateDatalet();
          String testFileName = "identity";
          d.inputName = testLocation.getPath() + File.separator + testFileName 
+ ".xsl";
          d.xmlName = testLocation.getPath() + File.separator + testFileName + 
".xml";
          d.outputName = outLocation.getPath() + File.separator + testFileName 
+ ".out";
          d.goldName = goldLocation.getPath() + File.separator + testFileName + 
".out";
          // Validation TransformStates for RootTemplate
          ExpectedTransformState ets = new ExpectedTransformState();
          ets.setName("doc");
          ets.set("line", ExpectedObject.MUST_EQUAL, new Integer(6));
          ets.set("column", ExpectedObject.MUST_EQUAL, new Integer(8));
          ets.set("event", ExpectedObject.MUST_EQUAL, "startElement:");
          ets.set("current.match", ExpectedObject.MUST_EQUAL, "@*|node()");
          ets.set("matched.match", ExpectedObject.MUST_EQUAL, "@*|node()");
          // Add the expected object(s) to the datalet..
          d.expectedTransformStates.put(ets.getHashKey(), ets);
  
          ets = new ExpectedTransformState();
          ets.setName("copy");
          ets.set("line", ExpectedObject.MUST_EQUAL, new Integer(7));
          ets.set("column", ExpectedObject.MUST_EQUAL, new Integer(15));
          ets.set("event", ExpectedObject.MUST_EQUAL, "startElement:");
          ets.set("current.match", ExpectedObject.MUST_EQUAL, "@*|node()");
          // Add the expected object(s) to the datalet..
          d.expectedTransformStates.put(ets.getHashKey(), ets);
  
  // Comment out validation using ExpectedObjects since they hang 28-Jun-01 -sc
  ***********************************************/
          // Simple single file with call-template, modes
          TransformStateDatalet d = new TransformStateDatalet();
          String testFileName = "TransformState99a";
          d.inputName = testLocation.getPath() + File.separator + testFileName 
+ ".xsl";
          d.xmlName = testLocation.getPath() + File.separator + testFileName + 
".xml";
          d.outputName = outLocation.getPath() + File.separator + testFileName 
+ ".out";
          d.goldName = goldLocation.getPath() + File.separator + testFileName + 
".out";
          d.validate99.put("42.current.name", "apple");
          d.validate99.put("42.current.match", "pies-are-good");
          d.validate99.put("42.matched.name", "template-1-root");
          d.validate99.put("42.matched.match", "/");
  
          // .. and Add the datalet to the vector
          v.addElement(d);
  
          // Simple included file
          d = new TransformStateDatalet();
          testFileName = "TransformState99b"; // and TransformState99binc.xsl
          d.inputName = testLocation.getPath() + File.separator + testFileName 
+ ".xsl";
          d.xmlName = testLocation.getPath() + File.separator + testFileName + 
".xml";
          d.outputName = outLocation.getPath() + File.separator + testFileName 
+ ".out";
          d.goldName = goldLocation.getPath() + File.separator + testFileName + 
".out";
          // Note this should still be cross-checked for line numbers when 
using included files!
          d.validate99.put("27.current.name", "apple");
          d.validate99.put("27.current.match", "pies-are-good");
          d.validate99.put("27.matched.name", "template-1-root");
          d.validate99.put("27.matched.match", "/");
  
          // .. and Add the datalet to the vector
          v.addElement(d);
  
          // Simple imported file
          d = new TransformStateDatalet();
          testFileName = "TransformState99c"; // and TransformState99cimp.xsl
          d.inputName = testLocation.getPath() + File.separator + testFileName 
+ ".xsl";
          d.xmlName = testLocation.getPath() + File.separator + testFileName + 
".xml";
          d.outputName = outLocation.getPath() + File.separator + testFileName 
+ ".out";
          d.goldName = goldLocation.getPath() + File.separator + testFileName + 
".out";
          // Note this should still be cross-checked for line numbers when 
using included files!
          d.validate99.put("32.current.name", "apple");
          d.validate99.put("32.current.match", "pies-are-good");
          d.validate99.put("32.matched.name", "template-1-root");
          d.validate99.put("32.matched.match", "/");
  
          // .. and Add the datalet to the vector
          v.addElement(d);
  
          // All done: return full vector
          return v;
      }
  
  
      /**
       * Convenience method to get a Testlet to use.  
       * Hard-coded to return a TransformStateTestlet.
       * 
       * @return Testlet for use in this test; null if error
       */
      public TransformStateTestlet getTestlet()
      {
          try
          {
              // Create it and set our reporter into it
              TransformStateTestlet t = new TransformStateTestlet();
              t.setLogger((Logger)reporter);
              return t;
          }
          catch (Exception e)
          {
              // Ooops, problem, should get logged somehow
              return null;
          }
      }
  
  
      /**
       * Convenience method to print out usage information - update if needed.  
       * @return String denoting usage of this test class
       */
      public String usage()
      {
          return ("Common [optional] options supported by TransformStateTest:\n"
                  + "(Note: assumes inputDir=.\\tests\\api)\n"
                  + super.usage());   // Grab our parent classes usage as well
      }
  
  
      /**
       * Main method to run test from the command line - can be left alone.  
       * @param args command line argument array
       */
      public static void main(String[] args)
      {
          TransformStateTest app = new TransformStateTest();
          app.doMain(args);
      }
  }
  
  
  
  1.1                  
xml-xalan/test/java/src/org/apache/qetest/xalanj2/TransformStateTestlet.java
  
  Index: TransformStateTestlet.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/>.
   */
  
  /*
   *
   * TransformStateTestlet.java
   *
   */
  package org.apache.qetest.xalanj2;
  
  import org.apache.qetest.*;
  
  import javax.xml.transform.*;
  import javax.xml.transform.stream.*;
  import javax.xml.transform.sax.*;
  
  // Needed Xalan-J 2.x specific classes
  import org.apache.xalan.templates.ElemLiteralResult;
  import org.apache.xalan.templates.ElemTemplate;
  import org.apache.xalan.templates.ElemTemplateElement;
  import org.apache.xalan.transformer.TransformState;
  import org.apache.xalan.transformer.TransformerClient;
  import org.apache.xpath.XPath;
  import org.apache.xml.utils.QName;
  
  // Needed SAX, DOM, JAXP classes
  import org.w3c.dom.Node;
  import org.w3c.dom.traversal.NodeIterator;
  import org.xml.sax.Attributes;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.Locator;
  import org.xml.sax.SAXException;
  
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.PrintWriter;
  import java.io.StringWriter;
  import java.util.Hashtable;
  
  /**
   * Testlet for testing TransformState of a stylesheet.
   *
   * In progress - data-driven tests for tooling API's.
   * Currently uses cheap-o validation method
   *
   * @author [EMAIL PROTECTED]
   * @version $Id: TransformStateTestlet.java,v 1.1 2001/07/09 17:03:23 curcuru 
Exp $
   */
  public class TransformStateTestlet extends TestletImpl
          implements ContentHandler, TransformerClient
  
  {
      // Initialize our classname for TestletImpl's main() method
      static { thisClassName = "org.apache.qetest.xsl.TransformStateTestlet"; }
  
      // Initialize our defaultDatalet
      { defaultDatalet = (Datalet)new TransformStateDatalet(); }
  
      /** 
       * Class-wide copy of TransformStateDatalet.  
       * This is used in execute() and in various worker methods 
       * underneath the ContentHandler interface.
       */
      protected TransformStateDatalet tsDatalet = null;
  
      /**
       * Accesor method for a brief description of this test.  
       *
       * @return String describing what this TransformStateTestlet does.
       */
      public String getDescription()
      {
          return "TransformStateTestlet";
      }
  
  
      /**
       * Run this TransformStateTestlet: execute it's test and return.
       *
       * @param Datalet to use as data point for the test.
       */
      public void execute(Datalet d)
        {
          try
          {
              tsDatalet = (TransformStateDatalet)d;
          }
          catch (ClassCastException e)
          {
              logger.checkErr("Datalet provided is not a TransformStateDatalet; 
cannot continue with " + d);
              return;
          }
  
          logger.logMsg(Logger.STATUSMSG, "About to test: " 
                        + (null == tsDatalet.inputName
                           ? tsDatalet.xmlName
                           : tsDatalet.inputName));
          try
          {
              // Perform the transform
              TransformerFactory factory = TransformerFactory.newInstance();
              logger.logMsg(Logger.TRACEMSG, "---- About to newTransformer " + 
QetestUtils.filenameToURL(tsDatalet.inputName));
              Transformer transformer = factory.newTransformer(new 
StreamSource(QetestUtils.filenameToURL(tsDatalet.inputName)));
              logger.logMsg(Logger.TRACEMSG, "---- About to transform " + 
QetestUtils.filenameToURL(tsDatalet.xmlName) + " into: SAXResult(this-no disk 
output)");
  
              // Note most validation happens here: we get ContentHandler 
              //  callbacks from being in the SAXResult, and that's where 
              //  we do our validation
              transformer.transform(new 
StreamSource(QetestUtils.filenameToURL(tsDatalet.xmlName)),
                                    new SAXResult(this)); // use us to handle 
result
  
              logger.logMsg(Logger.INFOMSG, "---- Afterwards, 
this.transformState=" + transformState);
          }
          catch (Throwable t)
          {
              // Put the logThrowable first, so it appears before 
              //  the Fail record, and gets color-coded
              logger.logThrowable(Logger.ERRORMSG, t, getDescription() + " " + 
tsDatalet.getDescription());
              logger.checkFail(getDescription() + " " + 
tsDatalet.getDescription() 
                               + " threw: " + t.toString());
              return;
          }
        }
      ////////////////// partially Implement LoggingHandler ////////////////// 
      /** Cheap-o string representation of last event we got.  */
      protected String lastItem = LoggingHandler.NOTHING_HANDLED;
  
  
      /**
       * Accessor for string representation of last event we got.  
       * @param s string to set
       */
      protected void setLastItem(String s)
      {
          lastItem = s;
      }
  
  
      /**
       * Accessor for string representation of last event we got.  
       * @return last event string we had
       */
      public String getLast()
      {
          return lastItem;
      }
  
      /** 
       * Worker routine to validate a TransformState based on an event/value.  
       * Note: this may not be threadsafe!
       * //@todo actually add validation code - just logs out now
       * @param ts TransformState to validate, if null, just logs it
       * @param event our String constant of START_ELEMENT, etc.
       * @param value any String value of the current event 
       */
      protected void validateTransformState(TransformState ts, String event, 
String value)
      {
          if(null == transformState)
          {
              // We should never have a null TransformState since the 
              //  transformer should have always filled it in
              logger.checkErr("validateTransformState(ts-NULL!, " + event + 
")=" + value);
              return;
          }
          logTransformStateDump(logger, Logger.INFOMSG, ts, event, value);
  
          // Cheap-o validation: only validate items on column 99
          if (99 == ts.getCurrentElement().getColumnNumber())
          {
              int line = ts.getCurrentElement().getLineNumber();
              // Get cheap-o validation from the datalet for this line..
              String exp = (String)tsDatalet.validate99.get(line + 
".current.name");
              // .. If there's an expected value for this line's property..
              if (null != exp)
                  // .. Then check if it's equal and report pass/fail
                  checkString(ts.getCurrentTemplate().getName().toString(), 
exp, 
                              "Validate L" + line + "C99 .current.name");
  
              exp = (String)tsDatalet.validate99.get(line + ".current.match");
              if (null != exp)
                  
checkString(ts.getCurrentTemplate().getMatch().getPatternString(), exp, 
                              "Validate L" + line + "C99 .current.match");
  
              exp = (String)tsDatalet.validate99.get(line + ".current.mode");
              if (null != exp)
                  checkString(ts.getCurrentTemplate().getMode().toString(), 
exp, 
                              "Validate L" + line + "C99 .current.mode");
  
  
              exp = (String)tsDatalet.validate99.get(line + ".matched.name");
              if (null != exp)
                  checkString(ts.getMatchedTemplate().getName().toString(), 
exp, 
                              "Validate L" + line + "C99 .matched.name");
  
              exp = (String)tsDatalet.validate99.get(line + ".matched.match");
              if (null != exp)
                  
checkString(ts.getMatchedTemplate().getMatch().getPatternString(), exp, 
                              "Validate L" + line + "C99 .matched.match");
  
              exp = (String)tsDatalet.validate99.get(line + ".matched.mode");
              if (null != exp)
                  checkString(ts.getMatchedTemplate().getMode().toString(), 
exp, 
                              "Validate L" + line + "C99 .matched.mode");
          }
  
  /***********************************************
  // Comment out validation using ExpectedObjects since they hang 28-Jun-01 -sc
          // See if we have a matching expected state for this event
          //@todo use event string as part of hashkey!!!
          String marker = ExpectedTransformState.getHashKey(ts);
          // Add on the event as well; see ExpectedTransformState.getHashKey()
          //  for why we have to do this separately
          marker += ExpectedTransformState.SEP + event;
          ExpectedTransformState ets = 
(ExpectedTransformState)tsDatalet.expectedTransformStates.get(marker);
          logger.logMsg(Logger.TRACEMSG, "ETS-HACK:" + marker + "=" + ets);
          if (null != ets)
          {
              // Ask it to validate itself as needed
              synchronized(ets) // voodoo: attempt to solve hang problems
              {
                  ExpectedObjectCheckService.check(logger, ts, ets, "Compare 
ExpectedTransformState of " + marker);
              }
          }
  // Comment out validation using ExpectedObjects since they hang 28-Jun-01 -sc
  ***********************************************/
      }
  
      private void checkString(String act, String exp, String comment)
      {
          if (exp.equals(act))
              logger.checkPass(comment);
          else
              logger.checkFail(comment + "; act(" + act + ") exp(" + exp + ")");
      }
  
      ////////////////// Utility methods for TransformState ////////////////// 
      /**
       * Utility method to dump data from TransformState.  
       * @return String describing various bits of the state
       */
      protected void logTransformStateDump(Logger logger, int 
traceLoggingLevel, 
              TransformState ts, String event, String value)
      {
          String elemName = "transformStateDump";
          Hashtable attrs = new Hashtable();
          attrs.put("event", event);
          if (null != value)
              attrs.put("value", value);
          attrs.put("location", "L" + ts.getCurrentElement().getLineNumber()
                    + "C" + ts.getCurrentElement().getColumnNumber());
  
          StringBuffer buf = new StringBuffer();
          ElemTemplateElement elem = ts.getCurrentElement(); // may be actual 
or default template
          buf.append("  <currentElement>" 
                  + XMLFileLogger.escapeString(XalanDumper.dump(elem, 
XalanDumper.DUMP_DEFAULT)) + "</currentElement>");
  
          ElemTemplate currentTempl = ts.getCurrentTemplate(); // Actual 
current template
          buf.append("\n  <currentTemplate>" 
                  + XMLFileLogger.escapeString(XalanDumper.dump(currentTempl, 
XalanDumper.DUMP_DEFAULT)) + "</currentTemplate>");
  
          ElemTemplate matchTempl = ts.getMatchedTemplate(); // Actual matched 
template
          if (matchTempl != currentTempl)
              buf.append("\n  <matchedTemplate>" 
                  + XMLFileLogger.escapeString(XalanDumper.dump(matchTempl, 
XalanDumper.DUMP_DEFAULT)) + "</matchedTemplate>");
  
          // Optimization: skip most logging when on endElement
          if (!END_ELEMENT.equals(event))
          {
              Node n = ts.getCurrentNode();   // current context node in source 
tree
              buf.append("\n  <currentNode>" 
                      + XMLFileLogger.escapeString(XalanDumper.dump(n, 
XalanDumper.DUMP_DEFAULT)) + "</currentNode>");
  
              Node matchedNode = ts.getMatchedNode(); // node in source matched 
via getMatchedTemplate
              // Optimization: only output if different
              if (n != matchedNode)
                  buf.append("\n  <matchedNode>" 
                          + 
XMLFileLogger.escapeString(XalanDumper.dump(matchedNode, 
XalanDumper.DUMP_DEFAULT)) + "</matchedNode>");
  
              NodeIterator contextNodeList = ts.getContextNodeList(); // 
current context node list
              Node rootNode = contextNodeList.getRoot();
              // Optimization: only output if different
              if (n != rootNode)
                  buf.append("\n  <contextNodeListGetRoot>" 
                          + 
XMLFileLogger.escapeString(XalanDumper.dump(rootNode, 
XalanDumper.DUMP_DEFAULT)) + "</contextNodeListGetRoot>");
  
              Transformer transformer = ts.getTransformer(); // current 
transformer working
              // Optimization: only dump transformer at startElement to save 
space
              if (START_ELEMENT.equals(event))
              {
                  buf.append("\n  <transformer>" 
                          + 
XMLFileLogger.escapeString(XalanDumper.dump(transformer, 
XalanDumper.DUMP_DEFAULT)) + "</transformer>");
              }
              else
              {
                  // Just log error case if transformer is ever null
                  if (null == transformer)
                  buf.append("\n  <transformer>" 
                          + "ERROR! Transformer was null!" + "</transformer>");
              }
          }
  
          logger.logElement(traceLoggingLevel, elemName, attrs, buf.toString());
      }
  
      //-----------------------------------------------------------
      //---- Implement the TransformerClient interface
      //-----------------------------------------------------------
      /**
       * A TransformState object that we use to log state data.
       * This is the equivalent of the defaultHandler, even though 
       * that's not really the right metaphor.  This class could be 
       * upgraded to have both a default ContentHandler and a 
       * defaultTransformerClient in the future.
       */
      protected TransformState transformState = null;
  
  
      /**
       * Implement TransformerClient.setTransformState interface.  
       * Pass in a reference to a TransformState object, which
       * can be used during SAX ContentHandler events to obtain
       * information about he state of the transformation. This
       * method will be called before each startDocument event.
       *
       * @param ts A reference to a TransformState object
       */
      public void setTransformState(TransformState ts)
      {
          transformState = ts;
      }
  
      //-----------------------------------------------------------
      //---- Implement the ContentHandler interface
      //-----------------------------------------------------------
      protected final String START_ELEMENT = "startElement:";
      protected final String END_ELEMENT = "endElement:";
      protected final String CHARACTERS = "characters:";
  
      // String Locator.getPublicId() null if none available
      // String Locator.getPublicId() null if none available
      // int Locator.getLineNumber() -1 if none available
      // int Locator.getColumnNumber() -1 if none available
      protected Locator ourLocator = null;
      
      /** 
       * Implement ContentHandler.setDocumentLocator.  
       * If available, this should always be called prior to a 
       * startDocument event.
       */
      public void setDocumentLocator (Locator locator)
      {
          // Note: this implies this class is !not! threadsafe
          ourLocator = locator; // future use
          if (null != locator)
              setLastItem("setDocumentLocator.getSystemId():" + 
locator.getSystemId());
          else
              setLastItem("setDocumentLocator:NULL");
          logger.logMsg(Logger.INFOMSG, getLast());
      }
  
  
      /** Cached TransformState object during lifetime startDocument -> 
endDocument.  */
      // Note: is this correct? Will it always be the same object?
      protected TransformState docCachedTransformState = null;
      /** Implement ContentHandler.startDocument.  */
      public void startDocument ()
          throws SAXException
      {
          setLastItem("startDocument");
          logger.logMsg(Logger.INFOMSG, getLast());
          // Comment out check call since the spec'd functionality
          //  is very likely to change to *not* be in startDocument 19-Jun-01 
-sc 
          // logger.check((null != transformState), true, "transformState 
non-null in startDocument");
          logger.logMsg(Logger.STATUSMSG, "transformState in startDocument is: 
" + transformState);
          docCachedTransformState = transformState; // see endDocument
      }
  
  
      /** Implement ContentHandler.endDocument.  */
      public void endDocument()
          throws SAXException
      {
          setLastItem("endDocument");
          logger.logMsg(Logger.INFOMSG, getLast());
          // Comment out check call since the spec'd functionality
          //  is very likely to change to *not* be in startDocument 19-Jun-01 
-sc 
          // logger.checkObject(docCachedTransformState, transformState, 
          //               "transformState same in endDocument as 
startDocument"); // see startDocument
          logger.logMsg(Logger.STATUSMSG, "transformState in endDocument is: " 
+ transformState);
          docCachedTransformState = null;
      }
  
  
      /** Implement ContentHandler.startPrefixMapping.  */
      public void startPrefixMapping (String prefix, String uri)
          throws SAXException
      {
          setLastItem("startPrefixMapping: " + prefix + ", " + uri);
          logger.logMsg(Logger.INFOMSG, getLast());
      }
  
  
      /** Implement ContentHandler.endPrefixMapping.  */
      public void endPrefixMapping (String prefix)
          throws SAXException
      {
          setLastItem("endPrefixMapping: " + prefix);
          logger.logMsg(Logger.INFOMSG, getLast());
      }
  
  
      /** Implement ContentHandler.startElement.  */
      public void startElement (String namespaceURI, String localName,
                                String qName, Attributes atts)
          throws SAXException
      {
          StringBuffer buf = new StringBuffer();
          buf.append(namespaceURI + ", " 
                     + localName + ", " + qName + ";");
                     
          int n = atts.getLength();
          for(int i = 0; i < n; i++)
          {
              buf.append(", " + atts.getQName(i));
          }
          setLastItem(START_ELEMENT + buf.toString());
  
          validateTransformState(transformState, START_ELEMENT, buf.toString());
      }
  
  
      /** Implement ContentHandler.endElement.  */
      public void endElement (String namespaceURI, String localName, String 
qName)
          throws SAXException
      {
          setLastItem(END_ELEMENT + namespaceURI + ", " + localName + ", " + 
qName);
  
          validateTransformState(transformState, END_ELEMENT, null);
      }
  
  
      /** Implement ContentHandler.characters.  */
      public void characters (char ch[], int start, int length)
          throws SAXException
      {
          String s = new String(ch, start, length);
          setLastItem(CHARACTERS + "\"" + s + "\"");
  
          validateTransformState(transformState, CHARACTERS, s);
      }
  
  
      /** Implement ContentHandler.ignorableWhitespace.  */
      public void ignorableWhitespace (char ch[], int start, int length)
          throws SAXException
      {
          setLastItem("ignorableWhitespace: len " + length);
          logger.logMsg(Logger.INFOMSG, getLast());
      }
  
  
      /** Implement ContentHandler.processingInstruction.  */
      public void processingInstruction (String target, String data)
          throws SAXException
      {
          setLastItem("processingInstruction: " + target + ", " + data);
          logger.logMsg(Logger.INFOMSG, getLast());
      }
  
  
      /** Implement ContentHandler.skippedEntity.  */
      public void skippedEntity (String name)
          throws SAXException
      {
          setLastItem("skippedEntity: " + name);
          logger.logMsg(Logger.INFOMSG, getLast());
      }
  
  }  // end of class TransformStateTestlet
  
  
  
  

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

Reply via email to