--- /dev/null 2014-09-08 10:45:56.830930409 -0700 +++ new/test/javax/xml/jaxp/libs/org/apache/qetest/xslwrapper/TransformWrapper.java 2015-01-09 15:42:27.974196995 -0800 @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + */ +/* + * 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. + */ +package org.apache.qetest.xslwrapper; + +import java.util.Properties; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; + +/** + * Helper interface to wrapper various XSLT processors for testing. + * + * A TransformWrapper wraps a particular 'flavor' of XSLT processing. This + * includes both a particular XSLT implementation, such as Xalan or Saxon, as + * well as a particular method to perform processing, like using streams or DOMs + * to perform transforms. + * + * As an important side effect, this class should return timing information + * about the steps done to perform the transformation. Note that exactly what is + * timed and how it's timed should be clearly documented in implementing + * classes! + * + * This is not a general-purpose wrapper for doing XSLT transformations: for + * that, you might as well use the real javax.xml.transform package itself. + * However this does allow many conformance and performance tests to run + * comparatively between different flavors of processors. + * + * TransformWrapper is a bit of an awkward name, but I wanted to keep it + * separate from the pre-existing ProcessorWrapper that this replaces so we can + * ensure stability for Xalan testing while updating to this new class. + * + */ +public interface TransformWrapper { + /** + * URL for set/getAttribute: should be an integer to set for the output + * indent of the processor. + * + * This is a common enough attribute that most wrapper implementations + * should be able to support it in a straightforward manner. + */ + public static final String ATTRIBUTE_INDENT + = "http://xml.apache.org/xalan/wrapper/indent"; + + /** + * URL for set/getAttribute: should be an Object to attempt to set as a + * diagnostic log/stream for the processor. + * + */ + public static final String ATTRIBUTE_DIAGNOSTICS + = "http://xml.apache.org/xalan/wrapper/diagnostics"; + + /** + * Marker for Attributes to set on Processors. + * + * Options that startWith() this constant will actually be attempted to be + * set onto our underlying processor/transformer. + */ + public static final String SET_PROCESSOR_ATTRIBUTES + = "Processor.setAttribute."; + + /** + * Get a specific description of the wrappered processor. + * + * @return specific description of the underlying processor or transformer + * implementation: this should include both the general product name, as + * well as specific version info. If possible, should be implemented without + * actively creating an underlying processor. + */ + public Properties getProcessorInfo(); + + /** + * Actually create/initialize an underlying processor or factory. + * + * For TrAX/javax.xml.transform implementations, this creates a new + * TransformerFactory. For Xalan-J 1.x this creates an XSLTProcessor. Other + * implementations may or may not actually do any work in this method. + * + * @param options Properties of options, possibly specific to that + * implementation. For future use. + * + * @return (Object)getProcessor() as a side-effect, this will be null if + * there was any problem creating the processor OR if the underlying + * implementation doesn't use this + * @throws javax.xml.transform.TransformerConfigurationException when + * actual implementation can't initiate a TransformerFactory. + */ + public TransformerFactory newProcessor(Properties options) throws TransformerConfigurationException; + + /** + * Transform supplied xmlName file with the stylesheet in the xslName file + * into a resultName file. + * + * Names are assumed to be local path\filename references, and will be + * converted to URLs as needed for any underlying processor implementation. + * + * @param xmlName local path\filename of XML file to transform + * @param xslName local path\filename of XSL stylesheet to use + * @param resultName local path\filename to put result in + * + * @throws Exception any underlying exceptions from the wrapped processor + * are simply allowed to propagate; throws a RuntimeException if any other + * problems prevent us from actually completing the operation + */ + public void transform(String xmlName, String xslName, String resultName) + throws Exception; + + /** + * Pre-build/pre-compile a stylesheet. + * + * Although the actual mechanics are implementation-dependent, most + * processors have some method of pre-setting up the data needed by the + * stylesheet itself for later use in transforms. In + * TrAX/javax.xml.transform, this equates to creating a Templates object. + * + * Sets isStylesheetReady() to true if it succeeds. Users can then call + * transformWithStylesheet(xmlName, resultName) to actually perform a + * transformation with this pre-built stylesheet. + * + * @param xslName local path\filename of XSL stylesheet to use + * + * @throws Exception any underlying exceptions from the wrapped processor + * are simply allowed to propagate; throws a RuntimeException if any other + * problems prevent us from actually completing the operation + * + * @see #transformWithStylesheet(String xmlName, String resultName) + */ + public void buildStylesheet(String xslName) throws Exception; + + /** + * Reports if a pre-built/pre-compiled stylesheet is ready; presumably built + * by calling buildStylesheet(xslName). + * + * @return true if one is ready; false otherwise + * + * @see #buildStylesheet(String xslName) + */ + public boolean isStylesheetReady(); + + /** + * Transform supplied xmlName file with a pre-built/pre-compiled stylesheet + * into a resultName file. + * + * User must have called buildStylesheet(xslName) beforehand, obviously. + * Names are assumed to be local path\filename references, and will be + * converted to URLs as needed. + * + * @param xmlName local path\filename of XML file to transform + * @param resultName local path\filename to put result in + * + * @throws Exception any underlying exceptions from the wrappered processor + * are simply allowed to propagate; throws a RuntimeException if any other + * problems prevent us from actually completing the operation; throws an + * IllegalStateException if isStylesheetReady() == false. + * + * @see #buildStylesheet(String xslName) + */ + public void transformWithStylesheet(String xmlName, String resultName) + throws Exception; + + /** + * Transform supplied xmlName file with a stylesheet found in an + * xml-stylesheet PI into a resultName file. + * + * Names are assumed to be local path\filename references, and will be + * converted to URLs as needed. Implementations will use whatever facilities + * exist in their wrapped processor to fetch and build the stylesheet to + * use for the transform. + * + * @param xmlName local path\filename of XML file to transform + * @param resultName local path\filename to put result in + * + * @throws Exception any underlying exceptions from the wrapped processor + * are simply allowed to propagate; throws a RuntimeException if any other + * problems prevent us from actually completing the operation + */ + public void transformEmbedded(String xmlName, String resultName) + throws Exception; + + /** + * Set a stylesheet parameter for use in later transforms. + * + * This method merely stores the triple for use later in a transform + * operation. Note that the actual mechanisims for setting parameters in + * implementation differ, especially with regards to namespaces. + * + * Note that the namespace may not contain the "{" or "}" characters, since + * these would be illegal XML namespaces anyways; an + * IllegalArgumentException will be thrown; also the name must not be null. + * + * @param namespace for the parameter, must not contain {} + * @param name of the parameter, must not be null + * @param value of the parameter + * + * @throws IllegalArgumentException thrown if the namespace or name appears + * to be illegal. + */ + public void setParameter(String namespace, String name, String value) + throws IllegalArgumentException; + + /** + * Get a parameter that was set with setParameter. + * + * Only returns parameters set locally, not parameters exposed by the + * underlying processor implementation. Not terribly useful but I like + * providing gets for any sets I define. + * + * @param namespace for the parameter, must not contain {} + * @param name of the parameter, must not be null + * + * @return value of the parameter; null if not found + */ + public Object getParameter(String namespace, String name); + + /** + * Reset our parameters and wrapper state, and optionally force creation of + * a new underlying processor implementation. + * + * This always clears our built stylesheet and any parameters that have been + * set. If newProcessor is true, also forces a re-creation of our underlying + * processor as if by calling newProcessor(). + * + * @param newProcessor if we should reset our underlying processor + * implementation as well + */ + public void reset(boolean newProcessor); +}