blob: 4775ac2a87d84db448afe8d32d025b2b2ae219bb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id$
*/
package org.apache.qetest.xsl;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Constructor;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.qetest.Datalet;
import org.apache.qetest.FileBasedTest;
import org.apache.qetest.Logger;
import org.apache.qetest.QetestUtils;
import org.apache.qetest.Testlet;
import org.apache.qetest.xslwrapper.TransformWrapper;
import org.apache.qetest.xslwrapper.TransformWrapperFactory;
/**
* Test driver for XSLT stylesheet Testlets.
*
* This is a generic driver for XSLT-oriented Testlets, and
* supports iterating over either a user-supplied, specific list
* of files to test or over a directory tree of test files.
* Note there are a number of design decisions made that are
* just slightly specific to stylesheet testing, although this
* would be a good model for a completely generic TestletDriver.
*
* @author shane_curcuru@lotus.com
* @version $Id$
*/
public class StylesheetTestletDriver extends FileBasedTest
{
//-----------------------------------------------------
//-------- Constants for common input params --------
//-----------------------------------------------------
/**
* Parameter: Run a specific list of files, instead of
* iterating over directories.
* <p>Default: null, do normal iteration.</p>
*/
public static final String OPT_FILELIST = "fileList";
/** Name of fileList file to read in to get test definitions from. */
protected String fileList = null;
/**
* Parameter: FQCN or simple classname of Testlet to use.
* <p>User may pass in either a FQCN or just a base classname,
* and we will attempt to look it up in any of the most common
* Xalan-testing packages. See QetestUtils.testClassForName().</p>
* <p>Default: null, use StylesheetTestlet.</p>
*/
public static final String OPT_TESTLET = "testlet";
/** Classname of Testlet to use. */
protected String testlet = null;
/**
* Parameter: FQCN or simple classname of FilenameFilter for
* directories under testDir we will process.
* If fileList is not set, we simply go to our inputDir, and
* then use this filter to iterate through directories returned.
* <p>Default: null, use ConformanceDirRules.</p>
*/
public static final String OPT_DIRFILTER = "dirFilter";
/** Classname of FilenameFilter to use for dirs. */
protected String dirFilter = null;
/**
* Parameter: FQCN or simple classname of FilenameFilter for
* files within subdirs we will process.
* If fileList is not set, we simply go through all directories
* specified by directoryFilter, and then use this filter to
* find all stylesheet test files in that directory to test.
* Note that this does <b>not</b> handle embedded tests, where
* the XML document has an xml-stylesheet PI that defines the
* stylesheet to use to process it.
* <p>Default: null, use ConformanceFileRules.</p>
*/
public static final String OPT_FILEFILTER = "fileFilter";
/** Classname of FilenameFilter to use for files. */
protected String fileFilter = null;
/**
* Parameter: What flavor of TransformWrapper to use: trax.sax|trax.stream|other?
* <p>Default: trax.</p>
*/
public static final String OPT_FLAVOR = "flavor";
/** Parameter: What flavor of TransformWrapper to use: trax.sax|trax.stream|other? */
protected String flavor = "trax";
/**
* Parameter: Are there any embedded stylesheets in XML files?
* <p>Default: null (no embedded tests; otherwise specify
* semicolon delimited list of bare filenames something like
* 'axes02.xml;bool98.xml').</p>
*/
public static final String OPT_EMBEDDED = "embedded";
/** Parameter: Are there any embedded stylesheets in XML files? */
protected String embedded = null;
/**
* Parameter: Is there any preference to which gold file to use?
* <p>Default: null (use standard .out file)
* name of processor, could be XalanJ-I, XalanJ-C, or XalanC
* </p>
*/
public static final String OPT_PROCESSOR = "processor";
/** Parameter: What processor is being used? */
protected String processor = null;
/**
* Parameter: Is trace mode on?
* <p>Default: null (no trace)
* if on, non-null
* </p>
*/
public static final String OPT_TRACE = "trace";
/** Parameter: Are we tracing? */
protected String traceMode = null;
/**
* Parameter: Name of test (Conf, Accept) as StylesheetTestletDriver
* can be used for more than one bucket
* <p>Default: null (use StylesheetTestletDriver)
* </p>
*/
public static final String OPT_TESTNAME = "testName";
/** Unique runId for each specific invocation of this test driver. */
protected String runId = null;
/** Convenience constant: .xml extension for input data file. */
public static final String XML_EXTENSION = ".xml";
/** Convenience constant: .xsl extension for stylesheet file. */
public static final String XSL_EXTENSION = ".xsl";
/** Convenience constant: .out extension for output result file. */
public static final String OUT_EXTENSION = ".out";
/** Convenience constant: .log extension for log file. */
public static final String LOG_EXTENSION = ".log";
/** Just initialize test name, comment; numTestCases is not used. */
public StylesheetTestletDriver()
{
testName = "StylesheetTestletDriver";
testComment = "Test driver for XSLT stylesheet Testlets";
}
/**
* Initialize this test - fill in parameters.
* Simply fills in convenience variables from user parameters.
*
* @param p unused
* @return true
*/
public boolean doTestFileInit(Properties p)
{
// Copy any of our parameters from testProps to
// our local convenience variables
testlet = testProps.getProperty(OPT_TESTLET, testlet);
dirFilter = testProps.getProperty(OPT_DIRFILTER, dirFilter);
fileFilter = testProps.getProperty(OPT_FILEFILTER, fileFilter);
fileList = testProps.getProperty(OPT_FILELIST, fileList);
flavor = testProps.getProperty(OPT_FLAVOR, flavor);
embedded = testProps.getProperty(OPT_EMBEDDED, embedded);
processor = testProps.getProperty(OPT_PROCESSOR, processor);
testName = testProps.getProperty(OPT_TESTNAME, testName);
traceMode = testProps.getProperty(OPT_TRACE, traceMode);
// Grab a unique runid for logging out with our tests
// Used in results reporting stylesheets to differentiate
// between different test runs
runId = QetestUtils.createRunId(testProps.getProperty("runId"));
testProps.put("runId", runId); // put back in the properties
// for later use
return true;
}
/**
* Run through the directory given to us and run tests found
* in subdirs; or run through our fileList.
*
* This method logs some basic runtime data (like the actual
* testlet and ProcessorWrapper implementations used) and
* then decides to either run a user-specified fileList or to
* use our dirFilter to iterate over the inputDir.
*
* @param p Properties block of options to use - unused
* @return true if OK, false if we should abort
*/
public boolean runTestCases(Properties p)
{
// First log out any other runtime information, like the
// actual flavor of ProcessorWrapper, etc.
try
{
// Note that each of these calls actually force the
// creation of an actual object of each type: this is
// required since we may default the types or our call
// to QetestUtils.testClassForName() may return a
// different classname than the user actually specified
// Care should be taken that the construction of objects
// here does not affect our testing later on
// Just grab all the info from the TransformWrapper...
Properties runtimeProps = TransformWrapperFactory.newWrapper(flavor).getProcessorInfo();
// ... and add a few extra things ourselves
runtimeProps.put("actual.testlet", getTestlet());
runtimeProps.put("actual.dirFilter", getDirFilter());
runtimeProps.put("actual.fileFilter", getFileFilter());
reporter.logHashtable(Logger.CRITICALMSG, runtimeProps,
"actual.runtime information");
}
catch (Exception e)
{
reporter.logWarningMsg("Logging actual.runtime threw: " + e.toString());
reporter.logThrowable(Logger.WARNINGMSG, e, "Logging actual.runtime threw");
}
// Now either run a list of specific tests the user specified,
// or do the default of iterating over a set of directories
if (null != fileList)
{
// Process the specific list of tests the user supplied
String desc = "User-supplied fileList: " + fileList; // provide default value
// Use static worker class to process the list
Vector datalets = StylesheetDataletManager.readFileList(reporter, fileList, desc, testProps);
// Actually process the specified files in a testCase
processFileList(datalets, desc);
}
else
{
// Do the default, which is to iterate over the inputDir
// Note that this calls the testCaseInit/testCaseClose
// logging methods itself
processInputDir();
}
return true;
}
/**
* Do the default: test all stylesheets found in subdirs
* of our inputDir, using FilenameFilters for dirs and files.
* This only goes down one level in the tree, eg:
* <ul>inputDir = tests/conf
* <li>tests/conf - not tested</li>
* <li>tests/conf/boolean - test all boolean*.xsl files</li>
* <li>tests/conf/copy - test all copy*.xsl files</li>
* <li>tests/conf/copy/foo - not tested</li>
* <li>tests/conf/xmanual - not tested, since default
* ConformanceDirRules excludes dirs starting with 'x|X'</li>
* <li>tests/whitespace - test all whitespace*.xsl files</li>
* <li>etc.</li>
* </ul>
* Parameters: none, uses our internal members inputDir,
* outputDir, testlet, etc.
*/
public void processInputDir()
{
// Ensure the inputDir is there - we must have a valid location for input files
File testDirectory = new File(inputDir);
if (!testDirectory.exists())
{
// Try a default inputDir
String oldInputDir = inputDir; // cache for potential error message
testDirectory = new File((inputDir = getDefaultInputDir()));
if (!testDirectory.exists())
{
// No inputDir, can't do any tests!
// @todo check if this is the best way to express this
reporter.checkErr("inputDir(" + oldInputDir
+ ", or " + inputDir + ") does not exist, aborting!");
return;
}
}
reporter.logInfoMsg("inputDir(" + testDirectory.getPath()
+ ") looking for subdirs with: " + dirFilter);
// Use our filter to get a list of directories to process
String subdirs[] = testDirectory.list(getDirFilter());
// Validate that we have some valid directories to process
if ((null == subdirs) || (subdirs.length <= 0))
{
reporter.checkErr("inputDir(" + testDirectory.getPath()
+ ") no valid subdirs found!");
return;
}
int numSubdirs = subdirs.length;
// For every subdirectory, check if we should run tests in it
for (int i = 0; i < numSubdirs; i++)
{
File subTestDir = new File(testDirectory, subdirs[i]);
if ((null == subTestDir) || (!subTestDir.exists()))
{
// Just log it and continue; presumably we'll find
// other directories to test
reporter.logWarningMsg("subTestDir(" + subTestDir.getPath()
+ ") does not exist, skipping!");
continue;
}
// Construct matching directories for outputs and golds
File subOutDir = new File(outputDir, subdirs[i]);
File subGoldDir = new File(goldDir, subdirs[i]);
// Validate that each of the specified dirs exists
// Returns directory references like so:
// testDirectory = 0, outDirectory = 1, goldDirectory = 2
File[] dirs = validateDirs(new File[] { subTestDir },
new File[] { subOutDir, subGoldDir });
if (null == dirs) // also ensures that dirs[0] is non-null
{
// Just log it and continue; presumably we'll find
// other directories to test
reporter.logWarningMsg("subTestDir(" + subTestDir.getPath()
+ ") or associated dirs does not exist, skipping!");
continue;
}
// Call worker method to process the individual directory
// and get a list of .xsl files to test
Vector files = getFilesFromDir(subTestDir, getFileFilter(), embedded);
Hashtable goldFiles = getGoldsFromDir(subGoldDir, getGoldFileFilter(), processor);
// 'Transform' the list of individual test files into a
// list of Datalets with all fields filled in
//@todo should getFilesFromDir and buildDatalets be combined?
Vector datalets = buildDatalets(files, subTestDir, subOutDir, subGoldDir, goldFiles);
if ((null == datalets) || (0 == datalets.size()))
{
// Just log it and continue; presumably we'll find
// other directories to test
reporter.logWarningMsg("subTestDir(" + subTestDir.getPath()
+ ") did not contain any tests, skipping!");
continue;
}
// Now process the list of files found in this dir
processFileList(datalets, "Conformance test of: " + subdirs[i]);
} // end of for...
}
/**
* Run a list of stylesheet tests through a Testlet.
* The file names are assumed to be fully specified, and we assume
* the corresponding directories exist.
* Each fileList is turned into a testcase.
*
* @param vector of Datalet objects to pass in
* @param desc String to use as testCase description
*/
public void processFileList(Vector datalets, String desc)
{
// Validate arguments
if ((null == datalets) || (0 == datalets.size()))
{
// Bad arguments, report it as an error
// Note: normally, this should never happen, since
// this class normally validates these arguments
// before calling us
reporter.checkErr("Testlet or datalets are null/blank, nothing to test!");
return;
}
// Put everything else into a testCase
// This is not necessary, but feels a lot nicer to
// break up large test sets
reporter.testCaseInit(desc);
// Now just go through the list and process each set
int numDatalets = datalets.size();
reporter.logInfoMsg("processFileList() with " + numDatalets
+ " potential tests");
// Iterate over every datalet and test it
for (int ctr = 0; ctr < numDatalets; ctr++)
{
try
{
// 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((Datalet)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");
}
} // of while...
reporter.testCaseClose();
}
/**
* Use the supplied filter on given directory to return a list
* of stylesheet tests to be run.
* Uses the normal filter for variations of *.xsl files, and
* also constructs names for any -embedded tests found (which
* may be .xml with xml-stylesheet PI's, not just .xsl)
*
* @param dir directory to scan
* @param filter to use on this directory; if null, uses default
* @param embeddedFiles special list of embedded files to find
* @return Vector of local path\filenames of tests to run;
* the tests themselves will exist; null if error
*/
public Vector getFilesFromDir(File dir, FilenameFilter filter, String embeddedFiles)
{
// Validate arguments
if ((null == dir) || (!dir.exists()))
{
// Bad arguments, report it as an error
// Note: normally, this should never happen, since
// this class normally validates these arguments
// before calling us
reporter.logWarningMsg("getFilesFromDir(" + dir.toString() + ") dir null or does not exist");
return null;
}
// Get the list of 'normal' test files
String[] files = dir.list(filter);
Vector v = new Vector(files.length);
for (int i = 0; i < files.length; i++)
{
v.addElement(files[i]);
}
reporter.logTraceMsg("getFilesFromDir(" + dir.toString() + ") found " + v.size() + " xsl files to test");
// Also get a list of any embedded test files here
// Optimization: only look for embedded files when likely to find them
if ((null != embeddedFiles) && (embeddedFiles.indexOf(dir.getName()) > -1))
{
// OK, presumably we have an embedded file in the current dir,
// add that name
StringTokenizer st = new StringTokenizer(embeddedFiles, ";");//@todo resource ;
while (st.hasMoreTokens())
{
String embeddedName = st.nextToken();
// Check if it's in our dir...
if (embeddedName.startsWith(dir.getName()))
{
// ...and that it exists
if ((new File(dir.getPath() + File.separator + embeddedName)).exists())
{
v.addElement(embeddedName);
}
else
{
reporter.logWarningMsg("Requested embedded file " + dir.getPath() + File.separator + embeddedName
+ " does not exist, skipping");
}
}
}
}
reporter.logTraceMsg("getFilesFromDir(" + dir.toString() + ") found " + v.size() + " total files to test");
return v;
}
/**
* Use the supplied filter on given directory to return a list
* of stylesheet tests to be run.
* Uses the normal filter for variations of *.xsl files, and
* also constructs names for any -embedded tests found (which
* may be .xml with xml-stylesheet PI's, not just .xsl)
*
* @param dir directory to scan
* @param filter to use on this directory; if null, uses default
* @param embeddedFiles special list of embedded files to find
* @return Vector of local path\filenames of tests to run;
* the tests themselves will exist; null if error
*/
public Hashtable getGoldsFromDir(File dir, FilenameFilter filter, String processor)
{
// Validate arguments
if ((null == dir) || (!dir.exists()))
{
// Bad arguments, report it as an error
// Note: normally, this should never happen, since
// this class normally validates these arguments
// before calling us
reporter.logWarningMsg("getGoldsFromDir(" + dir.toString() + ") dir null or does not exist");
return null;
}
// Get the list of 'normal' test files
String[] files = dir.list(filter);
Hashtable h = new Hashtable();
for (int i = 0; i < files.length; i++)
{
// Check after the first .
// if "out", assume to be 'default' file
// if name of the processor, override default file.
StringTokenizer strTok = new StringTokenizer(files[i],".");
String testCase = strTok.nextToken();
String procChk = strTok.nextToken();
if (procChk.equals(processor) ||
(procChk.equals("out") && h.get(testCase) == null)) {
h.put(testCase,files[i]);
}
}
reporter.logTraceMsg("getGoldsFromDir(" + dir.toString() + ") found " + h.size() + " gold files to test");
return h;
}
/**
* Transform a vector of individual test names into a Vector
* of filled-in datalets to be tested
*
* This basically just calculates local path\filenames across
* the three presumably-parallel directory trees of testLocation
* (inputDir), outLocation (outputDir) and goldLocation
* (goldDir). It then stuffs each of these values plus some
* generic info like our testProps into each datalet it creates.
*
* @param files Vector of local path\filenames to be tested
* @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,
Hashtable goldFiles)
{
// Validate arguments
if ((null == files) || (files.size() < 1))
{
// Bad arguments, report it as an error
// Note: normally, this should never happen, since
// this class normally validates these arguments
// before calling us
reporter.logWarningMsg("buildDatalets null or empty file vector");
return null;
}
Vector v = new Vector(files.size());
// For every file in the vector, construct the matching
// out, gold, and xml/xsl files
for (Enumeration elements = files.elements();
elements.hasMoreElements(); /* no increment portion */ )
{
String file = null;
try
{
file = (String)elements.nextElement();
}
catch (ClassCastException cce)
{
// Just skip this entry
reporter.logWarningMsg("Bad file element found, skipping: " + cce.toString());
continue;
}
// Check if it's a normal .xsl file, or a .xml file
// (we assume .xml files are embedded tests!)
StylesheetDatalet d = new StylesheetDatalet();
if (file.endsWith(XML_EXTENSION))
{
d.xmlName = testLocation.getPath() + File.separator + file;
String fileNameRoot = file.substring(0, file.indexOf(XML_EXTENSION));
d.inputName = null;
d.outputName = outLocation.getPath() + File.separator + fileNameRoot + OUT_EXTENSION;
if (goldFiles != null && goldFiles.get(fileNameRoot) != null) {
d.goldName = goldLocation.getPath() + File.separator + goldFiles.get(fileNameRoot);
} else {
d.goldName = goldLocation.getPath() + File.separator + fileNameRoot + OUT_EXTENSION;
}
}
else if (file.endsWith(XSL_EXTENSION))
{
d.inputName = testLocation.getPath() + File.separator + file;
String fileNameRoot = file.substring(0, file.indexOf(XSL_EXTENSION));
d.xmlName = testLocation.getPath() + File.separator + fileNameRoot + XML_EXTENSION;
d.outputName = outLocation.getPath() + File.separator + fileNameRoot + OUT_EXTENSION;
d.goldName = goldLocation.getPath() + File.separator + fileNameRoot + OUT_EXTENSION;
if (goldFiles != null && goldFiles.get(fileNameRoot) != null) {
d.goldName = goldLocation.getPath() + File.separator + goldFiles.get(fileNameRoot);
} else {
d.goldName = goldLocation.getPath() + File.separator + fileNameRoot + OUT_EXTENSION;
}
}
else
{
// Hmmm - I'm not sure what we should do here
reporter.logWarningMsg("Unexpected test file found, skipping: " + file);
continue;
}
d.setDescription(file);
d.flavor = flavor;
// Also copy over our own testProps as it's
// options: this allows for future expansion
// of values in the datalet
d.options = new Properties(testProps);
// Optimization: put in a copy of our fileChecker, so
// that each testlet doesn't have to create it's own
// fileCheckers should not store state, so this
// shouldn't affect the testing at all
d.options.put("fileCheckerImpl", fileChecker);
if (traceMode != null) {
d.options.put(TransformWrapper.SET_PROCESSOR_ATTRIBUTES + "setTraceListener", d.outputName + LOG_EXTENSION);
}
v.addElement(d);
}
return v;
}
/**
* Validate existence of or create various directories needed.
* <p>If any optionalDir cannot be created, it's array entry
* will be null.</p>
*
* @param requiredDirs array of directories that must previously
* exist; if none do, will return null; if none passed, return null
* @param optionalDirs array of optional directories; if they do
* not exist they'll be created
* @return array of file objects, null if any error; all
* required dirs are first, in order; then all optionalDirs
*/
public File[] validateDirs(File[] requiredDirs, File[] optionalDirs)
{
if ((null == requiredDirs) || (0 == requiredDirs.length))
{
return null;
}
File[] dirs = new File[(requiredDirs.length + optionalDirs.length)];
int ctr = 0;
try
{
// Validate requiredDirs exist first
for (int ir = 0; ir < requiredDirs.length; ir++)
{
if (!requiredDirs[ir].exists())
{
reporter.logErrorMsg("validateDirs("
+ requiredDirs[ir]
+ ") requiredDir did not exist!");
return null;
}
dirs[ctr] = requiredDirs[ir];
ctr++;
}
// Create any optionalDirs needed
for (int iopt = 0; iopt < optionalDirs.length; iopt++)
{
if (!optionalDirs[iopt].exists())
{
if (!optionalDirs[iopt].mkdirs())
{
reporter.logWarningMsg("validateDirs("
+ optionalDirs[iopt]
+ ") optionalDir could not be created");
dirs[ctr] = null;
}
else
{
reporter.logTraceMsg("validateDirs("
+ optionalDirs[iopt]
+ ") optionalDir was created");
dirs[ctr] = optionalDirs[iopt];
}
}
else
{
// It does previously exist, so copy it over
dirs[ctr] = optionalDirs[iopt];
}
ctr++;
}
}
catch (Exception e)
{
reporter.logThrowable(Logger.ERRORMSG, e, "validateDirs threw: " + e.toString());
return null;
}
return dirs;
}
/** Default FilenameFilter FQCN for directories. */
protected String defaultDirFilter = "org.apache.qetest.xsl.ConformanceDirRules";
/** Default FilenameFilter FQCN for files. */
protected String defaultFileFilter = "org.apache.qetest.xsl.ConformanceFileRules";
/** Default GoldFilenameFilter FQCN for files. */
protected String defaultGoldFileFilter = "org.apache.qetest.xsl.GoldFileRules";
/** Default Testlet FQCN for executing stylesheet tests. */
protected String defaultTestlet = "org.apache.qetest.xsl.StylesheetTestlet";
/** Cached Testlet Class; used for life of this test. */
protected Class cachedTestletClazz = null;
/**
* Convenience method to get a Testlet to use.
* Attempts to return one as specified by our testlet parameter,
* otherwise returns a default StylesheetTestlet.
*
* @return Testlet for use in this test; null if error
*/
public Testlet getTestlet()
{
// Find a Testlet class to use if we haven't already
if (null == cachedTestletClazz)
{
cachedTestletClazz = QetestUtils.testClassForName(testlet,
QetestUtils.defaultPackages,
defaultTestlet);
}
try
{
// Create it and set our reporter into it
Testlet t = (Testlet)cachedTestletClazz.newInstance();
t.setLogger((Logger)reporter);
return (Testlet)t;
}
catch (Exception e)
{
// Ooops, none found! This should be very rare, since
// we know the defaultTestlet should be found
return null;
}
}
/**
* Convenience method to get a default filter for directories.
* Uses category member variable if set.
*
* @return FilenameFilter using ConformanceDirRules(category).
*/
public FilenameFilter getDirFilter()
{
// Find a FilenameFilter class to use
Class clazz = QetestUtils.testClassForName(dirFilter,
QetestUtils.defaultPackages,
defaultDirFilter);
try
{
// Create it, optionally with a category
String category = testProps.getProperty(OPT_CATEGORY);
if ((null != category) && (category.length() > 1)) // Arbitrary check for non-null, non-blank string
{
Class[] parameterTypes = { java.lang.String.class };
Constructor ctor = clazz.getConstructor(parameterTypes);
Object[] ctorArgs = { category };
return (FilenameFilter)ctor.newInstance(ctorArgs);
}
else
{
return (FilenameFilter)clazz.newInstance();
}
}
catch (Exception e)
{
// Ooops, none found!
return null;
}
}
/**
* Convenience method to get a default filter for files.
* Uses excludes member variable if set.
*
* @return FilenameFilter using ConformanceFileRules(excludes).
*/
public FilenameFilter getFileFilter()
{
// Find a FilenameFilter class to use
Class clazz = QetestUtils.testClassForName(fileFilter,
QetestUtils.defaultPackages,
defaultFileFilter);
try
{
// Create it, optionally with excludes
String excludes = testProps.getProperty(OPT_EXCLUDES);
if ((null != excludes) && (excludes.length() > 1)) // Arbitrary check for non-null, non-blank string
{
Class[] parameterTypes = { java.lang.String.class };
Constructor ctor = clazz.getConstructor(parameterTypes);
Object[] ctorArgs = { excludes };
return (FilenameFilter) ctor.newInstance(ctorArgs);
}
else
{
return (FilenameFilter)clazz.newInstance();
}
}
catch (Exception e)
{
// Ooops, none found!
return null;
}
}
/**
* Convenience method to get a default filter for files.
* Uses excludes member variable if set.
*
* @return FilenameFilter using ConformanceFileRules(excludes).
*/
public FilenameFilter getGoldFileFilter()
{
// Find a FilenameFilter class to use
Class clazz = QetestUtils.testClassForName(fileFilter,
QetestUtils.defaultPackages,
defaultGoldFileFilter);
try
{
// Create it, optionally with excludes
String excludes = testProps.getProperty(OPT_EXCLUDES);
if ((null != excludes) && (excludes.length() > 1)) // Arbitrary check for non-null, non-blank string
{
Class[] parameterTypes = { java.lang.String.class };
Constructor ctor = clazz.getConstructor(parameterTypes);
Object[] ctorArgs = { excludes };
return (FilenameFilter) ctor.newInstance(ctorArgs);
}
else
{
return (FilenameFilter)clazz.newInstance();
}
}
catch (Exception e)
{
// Ooops, none found!
return null;
}
}
/**
* Convenience method to get a default inputDir when none or
* a bad one was given.
* @return String pathname of default inputDir "tests\conf".
*/
public String getDefaultInputDir()
{
return "tests" + File.separator + "conf";
}
/**
* Convenience method to print out usage information - update if needed.
* @return String denoting usage of this test class
*/
public String usage()
{
return ("Additional options supported by StylesheetTestletDriver:\n"
+ " -" + OPT_FILELIST
+ " <name of listfile of tests to run>\n"
+ " -" + OPT_DIRFILTER
+ " <classname of FilenameFilter for dirs>\n"
+ " -" + OPT_FILEFILTER
+ " <classname of FilenameFilter for files>\n"
+ " -" + OPT_TESTLET
+ " <classname of Testlet to execute tests with>\n"
+ " -" + OPT_EMBEDDED
+ " <list;of;specific file.xml embedded tests to run>\n"
+ " -" + OPT_FLAVOR
+ " <trax.sax|trax.dom|etc> which TransformWrapper to use\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)
{
StylesheetTestletDriver app = new StylesheetTestletDriver();
app.doMain(args);
}
}