/*
 * 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: TransformerImpl.java 1581058 2014-03-24 20:55:14Z ggregory $
 */
package org.apache.xalan.transformer;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.xalan.extensions.ExtensionsTable;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xml.serializer.Method;
import org.apache.xml.serializer.Serializer;
import org.apache.xml.serializer.SerializerFactory;
import org.apache.xalan.templates.AVT;
import org.apache.xalan.templates.Constants;
import org.apache.xalan.templates.ElemAttributeSet;
import org.apache.xalan.templates.ElemForEach;
import org.apache.xalan.templates.ElemSort;
import org.apache.xalan.templates.ElemTemplate;
import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xalan.templates.ElemTextLiteral;
import org.apache.xalan.templates.ElemVariable;
import org.apache.xalan.templates.OutputProperties;
import org.apache.xalan.templates.Stylesheet;
import org.apache.xalan.templates.StylesheetComposed;
import org.apache.xalan.templates.StylesheetRoot;
import org.apache.xalan.templates.XUnresolvedVariable;
import org.apache.xalan.trace.GenerateEvent;
import org.apache.xalan.trace.TraceManager;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.dtm.DTMManager;
import org.apache.xml.dtm.DTMWSFilter;
import org.apache.xml.serializer.ToSAXHandler;
import org.apache.xml.serializer.ToTextStream;
import org.apache.xml.serializer.ToXMLSAXHandler;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.utils.BoolStack;
import org.apache.xml.utils.DOMBuilder;
import org.apache.xml.utils.NodeVector;
import org.apache.xml.utils.ObjectPool;
import org.apache.xml.utils.ObjectStack;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.SAXSourceLocator;
import org.apache.xml.utils.ThreadControllerWrapper;
import org.apache.xpath.Arg;
import org.apache.xpath.ExtensionsProvider;
import org.apache.xpath.VariableStack;
import org.apache.xpath.XPathContext;
import org.apache.xpath.functions.FuncExtFunction;
import org.apache.xpath.objects.XObject;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;

This class implements the Transformer interface, and is the core representation of the transformation execution.

@xsl.usageadvanced
/** * This class implements the * {@link javax.xml.transform.Transformer} interface, and is the core * representation of the transformation execution.</p> * @xsl.usage advanced */
public class TransformerImpl extends Transformer implements Runnable, DTMWSFilter, ExtensionsProvider, org.apache.xml.serializer.SerializerTrace { // Synch object to gaurd against setting values from the TrAX interface // or reentry while the transform is going on.
NEEDSDOC Field m_reentryGuard
/** NEEDSDOC Field m_reentryGuard */
private Boolean m_reentryGuard = new Boolean(true);
This is null unless we own the stream.
/** * This is null unless we own the stream. */
private java.io.FileOutputStream m_outputStream = null;
True if the parser events should be on the main thread, false if not. Experemental. Can not be set right now.
/** * True if the parser events should be on the main thread, * false if not. Experemental. Can not be set right now. */
private boolean m_parserEventsOnMain = true;
The thread that the transformer is running on.
/** The thread that the transformer is running on. */
private Thread m_transformThread;
The base URL of the source tree.
/** The base URL of the source tree. */
private String m_urlOfSource = null;
The Result object at the start of the transform, if any.
/** The Result object at the start of the transform, if any. */
private Result m_outputTarget = null;
The output format object set by the user. May be null.
/** * The output format object set by the user. May be null. */
private OutputProperties m_outputFormat;
The content handler for the source input tree.
/** * The content handler for the source input tree. */
ContentHandler m_inputContentHandler;
The content handler for the result tree.
/** * The content handler for the result tree. */
private ContentHandler m_outputContentHandler = null; // /* // * Use member variable to store param variables as they're // * being created, use member variable so we don't // * have to create a new vector every time. // */ // private Vector m_newVars = new Vector();
The JAXP Document Builder, mainly to create Result Tree Fragments.
/** The JAXP Document Builder, mainly to create Result Tree Fragments. */
DocumentBuilder m_docBuilder = null;
A pool of ResultTreeHandlers, for serialization of a subtree to text. Please note that each of these also holds onto a Text Serializer.
/** * A pool of ResultTreeHandlers, for serialization of a subtree to text. * Please note that each of these also holds onto a Text Serializer. */
private ObjectPool m_textResultHandlerObjectPool = new ObjectPool(ToTextStream.class);
Related to m_textResultHandlerObjectPool, this is a pool of StringWriters, which are passed to the Text Serializers. (I'm not sure if this is really needed any more. -sb)
/** * Related to m_textResultHandlerObjectPool, this is a pool of * StringWriters, which are passed to the Text Serializers. * (I'm not sure if this is really needed any more. -sb) */
private ObjectPool m_stringWriterObjectPool = new ObjectPool(StringWriter.class);
A static text format object, which can be used over and over to create the text serializers.
/** * A static text format object, which can be used over and * over to create the text serializers. */
private OutputProperties m_textformat = new OutputProperties(Method.TEXT); // Commenteded out in response to problem reported by // Nicola Brown <Nicola.Brown@jacobsrimell.com> // /** // * Flag to let us know if an exception should be reported inside the // * postExceptionFromThread method. This is needed if the transform is // * being generated from SAX events, and thus there is no central place // * to report the exception from. (An exception is usually picked up in // * the main thread from the transform thread in {@link #transform(Source source)} // * from {@link #getExceptionThrown()}. ) // */ // private boolean m_reportInPostExceptionFromThread = false;
A node vector used as a stack to track the current ElemTemplateElement. Needed for the org.apache.xalan.transformer.TransformState interface, so a tool can discover the calling template. Note the use of an array for this limits the recursion depth to 4K.
/** * A node vector used as a stack to track the current * ElemTemplateElement. Needed for the * org.apache.xalan.transformer.TransformState interface, * so a tool can discover the calling template. Note the use of an array * for this limits the recursion depth to 4K. */
ObjectStack m_currentTemplateElements = new ObjectStack(XPathContext.RECURSIONLIMIT); /** The top of the currentTemplateElements stack. */ //int m_currentTemplateElementsTop = 0;
A node vector used as a stack to track the current ElemTemplate that was matched. Needed for the org.apache.xalan.transformer.TransformState interface, so a tool can discover the matched template
/** * A node vector used as a stack to track the current * ElemTemplate that was matched. * Needed for the * org.apache.xalan.transformer.TransformState interface, * so a tool can discover the matched template */
Stack m_currentMatchTemplates = new Stack();
A node vector used as a stack to track the current node that was matched. Needed for the org.apache.xalan.transformer.TransformState interface, so a tool can discover the matched node.
/** * A node vector used as a stack to track the current * node that was matched. * Needed for the * org.apache.xalan.transformer.TransformState interface, * so a tool can discover the matched * node. */
NodeVector m_currentMatchedNodes = new NodeVector();
The root of a linked set of stylesheets.
/** * The root of a linked set of stylesheets. */
private StylesheetRoot m_stylesheetRoot = null;
If this is set to true, do not warn about pattern match conflicts.
/** * If this is set to true, do not warn about pattern * match conflicts. */
private boolean m_quietConflictWarnings = true;
The liason to the XML parser, so the XSL processor can handle included files, and the like, and do the initial parse of the XSL document.
/** * The liason to the XML parser, so the XSL processor * can handle included files, and the like, and do the * initial parse of the XSL document. */
private XPathContext m_xcontext;
Object to guard agains infinite recursion when doing queries.
/** * Object to guard agains infinite recursion when * doing queries. */
private StackGuard m_stackGuard;
Output handler to bottleneck SAX events.
/** * Output handler to bottleneck SAX events. */
private SerializationHandler m_serializationHandler;
The key manager, which manages xsl:keys.
/** The key manager, which manages xsl:keys. */
private KeyManager m_keyManager = new KeyManager();
Stack for the purposes of flagging infinite recursion with attribute sets.
/** * Stack for the purposes of flagging infinite recursion with * attribute sets. */
Stack m_attrSetStack = null;
The table of counters for xsl:number support.
See Also:
  • ElemNumber
/** * The table of counters for xsl:number support. * @see ElemNumber */
CountersTable m_countersTable = null;
Is > 0 when we're processing a for-each.
/** * Is > 0 when we're processing a for-each. */
BoolStack m_currentTemplateRuleIsNull = new BoolStack();
Keeps track of the result delivered by any EXSLT func:result instruction that has been executed for the currently active EXSLT func:function
/** * Keeps track of the result delivered by any EXSLT <code>func:result</code> * instruction that has been executed for the currently active EXSLT * <code>func:function</code> */
ObjectStack m_currentFuncResult = new ObjectStack();
The message manager, which manages error messages, warning messages, and other types of message events.
/** * The message manager, which manages error messages, warning * messages, and other types of message events. */
private MsgMgr m_msgMgr;
The flag for the setting of the optimize feature; This flag should have the same value as the FEATURE_OPTIMIZE feature which is set by the TransformerFactory.setAttribut() method before a Transformer is created
/** * The flag for the setting of the optimize feature; * This flag should have the same value as the FEATURE_OPTIMIZE feature * which is set by the TransformerFactory.setAttribut() method before a * Transformer is created */
private boolean m_optimizer = true;
The flag for the setting of the incremental feature; This flag should have the same value as the FEATURE_INCREMENTAL feature which is set by the TransformerFactory.setAttribut() method before a Transformer is created
/** * The flag for the setting of the incremental feature; * This flag should have the same value as the FEATURE_INCREMENTAL feature * which is set by the TransformerFactory.setAttribut() method before a * Transformer is created */
private boolean m_incremental = false;
The flag for the setting of the source_location feature; This flag should have the same value as the FEATURE_SOURCE_LOCATION feature which is set by the TransformerFactory.setAttribut() method before a Transformer is created
/** * The flag for the setting of the source_location feature; * This flag should have the same value as the FEATURE_SOURCE_LOCATION feature * which is set by the TransformerFactory.setAttribut() method before a * Transformer is created */
private boolean m_source_location = false;
This is a compile-time flag to turn off calling of trace listeners. Set this to false for optimization purposes.
/** * This is a compile-time flag to turn off calling * of trace listeners. Set this to false for optimization purposes. */
private boolean m_debug = false;
The SAX error handler, where errors and warnings are sent.
/** * The SAX error handler, where errors and warnings are sent. */
private ErrorListener m_errorHandler = new org.apache.xml.utils.DefaultErrorHandler(false);
The trace manager.
/** * The trace manager. */
private TraceManager m_traceManager = new TraceManager(this);
If the transform thread throws an exception, the exception needs to be stashed away so that the main thread can pass it on to the client.
/** * If the transform thread throws an exception, the exception needs to * be stashed away so that the main thread can pass it on to the * client. */
private Exception m_exceptionThrown = null;
The InputSource for the source tree, which is needed if the parse thread is not the main thread, in order for the parse thread's run method to get to the input source. (Delete this if reversing threads is outlawed. -sb)
/** * The InputSource for the source tree, which is needed if the * parse thread is not the main thread, in order for the parse * thread's run method to get to the input source. * (Delete this if reversing threads is outlawed. -sb) */
private Source m_xmlSource;
This is needed for support of setSourceTreeDocForThread(Node doc), which must be called in order for the transform thread's run method to obtain the root of the source tree to be transformed.
/** * This is needed for support of setSourceTreeDocForThread(Node doc), * which must be called in order for the transform thread's run * method to obtain the root of the source tree to be transformed. */
private int m_doc;
If the the transform is on the secondary thread, we need to know when it is done, so we can return.
/** * If the the transform is on the secondary thread, we * need to know when it is done, so we can return. */
private boolean m_isTransformDone = false;
Flag to to tell if the tranformer needs to be reset.
/** Flag to to tell if the tranformer needs to be reset. */
private boolean m_hasBeenReset = false;
NEEDSDOC Field m_shouldReset
/** NEEDSDOC Field m_shouldReset */
private boolean m_shouldReset = true;
NEEDSDOC Method setShouldReset NEEDSDOC @param shouldReset
/** * NEEDSDOC Method setShouldReset * * * NEEDSDOC @param shouldReset */
public void setShouldReset(boolean shouldReset) { m_shouldReset = shouldReset; }
A stack of current template modes.
/** * A stack of current template modes. */
private Stack m_modes = new Stack(); //========================================================== // SECTION: Constructor //==========================================================
Construct a TransformerImpl.
Params:
  • stylesheet – The root of the stylesheet tree.
/** * Construct a TransformerImpl. * * @param stylesheet The root of the stylesheet tree. */
public TransformerImpl(StylesheetRoot stylesheet) // throws javax.xml.transform.TransformerException { m_optimizer = stylesheet.getOptimizer(); m_incremental = stylesheet.getIncremental(); m_source_location = stylesheet.getSource_location(); setStylesheet(stylesheet); XPathContext xPath = new XPathContext(this); xPath.setIncremental(m_incremental); xPath.getDTMManager().setIncremental(m_incremental); xPath.setSource_location(m_source_location); xPath.getDTMManager().setSource_location(m_source_location); if (stylesheet.isSecureProcessing()) xPath.setSecureProcessing(true); setXPathContext(xPath); getXPathContext().setNamespaceContext(stylesheet); m_stackGuard = new StackGuard(this); } // ================ ExtensionsTable ===================
The table of ExtensionHandlers.
/** * The table of ExtensionHandlers. */
private ExtensionsTable m_extensionsTable = null;
Get the extensions table object.
Returns:The extensions table.
/** * Get the extensions table object. * * @return The extensions table. */
public ExtensionsTable getExtensionsTable() { return m_extensionsTable; }
If the stylesheet contains extensions, set the extensions table object.
Params:
  • sroot – The stylesheet.
Throws:
/** * If the stylesheet contains extensions, set the extensions table object. * * * @param sroot The stylesheet. * @throws javax.xml.transform.TransformerException */
void setExtensionsTable(StylesheetRoot sroot) throws javax.xml.transform.TransformerException { try { if (sroot.getExtensions() != null) //only load extensions if secureProcessing is disabled if(!sroot.isSecureProcessing()) m_extensionsTable = new ExtensionsTable(sroot); } catch (javax.xml.transform.TransformerException te) {te.printStackTrace();} } //== Implementation of the XPath ExtensionsProvider interface. public boolean functionAvailable(String ns, String funcName) throws javax.xml.transform.TransformerException { return getExtensionsTable().functionAvailable(ns, funcName); } public boolean elementAvailable(String ns, String elemName) throws javax.xml.transform.TransformerException { return getExtensionsTable().elementAvailable(ns, elemName); } public Object extFunction(String ns, String funcName, Vector argVec, Object methodKey) throws javax.xml.transform.TransformerException {//System.out.println("TransImpl.extFunction() " + ns + " " + funcName +" " + getExtensionsTable()); return getExtensionsTable().extFunction(ns, funcName, argVec, methodKey, getXPathContext().getExpressionContext()); } public Object extFunction(FuncExtFunction extFunction, Vector argVec) throws javax.xml.transform.TransformerException { return getExtensionsTable().extFunction(extFunction, argVec, getXPathContext().getExpressionContext()); } //=========================
Reset the state. This needs to be called after a process() call is invoked, if the processor is to be used again.
/** * Reset the state. This needs to be called after a process() call * is invoked, if the processor is to be used again. */
public void reset() { if (!m_hasBeenReset && m_shouldReset) { m_hasBeenReset = true; if (this.m_outputStream != null) { try { m_outputStream.close(); } catch (java.io.IOException ioe){} } m_outputStream = null; // I need to look more carefully at which of these really // needs to be reset. m_countersTable = null; m_xcontext.reset(); m_xcontext.getVarStack().reset(); resetUserParameters(); m_currentTemplateElements.removeAllElements(); m_currentMatchTemplates.removeAllElements(); m_currentMatchedNodes.removeAllElements(); m_serializationHandler = null; m_outputTarget = null; m_keyManager = new KeyManager(); m_attrSetStack = null; m_countersTable = null; m_currentTemplateRuleIsNull = new BoolStack(); m_xmlSource = null; m_doc = DTM.NULL; m_isTransformDone = false; m_transformThread = null; // m_inputContentHandler = null; // For now, reset the document cache each time. m_xcontext.getSourceTreeManager().reset(); } // m_reportInPostExceptionFromThread = false; }
getProperty returns the current setting of the property described by the property argument. %REVIEW% Obsolete now that source_location is handled in the TransformerFactory?
Params:
  • property – a String value
Returns:a boolean value
/** * <code>getProperty</code> returns the current setting of the * property described by the <code>property</code> argument. * * %REVIEW% Obsolete now that source_location is handled in the TransformerFactory? * * @param property a <code>String</code> value * @return a <code>boolean</code> value */
public boolean getProperty(String property) { return false; }
Set a runtime property for this TransformerImpl. %REVIEW% Obsolete now that source_location is handled in the TransformerFactory?
Params:
  • property – a String value
  • value – an Object value
/** * Set a runtime property for this <code>TransformerImpl</code>. * * %REVIEW% Obsolete now that source_location is handled in the TransformerFactory? * * @param property a <code>String</code> value * @param value an <code>Object</code> value */
public void setProperty(String property, Object value) { } // ========= Transformer Interface Implementation ==========
Get true if the parser events should be on the main thread, false if not. Experimental. Can not be set right now.
Returns:true if the parser events should be on the main thread, false if not.
@xsl.usageexperimental
/** * Get true if the parser events should be on the main thread, * false if not. Experimental. Can not be set right now. * * @return true if the parser events should be on the main thread, * false if not. * @xsl.usage experimental */
public boolean isParserEventsOnMain() { return m_parserEventsOnMain; }
Get the thread that the transform process is on.
Returns:The thread that the transform process is on, or null.
@xsl.usageinternal
/** * Get the thread that the transform process is on. * * @return The thread that the transform process is on, or null. * @xsl.usage internal */
public Thread getTransformThread() { return m_transformThread; }
Get the thread that the transform process is on.
Params:
  • t – The transform thread, may be null.
@xsl.usageinternal
/** * Get the thread that the transform process is on. * * @param t The transform thread, may be null. * @xsl.usage internal */
public void setTransformThread(Thread t) { m_transformThread = t; }
NEEDSDOC Field m_hasTransformThreadErrorCatcher
/** NEEDSDOC Field m_hasTransformThreadErrorCatcher */
private boolean m_hasTransformThreadErrorCatcher = false;
Return true if the transform was initiated from the transform method, otherwise it was probably done from a pure parse events. NEEDSDOC ($objectName$) @return
/** * Return true if the transform was initiated from the transform method, * otherwise it was probably done from a pure parse events. * * NEEDSDOC ($objectName$) @return */
public boolean hasTransformThreadErrorCatcher() { return m_hasTransformThreadErrorCatcher; }
Process the source tree to SAX parse events.
Params:
  • source – The input for the source tree.
Throws:
/** * Process the source tree to SAX parse events. * @param source The input for the source tree. * * @throws TransformerException */
public void transform(Source source) throws TransformerException { transform(source, true); }
Process the source tree to SAX parse events.
Params:
  • source – The input for the source tree.
  • shouldRelease – Flag indicating whether to release DTMManager.
Throws:
/** * Process the source tree to SAX parse events. * @param source The input for the source tree. * @param shouldRelease Flag indicating whether to release DTMManager. * * @throws TransformerException */
public void transform(Source source, boolean shouldRelease) throws TransformerException { try { // Patch for bugzilla #13863. If we don't reset the namespaceContext // then we will get a NullPointerException if transformer is reused // (for stylesheets that use xsl:key). Not sure if this should go // here or in reset(). -is if(getXPathContext().getNamespaceContext() == null){ getXPathContext().setNamespaceContext(getStylesheet()); } String base = source.getSystemId(); // If no systemID of the source, use the base of the stylesheet. if(null == base) { base = m_stylesheetRoot.getBaseIdentifier(); } // As a last resort, use the current user dir. if(null == base) { String currentDir = ""; try { currentDir = System.getProperty("user.dir"); } catch (SecurityException se) {}// user.dir not accessible from applet if (currentDir.startsWith(java.io.File.separator)) base = "file://" + currentDir; else base = "file:///" + currentDir; base = base + java.io.File.separatorChar + source.getClass().getName(); } setBaseURLOfSource(base); DTMManager mgr = m_xcontext.getDTMManager(); /* * According to JAXP1.2, new SAXSource()/StreamSource() * should create an empty input tree, with a default root node. * new DOMSource()creates an empty document using DocumentBuilder. * newDocument(); Use DocumentBuilder.newDocument() for all 3 situations, * since there is no clear spec. how to create an empty tree when * both SAXSource() and StreamSource() are used. */ if ((source instanceof StreamSource && source.getSystemId()==null && ((StreamSource)source).getInputStream()==null && ((StreamSource)source).getReader()==null)|| (source instanceof SAXSource && ((SAXSource)source).getInputSource()==null && ((SAXSource)source).getXMLReader()==null )|| (source instanceof DOMSource && ((DOMSource)source).getNode()==null)){ try { DocumentBuilderFactory builderF = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderF.newDocumentBuilder(); String systemID = source.getSystemId(); source = new DOMSource(builder.newDocument()); // Copy system ID from original, empty Source to new Source if (systemID != null) { source.setSystemId(systemID); } } catch (ParserConfigurationException e) { fatalError(e); } } DTM dtm = mgr.getDTM(source, false, this, true, true); dtm.setDocumentBaseURI(base); boolean hardDelete = true; // %REVIEW% I have to think about this. -sb try { // NOTE: This will work because this is _NOT_ a shared DTM, and thus has // only a single Document node. If it could ever be an RTF or other // shared DTM, look at dtm.getDocumentRoot(nodeHandle). this.transformNode(dtm.getDocument()); } finally { if (shouldRelease) mgr.release(dtm, hardDelete); } // Kick off the parse. When the ContentHandler gets // the startDocument event, it will call transformNode( node ). // reader.parse( xmlSource ); // This has to be done to catch exceptions thrown from // the transform thread spawned by the STree handler. Exception e = getExceptionThrown(); if (null != e) { if (e instanceof javax.xml.transform.TransformerException) { throw (javax.xml.transform.TransformerException) e; } else if (e instanceof org.apache.xml.utils.WrappedRuntimeException) { fatalError( ((org.apache.xml.utils.WrappedRuntimeException) e).getException()); } else { throw new javax.xml.transform.TransformerException(e); } } else if (null != m_serializationHandler) { m_serializationHandler.endDocument(); } } catch (org.apache.xml.utils.WrappedRuntimeException wre) { Throwable throwable = wre.getException(); while (throwable instanceof org.apache.xml.utils.WrappedRuntimeException) { throwable = ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException(); } fatalError(throwable); } // Patch attributed to David Eisenberg <david@catcode.com> catch (org.xml.sax.SAXParseException spe) { fatalError(spe); } catch (org.xml.sax.SAXException se) { m_errorHandler.fatalError(new TransformerException(se)); } finally { m_hasTransformThreadErrorCatcher = false; // This looks to be redundent to the one done in TransformNode. reset(); } } private void fatalError(Throwable throwable) throws TransformerException { if (throwable instanceof org.xml.sax.SAXParseException) m_errorHandler.fatalError(new TransformerException(throwable.getMessage(),new SAXSourceLocator((org.xml.sax.SAXParseException)throwable))); else m_errorHandler.fatalError(new TransformerException(throwable)); }
Get the base URL of the source.
Returns:The base URL of the source tree, or null.
/** * Get the base URL of the source. * * @return The base URL of the source tree, or null. */
public String getBaseURLOfSource() { return m_urlOfSource; }
Get the base URL of the source. NEEDSDOC @param base
Returns:The base URL of the source tree, or null.
/** * Get the base URL of the source. * * * NEEDSDOC @param base * @return The base URL of the source tree, or null. */
public void setBaseURLOfSource(String base) { m_urlOfSource = base; }
Get the original output target.
Returns:The Result object used to kick of the transform or null.
/** * Get the original output target. * * @return The Result object used to kick of the transform or null. */
public Result getOutputTarget() { return m_outputTarget; }
Set the original output target. This is useful when using a SAX transform and supplying a ContentHandler or when the URI of the output target should not be the same as the systemID of the original output target. NEEDSDOC @param outputTarget
/** * Set the original output target. This is useful when using a SAX transform and * supplying a ContentHandler or when the URI of the output target should * not be the same as the systemID of the original output target. * * * NEEDSDOC @param outputTarget */
public void setOutputTarget(Result outputTarget) { m_outputTarget = outputTarget; }
Get an output property that is in effect for the transformation. The property specified may be a property that was set with setOutputProperty, or it may be a property specified in the stylesheet. NEEDSDOC @param qnameString
Throws:
See Also:
Returns:The string value of the output property, or null if no property was found.
/** * Get an output property that is in effect for the * transformation. The property specified may be a property * that was set with setOutputProperty, or it may be a * property specified in the stylesheet. * * NEEDSDOC @param qnameString * * @return The string value of the output property, or null * if no property was found. * * @throws IllegalArgumentException If the property is not supported. * * @see javax.xml.transform.OutputKeys */
public String getOutputProperty(String qnameString) throws IllegalArgumentException { String value = null; OutputProperties props = getOutputFormat(); value = props.getProperty(qnameString); if (null == value) { if (!OutputProperties.isLegalPropertyKey(qnameString)) throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{qnameString})); //"output property not recognized: " //+ qnameString); } return value; }
Get the value of a property, without using the default properties. This can be used to test if a property has been explicitly set by the stylesheet or user. NEEDSDOC @param qnameString
Throws:
Returns:The value of the property, or null if not found.
/** * Get the value of a property, without using the default properties. This * can be used to test if a property has been explicitly set by the stylesheet * or user. * * NEEDSDOC @param qnameString * * @return The value of the property, or null if not found. * * @throws IllegalArgumentException If the property is not supported, * and is not namespaced. */
public String getOutputPropertyNoDefault(String qnameString) throws IllegalArgumentException { String value = null; OutputProperties props = getOutputFormat(); value = (String) props.getProperties().get(qnameString); if (null == value) { if (!OutputProperties.isLegalPropertyKey(qnameString)) throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{qnameString})); //"output property not recognized: " // + qnameString); } return value; }
This method is used to set or override the value of the effective xsl:output attribute values specified in the stylesheet.

The recognized standard output properties are:

  • cdata-section-elements
  • doctype-system
  • doctype-public
  • indent
  • media-type
  • method
  • omit-xml-declaration
  • standalone
  • version

For example:

  tran.setOutputProperty("standalone", "yes");

In the case of the cdata-section-elements property, the value should be a whitespace separated list of element names. The element name is the local name of the element, if it is in no namespace, or, the URI in braces followed immediately by the local name if the element is in that namespace. For example:

tran.setOutputProperty(
  "cdata-section-elements", 
  "elem1 {http://example.uri}elem2 elem3");

The recognized Xalan extension elements are:

  • content-handler
  • entities
  • indent-amount
  • line-separator
  • omit-meta-tag
  • use-url-escaping

These must be in the extension namespace of "http://xml.apache.org/xalan". This is accomplished by putting the namespace URI in braces before the property name, for example:

  tran.setOutputProperty(
    "{http://xml.apache.org/xalan}line-separator" ,
    "\n");
Params:
  • name – The property name.
  • value – The requested value for the property.
Throws:
/** * This method is used to set or override the value * of the effective xsl:output attribute values * specified in the stylesheet. * <p> * The recognized standard output properties are: * <ul> * <li>cdata-section-elements * <li>doctype-system * <li>doctype-public * <li>indent * <li>media-type * <li>method * <li>omit-xml-declaration * <li>standalone * <li>version * </ul> * <p> * For example: * <pre> * tran.setOutputProperty("standalone", "yes"); * </pre> * <p> * In the case of the cdata-section-elements property, * the value should be a whitespace separated list of * element names. The element name is the local name * of the element, if it is in no namespace, or, the URI * in braces followed immediately by the local name * if the element is in that namespace. For example: * <pre> * tran.setOutputProperty( * "cdata-section-elements", * "elem1 {http://example.uri}elem2 elem3"); * </pre> * <p> * The recognized Xalan extension elements are: * <ul> * <li>content-handler * <li>entities * <li>indent-amount * <li>line-separator * <li>omit-meta-tag * <li>use-url-escaping * </ul> * <p> * These must be in the extension namespace of * "http://xml.apache.org/xalan". This is accomplished * by putting the namespace URI in braces before the * property name, for example: * <pre> * tran.setOutputProperty( * "{http://xml.apache.org/xalan}line-separator" , * "\n"); * </pre> * * @param name The property name. * @param value The requested value for the property. * @throws IllegalArgumentException if the property name is not legal. */
public void setOutputProperty(String name, String value) throws IllegalArgumentException { synchronized (m_reentryGuard) { // Get the output format that was set by the user, otherwise get the // output format from the stylesheet. if (null == m_outputFormat) { m_outputFormat = (OutputProperties) getStylesheet().getOutputComposed().clone(); } if (!OutputProperties.isLegalPropertyKey(name)) throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{name})); //"output property not recognized: " //+ name); m_outputFormat.setProperty(name, value); } }
Set the output properties for the transformation. These properties will override properties set in the templates with xsl:output.

If argument to this function is null, any properties previously set will be removed.

Params:
  • oformat – A set of output properties that will be used to override any of the same properties in effect for the transformation.
Throws:
See Also:
/** * Set the output properties for the transformation. These * properties will override properties set in the templates * with xsl:output. * * <p>If argument to this function is null, any properties * previously set will be removed.</p> * * @param oformat A set of output properties that will be * used to override any of the same properties in effect * for the transformation. * * @see javax.xml.transform.OutputKeys * @see java.util.Properties * * @throws IllegalArgumentException if any of the argument keys are not * recognized and are not namespace qualified. */
public void setOutputProperties(Properties oformat) throws IllegalArgumentException { synchronized (m_reentryGuard) { if (null != oformat) { // See if an *explicit* method was set. String method = (String) oformat.get(OutputKeys.METHOD); if (null != method) m_outputFormat = new OutputProperties(method); else if(m_outputFormat==null) m_outputFormat = new OutputProperties(); m_outputFormat.copyFrom(oformat); // copyFrom does not set properties that have been already set, so // this must be called after, which is a bit in the reverse from // what one might think. m_outputFormat.copyFrom(m_stylesheetRoot.getOutputProperties()); } else { // if oformat is null JAXP says that any props previously set are removed // and we are to revert back to those in the templates object (i.e. Stylesheet). m_outputFormat = null; } } }
Get a copy of the output properties for the transformation. These properties will override properties set in the templates with xsl:output.

Note that mutation of the Properties object returned will not effect the properties that the transformation contains.

Returns: A copy of the set of output properties in effect for the next transformation. NEEDSDOC ($objectName$) @return
/** * Get a copy of the output properties for the transformation. These * properties will override properties set in the templates * with xsl:output. * * <p>Note that mutation of the Properties object returned will not * effect the properties that the transformation contains.</p> * * @return A copy of the set of output properties in effect * for the next transformation. * * NEEDSDOC ($objectName$) @return */
public Properties getOutputProperties() { return (Properties) getOutputFormat().getProperties().clone(); }
Create a result ContentHandler from a Result object, based on the current OutputProperties.
Params:
  • outputTarget – Where the transform result should go, should not be null.
Throws:
Returns:A valid ContentHandler that will create the result tree when it is fed SAX events.
/** * Create a result ContentHandler from a Result object, based * on the current OutputProperties. * * @param outputTarget Where the transform result should go, * should not be null. * * @return A valid ContentHandler that will create the * result tree when it is fed SAX events. * * @throws TransformerException */
public SerializationHandler createSerializationHandler(Result outputTarget) throws TransformerException { SerializationHandler xoh = createSerializationHandler(outputTarget, getOutputFormat()); return xoh; }
Create a ContentHandler from a Result object and an OutputProperties.
Params:
  • outputTarget – Where the transform result should go, should not be null.
  • format – The OutputProperties object that will contain instructions on how to serialize the output.
Throws:
Returns:A valid ContentHandler that will create the result tree when it is fed SAX events.
/** * Create a ContentHandler from a Result object and an OutputProperties. * * @param outputTarget Where the transform result should go, * should not be null. * @param format The OutputProperties object that will contain * instructions on how to serialize the output. * * @return A valid ContentHandler that will create the * result tree when it is fed SAX events. * * @throws TransformerException */
public SerializationHandler createSerializationHandler( Result outputTarget, OutputProperties format) throws TransformerException { SerializationHandler xoh; // If the Result object contains a Node, then create // a ContentHandler that will add nodes to the input node. org.w3c.dom.Node outputNode = null; if (outputTarget instanceof DOMResult) { outputNode = ((DOMResult) outputTarget).getNode(); org.w3c.dom.Node nextSibling = ((DOMResult)outputTarget).getNextSibling(); org.w3c.dom.Document doc; short type; if (null != outputNode) { type = outputNode.getNodeType(); doc = (org.w3c.dom.Node.DOCUMENT_NODE == type) ? (org.w3c.dom.Document) outputNode : outputNode.getOwnerDocument(); } else { boolean isSecureProcessing = m_stylesheetRoot.isSecureProcessing(); doc = org.apache.xml.utils.DOMHelper.createDocument(isSecureProcessing); outputNode = doc; type = outputNode.getNodeType(); ((DOMResult) outputTarget).setNode(outputNode); } DOMBuilder handler = (org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE == type) ? new DOMBuilder(doc, (org.w3c.dom.DocumentFragment) outputNode) : new DOMBuilder(doc, outputNode); if (nextSibling != null) handler.setNextSibling(nextSibling); String encoding = format.getProperty(OutputKeys.ENCODING); xoh = new ToXMLSAXHandler(handler, (LexicalHandler)handler, encoding); } else if (outputTarget instanceof SAXResult) { ContentHandler handler = ((SAXResult) outputTarget).getHandler(); if (null == handler) throw new IllegalArgumentException( "handler can not be null for a SAXResult"); LexicalHandler lexHandler; if (handler instanceof LexicalHandler) lexHandler = (LexicalHandler) handler; else lexHandler = null; String encoding = format.getProperty(OutputKeys.ENCODING); String method = format.getProperty(OutputKeys.METHOD); ToXMLSAXHandler toXMLSAXHandler = new ToXMLSAXHandler(handler, lexHandler, encoding); toXMLSAXHandler.setShouldOutputNSAttr(false); xoh = toXMLSAXHandler; String publicID = format.getProperty(OutputKeys.DOCTYPE_PUBLIC); String systemID = format.getProperty(OutputKeys.DOCTYPE_SYSTEM); if (systemID != null) xoh.setDoctypeSystem(systemID); if (publicID != null) xoh.setDoctypePublic(publicID); if (handler instanceof TransformerClient) { XalanTransformState state = new XalanTransformState(); ((TransformerClient)handler).setTransformState(state); ((ToSAXHandler)xoh).setTransformState(state); } } // Otherwise, create a ContentHandler that will serialize the // result tree to either a stream or a writer. else if (outputTarget instanceof StreamResult) { StreamResult sresult = (StreamResult) outputTarget; try { SerializationHandler serializer = (SerializationHandler) SerializerFactory.getSerializer(format.getProperties()); if (null != sresult.getWriter()) serializer.setWriter(sresult.getWriter()); else if (null != sresult.getOutputStream()) serializer.setOutputStream(sresult.getOutputStream()); else if (null != sresult.getSystemId()) { String fileURL = sresult.getSystemId(); if (fileURL.startsWith("file:///")) { if (fileURL.substring(8).indexOf(":") >0) fileURL = fileURL.substring(8); else fileURL = fileURL.substring(7); } else if (fileURL.startsWith("file:/")) { if (fileURL.substring(6).indexOf(":") >0) fileURL = fileURL.substring(6); else fileURL = fileURL.substring(5); } m_outputStream = new java.io.FileOutputStream(fileURL); serializer.setOutputStream(m_outputStream); xoh = serializer; } else throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_OUTPUT_SPECIFIED, null)); //"No output specified!"); // handler = serializer.asContentHandler(); // this.setSerializer(serializer); xoh = serializer; } // catch (UnsupportedEncodingException uee) // { // throw new TransformerException(uee); // } catch (IOException ioe) { throw new TransformerException(ioe); } } else { throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_TRANSFORM_TO_RESULT_TYPE, new Object[]{outputTarget.getClass().getName()})); //"Can't transform to a Result of type " //+ outputTarget.getClass().getName() //+ "!"); } // before we forget, lets make the created handler hold a reference // to the current TransformImpl object xoh.setTransformer(this); SourceLocator srcLocator = getStylesheet(); xoh.setSourceLocator(srcLocator); return xoh; }
Process the source tree to the output result.
Params:
  • xmlSource – The input for the source tree.
  • outputTarget – The output source target.
Throws:
/** * Process the source tree to the output result. * @param xmlSource The input for the source tree. * @param outputTarget The output source target. * * @throws TransformerException */
public void transform(Source xmlSource, Result outputTarget) throws TransformerException { transform(xmlSource, outputTarget, true); }
Process the source tree to the output result.
Params:
  • xmlSource – The input for the source tree.
  • outputTarget – The output source target.
  • shouldRelease – Flag indicating whether to release DTMManager.
Throws:
/** * Process the source tree to the output result. * @param xmlSource The input for the source tree. * @param outputTarget The output source target. * @param shouldRelease Flag indicating whether to release DTMManager. * * @throws TransformerException */
public void transform(Source xmlSource, Result outputTarget, boolean shouldRelease) throws TransformerException { synchronized (m_reentryGuard) { SerializationHandler xoh = createSerializationHandler(outputTarget); this.setSerializationHandler(xoh); m_outputTarget = outputTarget; transform(xmlSource, shouldRelease); } }
Process the source node to the output result, if the processor supports the "http://xml.org/trax/features/dom/input" feature. %REVIEW% Do we need a Node version of this?
Params:
  • node – The input source node, which can be any valid DTM node.
  • outputTarget – The output source target.
Throws:
/** * Process the source node to the output result, if the * processor supports the "http://xml.org/trax/features/dom/input" * feature. * %REVIEW% Do we need a Node version of this? * @param node The input source node, which can be any valid DTM node. * @param outputTarget The output source target. * * @throws TransformerException */
public void transformNode(int node, Result outputTarget) throws TransformerException { SerializationHandler xoh = createSerializationHandler(outputTarget); this.setSerializationHandler(xoh); m_outputTarget = outputTarget; transformNode(node); }
Process the source node to the output result, if the processor supports the "http://xml.org/trax/features/dom/input" feature. %REVIEW% Do we need a Node version of this?
Params:
  • node – The input source node, which can be any valid DTM node.
Throws:
/** * Process the source node to the output result, if the * processor supports the "http://xml.org/trax/features/dom/input" * feature. * %REVIEW% Do we need a Node version of this? * @param node The input source node, which can be any valid DTM node. * * @throws TransformerException */
public void transformNode(int node) throws TransformerException { //dml setExtensionsTable(getStylesheet()); // Make sure we're not writing to the same output content handler. synchronized (m_serializationHandler) { m_hasBeenReset = false; XPathContext xctxt = getXPathContext(); DTM dtm = xctxt.getDTM(node); try { pushGlobalVars(node); // ========== // Give the top-level templates a chance to pass information into // the context (this is mainly for setting up tables for extensions). StylesheetRoot stylesheet = this.getStylesheet(); int n = stylesheet.getGlobalImportCount(); for (int i = 0; i < n; i++) { StylesheetComposed imported = stylesheet.getGlobalImport(i); int includedCount = imported.getIncludeCountComposed(); for (int j = -1; j < includedCount; j++) { Stylesheet included = imported.getIncludeComposed(j); included.runtimeInit(this); for (ElemTemplateElement child = included.getFirstChildElem(); child != null; child = child.getNextSiblingElem()) { child.runtimeInit(this); } } } // =========== // System.out.println("Calling applyTemplateToNode - "+Thread.currentThread().getName()); DTMIterator dtmIter = new org.apache.xpath.axes.SelfIteratorNoPredicate(); dtmIter.setRoot(node, xctxt); xctxt.pushContextNodeList(dtmIter); try { this.applyTemplateToNode(null, null, node); } finally { xctxt.popContextNodeList(); } // m_stylesheetRoot.getStartRule().execute(this); // System.out.println("Done with applyTemplateToNode - "+Thread.currentThread().getName()); if (null != m_serializationHandler) { m_serializationHandler.endDocument(); } } catch (Exception se) { // System.out.println(Thread.currentThread().getName()+" threw an exception! " // +se.getMessage()); // If an exception was thrown, we need to make sure that any waiting // handlers can terminate, which I guess is best done by sending // an endDocument. // SAXSourceLocator while(se instanceof org.apache.xml.utils.WrappedRuntimeException) { Exception e = ((org.apache.xml.utils.WrappedRuntimeException)se).getException(); if(null != e) se = e; } if (null != m_serializationHandler) { try { if(se instanceof org.xml.sax.SAXParseException) m_serializationHandler.fatalError((org.xml.sax.SAXParseException)se); else if(se instanceof TransformerException) { TransformerException te = ((TransformerException)se); SAXSourceLocator sl = new SAXSourceLocator( te.getLocator() ); m_serializationHandler.fatalError(new org.xml.sax.SAXParseException(te.getMessage(), sl, te)); } else { m_serializationHandler.fatalError(new org.xml.sax.SAXParseException(se.getMessage(), new SAXSourceLocator(), se)); } } catch (Exception e){} } if(se instanceof TransformerException) { m_errorHandler.fatalError((TransformerException)se); } else if(se instanceof org.xml.sax.SAXParseException) { m_errorHandler.fatalError(new TransformerException(se.getMessage(), new SAXSourceLocator((org.xml.sax.SAXParseException)se), se)); } else { m_errorHandler.fatalError(new TransformerException(se)); } } finally { this.reset(); } } }
Get a SAX2 ContentHandler for the input.
Returns:A valid ContentHandler, which should never be null, as long as getFeature("http://xml.org/trax/features/sax/input") returns true.
/** * Get a SAX2 ContentHandler for the input. * * @return A valid ContentHandler, which should never be null, as * long as getFeature("http://xml.org/trax/features/sax/input") * returns true. */
public ContentHandler getInputContentHandler() { return getInputContentHandler(false); }
Get a SAX2 ContentHandler for the input.
Params:
  • doDocFrag – true if a DocumentFragment should be created as the root, rather than a Document.
Returns:A valid ContentHandler, which should never be null, as long as getFeature("http://xml.org/trax/features/sax/input") returns true.
/** * Get a SAX2 ContentHandler for the input. * * @param doDocFrag true if a DocumentFragment should be created as * the root, rather than a Document. * * @return A valid ContentHandler, which should never be null, as * long as getFeature("http://xml.org/trax/features/sax/input") * returns true. */
public ContentHandler getInputContentHandler(boolean doDocFrag) { if (null == m_inputContentHandler) { // if(null == m_urlOfSource && null != m_stylesheetRoot) // m_urlOfSource = m_stylesheetRoot.getBaseIdentifier(); m_inputContentHandler = new TransformerHandlerImpl(this, doDocFrag, m_urlOfSource); } return m_inputContentHandler; }
Get a SAX2 DeclHandler for the input.
Returns:A valid DeclHandler, which should never be null, as long as getFeature("http://xml.org/trax/features/sax/input") returns true.
/** * Get a SAX2 DeclHandler for the input. * @return A valid DeclHandler, which should never be null, as * long as getFeature("http://xml.org/trax/features/sax/input") * returns true. */
public DeclHandler getInputDeclHandler() { if (m_inputContentHandler instanceof DeclHandler) return (DeclHandler) m_inputContentHandler; else return null; }
Get a SAX2 LexicalHandler for the input.
Returns:A valid LexicalHandler, which should never be null, as long as getFeature("http://xml.org/trax/features/sax/input") returns true.
/** * Get a SAX2 LexicalHandler for the input. * @return A valid LexicalHandler, which should never be null, as * long as getFeature("http://xml.org/trax/features/sax/input") * returns true. */
public LexicalHandler getInputLexicalHandler() { if (m_inputContentHandler instanceof LexicalHandler) return (LexicalHandler) m_inputContentHandler; else return null; }
Set the output properties for the transformation. These properties will override properties set in the templates with xsl:output.
Params:
  • oformat – A valid OutputProperties object (which will not be mutated), or null.
/** * Set the output properties for the transformation. These * properties will override properties set in the templates * with xsl:output. * * @param oformat A valid OutputProperties object (which will * not be mutated), or null. */
public void setOutputFormat(OutputProperties oformat) { m_outputFormat = oformat; }
Get the output properties used for the transformation.
Returns:the output format that was set by the user, otherwise the output format from the stylesheet.
/** * Get the output properties used for the transformation. * * @return the output format that was set by the user, * otherwise the output format from the stylesheet. */
public OutputProperties getOutputFormat() { // Get the output format that was set by the user, otherwise get the // output format from the stylesheet. OutputProperties format = (null == m_outputFormat) ? getStylesheet().getOutputComposed() : m_outputFormat; return format; }
Set a parameter for the templates.
Params:
  • name – The name of the parameter.
  • namespace – The namespace of the parameter.
  • value – The value object. This can be any valid Java object -- it's up to the processor to provide the proper coersion to the object, or simply pass it on for use in extensions.
/** * Set a parameter for the templates. * * @param name The name of the parameter. * @param namespace The namespace of the parameter. * @param value The value object. This can be any valid Java object * -- it's up to the processor to provide the proper * coersion to the object, or simply pass it on for use * in extensions. */
public void setParameter(String name, String namespace, Object value) { VariableStack varstack = getXPathContext().getVarStack(); QName qname = new QName(namespace, name); XObject xobject = XObject.create(value, getXPathContext()); StylesheetRoot sroot = m_stylesheetRoot; Vector vars = sroot.getVariablesAndParamsComposed(); int i = vars.size(); while (--i >= 0) { ElemVariable variable = (ElemVariable)vars.elementAt(i); if(variable.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE && variable.getName().equals(qname)) { varstack.setGlobalVariable(i, xobject); } } }
NEEDSDOC Field m_userParams
/** NEEDSDOC Field m_userParams */
Vector m_userParams;
Set a parameter for the transformation.
Params:
  • name – The name of the parameter, which may have a namespace URI.
  • value – The value object. This can be any valid Java object -- it's up to the processor to provide the proper coersion to the object, or simply pass it on for use in extensions.
/** * Set a parameter for the transformation. * * @param name The name of the parameter, * which may have a namespace URI. * @param value The value object. This can be any valid Java object * -- it's up to the processor to provide the proper * coersion to the object, or simply pass it on for use * in extensions. */
public void setParameter(String name, Object value) { if (value == null) { throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_SET_PARAM_VALUE, new Object[]{name})); } StringTokenizer tokenizer = new StringTokenizer(name, "{}", false); try { // The first string might be the namespace, or it might be // the local name, if the namespace is null. String s1 = tokenizer.nextToken(); String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null; if (null == m_userParams) m_userParams = new Vector(); if (null == s2) { replaceOrPushUserParam(new QName(s1), XObject.create(value, getXPathContext())); setParameter(s1, null, value); } else { replaceOrPushUserParam(new QName(s1, s2), XObject.create(value, getXPathContext())); setParameter(s2, s1, value); } } catch (java.util.NoSuchElementException nsee) { // Should throw some sort of an error. } }
NEEDSDOC Method replaceOrPushUserParam NEEDSDOC @param qname NEEDSDOC @param xval
/** * NEEDSDOC Method replaceOrPushUserParam * * * NEEDSDOC @param qname * NEEDSDOC @param xval */
private void replaceOrPushUserParam(QName qname, XObject xval) { int n = m_userParams.size(); for (int i = n - 1; i >= 0; i--) { Arg arg = (Arg) m_userParams.elementAt(i); if (arg.getQName().equals(qname)) { m_userParams.setElementAt(new Arg(qname, xval, true), i); return; } } m_userParams.addElement(new Arg(qname, xval, true)); }
Get a parameter that was explicitly set with setParameter or setParameters. NEEDSDOC @param name
Returns:A parameter that has been set with setParameter or setParameters, *not* all the xsl:params on the stylesheet (which require a transformation Source to be evaluated).
/** * Get a parameter that was explicitly set with setParameter * or setParameters. * * * NEEDSDOC @param name * @return A parameter that has been set with setParameter * or setParameters, * *not* all the xsl:params on the stylesheet (which require * a transformation Source to be evaluated). */
public Object getParameter(String name) { try { // VariableStack varstack = getXPathContext().getVarStack(); // The first string might be the namespace, or it might be // the local name, if the namespace is null. QName qname = QName.getQNameFromString(name); if (null == m_userParams) return null; int n = m_userParams.size(); for (int i = n - 1; i >= 0; i--) { Arg arg = (Arg) m_userParams.elementAt(i); if (arg.getQName().equals(qname)) { return arg.getVal().object(); } } return null; } catch (java.util.NoSuchElementException nsee) { // Should throw some sort of an error. return null; } }
Reset parameters that the user specified for the transformation. Called during transformer.reset() after we have cleared the variable stack. We need to make sure that user params are reset so that the transformer object can be reused.
/** * Reset parameters that the user specified for the transformation. * Called during transformer.reset() after we have cleared the * variable stack. We need to make sure that user params are * reset so that the transformer object can be reused. */
private void resetUserParameters() { try { if (null == m_userParams) return; int n = m_userParams.size(); for (int i = n - 1; i >= 0; i--) { Arg arg = (Arg) m_userParams.elementAt(i); QName name = arg.getQName(); // The first string might be the namespace, or it might be // the local name, if the namespace is null. String s1 = name.getNamespace(); String s2 = name.getLocalPart(); setParameter(s2, s1, arg.getVal().object()); } } catch (java.util.NoSuchElementException nsee) { // Should throw some sort of an error. } }
Set a bag of parameters for the transformation. Note that these will not be additive, they will replace the existing set of parameters. NEEDSDOC @param params
/** * Set a bag of parameters for the transformation. Note that * these will not be additive, they will replace the existing * set of parameters. * * NEEDSDOC @param params */
public void setParameters(Properties params) { clearParameters(); Enumeration names = params.propertyNames(); while (names.hasMoreElements()) { String name = params.getProperty((String) names.nextElement()); StringTokenizer tokenizer = new StringTokenizer(name, "{}", false); try { // The first string might be the namespace, or it might be // the local name, if the namespace is null. String s1 = tokenizer.nextToken(); String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null; if (null == s2) setParameter(s1, null, params.getProperty(name)); else setParameter(s2, s1, params.getProperty(name)); } catch (java.util.NoSuchElementException nsee) { // Should throw some sort of an error. } } }
Reset the parameters to a null list.
/** * Reset the parameters to a null list. */
public void clearParameters() { synchronized (m_reentryGuard) { VariableStack varstack = new VariableStack(); m_xcontext.setVarStack(varstack); m_userParams = null; } }
Internal -- push the global variables from the Stylesheet onto the context's runtime variable stack.

If we encounter a variable that is already defined in the variable stack, we ignore it. This is because the second variable definition will be at a lower import precedence. Presumably, global"variables at the same import precedence with the same name will have been caught during the recompose process.

However, if we encounter a parameter that is already defined in the variable stack, we need to see if this is a parameter whose value was supplied by a setParameter call. If so, we need to "receive" the one already in the stack, ignoring this one. If it is just an earlier xsl:param or xsl:variable definition, we ignore it using the same reasoning as explained above for the variable.

Params:
  • contextNode – The root of the source tree, can't be null.
Throws:
/** * Internal -- push the global variables from the Stylesheet onto * the context's runtime variable stack. * <p>If we encounter a variable * that is already defined in the variable stack, we ignore it. This * is because the second variable definition will be at a lower import * precedence. Presumably, global"variables at the same import precedence * with the same name will have been caught during the recompose process. * <p>However, if we encounter a parameter that is already defined in the * variable stack, we need to see if this is a parameter whose value was * supplied by a setParameter call. If so, we need to "receive" the one * already in the stack, ignoring this one. If it is just an earlier * xsl:param or xsl:variable definition, we ignore it using the same * reasoning as explained above for the variable. * * @param contextNode The root of the source tree, can't be null. * * @throws TransformerException */
protected void pushGlobalVars(int contextNode) throws TransformerException { XPathContext xctxt = m_xcontext; VariableStack vs = xctxt.getVarStack(); StylesheetRoot sr = getStylesheet(); Vector vars = sr.getVariablesAndParamsComposed(); int i = vars.size(); vs.link(i); while (--i >= 0) { ElemVariable v = (ElemVariable) vars.elementAt(i); // XObject xobj = v.getValue(this, contextNode); XObject xobj = new XUnresolvedVariable(v, contextNode, this, vs.getStackFrame(), 0, true); if(null == vs.elementAt(i)) vs.setGlobalVariable(i, xobj); } }
Set an object that will be used to resolve URIs used in document(), etc.
Params:
  • resolver – An object that implements the URIResolver interface, or null.
/** * Set an object that will be used to resolve URIs used in * document(), etc. * @param resolver An object that implements the URIResolver interface, * or null. */
public void setURIResolver(URIResolver resolver) { synchronized (m_reentryGuard) { m_xcontext.getSourceTreeManager().setURIResolver(resolver); } }
Get an object that will be used to resolve URIs used in document(), etc.
Returns:An object that implements the URIResolver interface, or null.
/** * Get an object that will be used to resolve URIs used in * document(), etc. * * @return An object that implements the URIResolver interface, * or null. */
public URIResolver getURIResolver() { return m_xcontext.getSourceTreeManager().getURIResolver(); } // ======== End Transformer Implementation ========
Set the content event handler. NEEDSDOC @param handler
Throws:
See Also:
/** * Set the content event handler. * * NEEDSDOC @param handler * @throws java.lang.NullPointerException If the handler * is null. * @see org.xml.sax.XMLReader#setContentHandler */
public void setContentHandler(ContentHandler handler) { if (handler == null) { throw new NullPointerException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_CONTENT_HANDLER, null)); //"Null content handler"); } else { m_outputContentHandler = handler; if (null == m_serializationHandler) { ToXMLSAXHandler h = new ToXMLSAXHandler(); h.setContentHandler(handler); h.setTransformer(this); m_serializationHandler = h; } else m_serializationHandler.setContentHandler(handler); } }
Get the content event handler.
See Also:
Returns:The current content handler, or null if none was set.
/** * Get the content event handler. * * @return The current content handler, or null if none was set. * @see org.xml.sax.XMLReader#getContentHandler */
public ContentHandler getContentHandler() { return m_outputContentHandler; }
Given a stylesheet element, create a result tree fragment from it's contents. The fragment will be built within the shared RTF DTM system used as a variable stack.
Params:
  • templateParent – The template element that holds the fragment.
Throws:
Returns:the NodeHandle for the root node of the resulting RTF.
@xsl.usageadvanced
/** * Given a stylesheet element, create a result tree fragment from it's * contents. The fragment will be built within the shared RTF DTM system * used as a variable stack. * @param templateParent The template element that holds the fragment. * @return the NodeHandle for the root node of the resulting RTF. * * @throws TransformerException * @xsl.usage advanced */
public int transformToRTF(ElemTemplateElement templateParent) throws TransformerException { // Retrieve a DTM to contain the RTF. At this writing, this may be a // multi-document DTM (SAX2RTFDTM). DTM dtmFrag = m_xcontext.getRTFDTM(); return transformToRTF(templateParent,dtmFrag); }
Given a stylesheet element, create a result tree fragment from it's contents. The fragment will also use the shared DTM system, but will obtain its space from the global variable pool rather than the dynamic variable stack. This allows late binding of XUnresolvedVariables without the risk that their content will be discarded when the variable stack is popped.
Params:
  • templateParent – The template element that holds the fragment.
Throws:
Returns:the NodeHandle for the root node of the resulting RTF.
@xsl.usageadvanced
/** * Given a stylesheet element, create a result tree fragment from it's * contents. The fragment will also use the shared DTM system, but will * obtain its space from the global variable pool rather than the dynamic * variable stack. This allows late binding of XUnresolvedVariables without * the risk that their content will be discarded when the variable stack * is popped. * * @param templateParent The template element that holds the fragment. * @return the NodeHandle for the root node of the resulting RTF. * * @throws TransformerException * @xsl.usage advanced */
public int transformToGlobalRTF(ElemTemplateElement templateParent) throws TransformerException { // Retrieve a DTM to contain the RTF. At this writing, this may be a // multi-document DTM (SAX2RTFDTM). DTM dtmFrag = m_xcontext.getGlobalRTFDTM(); return transformToRTF(templateParent,dtmFrag); }
Given a stylesheet element, create a result tree fragment from it's contents.
Params:
  • templateParent – The template element that holds the fragment.
  • dtmFrag – The DTM to write the RTF into
Throws:
Returns:the NodeHandle for the root node of the resulting RTF.
@xsl.usageadvanced
/** * Given a stylesheet element, create a result tree fragment from it's * contents. * @param templateParent The template element that holds the fragment. * @param dtmFrag The DTM to write the RTF into * @return the NodeHandle for the root node of the resulting RTF. * * @throws TransformerException * @xsl.usage advanced */
private int transformToRTF(ElemTemplateElement templateParent,DTM dtmFrag) throws TransformerException { XPathContext xctxt = m_xcontext; ContentHandler rtfHandler = dtmFrag.getContentHandler(); // Obtain the ResultTreeFrag's root node. // NOTE: In SAX2RTFDTM, this value isn't available until after // the startDocument has been issued, so assignment has been moved // down a bit in the code. int resultFragment; // not yet reliably = dtmFrag.getDocument(); // Save the current result tree handler. SerializationHandler savedRTreeHandler = this.m_serializationHandler; // And make a new handler for the RTF. ToSAXHandler h = new ToXMLSAXHandler(); h.setContentHandler(rtfHandler); h.setTransformer(this); // Replace the old handler (which was already saved) m_serializationHandler = h; // use local variable for the current handler SerializationHandler rth = m_serializationHandler; try { rth.startDocument(); // startDocument is "bottlenecked" in RTH. We need it acted upon immediately, // to set the DTM's state as in-progress, so that if the xsl:variable's body causes // further RTF activity we can keep that from bashing this DTM. rth.flushPending(); try { // Do the transformation of the child elements. executeChildTemplates(templateParent, true); // Make sure everything is flushed! rth.flushPending(); // Get the document ID. May not exist until the RTH has not only // received, but flushed, the startDocument, and may be invalid // again after the document has been closed (still debating that) // ... so waiting until just before the end seems simplest/safest. resultFragment = dtmFrag.getDocument(); } finally { rth.endDocument(); } } catch (org.xml.sax.SAXException se) { throw new TransformerException(se); } finally { // Restore the previous result tree handler. this.m_serializationHandler = savedRTreeHandler; } return resultFragment; }
Get the StringWriter pool, so that StringWriter objects may be reused.
Returns:The string writer pool, not null.
@xsl.usageinternal
/** * Get the StringWriter pool, so that StringWriter * objects may be reused. * * @return The string writer pool, not null. * @xsl.usage internal */
public ObjectPool getStringWriterPool() { return m_stringWriterObjectPool; }
Take the contents of a template element, process it, and convert it to a string.
Params:
  • elem – The parent element whose children will be output as a string.
Throws:
Returns:The stringized result of executing the elements children.
@xsl.usageadvanced
/** * Take the contents of a template element, process it, and * convert it to a string. * * @param elem The parent element whose children will be output * as a string. * * @return The stringized result of executing the elements children. * * @throws TransformerException * @xsl.usage advanced */
public String transformToString(ElemTemplateElement elem) throws TransformerException { ElemTemplateElement firstChild = elem.getFirstChildElem(); if(null == firstChild) return ""; if(elem.hasTextLitOnly() && m_optimizer) { return ((ElemTextLiteral)firstChild).getNodeValue(); } // Save the current result tree handler. SerializationHandler savedRTreeHandler = this.m_serializationHandler; // Create a Serializer object that will handle the SAX events // and build the ResultTreeFrag nodes. StringWriter sw = (StringWriter) m_stringWriterObjectPool.getInstance(); m_serializationHandler = (ToTextStream) m_textResultHandlerObjectPool.getInstance(); if (null == m_serializationHandler) { // if we didn't get one from the pool, go make a new one Serializer serializer = org.apache.xml.serializer.SerializerFactory.getSerializer( m_textformat.getProperties()); m_serializationHandler = (SerializationHandler) serializer; } m_serializationHandler.setTransformer(this); m_serializationHandler.setWriter(sw); String result; try { /* Don't call startDocument, the SerializationHandler will * generate its own internal startDocument call anyways */ // this.m_serializationHandler.startDocument(); // Do the transformation of the child elements. executeChildTemplates(elem, true); this.m_serializationHandler.endDocument(); result = sw.toString(); } catch (org.xml.sax.SAXException se) { throw new TransformerException(se); } finally { sw.getBuffer().setLength(0); try { sw.close(); } catch (Exception ioe){} m_stringWriterObjectPool.freeInstance(sw); m_serializationHandler.reset(); m_textResultHandlerObjectPool.freeInstance(m_serializationHandler); // Restore the previous result tree handler. m_serializationHandler = savedRTreeHandler; } return result; }
Given an element and mode, find the corresponding template and process the contents.
Params:
  • xslInstruction – The calling element.
  • template – The template to use if xsl:for-each, current template for apply-imports, or null.
  • child – The source context node.
Throws:
Returns:true if applied a template, false if not.
@xsl.usageadvanced
/** * Given an element and mode, find the corresponding * template and process the contents. * * @param xslInstruction The calling element. * @param template The template to use if xsl:for-each, current template for apply-imports, or null. * @param child The source context node. * @throws TransformerException * @return true if applied a template, false if not. * @xsl.usage advanced */
public boolean applyTemplateToNode(ElemTemplateElement xslInstruction, // xsl:apply-templates or xsl:for-each ElemTemplate template, int child) throws TransformerException { DTM dtm = m_xcontext.getDTM(child); short nodeType = dtm.getNodeType(child); boolean isDefaultTextRule = false; boolean isApplyImports = false; isApplyImports = ((xslInstruction == null) ? false : xslInstruction.getXSLToken() == Constants.ELEMNAME_APPLY_IMPORTS); if (null == template || isApplyImports) { int maxImportLevel, endImportLevel=0; if (isApplyImports) { maxImportLevel = template.getStylesheetComposed().getImportCountComposed() - 1; endImportLevel = template.getStylesheetComposed().getEndImportCountComposed(); } else { maxImportLevel = -1; } // If we're trying an xsl:apply-imports at the top level (ie there are no // imported stylesheets), we need to indicate that there is no matching template. // The above logic will calculate a maxImportLevel of -1 which indicates // that we should find any template. This is because a value of -1 for // maxImportLevel has a special meaning. But we don't want that. // We want to match -no- templates. See bugzilla bug 1170. if (isApplyImports && (maxImportLevel == -1)) { template = null; } else { // Find the XSL template that is the best match for the // element. XPathContext xctxt = m_xcontext; try { xctxt.pushNamespaceContext(xslInstruction); QName mode = this.getMode(); if (isApplyImports) template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode, maxImportLevel, endImportLevel, m_quietConflictWarnings, dtm); else template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode, m_quietConflictWarnings, dtm); } finally { xctxt.popNamespaceContext(); } } // If that didn't locate a node, fall back to a default template rule. // See http://www.w3.org/TR/xslt#built-in-rule. if (null == template) { switch (nodeType) { case DTM.DOCUMENT_FRAGMENT_NODE : case DTM.ELEMENT_NODE : template = m_stylesheetRoot.getDefaultRule(); break; case DTM.CDATA_SECTION_NODE : case DTM.TEXT_NODE : case DTM.ATTRIBUTE_NODE : template = m_stylesheetRoot.getDefaultTextRule(); isDefaultTextRule = true; break; case DTM.DOCUMENT_NODE : template = m_stylesheetRoot.getDefaultRootRule(); break; default : // No default rules for processing instructions and the like. return false; } } } // If we are processing the default text rule, then just clone // the value directly to the result tree. try { pushElemTemplateElement(template); m_xcontext.pushCurrentNode(child); pushPairCurrentMatched(template, child); // Fix copy copy29 test. if (!isApplyImports) { DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager()); m_xcontext.pushContextNodeList(cnl); } if (isDefaultTextRule) { switch (nodeType) { case DTM.CDATA_SECTION_NODE : case DTM.TEXT_NODE : ClonerToResultTree.cloneToResultTree(child, nodeType, dtm, getResultTreeHandler(), false); break; case DTM.ATTRIBUTE_NODE : dtm.dispatchCharactersEvents(child, getResultTreeHandler(), false); break; } } else { // Fire a trace event for the template. if (m_debug) getTraceManager().fireTraceEvent(template); // And execute the child templates. // 9/11/00: If template has been compiled, hand off to it // since much (most? all?) of the processing has been inlined. // (It would be nice if there was a single entry point that // worked for both... but the interpretive system works by // having the Tranformer execute the children, while the // compiled obviously has to run its own code. It's // also unclear that "execute" is really the right name for // that entry point.) m_xcontext.setSAXLocator(template); // m_xcontext.getVarStack().link(); m_xcontext.getVarStack().link(template.m_frameSize); executeChildTemplates(template, true); if (m_debug) getTraceManager().fireTraceEndEvent(template); } } catch (org.xml.sax.SAXException se) { throw new TransformerException(se); } finally { if (!isDefaultTextRule) m_xcontext.getVarStack().unlink(); m_xcontext.popCurrentNode(); if (!isApplyImports) { m_xcontext.popContextNodeList(); } popCurrentMatched(); popElemTemplateElement(); } return true; }
Execute each of the children of a template element. This method is only for extension use.
Params:
  • elem – The ElemTemplateElement that contains the children that should execute. NEEDSDOC @param context
  • mode – The current mode.
  • handler – The ContentHandler to where the result events should be fed.
Throws:
@xsl.usageadvanced
/** * Execute each of the children of a template element. This method * is only for extension use. * * @param elem The ElemTemplateElement that contains the children * that should execute. * NEEDSDOC @param context * @param mode The current mode. * @param handler The ContentHandler to where the result events * should be fed. * * @throws TransformerException * @xsl.usage advanced */
public void executeChildTemplates( ElemTemplateElement elem, org.w3c.dom.Node context, QName mode, ContentHandler handler) throws TransformerException { XPathContext xctxt = m_xcontext; try { if(null != mode) pushMode(mode); xctxt.pushCurrentNode(xctxt.getDTMHandleFromNode(context)); executeChildTemplates(elem, handler); } finally { xctxt.popCurrentNode(); // I'm not sure where or why this was here. It is clearly in // error though, without a corresponding pushMode(). if (null != mode) popMode(); } }
Execute each of the children of a template element.
Params:
  • elem – The ElemTemplateElement that contains the children that should execute.
  • shouldAddAttrs – true if xsl:attributes should be executed.
Throws:
@xsl.usageadvanced
/** * Execute each of the children of a template element. * * @param elem The ElemTemplateElement that contains the children * that should execute. * @param shouldAddAttrs true if xsl:attributes should be executed. * * @throws TransformerException * @xsl.usage advanced */
public void executeChildTemplates( ElemTemplateElement elem, boolean shouldAddAttrs) throws TransformerException { // Does this element have any children? ElemTemplateElement t = elem.getFirstChildElem(); if (null == t) return; if(elem.hasTextLitOnly() && m_optimizer) { char[] chars = ((ElemTextLiteral)t).getChars(); try { // Have to push stuff on for tooling... this.pushElemTemplateElement(t); m_serializationHandler.characters(chars, 0, chars.length); } catch(SAXException se) { throw new TransformerException(se); } finally { this.popElemTemplateElement(); } return; } // // Check for infinite loops if we have to. // boolean check = (m_stackGuard.m_recursionLimit > -1); // // if (check) // getStackGuard().push(elem, xctxt.getCurrentNode()); XPathContext xctxt = m_xcontext; xctxt.pushSAXLocatorNull(); int currentTemplateElementsTop = m_currentTemplateElements.size(); m_currentTemplateElements.push(null); try { // Loop through the children of the template, calling execute on // each of them. for (; t != null; t = t.getNextSiblingElem()) { if (!shouldAddAttrs && t.getXSLToken() == Constants.ELEMNAME_ATTRIBUTE) continue; xctxt.setSAXLocator(t); m_currentTemplateElements.setElementAt(t,currentTemplateElementsTop); t.execute(this); } } catch(RuntimeException re) { TransformerException te = new TransformerException(re); te.setLocator(t); throw te; } finally { m_currentTemplateElements.pop(); xctxt.popSAXLocator(); } // Check for infinite loops if we have to // if (check) // getStackGuard().pop(); }
Execute each of the children of a template element.
Params:
  • elem – The ElemTemplateElement that contains the children that should execute.
  • handler – The ContentHandler to where the result events should be fed.
Throws:
@xsl.usageadvanced
/** * Execute each of the children of a template element. * * @param elem The ElemTemplateElement that contains the children * that should execute. * @param handler The ContentHandler to where the result events * should be fed. * * @throws TransformerException * @xsl.usage advanced */
public void executeChildTemplates( ElemTemplateElement elem, ContentHandler handler) throws TransformerException { SerializationHandler xoh = this.getSerializationHandler(); // These may well not be the same! In this case when calling // the Redirect extension, it has already set the ContentHandler // in the Transformer. SerializationHandler savedHandler = xoh; try { xoh.flushPending(); // %REVIEW% Make sure current node is being pushed. LexicalHandler lex = null; if (handler instanceof LexicalHandler) { lex = (LexicalHandler) handler; } m_serializationHandler = new ToXMLSAXHandler(handler, lex, savedHandler.getEncoding()); m_serializationHandler.setTransformer(this); executeChildTemplates(elem, true); } catch (TransformerException e) { throw e; } catch (SAXException se) { throw new TransformerException(se); } finally { m_serializationHandler = savedHandler; } }
Get the keys for the xsl:sort elements. Note: Should this go into ElemForEach?
Params:
  • foreach – Valid ElemForEach element, not null.
  • sourceNodeContext – The current node context in the source tree, needed to evaluate the Attribute Value Templates.
Throws:
Returns:A Vector of NodeSortKeys, or null.
@xsl.usageadvanced
/** * Get the keys for the xsl:sort elements. * Note: Should this go into ElemForEach? * * @param foreach Valid ElemForEach element, not null. * @param sourceNodeContext The current node context in the source tree, * needed to evaluate the Attribute Value Templates. * * @return A Vector of NodeSortKeys, or null. * * @throws TransformerException * @xsl.usage advanced */
public Vector processSortKeys(ElemForEach foreach, int sourceNodeContext) throws TransformerException { Vector keys = null; XPathContext xctxt = m_xcontext; int nElems = foreach.getSortElemCount(); if (nElems > 0) keys = new Vector(); // March backwards, collecting the sort keys. for (int i = 0; i < nElems; i++) { ElemSort sort = foreach.getSortElem(i); if (m_debug) getTraceManager().fireTraceEvent(sort); String langString = (null != sort.getLang()) ? sort.getLang().evaluate(xctxt, sourceNodeContext, foreach) : null; String dataTypeString = sort.getDataType().evaluate(xctxt, sourceNodeContext, foreach); if (dataTypeString.indexOf(":") >= 0) System.out.println( "TODO: Need to write the hooks for QNAME sort data type"); else if (!(dataTypeString.equalsIgnoreCase(Constants.ATTRVAL_DATATYPE_TEXT)) &&!(dataTypeString.equalsIgnoreCase( Constants.ATTRVAL_DATATYPE_NUMBER))) foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE, new Object[]{ Constants.ATTRNAME_DATATYPE, dataTypeString }); boolean treatAsNumbers = ((null != dataTypeString) && dataTypeString.equals( Constants.ATTRVAL_DATATYPE_NUMBER)) ? true : false; String orderString = sort.getOrder().evaluate(xctxt, sourceNodeContext, foreach); if (!(orderString.equalsIgnoreCase(Constants.ATTRVAL_ORDER_ASCENDING)) &&!(orderString.equalsIgnoreCase( Constants.ATTRVAL_ORDER_DESCENDING))) foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE, new Object[]{ Constants.ATTRNAME_ORDER, orderString }); boolean descending = ((null != orderString) && orderString.equals( Constants.ATTRVAL_ORDER_DESCENDING)) ? true : false; AVT caseOrder = sort.getCaseOrder(); boolean caseOrderUpper; if (null != caseOrder) { String caseOrderString = caseOrder.evaluate(xctxt, sourceNodeContext, foreach); if (!(caseOrderString.equalsIgnoreCase(Constants.ATTRVAL_CASEORDER_UPPER)) &&!(caseOrderString.equalsIgnoreCase( Constants.ATTRVAL_CASEORDER_LOWER))) foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE, new Object[]{ Constants.ATTRNAME_CASEORDER, caseOrderString }); caseOrderUpper = ((null != caseOrderString) && caseOrderString.equals( Constants.ATTRVAL_CASEORDER_UPPER)) ? true : false; } else { caseOrderUpper = false; } keys.addElement(new NodeSortKey(this, sort.getSelect(), treatAsNumbers, descending, langString, caseOrderUpper, foreach)); if (m_debug) getTraceManager().fireTraceEndEvent(sort); } return keys; } //========================================================== // SECTION: TransformState implementation //==========================================================
Get the stack of ElemTemplateElements.
Returns:A copy of stack that contains the xsl element instructions, the earliest called in index zero, and the latest called in index size()-1.
/** * Get the stack of ElemTemplateElements. * * @return A copy of stack that contains the xsl element instructions, * the earliest called in index zero, and the latest called in index size()-1. */
public Vector getElementCallstack() { Vector elems = new Vector(); int nStackSize = m_currentTemplateElements.size(); for(int i = 0; i < nStackSize; i++) { ElemTemplateElement elem = (ElemTemplateElement) m_currentTemplateElements.elementAt(i); if(null != elem) { elems.addElement(elem); } } return elems; }
Get the count of how many elements are active.
Returns:The number of active elements on the currentTemplateElements stack.
/** * Get the count of how many elements are * active. * @return The number of active elements on * the currentTemplateElements stack. */
public int getCurrentTemplateElementsCount() { return m_currentTemplateElements.size(); }
Get the count of how many elements are active.
Returns:The number of active elements on the currentTemplateElements stack.
/** * Get the count of how many elements are * active. * @return The number of active elements on * the currentTemplateElements stack. */
public ObjectStack getCurrentTemplateElements() { return m_currentTemplateElements; }
Push the current template element.
Params:
  • elem – The current ElemTemplateElement (may be null, and then set via setCurrentElement).
/** * Push the current template element. * * @param elem The current ElemTemplateElement (may be null, and then * set via setCurrentElement). */
public void pushElemTemplateElement(ElemTemplateElement elem) { m_currentTemplateElements.push(elem); }
Pop the current template element.
/** * Pop the current template element. */
public void popElemTemplateElement() { m_currentTemplateElements.pop(); }
Set the top of the current template elements stack.
Params:
  • e – The current ElemTemplateElement about to be executed.
/** * Set the top of the current template elements * stack. * * @param e The current ElemTemplateElement about to * be executed. */
public void setCurrentElement(ElemTemplateElement e) { m_currentTemplateElements.setTop(e); }
Retrieves the current ElemTemplateElement that is being executed.
Returns:The current ElemTemplateElement that is executing, should not normally be null.
/** * Retrieves the current ElemTemplateElement that is * being executed. * * @return The current ElemTemplateElement that is executing, * should not normally be null. */
public ElemTemplateElement getCurrentElement() { return (m_currentTemplateElements.size() > 0) ? (ElemTemplateElement) m_currentTemplateElements.peek() : null; }
This method retrieves the current context node in the source tree.
Returns:The current context node (should never be null?).
/** * This method retrieves the current context node * in the source tree. * * @return The current context node (should never be null?). */
public int getCurrentNode() { return m_xcontext.getCurrentNode(); }
Get the call stack of xsl:template elements.
Returns:A copy of stack that contains the xsl:template (ElemTemplate) instructions, the earliest called in index zero, and the latest called in index size()-1.
/** * Get the call stack of xsl:template elements. * * @return A copy of stack that contains the xsl:template * (ElemTemplate) instructions, the earliest called in index * zero, and the latest called in index size()-1. */
public Vector getTemplateCallstack() { Vector elems = new Vector(); int nStackSize = m_currentTemplateElements.size(); for(int i = 0; i < nStackSize; i++) { ElemTemplateElement elem = (ElemTemplateElement) m_currentTemplateElements.elementAt(i); if(null != elem && (elem.getXSLToken() != Constants.ELEMNAME_TEMPLATE)) { elems.addElement(elem); } } return elems; }
This method retrieves the xsl:template that is in effect, which may be a matched template or a named template.

Please note that the ElemTemplate returned may be a default template, and thus may not have a template defined in the stylesheet.

Returns:The current xsl:template, should not be null.
/** * This method retrieves the xsl:template * that is in effect, which may be a matched template * or a named template. * * <p>Please note that the ElemTemplate returned may * be a default template, and thus may not have a template * defined in the stylesheet.</p> * * @return The current xsl:template, should not be null. */
public ElemTemplate getCurrentTemplate() { ElemTemplateElement elem = getCurrentElement(); while ((null != elem) && (elem.getXSLToken() != Constants.ELEMNAME_TEMPLATE)) { elem = elem.getParentElem(); } return (ElemTemplate) elem; }
Push both the current xsl:template or xsl:for-each onto the stack, along with the child node that was matched. (Note: should this only be used for xsl:templates?? -sb)
Params:
  • template – xsl:template or xsl:for-each.
  • child – The child that was matched.
/** * Push both the current xsl:template or xsl:for-each onto the * stack, along with the child node that was matched. * (Note: should this only be used for xsl:templates?? -sb) * * @param template xsl:template or xsl:for-each. * @param child The child that was matched. */
public void pushPairCurrentMatched(ElemTemplateElement template, int child) { m_currentMatchTemplates.push(template); m_currentMatchedNodes.push(child); }
Pop the elements that were pushed via pushPairCurrentMatched.
/** * Pop the elements that were pushed via pushPairCurrentMatched. */
public void popCurrentMatched() { m_currentMatchTemplates.pop(); m_currentMatchedNodes.pop(); }
This method retrieves the xsl:template that was matched. Note that this may not be the same thing as the current template (which may be from getCurrentElement()), since a named template may be in effect.
Returns:The pushed template that was pushed via pushPairCurrentMatched.
/** * This method retrieves the xsl:template * that was matched. Note that this may not be * the same thing as the current template (which * may be from getCurrentElement()), since a named * template may be in effect. * * @return The pushed template that was pushed via pushPairCurrentMatched. */
public ElemTemplate getMatchedTemplate() { return (ElemTemplate) m_currentMatchTemplates.peek(); }
Retrieves the node in the source tree that matched the template obtained via getMatchedTemplate().
Returns:The matched node that corresponds to the match attribute of the current xsl:template.
/** * Retrieves the node in the source tree that matched * the template obtained via getMatchedTemplate(). * * @return The matched node that corresponds to the * match attribute of the current xsl:template. */
public int getMatchedNode() { return m_currentMatchedNodes.peepTail(); }
Get the current context node list.
Returns:A reset clone of the context node list.
/** * Get the current context node list. * * @return A reset clone of the context node list. */
public DTMIterator getContextNodeList() { try { DTMIterator cnl = m_xcontext.getContextNodeList(); return (cnl == null) ? null : (DTMIterator) cnl.cloneWithReset(); } catch (CloneNotSupportedException cnse) { // should never happen. return null; } }
Get the TrAX Transformer object in effect.
Returns:This object.
/** * Get the TrAX Transformer object in effect. * * @return This object. */
public Transformer getTransformer() { return this; } //========================================================== // SECTION: Accessor Functions //==========================================================
Set the stylesheet for this processor. If this is set, then the process calls that take only the input .xml will use this instead of looking for a stylesheet PI. Also, setting the stylesheet is needed if you are going to use the processor as a SAX ContentHandler.
Params:
  • stylesheetRoot – A non-null StylesheetRoot object, or null if you wish to clear the stylesheet reference.
/** * Set the stylesheet for this processor. If this is set, then the * process calls that take only the input .xml will use * this instead of looking for a stylesheet PI. Also, * setting the stylesheet is needed if you are going * to use the processor as a SAX ContentHandler. * * @param stylesheetRoot A non-null StylesheetRoot object, * or null if you wish to clear the stylesheet reference. */
public void setStylesheet(StylesheetRoot stylesheetRoot) { m_stylesheetRoot = stylesheetRoot; }
Get the current stylesheet for this processor.
Returns:The stylesheet that is associated with this transformer.
/** * Get the current stylesheet for this processor. * * @return The stylesheet that is associated with this * transformer. */
public final StylesheetRoot getStylesheet() { return m_stylesheetRoot; }
Get quietConflictWarnings property. If the quietConflictWarnings property is set to true, warnings about pattern conflicts won't be printed to the diagnostics stream.
Returns:True if this transformer should not report template match conflicts.
/** * Get quietConflictWarnings property. If the quietConflictWarnings * property is set to true, warnings about pattern conflicts won't be * printed to the diagnostics stream. * * @return True if this transformer should not report * template match conflicts. */
public boolean getQuietConflictWarnings() { return m_quietConflictWarnings; }
If the quietConflictWarnings property is set to true, warnings about pattern conflicts won't be printed to the diagnostics stream. False by default. (Currently setting this property will have no effect.)
Params:
  • b – true if conflict warnings should be suppressed.
/** * If the quietConflictWarnings property is set to * true, warnings about pattern conflicts won't be * printed to the diagnostics stream. * False by default. * (Currently setting this property will have no effect.) * * @param b true if conflict warnings should be suppressed. */
public void setQuietConflictWarnings(boolean b) { m_quietConflictWarnings = b; }
Set the execution context for XPath.
Params:
  • xcontext – A non-null reference to the XPathContext associated with this transformer.
@xsl.usageinternal
/** * Set the execution context for XPath. * * @param xcontext A non-null reference to the XPathContext * associated with this transformer. * @xsl.usage internal */
public void setXPathContext(XPathContext xcontext) { m_xcontext = xcontext; }
Get the XPath context associated with this transformer.
Returns:The XPathContext reference, never null.
/** * Get the XPath context associated with this transformer. * * @return The XPathContext reference, never null. */
public final XPathContext getXPathContext() { return m_xcontext; }
Get the object used to guard the stack from recursion.
Returns:The StackGuard object, which should never be null.
@xsl.usageinternal
/** * Get the object used to guard the stack from * recursion. * * @return The StackGuard object, which should never be null. * @xsl.usage internal */
public StackGuard getStackGuard() { return m_stackGuard; }
Get the recursion limit. Used for infinite loop check. If the value is -1, do not check for infinite loops. Anyone who wants to enable that check should change the value of this variable to be the level of recursion that they want to check. Be careful setting this variable, if the number is too low, it may report an infinite loop situation, when there is none. Post version 1.0.0, we'll make this a runtime feature.
Returns:The limit on recursion, or -1 if no check is to be made.
/** * Get the recursion limit. * Used for infinite loop check. If the value is -1, do not * check for infinite loops. Anyone who wants to enable that * check should change the value of this variable to be the * level of recursion that they want to check. Be careful setting * this variable, if the number is too low, it may report an * infinite loop situation, when there is none. * Post version 1.0.0, we'll make this a runtime feature. * * @return The limit on recursion, or -1 if no check is to be made. */
public int getRecursionLimit() { return m_stackGuard.getRecursionLimit(); }
Set the recursion limit. Used for infinite loop check. If the value is -1, do not check for infinite loops. Anyone who wants to enable that check should change the value of this variable to be the level of recursion that they want to check. Be careful setting this variable, if the number is too low, it may report an infinite loop situation, when there is none. Post version 1.0.0, we'll make this a runtime feature.
Params:
  • limit – A number that represents the limit of recursion, or -1 if no checking is to be done.
/** * Set the recursion limit. * Used for infinite loop check. If the value is -1, do not * check for infinite loops. Anyone who wants to enable that * check should change the value of this variable to be the * level of recursion that they want to check. Be careful setting * this variable, if the number is too low, it may report an * infinite loop situation, when there is none. * Post version 1.0.0, we'll make this a runtime feature. * * @param limit A number that represents the limit of recursion, * or -1 if no checking is to be done. */
public void setRecursionLimit(int limit) { m_stackGuard.setRecursionLimit(limit); }
Get the SerializationHandler object.
Returns:The current SerializationHandler, which may not be the main result tree manager.
/** * Get the SerializationHandler object. * * @return The current SerializationHandler, which may not * be the main result tree manager. */
public SerializationHandler getResultTreeHandler() { return m_serializationHandler; }
Get the SerializationHandler object.
Returns:The current SerializationHandler, which may not be the main result tree manager.
/** * Get the SerializationHandler object. * * @return The current SerializationHandler, which may not * be the main result tree manager. */
public SerializationHandler getSerializationHandler() { return m_serializationHandler; }
Get the KeyManager object.
Returns:A reference to the KeyManager object, which should never be null.
/** * Get the KeyManager object. * * @return A reference to the KeyManager object, which should * never be null. */
public KeyManager getKeyManager() { return m_keyManager; }
Check to see if this is a recursive attribute definition.
Params:
  • attrSet – A non-null ElemAttributeSet reference.
Returns:true if the attribute set is recursive.
/** * Check to see if this is a recursive attribute definition. * * @param attrSet A non-null ElemAttributeSet reference. * * @return true if the attribute set is recursive. */
public boolean isRecursiveAttrSet(ElemAttributeSet attrSet) { if (null == m_attrSetStack) { m_attrSetStack = new Stack(); } if (!m_attrSetStack.empty()) { int loc = m_attrSetStack.search(attrSet); if (loc > -1) { return true; } } return false; }
Push an executing attribute set, so we can check for recursive attribute definitions.
Params:
  • attrSet – A non-null ElemAttributeSet reference.
/** * Push an executing attribute set, so we can check for * recursive attribute definitions. * * @param attrSet A non-null ElemAttributeSet reference. */
public void pushElemAttributeSet(ElemAttributeSet attrSet) { m_attrSetStack.push(attrSet); }
Pop the current executing attribute set.
/** * Pop the current executing attribute set. */
public void popElemAttributeSet() { m_attrSetStack.pop(); }
Get the table of counters, for optimized xsl:number support.
Returns:The CountersTable, never null.
/** * Get the table of counters, for optimized xsl:number support. * * @return The CountersTable, never null. */
public CountersTable getCountersTable() { if (null == m_countersTable) m_countersTable = new CountersTable(); return m_countersTable; }
Tell if the current template rule is null, i.e. if we are directly within an apply-templates. Used for xsl:apply-imports.
Returns:True if the current template rule is null.
/** * Tell if the current template rule is null, i.e. if we are * directly within an apply-templates. Used for xsl:apply-imports. * * @return True if the current template rule is null. */
public boolean currentTemplateRuleIsNull() { return ((!m_currentTemplateRuleIsNull.isEmpty()) && (m_currentTemplateRuleIsNull.peek() == true)); }
Push true if the current template rule is null, false otherwise.
Params:
  • b – True if the we are executing an xsl:for-each (or xsl:call-template?).
/** * Push true if the current template rule is null, false * otherwise. * * @param b True if the we are executing an xsl:for-each * (or xsl:call-template?). */
public void pushCurrentTemplateRuleIsNull(boolean b) { m_currentTemplateRuleIsNull.push(b); }
Push true if the current template rule is null, false otherwise.
/** * Push true if the current template rule is null, false * otherwise. */
public void popCurrentTemplateRuleIsNull() { m_currentTemplateRuleIsNull.pop(); }
Push a funcion result for the currently active EXSLT func:function.
Params:
  • val – the result of executing an EXSLT func:result instruction for the current func:function.
/** * Push a funcion result for the currently active EXSLT * <code>func:function</code>. * * @param val the result of executing an EXSLT * <code>func:result</code> instruction for the current * <code>func:function</code>. */
public void pushCurrentFuncResult(Object val) { m_currentFuncResult.push(val); }
Pops the result of the currently active EXSLT func:function.
Returns:the value of the func:function
/** * Pops the result of the currently active EXSLT <code>func:function</code>. * * @return the value of the <code>func:function</code> */
public Object popCurrentFuncResult() { return m_currentFuncResult.pop(); }
Determines whether an EXSLT func:result instruction has been executed for the currently active EXSLT func:function.
Returns:true if and only if a func:result instruction has been executed
/** * Determines whether an EXSLT <code>func:result</code> instruction has been * executed for the currently active EXSLT <code>func:function</code>. * * @return <code>true</code> if and only if a <code>func:result</code> * instruction has been executed */
public boolean currentFuncResultSeen() { return !m_currentFuncResult.empty() && m_currentFuncResult.peek() != null; }
Return the message manager.
Returns:The message manager, never null.
/** * Return the message manager. * * @return The message manager, never null. */
public MsgMgr getMsgMgr() { if (null == m_msgMgr) m_msgMgr = new MsgMgr(this); return m_msgMgr; }
Set the error event listener.
Params:
  • listener – The new error listener.
Throws:
/** * Set the error event listener. * * @param listener The new error listener. * @throws IllegalArgumentException if */
public void setErrorListener(ErrorListener listener) throws IllegalArgumentException { synchronized (m_reentryGuard) { if (listener == null) throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_ERROR_HANDLER, null)); //"Null error handler"); m_errorHandler = listener; } }
Get the current error event handler.
Returns:The current error handler, which should never be null.
/** * Get the current error event handler. * * @return The current error handler, which should never be null. */
public ErrorListener getErrorListener() { return m_errorHandler; }
Get an instance of the trace manager for this transformation. This object can be used to set trace listeners on various events during the transformation.
Returns:A reference to the TraceManager, never null.
/** * Get an instance of the trace manager for this transformation. * This object can be used to set trace listeners on various * events during the transformation. * * @return A reference to the TraceManager, never null. */
public TraceManager getTraceManager() { return m_traceManager; }
Look up the value of a feature.

The feature name is any fully-qualified URI. It is possible for an TransformerFactory to recognize a feature name but to be unable to return its value; this is especially true in the case of an adapter for a SAX1 Parser, which has no way of knowing whether the underlying parser is validating, for example.

Open issues:

Should getFeature be changed to hasFeature?

Keith Visco writes: Should getFeature be changed to hasFeature? It returns a boolean which indicated whether the "state" of feature is "true or false". I assume this means whether or not a feature is supported? I know SAX is using "getFeature", but to me "hasFeature" is cleaner.
Params:
  • name – The feature name, which is a fully-qualified URI.
Throws:
Returns:The current state of the feature (true or false).
/** * Look up the value of a feature. * * <p>The feature name is any fully-qualified URI. It is * possible for an TransformerFactory to recognize a feature name but * to be unable to return its value; this is especially true * in the case of an adapter for a SAX1 Parser, which has * no way of knowing whether the underlying parser is * validating, for example.</p> * * <h3>Open issues:</h3> * <dl> * <dt><h4>Should getFeature be changed to hasFeature?</h4></dt> * <dd>Keith Visco writes: Should getFeature be changed to hasFeature? * It returns a boolean which indicated whether the "state" * of feature is "true or false". I assume this means whether * or not a feature is supported? I know SAX is using "getFeature", * but to me "hasFeature" is cleaner.</dd> * </dl> * * @param name The feature name, which is a fully-qualified * URI. * @return The current state of the feature (true or false). * @throws org.xml.sax.SAXNotRecognizedException When the * TransformerFactory does not recognize the feature name. * @throws org.xml.sax.SAXNotSupportedException When the * TransformerFactory recognizes the feature name but * cannot determine its value at this time. * * @throws SAXNotRecognizedException * @throws SAXNotSupportedException */
public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { if ("http://xml.org/trax/features/sax/input".equals(name)) return true; else if ("http://xml.org/trax/features/dom/input".equals(name)) return true; throw new SAXNotRecognizedException(name); } // %TODO% Doc
NEEDSDOC Method getMode NEEDSDOC (getMode) @return
/** * NEEDSDOC Method getMode * * * NEEDSDOC (getMode) @return */
public QName getMode() { return m_modes.isEmpty() ? null : (QName) m_modes.peek(); } // %TODO% Doc
NEEDSDOC Method pushMode NEEDSDOC @param mode
/** * NEEDSDOC Method pushMode * * * NEEDSDOC @param mode */
public void pushMode(QName mode) { m_modes.push(mode); } // %TODO% Doc
NEEDSDOC Method popMode
/** * NEEDSDOC Method popMode * */
public void popMode() { m_modes.pop(); }
Called by SourceTreeHandler to start the transformation in a separate thread NEEDSDOC @param priority
/** * Called by SourceTreeHandler to start the transformation * in a separate thread * * NEEDSDOC @param priority */
public void runTransformThread(int priority) { // used in SourceTreeHandler Thread t = ThreadControllerWrapper.runThread(this, priority); this.setTransformThread(t); }
Called by this.transform() if isParserEventsOnMain()==false. Similar with runTransformThread(), but no priority is set and setTransformThread is not set.
/** * Called by this.transform() if isParserEventsOnMain()==false. * Similar with runTransformThread(), but no priority is set * and setTransformThread is not set. */
public void runTransformThread() { ThreadControllerWrapper.runThread(this, -1); }
Called by CoRoutineSAXParser. Launches the CoroutineSAXParser in a thread, and prepares it to invoke the parser from that thread upon request.
/** * Called by CoRoutineSAXParser. Launches the CoroutineSAXParser * in a thread, and prepares it to invoke the parser from that thread * upon request. * */
public static void runTransformThread(Runnable runnable) { ThreadControllerWrapper.runThread(runnable, -1); }
Used by SourceTreeHandler to wait until the transform completes
Throws:
  • SAXException –
/** * Used by SourceTreeHandler to wait until the transform * completes * * @throws SAXException */
public void waitTransformThread() throws SAXException { // This is called to make sure the task is done. // It is possible that the thread has been reused - // but for a different transformation. ( what if we // recycle the transformer ? Not a problem since this is // still in use. ) Thread transformThread = this.getTransformThread(); if (null != transformThread) { try { ThreadControllerWrapper.waitThread(transformThread, this); if (!this.hasTransformThreadErrorCatcher()) { Exception e = this.getExceptionThrown(); if (null != e) { e.printStackTrace(); throw new org.xml.sax.SAXException(e); } } this.setTransformThread(null); } catch (InterruptedException ie){} } }
Get the exception thrown by the secondary thread (normally the transform thread).
Returns:The thrown exception, or null if no exception was thrown.
/** * Get the exception thrown by the secondary thread (normally * the transform thread). * * @return The thrown exception, or null if no exception was * thrown. */
public Exception getExceptionThrown() { return m_exceptionThrown; }
Set the exception thrown by the secondary thread (normally the transform thread).
Params:
  • e – The thrown exception, or null if no exception was thrown.
/** * Set the exception thrown by the secondary thread (normally * the transform thread). * * @param e The thrown exception, or null if no exception was * thrown. */
public void setExceptionThrown(Exception e) { m_exceptionThrown = e; }
This is just a way to set the document for run().
Params:
  • doc – A non-null reference to the root of the tree to be transformed.
/** * This is just a way to set the document for run(). * * @param doc A non-null reference to the root of the * tree to be transformed. */
public void setSourceTreeDocForThread(int doc) { m_doc = doc; }
Set the input source for the source tree, which is needed if the parse thread is not the main thread, in order for the parse thread's run method to get to the input source.
Params:
  • source – The input source for the source tree.
/** * Set the input source for the source tree, which is needed if the * parse thread is not the main thread, in order for the parse * thread's run method to get to the input source. * * @param source The input source for the source tree. */
public void setXMLSource(Source source) { m_xmlSource = source; }
Tell if the transform method is completed.
Returns:True if transformNode has completed, or an exception was thrown.
/** * Tell if the transform method is completed. * * @return True if transformNode has completed, or * an exception was thrown. */
public boolean isTransformDone() { synchronized (this) { return m_isTransformDone; } }
Set if the transform method is completed.
Params:
  • done – True if transformNode has completed, or an exception was thrown.
/** * Set if the transform method is completed. * * @param done True if transformNode has completed, or * an exception was thrown. */
public void setIsTransformDone(boolean done) { synchronized (this) { m_isTransformDone = done; } }
From a secondary thread, post the exception, so that it can be picked up from the main thread.
Params:
  • e – The exception that was thrown.
/** * From a secondary thread, post the exception, so that * it can be picked up from the main thread. * * @param e The exception that was thrown. */
void postExceptionFromThread(Exception e) { // Commented out in response to problem reported by Nicola Brown <Nicola.Brown@jacobsrimell.com> // if(m_reportInPostExceptionFromThread) // { // // Consider re-throwing the exception if this flag is set. // e.printStackTrace(); // } // %REVIEW Need DTM equivelent? // if (m_inputContentHandler instanceof SourceTreeHandler) // { // SourceTreeHandler sth = (SourceTreeHandler) m_inputContentHandler; // // sth.setExceptionThrown(e); // } // ContentHandler ch = getContentHandler(); // if(ch instanceof SourceTreeHandler) // { // SourceTreeHandler sth = (SourceTreeHandler) ch; // ((TransformerImpl)(sth.getTransformer())).postExceptionFromThread(e); // } m_isTransformDone = true; m_exceptionThrown = e; ; // should have already been reported via the error handler? synchronized (this) { // See message from me on 3/27/2001 to Patrick Moore. // String msg = e.getMessage(); // System.out.println(e.getMessage()); // Is this really needed? -sb notifyAll(); // if (null == msg) // { // // // m_throwNewError = false; // e.printStackTrace(); // } // throw new org.apache.xml.utils.WrappedRuntimeException(e); } }
Run the transform thread.
/** * Run the transform thread. */
public void run() { m_hasBeenReset = false; try { // int n = ((SourceTreeHandler)getInputContentHandler()).getDTMRoot(); // transformNode(n); try { m_isTransformDone = false; // Should no longer be needed... // if(m_inputContentHandler instanceof TransformerHandlerImpl) // { // TransformerHandlerImpl thi = (TransformerHandlerImpl)m_inputContentHandler; // thi.waitForInitialEvents(); // } transformNode(m_doc); } catch (Exception e) { // e.printStackTrace(); // Strange that the other catch won't catch this... if (null != m_transformThread) postExceptionFromThread(e); // Assume we're on the main thread else throw new RuntimeException(e.getMessage()); } finally { m_isTransformDone = true; if (m_inputContentHandler instanceof TransformerHandlerImpl) { ((TransformerHandlerImpl) m_inputContentHandler).clearCoRoutine(); } // synchronized (this) // { // notifyAll(); // } } } catch (Exception e) { // e.printStackTrace(); if (null != m_transformThread) postExceptionFromThread(e); else throw new RuntimeException(e.getMessage()); // Assume we're on the main thread. } } // Fragment re-execution interfaces for a tool.
This will get a snapshot of the current executing context
Returns:TransformSnapshot object, snapshot of executing context
Deprecated:This is an internal tooling API that nobody seems to be using
/** * This will get a snapshot of the current executing context * * * @return TransformSnapshot object, snapshot of executing context * @deprecated This is an internal tooling API that nobody seems to be using */
public TransformSnapshot getSnapshot() { return new TransformSnapshotImpl(this); }
This will execute the following XSLT instructions from the snapshot point, after the stylesheet execution context has been reset from the snapshot point.
Params:
  • ts – The snapshot of where to start execution
Throws:
Deprecated:This is an internal tooling API that nobody seems to be using
/** * This will execute the following XSLT instructions * from the snapshot point, after the stylesheet execution * context has been reset from the snapshot point. * * @param ts The snapshot of where to start execution * * @throws TransformerException * @deprecated This is an internal tooling API that nobody seems to be using */
public void executeFromSnapshot(TransformSnapshot ts) throws TransformerException { ElemTemplateElement template = getMatchedTemplate(); int child = getMatchedNode(); pushElemTemplateElement(template); //needed?? m_xcontext.pushCurrentNode(child); //needed?? this.executeChildTemplates(template, true); // getResultTreeHandler()); }
This will reset the stylesheet execution context from the snapshot point.
Params:
  • ts – The snapshot of where to start execution
Deprecated:This is an internal tooling API that nobody seems to be using
/** * This will reset the stylesheet execution context * from the snapshot point. * * @param ts The snapshot of where to start execution * @deprecated This is an internal tooling API that nobody seems to be using */
public void resetToStylesheet(TransformSnapshot ts) { ((TransformSnapshotImpl) ts).apply(this); }
NEEDSDOC Method stopTransformation
/** * NEEDSDOC Method stopTransformation * */
public void stopTransformation(){}
Test whether whitespace-only text nodes are visible in the logical view of DTM. Normally, this function will be called by the implementation of DTM; it is not normally called directly from user code.
Params:
  • elementHandle – int Handle of the element.
Returns:one of NOTSTRIP, STRIP, or INHERIT.
/** * Test whether whitespace-only text nodes are visible in the logical * view of <code>DTM</code>. Normally, this function * will be called by the implementation of <code>DTM</code>; * it is not normally called directly from * user code. * * @param elementHandle int Handle of the element. * @return one of NOTSTRIP, STRIP, or INHERIT. */
public short getShouldStripSpace(int elementHandle, DTM dtm) { try { org.apache.xalan.templates.WhiteSpaceInfo info = m_stylesheetRoot.getWhiteSpaceInfo(m_xcontext, elementHandle, dtm); if (null == info) { return DTMWSFilter.INHERIT; } else { // System.out.println("getShouldStripSpace: "+info.getShouldStripSpace()); return info.getShouldStripSpace() ? DTMWSFilter.STRIP : DTMWSFilter.NOTSTRIP; } } catch (TransformerException se) { return DTMWSFilter.INHERIT; } }
Initializer method.
Params:
  • transformer – non-null transformer instance
  • realHandler – Content Handler instance
/** * Initializer method. * * @param transformer non-null transformer instance * @param realHandler Content Handler instance */
public void init(ToXMLSAXHandler h,Transformer transformer, ContentHandler realHandler) { h.setTransformer(transformer); h.setContentHandler(realHandler); } public void setSerializationHandler(SerializationHandler xoh) { m_serializationHandler = xoh; }
Fire off characters, cdate events.
See Also:
  • fireGenerateEvent.fireGenerateEvent(int, char[], int, int)
/** * Fire off characters, cdate events. * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, char[], int, int) */
public void fireGenerateEvent( int eventType, char[] ch, int start, int length) { GenerateEvent ge = new GenerateEvent(this, eventType, ch, start, length); m_traceManager.fireGenerateEvent(ge); }
Fire off startElement, endElement events.
See Also:
  • fireGenerateEvent.fireGenerateEvent(int, String, Attributes)
/** * Fire off startElement, endElement events. * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String, Attributes) */
public void fireGenerateEvent( int eventType, String name, Attributes atts) { GenerateEvent ge = new GenerateEvent(this, eventType, name, atts); m_traceManager.fireGenerateEvent(ge); }
Fire off processingInstruction events.
See Also:
  • fireGenerateEvent.fireGenerateEvent(int, String, String)
/** * Fire off processingInstruction events. * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String, String) */
public void fireGenerateEvent(int eventType, String name, String data) { GenerateEvent ge = new GenerateEvent(this, eventType, name,data); m_traceManager.fireGenerateEvent(ge); }
Fire off comment and entity ref events.
See Also:
  • fireGenerateEvent.fireGenerateEvent(int, String)
/** * Fire off comment and entity ref events. * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String) */
public void fireGenerateEvent(int eventType, String data) { GenerateEvent ge = new GenerateEvent(this, eventType, data); m_traceManager.fireGenerateEvent(ge); }
Fire off startDocument, endDocument events.
See Also:
  • fireGenerateEvent.fireGenerateEvent(int)
/** * Fire off startDocument, endDocument events. * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int) */
public void fireGenerateEvent(int eventType) { GenerateEvent ge = new GenerateEvent(this, eventType); m_traceManager.fireGenerateEvent(ge); }
See Also:
  • hasTraceListeners.hasTraceListeners()
/** * @see org.apache.xml.serializer.SerializerTrace#hasTraceListeners() */
public boolean hasTraceListeners() { return m_traceManager.hasTraceListeners(); } public boolean getDebug() { return m_debug; } public void setDebug(boolean b) { m_debug = b; }
Returns:Incremental flag
/** * @return Incremental flag */
public boolean getIncremental() { return m_incremental; }
Returns:Optimization flag
/** * @return Optimization flag */
public boolean getOptimize() { return m_optimizer; }
Returns:Source location flag
/** * @return Source location flag */
public boolean getSource_location() { return m_source_location; } } // end TransformerImpl class