Source Code Cross Referenced for TransformerImpl.java in  » XML » xalan » org » apache » xalan » transformer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xalan » org.apache.xalan.transformer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999-2004 The Apache Software Foundation.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *     http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        /*
0017:         * $Id: TransformerImpl.java,v 1.167 2005/07/15 22:21:30 mcnamara Exp $
0018:         */
0019:        package org.apache.xalan.transformer;
0020:
0021:        import java.io.IOException;
0022:        import java.io.StringWriter;
0023:        import java.util.Enumeration;
0024:        import java.util.Properties;
0025:        import java.util.Stack;
0026:        import java.util.StringTokenizer;
0027:        import java.util.Vector;
0028:
0029:        import javax.xml.parsers.DocumentBuilder;
0030:        import javax.xml.parsers.DocumentBuilderFactory;
0031:        import javax.xml.parsers.ParserConfigurationException;
0032:        import javax.xml.transform.ErrorListener;
0033:        import javax.xml.transform.OutputKeys;
0034:        import javax.xml.transform.Result;
0035:        import javax.xml.transform.Source;
0036:        import javax.xml.transform.SourceLocator;
0037:        import javax.xml.transform.Transformer;
0038:        import javax.xml.transform.TransformerException;
0039:        import javax.xml.transform.URIResolver;
0040:        import javax.xml.transform.dom.DOMResult;
0041:        import javax.xml.transform.dom.DOMSource;
0042:        import javax.xml.transform.sax.SAXResult;
0043:        import javax.xml.transform.sax.SAXSource;
0044:        import javax.xml.transform.stream.StreamResult;
0045:        import javax.xml.transform.stream.StreamSource;
0046:
0047:        import org.apache.xalan.extensions.ExtensionsTable;
0048:        import org.apache.xalan.res.XSLMessages;
0049:        import org.apache.xalan.res.XSLTErrorResources;
0050:        import org.apache.xml.serializer.Method;
0051:        import org.apache.xml.serializer.Serializer;
0052:        import org.apache.xml.serializer.SerializerFactory;
0053:        import org.apache.xalan.templates.AVT;
0054:        import org.apache.xalan.templates.Constants;
0055:        import org.apache.xalan.templates.ElemAttributeSet;
0056:        import org.apache.xalan.templates.ElemForEach;
0057:        import org.apache.xalan.templates.ElemSort;
0058:        import org.apache.xalan.templates.ElemTemplate;
0059:        import org.apache.xalan.templates.ElemTemplateElement;
0060:        import org.apache.xalan.templates.ElemTextLiteral;
0061:        import org.apache.xalan.templates.ElemVariable;
0062:        import org.apache.xalan.templates.OutputProperties;
0063:        import org.apache.xalan.templates.Stylesheet;
0064:        import org.apache.xalan.templates.StylesheetComposed;
0065:        import org.apache.xalan.templates.StylesheetRoot;
0066:        import org.apache.xalan.templates.XUnresolvedVariable;
0067:        import org.apache.xalan.trace.GenerateEvent;
0068:        import org.apache.xalan.trace.TraceManager;
0069:        import org.apache.xml.dtm.DTM;
0070:        import org.apache.xml.dtm.DTMIterator;
0071:        import org.apache.xml.dtm.DTMManager;
0072:        import org.apache.xml.dtm.DTMWSFilter;
0073:        import org.apache.xml.serializer.ToHTMLSAXHandler;
0074:        import org.apache.xml.serializer.ToSAXHandler;
0075:        import org.apache.xml.serializer.ToTextSAXHandler;
0076:        import org.apache.xml.serializer.ToTextStream;
0077:        import org.apache.xml.serializer.ToXMLSAXHandler;
0078:        import org.apache.xml.serializer.SerializationHandler;
0079:        import org.apache.xml.utils.BoolStack;
0080:        import org.apache.xml.utils.DOMBuilder;
0081:        import org.apache.xml.utils.NodeVector;
0082:        import org.apache.xml.utils.ObjectPool;
0083:        import org.apache.xml.utils.ObjectStack;
0084:        import org.apache.xml.utils.QName;
0085:        import org.apache.xml.utils.SAXSourceLocator;
0086:        import org.apache.xml.utils.ThreadControllerWrapper;
0087:        import org.apache.xpath.Arg;
0088:        import org.apache.xpath.ExtensionsProvider;
0089:        import org.apache.xpath.VariableStack;
0090:        import org.apache.xpath.XPathContext;
0091:        import org.apache.xpath.functions.FuncExtFunction;
0092:        import org.apache.xpath.objects.XObject;
0093:        import org.xml.sax.Attributes;
0094:        import org.xml.sax.ContentHandler;
0095:        import org.xml.sax.SAXException;
0096:        import org.xml.sax.SAXNotRecognizedException;
0097:        import org.xml.sax.SAXNotSupportedException;
0098:        import org.xml.sax.ext.DeclHandler;
0099:        import org.xml.sax.ext.LexicalHandler;
0100:
0101:        /**
0102:         * This class implements the
0103:         * {@link javax.xml.transform.Transformer} interface, and is the core
0104:         * representation of the transformation execution.</p>
0105:         * @xsl.usage advanced
0106:         */
0107:        public class TransformerImpl extends Transformer implements  Runnable,
0108:                DTMWSFilter, ExtensionsProvider,
0109:                org.apache.xml.serializer.SerializerTrace {
0110:
0111:            // Synch object to gaurd against setting values from the TrAX interface 
0112:            // or reentry while the transform is going on.
0113:
0114:            /** NEEDSDOC Field m_reentryGuard          */
0115:            private Boolean m_reentryGuard = new Boolean(true);
0116:
0117:            /**
0118:             * This is null unless we own the stream.
0119:             */
0120:            private java.io.FileOutputStream m_outputStream = null;
0121:
0122:            /**
0123:             * True if the parser events should be on the main thread,
0124:             * false if not.  Experemental.  Can not be set right now.
0125:             */
0126:            private boolean m_parserEventsOnMain = true;
0127:
0128:            /** The thread that the transformer is running on. */
0129:            private Thread m_transformThread;
0130:
0131:            /** The base URL of the source tree. */
0132:            private String m_urlOfSource = null;
0133:
0134:            /** The Result object at the start of the transform, if any. */
0135:            private Result m_outputTarget = null;
0136:
0137:            /**
0138:             * The output format object set by the user.  May be null.
0139:             */
0140:            private OutputProperties m_outputFormat;
0141:
0142:            /**
0143:             * The content handler for the source input tree.
0144:             */
0145:            ContentHandler m_inputContentHandler;
0146:
0147:            /**
0148:             * The content handler for the result tree.
0149:             */
0150:            private ContentHandler m_outputContentHandler = null;
0151:
0152:            //  /*
0153:            //   * Use member variable to store param variables as they're
0154:            //   * being created, use member variable so we don't
0155:            //   * have to create a new vector every time.
0156:            //   */
0157:            //  private Vector m_newVars = new Vector();
0158:
0159:            /** The JAXP Document Builder, mainly to create Result Tree Fragments. */
0160:            DocumentBuilder m_docBuilder = null;
0161:
0162:            /**
0163:             * A pool of ResultTreeHandlers, for serialization of a subtree to text.
0164:             *  Please note that each of these also holds onto a Text Serializer.  
0165:             */
0166:            private ObjectPool m_textResultHandlerObjectPool = new ObjectPool(
0167:                    ToTextStream.class);
0168:
0169:            /**
0170:             * Related to m_textResultHandlerObjectPool, this is a pool of
0171:             * StringWriters, which are passed to the Text Serializers.
0172:             * (I'm not sure if this is really needed any more.  -sb)      
0173:             */
0174:            private ObjectPool m_stringWriterObjectPool = new ObjectPool(
0175:                    StringWriter.class);
0176:
0177:            /**
0178:             * A static text format object, which can be used over and
0179:             * over to create the text serializers.    
0180:             */
0181:            private OutputProperties m_textformat = new OutputProperties(
0182:                    Method.TEXT);
0183:
0184:            // Commenteded out in response to problem reported by 
0185:            // Nicola Brown <Nicola.Brown@jacobsrimell.com>
0186:            //  /**
0187:            //   * Flag to let us know if an exception should be reported inside the 
0188:            //   * postExceptionFromThread method.  This is needed if the transform is 
0189:            //   * being generated from SAX events, and thus there is no central place 
0190:            //   * to report the exception from.  (An exception is usually picked up in 
0191:            //   * the main thread from the transform thread in {@link #transform(Source source)} 
0192:            //   * from {@link #getExceptionThrown()}. )
0193:            //   */
0194:            //  private boolean m_reportInPostExceptionFromThread = false;
0195:
0196:            /**
0197:             * A node vector used as a stack to track the current
0198:             * ElemTemplateElement.  Needed for the
0199:             * org.apache.xalan.transformer.TransformState interface,
0200:             * so a tool can discover the calling template. Note the use of an array 
0201:             * for this limits the recursion depth to 4K.
0202:             */
0203:            ObjectStack m_currentTemplateElements = new ObjectStack(
0204:                    XPathContext.RECURSIONLIMIT);
0205:
0206:            /** The top of the currentTemplateElements stack. */
0207:            //int m_currentTemplateElementsTop = 0;
0208:            /**
0209:             * A node vector used as a stack to track the current
0210:             * ElemTemplate that was matched.
0211:             * Needed for the
0212:             * org.apache.xalan.transformer.TransformState interface,
0213:             * so a tool can discover the matched template
0214:             */
0215:            Stack m_currentMatchTemplates = new Stack();
0216:
0217:            /**
0218:             * A node vector used as a stack to track the current
0219:             * node that was matched.
0220:             * Needed for the
0221:             * org.apache.xalan.transformer.TransformState interface,
0222:             * so a tool can discover the matched
0223:             * node. 
0224:             */
0225:            NodeVector m_currentMatchedNodes = new NodeVector();
0226:
0227:            /**
0228:             * The root of a linked set of stylesheets.
0229:             */
0230:            private StylesheetRoot m_stylesheetRoot = null;
0231:
0232:            /**
0233:             * If this is set to true, do not warn about pattern
0234:             * match conflicts.
0235:             */
0236:            private boolean m_quietConflictWarnings = true;
0237:
0238:            /**
0239:             * The liason to the XML parser, so the XSL processor
0240:             * can handle included files, and the like, and do the
0241:             * initial parse of the XSL document.
0242:             */
0243:            private XPathContext m_xcontext;
0244:
0245:            /**
0246:             * Object to guard agains infinite recursion when
0247:             * doing queries.
0248:             */
0249:            private StackGuard m_stackGuard;
0250:
0251:            /**
0252:             * Output handler to bottleneck SAX events.
0253:             */
0254:            private SerializationHandler m_serializationHandler;
0255:
0256:            /** The key manager, which manages xsl:keys. */
0257:            private KeyManager m_keyManager = new KeyManager();
0258:
0259:            /**
0260:             * Stack for the purposes of flagging infinite recursion with
0261:             * attribute sets.
0262:             */
0263:            Stack m_attrSetStack = null;
0264:
0265:            /**
0266:             * The table of counters for xsl:number support.
0267:             * @see ElemNumber
0268:             */
0269:            CountersTable m_countersTable = null;
0270:
0271:            /**
0272:             * Is > 0 when we're processing a for-each.
0273:             */
0274:            BoolStack m_currentTemplateRuleIsNull = new BoolStack();
0275:
0276:            /**
0277:             * Keeps track of the result delivered by any EXSLT <code>func:result</code>
0278:             * instruction that has been executed for the currently active EXSLT
0279:             * <code>func:function</code>
0280:             */
0281:            ObjectStack m_currentFuncResult = new ObjectStack();
0282:
0283:            /**
0284:             * The message manager, which manages error messages, warning
0285:             * messages, and other types of message events.   
0286:             */
0287:            private MsgMgr m_msgMgr;
0288:
0289:            /**
0290:             * The flag for the setting of the optimize feature;
0291:             * This flag should have the same value as the FEATURE_OPTIMIZE feature
0292:             * which is set by the TransformerFactory.setAttribut() method before a
0293:             * Transformer is created
0294:             */
0295:            private boolean m_optimizer = true;
0296:
0297:            /**
0298:             * The flag for the setting of the incremental feature;
0299:             * This flag should have the same value as the FEATURE_INCREMENTAL feature
0300:             * which is set by the TransformerFactory.setAttribut() method before a
0301:             * Transformer is created
0302:             */
0303:            private boolean m_incremental = false;
0304:
0305:            /**
0306:             * The flag for the setting of the source_location feature;
0307:             * This flag should have the same value as the FEATURE_SOURCE_LOCATION feature
0308:             * which is set by the TransformerFactory.setAttribut() method before a
0309:             * Transformer is created
0310:             */
0311:            private boolean m_source_location = false;
0312:
0313:            /**
0314:             * This is a compile-time flag to turn off calling
0315:             * of trace listeners. Set this to false for optimization purposes.
0316:             */
0317:            private boolean m_debug = false;
0318:
0319:            /**
0320:             * The SAX error handler, where errors and warnings are sent.
0321:             */
0322:            private ErrorListener m_errorHandler = new org.apache.xml.utils.DefaultErrorHandler(
0323:                    false);
0324:
0325:            /**
0326:             * The trace manager.
0327:             */
0328:            private TraceManager m_traceManager = new TraceManager(this );
0329:
0330:            /**
0331:             * If the transform thread throws an exception, the exception needs to
0332:             * be stashed away so that the main thread can pass it on to the
0333:             * client. 
0334:             */
0335:            private Exception m_exceptionThrown = null;
0336:
0337:            /**
0338:             * The InputSource for the source tree, which is needed if the
0339:             * parse thread is not the main thread, in order for the parse
0340:             * thread's run method to get to the input source.
0341:             * (Delete this if reversing threads is outlawed. -sb)    
0342:             */
0343:            private Source m_xmlSource;
0344:
0345:            /**
0346:             * This is needed for support of setSourceTreeDocForThread(Node doc),
0347:             * which must be called in order for the transform thread's run
0348:             * method to obtain the root of the source tree to be transformed.     
0349:             */
0350:            private int m_doc;
0351:
0352:            /**
0353:             * If the the transform is on the secondary thread, we
0354:             * need to know when it is done, so we can return.
0355:             */
0356:            private boolean m_isTransformDone = false;
0357:
0358:            /** Flag to to tell if the tranformer needs to be reset. */
0359:            private boolean m_hasBeenReset = false;
0360:
0361:            /** NEEDSDOC Field m_shouldReset          */
0362:            private boolean m_shouldReset = true;
0363:
0364:            /**
0365:             * NEEDSDOC Method setShouldReset 
0366:             *
0367:             *
0368:             * NEEDSDOC @param shouldReset
0369:             */
0370:            public void setShouldReset(boolean shouldReset) {
0371:                m_shouldReset = shouldReset;
0372:            }
0373:
0374:            /**
0375:             * A stack of current template modes.
0376:             */
0377:            private Stack m_modes = new Stack();
0378:
0379:            //==========================================================
0380:            // SECTION: Constructor
0381:            //==========================================================
0382:
0383:            /**
0384:             * Construct a TransformerImpl.
0385:             *
0386:             * @param stylesheet The root of the stylesheet tree.
0387:             */
0388:            public TransformerImpl(StylesheetRoot stylesheet)
0389:            // throws javax.xml.transform.TransformerException    
0390:            {
0391:                m_optimizer = stylesheet.getOptimizer();
0392:                m_incremental = stylesheet.getIncremental();
0393:                m_source_location = stylesheet.getSource_location();
0394:                setStylesheet(stylesheet);
0395:                XPathContext xPath = new XPathContext(this );
0396:                xPath.setIncremental(m_incremental);
0397:                xPath.getDTMManager().setIncremental(m_incremental);
0398:                xPath.setSource_location(m_source_location);
0399:                xPath.getDTMManager().setSource_location(m_source_location);
0400:
0401:                if (stylesheet.isSecureProcessing())
0402:                    xPath.setSecureProcessing(true);
0403:
0404:                setXPathContext(xPath);
0405:                getXPathContext().setNamespaceContext(stylesheet);
0406:                m_stackGuard = new StackGuard(this );
0407:            }
0408:
0409:            // ================ ExtensionsTable ===================
0410:
0411:            /**
0412:             * The table of ExtensionHandlers.
0413:             */
0414:            private ExtensionsTable m_extensionsTable = null;
0415:
0416:            /**
0417:             * Get the extensions table object. 
0418:             *
0419:             * @return The extensions table.
0420:             */
0421:            public ExtensionsTable getExtensionsTable() {
0422:                return m_extensionsTable;
0423:            }
0424:
0425:            /**
0426:             * If the stylesheet contains extensions, set the extensions table object.
0427:             *
0428:             *
0429:             * @param sroot The stylesheet.
0430:             * @throws javax.xml.transform.TransformerException
0431:             */
0432:            void setExtensionsTable(StylesheetRoot sroot)
0433:                    throws javax.xml.transform.TransformerException {
0434:                try {
0435:                    if (sroot.getExtensions() != null)
0436:                        m_extensionsTable = new ExtensionsTable(sroot);
0437:                } catch (javax.xml.transform.TransformerException te) {
0438:                    te.printStackTrace();
0439:                }
0440:            }
0441:
0442:            //== Implementation of the XPath ExtensionsProvider interface.
0443:
0444:            public boolean functionAvailable(String ns, String funcName)
0445:                    throws javax.xml.transform.TransformerException {
0446:                return getExtensionsTable().functionAvailable(ns, funcName);
0447:            }
0448:
0449:            public boolean elementAvailable(String ns, String elemName)
0450:                    throws javax.xml.transform.TransformerException {
0451:                return getExtensionsTable().elementAvailable(ns, elemName);
0452:            }
0453:
0454:            public Object extFunction(String ns, String funcName,
0455:                    Vector argVec, Object methodKey)
0456:                    throws javax.xml.transform.TransformerException {//System.out.println("TransImpl.extFunction() " + ns + " " + funcName +" " + getExtensionsTable());
0457:                return getExtensionsTable().extFunction(ns, funcName, argVec,
0458:                        methodKey, getXPathContext().getExpressionContext());
0459:            }
0460:
0461:            public Object extFunction(FuncExtFunction extFunction, Vector argVec)
0462:                    throws javax.xml.transform.TransformerException {
0463:                return getExtensionsTable().extFunction(extFunction, argVec,
0464:                        getXPathContext().getExpressionContext());
0465:            }
0466:
0467:            //=========================
0468:
0469:            /**
0470:             * Reset the state.  This needs to be called after a process() call
0471:             * is invoked, if the processor is to be used again.
0472:             */
0473:            public void reset() {
0474:
0475:                if (!m_hasBeenReset && m_shouldReset) {
0476:                    m_hasBeenReset = true;
0477:
0478:                    if (this .m_outputStream != null) {
0479:                        try {
0480:                            m_outputStream.close();
0481:                        } catch (java.io.IOException ioe) {
0482:                        }
0483:                    }
0484:
0485:                    m_outputStream = null;
0486:
0487:                    // I need to look more carefully at which of these really
0488:                    // needs to be reset.
0489:                    m_countersTable = null;
0490:
0491:                    m_xcontext.reset();
0492:
0493:                    m_xcontext.getVarStack().reset();
0494:                    resetUserParameters();
0495:
0496:                    m_currentTemplateElements.removeAllElements();
0497:                    m_currentMatchTemplates.removeAllElements();
0498:                    m_currentMatchedNodes.removeAllElements();
0499:
0500:                    m_serializationHandler = null;
0501:                    m_outputTarget = null;
0502:                    m_keyManager = new KeyManager();
0503:                    m_attrSetStack = null;
0504:                    m_countersTable = null;
0505:                    m_currentTemplateRuleIsNull = new BoolStack();
0506:                    m_xmlSource = null;
0507:                    m_doc = DTM.NULL;
0508:                    m_isTransformDone = false;
0509:                    m_transformThread = null;
0510:
0511:                    // m_inputContentHandler = null;
0512:                    // For now, reset the document cache each time.
0513:                    m_xcontext.getSourceTreeManager().reset();
0514:                }
0515:
0516:                //    m_reportInPostExceptionFromThread = false;
0517:            }
0518:
0519:            /**
0520:             * <code>getProperty</code> returns the current setting of the
0521:             * property described by the <code>property</code> argument.
0522:             *
0523:             * %REVIEW% Obsolete now that source_location is handled in the TransformerFactory?
0524:             *
0525:             * @param property a <code>String</code> value
0526:             * @return a <code>boolean</code> value
0527:             */
0528:            public boolean getProperty(String property) {
0529:                return false;
0530:            }
0531:
0532:            /**
0533:             * Set a runtime property for this <code>TransformerImpl</code>.
0534:             *
0535:             * %REVIEW% Obsolete now that source_location is handled in the TransformerFactory?
0536:             *
0537:             * @param property a <code>String</code> value
0538:             * @param value an <code>Object</code> value
0539:             */
0540:            public void setProperty(String property, Object value) {
0541:            }
0542:
0543:            // ========= Transformer Interface Implementation ==========
0544:
0545:            /**
0546:             * Get true if the parser events should be on the main thread,
0547:             * false if not.  Experimental.  Can not be set right now.
0548:             *
0549:             * @return true if the parser events should be on the main thread,
0550:             * false if not.
0551:             * @xsl.usage experimental
0552:             */
0553:            public boolean isParserEventsOnMain() {
0554:                return m_parserEventsOnMain;
0555:            }
0556:
0557:            /**
0558:             * Get the thread that the transform process is on.
0559:             *
0560:             * @return The thread that the transform process is on, or null.
0561:             * @xsl.usage internal
0562:             */
0563:            public Thread getTransformThread() {
0564:                return m_transformThread;
0565:            }
0566:
0567:            /**
0568:             * Get the thread that the transform process is on.
0569:             *
0570:             * @param t The transform thread, may be null.
0571:             * @xsl.usage internal
0572:             */
0573:            public void setTransformThread(Thread t) {
0574:                m_transformThread = t;
0575:            }
0576:
0577:            /** NEEDSDOC Field m_hasTransformThreadErrorCatcher          */
0578:            private boolean m_hasTransformThreadErrorCatcher = false;
0579:
0580:            /**
0581:             * Return true if the transform was initiated from the transform method,
0582:             * otherwise it was probably done from a pure parse events.
0583:             *
0584:             * NEEDSDOC ($objectName$) @return
0585:             */
0586:            public boolean hasTransformThreadErrorCatcher() {
0587:                return m_hasTransformThreadErrorCatcher;
0588:            }
0589:
0590:            /**
0591:             * Process the source tree to SAX parse events.
0592:             * @param source  The input for the source tree.
0593:             *
0594:             * @throws TransformerException
0595:             */
0596:            public void transform(Source source) throws TransformerException {
0597:                transform(source, true);
0598:            }
0599:
0600:            /**
0601:             * Process the source tree to SAX parse events.
0602:             * @param source  The input for the source tree.
0603:             * @param shouldRelease  Flag indicating whether to release DTMManager.
0604:             *
0605:             * @throws TransformerException
0606:             */
0607:            public void transform(Source source, boolean shouldRelease)
0608:                    throws TransformerException {
0609:
0610:                try {
0611:
0612:                    // Patch for bugzilla #13863.  If we don't reset the namespaceContext
0613:                    // then we will get a NullPointerException if transformer is reused 
0614:                    // (for stylesheets that use xsl:key).  Not sure if this should go 
0615:                    // here or in reset(). -is  
0616:                    if (getXPathContext().getNamespaceContext() == null) {
0617:                        getXPathContext().setNamespaceContext(getStylesheet());
0618:                    }
0619:                    String base = source.getSystemId();
0620:
0621:                    // If no systemID of the source, use the base of the stylesheet.
0622:                    if (null == base) {
0623:                        base = m_stylesheetRoot.getBaseIdentifier();
0624:                    }
0625:
0626:                    // As a last resort, use the current user dir.
0627:                    if (null == base) {
0628:                        String currentDir = "";
0629:                        try {
0630:                            currentDir = System.getProperty("user.dir");
0631:                        } catch (SecurityException se) {
0632:                        }// user.dir not accessible from applet
0633:
0634:                        if (currentDir.startsWith(java.io.File.separator))
0635:                            base = "file://" + currentDir;
0636:                        else
0637:                            base = "file:///" + currentDir;
0638:
0639:                        base = base + java.io.File.separatorChar
0640:                                + source.getClass().getName();
0641:                    }
0642:                    setBaseURLOfSource(base);
0643:                    DTMManager mgr = m_xcontext.getDTMManager();
0644:                    /*
0645:                     * According to JAXP1.2, new SAXSource()/StreamSource()
0646:                     * should create an empty input tree, with a default root node. 
0647:                     * new DOMSource()creates an empty document using DocumentBuilder.
0648:                     * newDocument(); Use DocumentBuilder.newDocument() for all 3 situations,
0649:                     * since there is no clear spec. how to create an empty tree when
0650:                     * both SAXSource() and StreamSource() are used.
0651:                     */
0652:                    if ((source instanceof  StreamSource
0653:                            && source.getSystemId() == null
0654:                            && ((StreamSource) source).getInputStream() == null && ((StreamSource) source)
0655:                            .getReader() == null)
0656:                            || (source instanceof  SAXSource
0657:                                    && ((SAXSource) source).getInputSource() == null && ((SAXSource) source)
0658:                                    .getXMLReader() == null)
0659:                            || (source instanceof  DOMSource && ((DOMSource) source)
0660:                                    .getNode() == null)) {
0661:                        try {
0662:                            DocumentBuilderFactory builderF = DocumentBuilderFactory
0663:                                    .newInstance();
0664:                            DocumentBuilder builder = builderF
0665:                                    .newDocumentBuilder();
0666:                            String systemID = source.getSystemId();
0667:                            source = new DOMSource(builder.newDocument());
0668:
0669:                            // Copy system ID from original, empty Source to new Source
0670:                            if (systemID != null) {
0671:                                source.setSystemId(systemID);
0672:                            }
0673:                        } catch (ParserConfigurationException e) {
0674:                            fatalError(e);
0675:                        }
0676:                    }
0677:                    DTM dtm = mgr.getDTM(source, false, this , true, true);
0678:                    dtm.setDocumentBaseURI(base);
0679:
0680:                    boolean hardDelete = true; // %REVIEW% I have to think about this. -sb
0681:
0682:                    try {
0683:                        // NOTE: This will work because this is _NOT_ a shared DTM, and thus has
0684:                        // only a single Document node. If it could ever be an RTF or other
0685:                        // shared DTM, look at dtm.getDocumentRoot(nodeHandle).
0686:                        this .transformNode(dtm.getDocument());
0687:                    } finally {
0688:                        if (shouldRelease)
0689:                            mgr.release(dtm, hardDelete);
0690:                    }
0691:
0692:                    // Kick off the parse.  When the ContentHandler gets 
0693:                    // the startDocument event, it will call transformNode( node ).
0694:                    // reader.parse( xmlSource );
0695:                    // This has to be done to catch exceptions thrown from 
0696:                    // the transform thread spawned by the STree handler.
0697:                    Exception e = getExceptionThrown();
0698:
0699:                    if (null != e) {
0700:                        if (e instanceof  javax.xml.transform.TransformerException) {
0701:                            throw (javax.xml.transform.TransformerException) e;
0702:                        } else if (e instanceof  org.apache.xml.utils.WrappedRuntimeException) {
0703:                            fatalError(((org.apache.xml.utils.WrappedRuntimeException) e)
0704:                                    .getException());
0705:                        } else {
0706:                            throw new javax.xml.transform.TransformerException(
0707:                                    e);
0708:                        }
0709:                    } else if (null != m_serializationHandler) {
0710:                        m_serializationHandler.endDocument();
0711:                    }
0712:                } catch (org.apache.xml.utils.WrappedRuntimeException wre) {
0713:                    Throwable throwable = wre.getException();
0714:
0715:                    while (throwable instanceof  org.apache.xml.utils.WrappedRuntimeException) {
0716:                        throwable = ((org.apache.xml.utils.WrappedRuntimeException) throwable)
0717:                                .getException();
0718:                    }
0719:
0720:                    fatalError(throwable);
0721:                }
0722:
0723:                // Patch attributed to David Eisenberg <david@catcode.com>
0724:                catch (org.xml.sax.SAXParseException spe) {
0725:                    fatalError(spe);
0726:                } catch (org.xml.sax.SAXException se) {
0727:                    m_errorHandler.fatalError(new TransformerException(se));
0728:                } finally {
0729:                    m_hasTransformThreadErrorCatcher = false;
0730:
0731:                    // This looks to be redundent to the one done in TransformNode.
0732:                    reset();
0733:                }
0734:            }
0735:
0736:            private void fatalError(Throwable throwable)
0737:                    throws TransformerException {
0738:                if (throwable instanceof  org.xml.sax.SAXParseException)
0739:                    m_errorHandler
0740:                            .fatalError(new TransformerException(throwable
0741:                                    .getMessage(), new SAXSourceLocator(
0742:                                    (org.xml.sax.SAXParseException) throwable)));
0743:                else
0744:                    m_errorHandler.fatalError(new TransformerException(
0745:                            throwable));
0746:
0747:            }
0748:
0749:            /**
0750:             * Get the base URL of the source.
0751:             *
0752:             * @return The base URL of the source tree, or null.
0753:             */
0754:            public String getBaseURLOfSource() {
0755:                return m_urlOfSource;
0756:            }
0757:
0758:            /**
0759:             * Get the base URL of the source.
0760:             *
0761:             *
0762:             * NEEDSDOC @param base
0763:             * @return The base URL of the source tree, or null.
0764:             */
0765:            public void setBaseURLOfSource(String base) {
0766:                m_urlOfSource = base;
0767:            }
0768:
0769:            /**
0770:             * Get the original output target.
0771:             *
0772:             * @return The Result object used to kick of the transform or null.
0773:             */
0774:            public Result getOutputTarget() {
0775:                return m_outputTarget;
0776:            }
0777:
0778:            /**
0779:             * Set the original output target.  This is useful when using a SAX transform and
0780:             * supplying a ContentHandler or when the URI of the output target should
0781:             * not be the same as the systemID of the original output target.
0782:             *
0783:             *
0784:             * NEEDSDOC @param outputTarget
0785:             */
0786:            public void setOutputTarget(Result outputTarget) {
0787:                m_outputTarget = outputTarget;
0788:            }
0789:
0790:            /**
0791:             * Get an output property that is in effect for the
0792:             * transformation.  The property specified may be a property
0793:             * that was set with setOutputProperty, or it may be a
0794:             * property specified in the stylesheet.
0795:             *
0796:             * NEEDSDOC @param qnameString
0797:             *
0798:             * @return The string value of the output property, or null
0799:             * if no property was found.
0800:             *
0801:             * @throws IllegalArgumentException If the property is not supported.
0802:             *
0803:             * @see javax.xml.transform.OutputKeys
0804:             */
0805:            public String getOutputProperty(String qnameString)
0806:                    throws IllegalArgumentException {
0807:
0808:                String value = null;
0809:                OutputProperties props = getOutputFormat();
0810:
0811:                value = props.getProperty(qnameString);
0812:
0813:                if (null == value) {
0814:                    if (!OutputProperties.isLegalPropertyKey(qnameString))
0815:                        throw new IllegalArgumentException(
0816:                                XSLMessages
0817:                                        .createMessage(
0818:                                                XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED,
0819:                                                new Object[] { qnameString })); //"output property not recognized: "
0820:                    //+ qnameString);
0821:                }
0822:
0823:                return value;
0824:            }
0825:
0826:            /**
0827:             * Get the value of a property, without using the default properties.  This
0828:             * can be used to test if a property has been explicitly set by the stylesheet
0829:             * or user.
0830:             *
0831:             * NEEDSDOC @param qnameString
0832:             *
0833:             * @return The value of the property, or null if not found.
0834:             *
0835:             * @throws IllegalArgumentException If the property is not supported,
0836:             * and is not namespaced.
0837:             */
0838:            public String getOutputPropertyNoDefault(String qnameString)
0839:                    throws IllegalArgumentException {
0840:
0841:                String value = null;
0842:                OutputProperties props = getOutputFormat();
0843:
0844:                value = (String) props.getProperties().get(qnameString);
0845:
0846:                if (null == value) {
0847:                    if (!OutputProperties.isLegalPropertyKey(qnameString))
0848:                        throw new IllegalArgumentException(
0849:                                XSLMessages
0850:                                        .createMessage(
0851:                                                XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED,
0852:                                                new Object[] { qnameString })); //"output property not recognized: "
0853:                    // + qnameString);
0854:                }
0855:
0856:                return value;
0857:            }
0858:
0859:            /**
0860:             * This method is used to set or override the value
0861:             * of the effective xsl:output attribute values
0862:             * specified in the stylesheet.
0863:             * <p>
0864:             * The recognized standard output properties are:
0865:             * <ul>
0866:             * <li>cdata-section-elements
0867:             * <li>doctype-system
0868:             * <li>doctype-public
0869:             * <li>indent
0870:             * <li>media-type
0871:             * <li>method
0872:             * <li>omit-xml-declaration
0873:             * <li>standalone
0874:             * <li>version
0875:             * </ul>
0876:             * <p>
0877:             * For example:
0878:             * <pre>
0879:             *   tran.setOutputProperty("standalone", "yes");
0880:             * </pre>
0881:             * <p>
0882:             * In the case of the cdata-section-elements property,
0883:             * the value should be a whitespace separated list of
0884:             * element names.  The element name is the local name
0885:             * of the element, if it is in no namespace, or, the URI
0886:             * in braces followed immediately by the local name
0887:             * if the element is in that namespace. For example: 
0888:             * <pre>
0889:             * tran.setOutputProperty(
0890:             *   "cdata-section-elements", 
0891:             *   "elem1 {http://example.uri}elem2 elem3");
0892:             * </pre>
0893:             * <p>
0894:             * The recognized Xalan extension elements are: 
0895:             * <ul>
0896:             * <li>content-handler
0897:             * <li>entities
0898:             * <li>indent-amount
0899:             * <li>line-separator
0900:             * <li>omit-meta-tag
0901:             * <li>use-url-escaping
0902:             * </ul>
0903:             * <p>
0904:             * These must be in the extension namespace of
0905:             * "http://xml.apache.org/xalan".  This is accomplished
0906:             * by putting the namespace URI in braces before the 
0907:             * property name, for example:
0908:             * <pre>
0909:             *   tran.setOutputProperty(
0910:             *     "{http://xml.apache.org/xalan}line-separator" ,
0911:             *     "\n");
0912:             * </pre> 
0913:             *
0914:             * @param name The property name.
0915:             * @param value The requested value for the property.
0916:             * @throws IllegalArgumentException if the property name is not legal.
0917:             */
0918:            public void setOutputProperty(String name, String value)
0919:                    throws IllegalArgumentException {
0920:
0921:                synchronized (m_reentryGuard) {
0922:
0923:                    // Get the output format that was set by the user, otherwise get the 
0924:                    // output format from the stylesheet.
0925:                    if (null == m_outputFormat) {
0926:                        m_outputFormat = (OutputProperties) getStylesheet()
0927:                                .getOutputComposed().clone();
0928:                    }
0929:
0930:                    if (!OutputProperties.isLegalPropertyKey(name))
0931:                        throw new IllegalArgumentException(
0932:                                XSLMessages
0933:                                        .createMessage(
0934:                                                XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED,
0935:                                                new Object[] { name })); //"output property not recognized: "
0936:                    //+ name);
0937:
0938:                    m_outputFormat.setProperty(name, value);
0939:                }
0940:            }
0941:
0942:            /**
0943:             * Set the output properties for the transformation.  These
0944:             * properties will override properties set in the templates
0945:             * with xsl:output.
0946:             *
0947:             * <p>If argument to this function is null, any properties
0948:             * previously set will be removed.</p>
0949:             *
0950:             * @param oformat A set of output properties that will be
0951:             * used to override any of the same properties in effect
0952:             * for the transformation.
0953:             *
0954:             * @see javax.xml.transform.OutputKeys
0955:             * @see java.util.Properties
0956:             *
0957:             * @throws IllegalArgumentException if any of the argument keys are not
0958:             * recognized and are not namespace qualified.   
0959:             */
0960:            public void setOutputProperties(Properties oformat)
0961:                    throws IllegalArgumentException {
0962:
0963:                synchronized (m_reentryGuard) {
0964:                    if (null != oformat) {
0965:
0966:                        // See if an *explicit* method was set.
0967:                        String method = (String) oformat.get(OutputKeys.METHOD);
0968:
0969:                        if (null != method)
0970:                            m_outputFormat = new OutputProperties(method);
0971:                        else if (m_outputFormat == null)
0972:                            m_outputFormat = new OutputProperties();
0973:
0974:                        m_outputFormat.copyFrom(oformat);
0975:                        // copyFrom does not set properties that have been already set, so 
0976:                        // this must be called after, which is a bit in the reverse from 
0977:                        // what one might think.
0978:                        m_outputFormat.copyFrom(m_stylesheetRoot
0979:                                .getOutputProperties());
0980:                    } else {
0981:                        // if oformat is null JAXP says that any props previously set are removed
0982:                        // and we are to revert back to those in the templates object (i.e. Stylesheet).
0983:                        m_outputFormat = null;
0984:                    }
0985:                }
0986:            }
0987:
0988:            /**
0989:             * Get a copy of the output properties for the transformation.  These
0990:             * properties will override properties set in the templates
0991:             * with xsl:output.
0992:             *
0993:             * <p>Note that mutation of the Properties object returned will not
0994:             * effect the properties that the transformation contains.</p>
0995:             *
0996:             * @return  A copy of the set of output properties in effect
0997:             * for the next transformation.
0998:             *
0999:             * NEEDSDOC ($objectName$) @return
1000:             */
1001:            public Properties getOutputProperties() {
1002:                return (Properties) getOutputFormat().getProperties().clone();
1003:            }
1004:
1005:            /**
1006:             * Create a result ContentHandler from a Result object, based
1007:             * on the current OutputProperties.
1008:             *
1009:             * @param outputTarget Where the transform result should go,
1010:             * should not be null.
1011:             *
1012:             * @return A valid ContentHandler that will create the
1013:             * result tree when it is fed SAX events.
1014:             *
1015:             * @throws TransformerException
1016:             */
1017:            public SerializationHandler createSerializationHandler(
1018:                    Result outputTarget) throws TransformerException {
1019:                SerializationHandler xoh = createSerializationHandler(
1020:                        outputTarget, getOutputFormat());
1021:                return xoh;
1022:            }
1023:
1024:            /**
1025:             * Create a ContentHandler from a Result object and an OutputProperties.
1026:             *
1027:             * @param outputTarget Where the transform result should go,
1028:             * should not be null.
1029:             * @param format The OutputProperties object that will contain
1030:             * instructions on how to serialize the output.
1031:             *
1032:             * @return A valid ContentHandler that will create the
1033:             * result tree when it is fed SAX events.
1034:             *
1035:             * @throws TransformerException
1036:             */
1037:            public SerializationHandler createSerializationHandler(
1038:                    Result outputTarget, OutputProperties format)
1039:                    throws TransformerException {
1040:
1041:                SerializationHandler xoh;
1042:
1043:                // If the Result object contains a Node, then create
1044:                // a ContentHandler that will add nodes to the input node.
1045:                org.w3c.dom.Node outputNode = null;
1046:
1047:                if (outputTarget instanceof  DOMResult) {
1048:                    outputNode = ((DOMResult) outputTarget).getNode();
1049:                    org.w3c.dom.Node nextSibling = ((DOMResult) outputTarget)
1050:                            .getNextSibling();
1051:
1052:                    org.w3c.dom.Document doc;
1053:                    short type;
1054:
1055:                    if (null != outputNode) {
1056:                        type = outputNode.getNodeType();
1057:                        doc = (org.w3c.dom.Node.DOCUMENT_NODE == type) ? (org.w3c.dom.Document) outputNode
1058:                                : outputNode.getOwnerDocument();
1059:                    } else {
1060:                        boolean isSecureProcessing = m_stylesheetRoot
1061:                                .isSecureProcessing();
1062:                        doc = org.apache.xml.utils.DOMHelper
1063:                                .createDocument(isSecureProcessing);
1064:                        outputNode = doc;
1065:                        type = outputNode.getNodeType();
1066:
1067:                        ((DOMResult) outputTarget).setNode(outputNode);
1068:                    }
1069:
1070:                    DOMBuilder handler = (org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE == type) ? new DOMBuilder(
1071:                            doc, (org.w3c.dom.DocumentFragment) outputNode)
1072:                            : new DOMBuilder(doc, outputNode);
1073:
1074:                    if (nextSibling != null)
1075:                        handler.setNextSibling(nextSibling);
1076:
1077:                    String encoding = format.getProperty(OutputKeys.ENCODING);
1078:                    xoh = new ToXMLSAXHandler(handler,
1079:                            (LexicalHandler) handler, encoding);
1080:                } else if (outputTarget instanceof  SAXResult) {
1081:                    ContentHandler handler = ((SAXResult) outputTarget)
1082:                            .getHandler();
1083:
1084:                    if (null == handler)
1085:                        throw new IllegalArgumentException(
1086:                                "handler can not be null for a SAXResult");
1087:
1088:                    LexicalHandler lexHandler;
1089:                    if (handler instanceof  LexicalHandler)
1090:                        lexHandler = (LexicalHandler) handler;
1091:                    else
1092:                        lexHandler = null;
1093:
1094:                    String encoding = format.getProperty(OutputKeys.ENCODING);
1095:                    String method = format.getProperty(OutputKeys.METHOD);
1096:                    if (org.apache.xml.serializer.Method.HTML.equals(method)) {
1097:                        xoh = new ToHTMLSAXHandler(handler, lexHandler,
1098:                                encoding);
1099:                    } else if (org.apache.xml.serializer.Method.TEXT
1100:                            .equals(method)) {
1101:                        xoh = new ToTextSAXHandler(handler, lexHandler,
1102:                                encoding);
1103:                    } else {
1104:                        ToXMLSAXHandler toXMLSAXHandler = new ToXMLSAXHandler(
1105:                                handler, lexHandler, encoding);
1106:                        toXMLSAXHandler.setShouldOutputNSAttr(false);
1107:                        xoh = toXMLSAXHandler;
1108:
1109:                    }
1110:
1111:                    String publicID = format
1112:                            .getProperty(OutputKeys.DOCTYPE_PUBLIC);
1113:                    String systemID = format
1114:                            .getProperty(OutputKeys.DOCTYPE_SYSTEM);
1115:                    if (systemID != null)
1116:                        xoh.setDoctypeSystem(systemID);
1117:                    if (publicID != null)
1118:                        xoh.setDoctypePublic(publicID);
1119:
1120:                    if (handler instanceof  TransformerClient) {
1121:                        XalanTransformState state = new XalanTransformState();
1122:                        ((TransformerClient) handler).setTransformState(state);
1123:                        ((ToSAXHandler) xoh).setTransformState(state);
1124:                    }
1125:
1126:                }
1127:
1128:                // Otherwise, create a ContentHandler that will serialize the
1129:                // result tree to either a stream or a writer.
1130:                else if (outputTarget instanceof  StreamResult) {
1131:                    StreamResult sresult = (StreamResult) outputTarget;
1132:                    String method = format.getProperty(OutputKeys.METHOD);
1133:
1134:                    try {
1135:                        SerializationHandler serializer = (SerializationHandler) SerializerFactory
1136:                                .getSerializer(format.getProperties());
1137:
1138:                        if (null != sresult.getWriter())
1139:                            serializer.setWriter(sresult.getWriter());
1140:                        else if (null != sresult.getOutputStream())
1141:                            serializer.setOutputStream(sresult
1142:                                    .getOutputStream());
1143:                        else if (null != sresult.getSystemId()) {
1144:                            String fileURL = sresult.getSystemId();
1145:
1146:                            if (fileURL.startsWith("file:///")) {
1147:                                if (fileURL.substring(8).indexOf(":") > 0)
1148:                                    fileURL = fileURL.substring(8);
1149:                                else
1150:                                    fileURL = fileURL.substring(7);
1151:                            } else if (fileURL.startsWith("file:/")) {
1152:                                if (fileURL.substring(6).indexOf(":") > 0)
1153:                                    fileURL = fileURL.substring(6);
1154:                                else
1155:                                    fileURL = fileURL.substring(5);
1156:                            }
1157:
1158:                            m_outputStream = new java.io.FileOutputStream(
1159:                                    fileURL);
1160:
1161:                            serializer.setOutputStream(m_outputStream);
1162:
1163:                            xoh = serializer;
1164:                        } else
1165:                            throw new TransformerException(
1166:                                    XSLMessages
1167:                                            .createMessage(
1168:                                                    XSLTErrorResources.ER_NO_OUTPUT_SPECIFIED,
1169:                                                    null)); //"No output specified!");
1170:
1171:                        // handler = serializer.asContentHandler();
1172:
1173:                        //  this.setSerializer(serializer);
1174:
1175:                        xoh = serializer;
1176:                    }
1177:                    //        catch (UnsupportedEncodingException uee)
1178:                    //        {
1179:                    //          throw new TransformerException(uee);
1180:                    //        }
1181:                    catch (IOException ioe) {
1182:                        throw new TransformerException(ioe);
1183:                    }
1184:                } else {
1185:                    throw new TransformerException(
1186:                            XSLMessages
1187:                                    .createMessage(
1188:                                            XSLTErrorResources.ER_CANNOT_TRANSFORM_TO_RESULT_TYPE,
1189:                                            new Object[] { outputTarget
1190:                                                    .getClass().getName() })); //"Can't transform to a Result of type "
1191:                    //+ outputTarget.getClass().getName()
1192:                    //+ "!");
1193:                }
1194:
1195:                // before we forget, lets make the created handler hold a reference
1196:                // to the current TransformImpl object
1197:                xoh.setTransformer(this );
1198:
1199:                SourceLocator srcLocator = getStylesheet();
1200:                xoh.setSourceLocator(srcLocator);
1201:
1202:                return xoh;
1203:
1204:            }
1205:
1206:            /**
1207:             * Process the source tree to the output result.
1208:             * @param xmlSource  The input for the source tree.
1209:             * @param outputTarget The output source target.
1210:             *
1211:             * @throws TransformerException
1212:             */
1213:            public void transform(Source xmlSource, Result outputTarget)
1214:                    throws TransformerException {
1215:                transform(xmlSource, outputTarget, true);
1216:            }
1217:
1218:            /**
1219:             * Process the source tree to the output result.
1220:             * @param xmlSource  The input for the source tree.
1221:             * @param outputTarget The output source target.
1222:             * @param shouldRelease  Flag indicating whether to release DTMManager. 
1223:             *
1224:             * @throws TransformerException
1225:             */
1226:            public void transform(Source xmlSource, Result outputTarget,
1227:                    boolean shouldRelease) throws TransformerException {
1228:
1229:                synchronized (m_reentryGuard) {
1230:                    SerializationHandler xoh = createSerializationHandler(outputTarget);
1231:                    this .setSerializationHandler(xoh);
1232:
1233:                    m_outputTarget = outputTarget;
1234:
1235:                    transform(xmlSource, shouldRelease);
1236:                }
1237:            }
1238:
1239:            /**
1240:             * Process the source node to the output result, if the
1241:             * processor supports the "http://xml.org/trax/features/dom/input"
1242:             * feature.
1243:             * %REVIEW% Do we need a Node version of this?
1244:             * @param node  The input source node, which can be any valid DTM node.
1245:             * @param outputTarget The output source target.
1246:             *
1247:             * @throws TransformerException
1248:             */
1249:            public void transformNode(int node, Result outputTarget)
1250:                    throws TransformerException {
1251:
1252:                SerializationHandler xoh = createSerializationHandler(outputTarget);
1253:                this .setSerializationHandler(xoh);
1254:
1255:                m_outputTarget = outputTarget;
1256:
1257:                transformNode(node);
1258:            }
1259:
1260:            /**
1261:             * Process the source node to the output result, if the
1262:             * processor supports the "http://xml.org/trax/features/dom/input"
1263:             * feature.
1264:             * %REVIEW% Do we need a Node version of this?
1265:             * @param node  The input source node, which can be any valid DTM node.
1266:             *
1267:             * @throws TransformerException
1268:             */
1269:            public void transformNode(int node) throws TransformerException {
1270:                //dml
1271:                setExtensionsTable(getStylesheet());
1272:                // Make sure we're not writing to the same output content handler.
1273:                synchronized (m_serializationHandler) {
1274:                    m_hasBeenReset = false;
1275:
1276:                    XPathContext xctxt = getXPathContext();
1277:                    DTM dtm = xctxt.getDTM(node);
1278:
1279:                    try {
1280:                        pushGlobalVars(node);
1281:
1282:                        // ==========
1283:                        // Give the top-level templates a chance to pass information into 
1284:                        // the context (this is mainly for setting up tables for extensions).
1285:                        StylesheetRoot stylesheet = this .getStylesheet();
1286:                        int n = stylesheet.getGlobalImportCount();
1287:
1288:                        for (int i = 0; i < n; i++) {
1289:                            StylesheetComposed imported = stylesheet
1290:                                    .getGlobalImport(i);
1291:                            int includedCount = imported
1292:                                    .getIncludeCountComposed();
1293:
1294:                            for (int j = -1; j < includedCount; j++) {
1295:                                Stylesheet included = imported
1296:                                        .getIncludeComposed(j);
1297:
1298:                                included.runtimeInit(this );
1299:
1300:                                for (ElemTemplateElement child = included
1301:                                        .getFirstChildElem(); child != null; child = child
1302:                                        .getNextSiblingElem()) {
1303:                                    child.runtimeInit(this );
1304:                                }
1305:                            }
1306:                        }
1307:                        // ===========        
1308:                        // System.out.println("Calling applyTemplateToNode - "+Thread.currentThread().getName());
1309:                        DTMIterator dtmIter = new org.apache.xpath.axes.SelfIteratorNoPredicate();
1310:                        dtmIter.setRoot(node, xctxt);
1311:                        xctxt.pushContextNodeList(dtmIter);
1312:                        try {
1313:                            this .applyTemplateToNode(null, null, node);
1314:                        } finally {
1315:                            xctxt.popContextNodeList();
1316:                        }
1317:                        // m_stylesheetRoot.getStartRule().execute(this);
1318:
1319:                        // System.out.println("Done with applyTemplateToNode - "+Thread.currentThread().getName());
1320:                        if (null != m_serializationHandler) {
1321:                            m_serializationHandler.endDocument();
1322:                        }
1323:                    } catch (Exception se) {
1324:
1325:                        // System.out.println(Thread.currentThread().getName()+" threw an exception! "
1326:                        //                   +se.getMessage());
1327:                        // If an exception was thrown, we need to make sure that any waiting 
1328:                        // handlers can terminate, which I guess is best done by sending 
1329:                        // an endDocument.
1330:
1331:                        // SAXSourceLocator
1332:                        while (se instanceof  org.apache.xml.utils.WrappedRuntimeException) {
1333:                            Exception e = ((org.apache.xml.utils.WrappedRuntimeException) se)
1334:                                    .getException();
1335:                            if (null != e)
1336:                                se = e;
1337:                        }
1338:
1339:                        if (null != m_serializationHandler) {
1340:                            try {
1341:                                if (se instanceof  org.xml.sax.SAXParseException)
1342:                                    m_serializationHandler
1343:                                            .fatalError((org.xml.sax.SAXParseException) se);
1344:                                else if (se instanceof  TransformerException) {
1345:                                    TransformerException te = ((TransformerException) se);
1346:                                    SAXSourceLocator sl = new SAXSourceLocator(
1347:                                            te.getLocator());
1348:                                    m_serializationHandler
1349:                                            .fatalError(new org.xml.sax.SAXParseException(
1350:                                                    te.getMessage(), sl, te));
1351:                                } else {
1352:                                    m_serializationHandler
1353:                                            .fatalError(new org.xml.sax.SAXParseException(
1354:                                                    se.getMessage(),
1355:                                                    new SAXSourceLocator(), se));
1356:                                }
1357:                            } catch (Exception e) {
1358:                            }
1359:                        }
1360:
1361:                        if (se instanceof  TransformerException) {
1362:                            m_errorHandler
1363:                                    .fatalError((TransformerException) se);
1364:                        } else if (se instanceof  org.xml.sax.SAXParseException) {
1365:                            m_errorHandler
1366:                                    .fatalError(new TransformerException(
1367:                                            se.getMessage(),
1368:                                            new SAXSourceLocator(
1369:                                                    (org.xml.sax.SAXParseException) se),
1370:                                            se));
1371:                        } else {
1372:                            m_errorHandler.fatalError(new TransformerException(
1373:                                    se));
1374:                        }
1375:
1376:                    } finally {
1377:                        this .reset();
1378:                    }
1379:                }
1380:            }
1381:
1382:            /**
1383:             * Get a SAX2 ContentHandler for the input.
1384:             *
1385:             * @return A valid ContentHandler, which should never be null, as
1386:             * long as getFeature("http://xml.org/trax/features/sax/input")
1387:             * returns true.
1388:             */
1389:            public ContentHandler getInputContentHandler() {
1390:                return getInputContentHandler(false);
1391:            }
1392:
1393:            /**
1394:             * Get a SAX2 ContentHandler for the input.
1395:             *
1396:             * @param doDocFrag true if a DocumentFragment should be created as
1397:             * the root, rather than a Document.
1398:             *
1399:             * @return A valid ContentHandler, which should never be null, as
1400:             * long as getFeature("http://xml.org/trax/features/sax/input")
1401:             * returns true.
1402:             */
1403:            public ContentHandler getInputContentHandler(boolean doDocFrag) {
1404:
1405:                if (null == m_inputContentHandler) {
1406:
1407:                    //      if(null == m_urlOfSource && null != m_stylesheetRoot)
1408:                    //        m_urlOfSource = m_stylesheetRoot.getBaseIdentifier();
1409:                    m_inputContentHandler = new TransformerHandlerImpl(this ,
1410:                            doDocFrag, m_urlOfSource);
1411:                }
1412:
1413:                return m_inputContentHandler;
1414:            }
1415:
1416:            /**
1417:             * Get a SAX2 DeclHandler for the input.
1418:             * @return A valid DeclHandler, which should never be null, as
1419:             * long as getFeature("http://xml.org/trax/features/sax/input")
1420:             * returns true.
1421:             */
1422:            public DeclHandler getInputDeclHandler() {
1423:
1424:                if (m_inputContentHandler instanceof  DeclHandler)
1425:                    return (DeclHandler) m_inputContentHandler;
1426:                else
1427:                    return null;
1428:            }
1429:
1430:            /**
1431:             * Get a SAX2 LexicalHandler for the input.
1432:             * @return A valid LexicalHandler, which should never be null, as
1433:             * long as getFeature("http://xml.org/trax/features/sax/input")
1434:             * returns true.
1435:             */
1436:            public LexicalHandler getInputLexicalHandler() {
1437:
1438:                if (m_inputContentHandler instanceof  LexicalHandler)
1439:                    return (LexicalHandler) m_inputContentHandler;
1440:                else
1441:                    return null;
1442:            }
1443:
1444:            /**
1445:             * Set the output properties for the transformation.  These
1446:             * properties will override properties set in the templates
1447:             * with xsl:output.
1448:             *
1449:             * @param oformat A valid OutputProperties object (which will
1450:             * not be mutated), or null.
1451:             */
1452:            public void setOutputFormat(OutputProperties oformat) {
1453:                m_outputFormat = oformat;
1454:            }
1455:
1456:            /**
1457:             * Get the output properties used for the transformation.
1458:             *
1459:             * @return the output format that was set by the user,
1460:             * otherwise the output format from the stylesheet.
1461:             */
1462:            public OutputProperties getOutputFormat() {
1463:
1464:                // Get the output format that was set by the user, otherwise get the 
1465:                // output format from the stylesheet.
1466:                OutputProperties format = (null == m_outputFormat) ? getStylesheet()
1467:                        .getOutputComposed()
1468:                        : m_outputFormat;
1469:
1470:                return format;
1471:            }
1472:
1473:            /**
1474:             * Set a parameter for the templates.
1475:             * 
1476:             * @param name The name of the parameter.
1477:             * @param namespace The namespace of the parameter.
1478:             * @param value The value object.  This can be any valid Java object
1479:             * -- it's up to the processor to provide the proper
1480:             * coersion to the object, or simply pass it on for use
1481:             * in extensions.
1482:             */
1483:            public void setParameter(String name, String namespace, Object value) {
1484:
1485:                VariableStack varstack = getXPathContext().getVarStack();
1486:                QName qname = new QName(namespace, name);
1487:                XObject xobject = XObject.create(value, getXPathContext());
1488:
1489:                StylesheetRoot sroot = m_stylesheetRoot;
1490:                Vector vars = sroot.getVariablesAndParamsComposed();
1491:                int i = vars.size();
1492:                while (--i >= 0) {
1493:                    ElemVariable variable = (ElemVariable) vars.elementAt(i);
1494:                    if (variable.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE
1495:                            && variable.getName().equals(qname)) {
1496:                        varstack.setGlobalVariable(i, xobject);
1497:                    }
1498:                }
1499:            }
1500:
1501:            /** NEEDSDOC Field m_userParams          */
1502:            Vector m_userParams;
1503:
1504:            /**
1505:             * Set a parameter for the transformation.
1506:             *
1507:             * @param name The name of the parameter,
1508:             *             which may have a namespace URI.
1509:             * @param value The value object.  This can be any valid Java object
1510:             * -- it's up to the processor to provide the proper
1511:             * coersion to the object, or simply pass it on for use
1512:             * in extensions.
1513:             */
1514:            public void setParameter(String name, Object value) {
1515:
1516:                if (value == null) {
1517:                    throw new IllegalArgumentException(
1518:                            XSLMessages
1519:                                    .createMessage(
1520:                                            XSLTErrorResources.ER_INVALID_SET_PARAM_VALUE,
1521:                                            new Object[] { name }));
1522:                }
1523:
1524:                StringTokenizer tokenizer = new StringTokenizer(name, "{}",
1525:                        false);
1526:
1527:                try {
1528:
1529:                    // The first string might be the namespace, or it might be 
1530:                    // the local name, if the namespace is null.
1531:                    String s1 = tokenizer.nextToken();
1532:                    String s2 = tokenizer.hasMoreTokens() ? tokenizer
1533:                            .nextToken() : null;
1534:
1535:                    if (null == m_userParams)
1536:                        m_userParams = new Vector();
1537:
1538:                    if (null == s2) {
1539:                        replaceOrPushUserParam(new QName(s1), XObject.create(
1540:                                value, getXPathContext()));
1541:                        setParameter(s1, null, value);
1542:                    } else {
1543:                        replaceOrPushUserParam(new QName(s1, s2), XObject
1544:                                .create(value, getXPathContext()));
1545:                        setParameter(s2, s1, value);
1546:                    }
1547:                } catch (java.util.NoSuchElementException nsee) {
1548:
1549:                    // Should throw some sort of an error.
1550:                }
1551:            }
1552:
1553:            /**
1554:             * NEEDSDOC Method replaceOrPushUserParam 
1555:             *
1556:             *
1557:             * NEEDSDOC @param qname
1558:             * NEEDSDOC @param xval
1559:             */
1560:            private void replaceOrPushUserParam(QName qname, XObject xval) {
1561:
1562:                int n = m_userParams.size();
1563:
1564:                for (int i = n - 1; i >= 0; i--) {
1565:                    Arg arg = (Arg) m_userParams.elementAt(i);
1566:
1567:                    if (arg.getQName().equals(qname)) {
1568:                        m_userParams
1569:                                .setElementAt(new Arg(qname, xval, true), i);
1570:
1571:                        return;
1572:                    }
1573:                }
1574:
1575:                m_userParams.addElement(new Arg(qname, xval, true));
1576:            }
1577:
1578:            /**
1579:             * Get a parameter that was explicitly set with setParameter
1580:             * or setParameters.
1581:             *
1582:             *
1583:             * NEEDSDOC @param name
1584:             * @return A parameter that has been set with setParameter
1585:             * or setParameters,
1586:             * *not* all the xsl:params on the stylesheet (which require
1587:             * a transformation Source to be evaluated).
1588:             */
1589:            public Object getParameter(String name) {
1590:
1591:                try {
1592:
1593:                    // VariableStack varstack = getXPathContext().getVarStack();
1594:                    // The first string might be the namespace, or it might be 
1595:                    // the local name, if the namespace is null.
1596:                    QName qname = QName.getQNameFromString(name);
1597:
1598:                    if (null == m_userParams)
1599:                        return null;
1600:
1601:                    int n = m_userParams.size();
1602:
1603:                    for (int i = n - 1; i >= 0; i--) {
1604:                        Arg arg = (Arg) m_userParams.elementAt(i);
1605:
1606:                        if (arg.getQName().equals(qname)) {
1607:                            return arg.getVal().object();
1608:                        }
1609:                    }
1610:
1611:                    return null;
1612:                } catch (java.util.NoSuchElementException nsee) {
1613:
1614:                    // Should throw some sort of an error.
1615:                    return null;
1616:                }
1617:            }
1618:
1619:            /**
1620:             * Reset parameters that the user specified for the transformation.
1621:             * Called during transformer.reset() after we have cleared the 
1622:             * variable stack. We need to make sure that user params are
1623:             * reset so that the transformer object can be reused. 
1624:             */
1625:            private void resetUserParameters() {
1626:
1627:                try {
1628:
1629:                    if (null == m_userParams)
1630:                        return;
1631:
1632:                    int n = m_userParams.size();
1633:                    for (int i = n - 1; i >= 0; i--) {
1634:                        Arg arg = (Arg) m_userParams.elementAt(i);
1635:                        QName name = arg.getQName();
1636:                        // The first string might be the namespace, or it might be 
1637:                        // the local name, if the namespace is null.
1638:                        String s1 = name.getNamespace();
1639:                        String s2 = name.getLocalPart();
1640:
1641:                        setParameter(s2, s1, arg.getVal().object());
1642:
1643:                    }
1644:
1645:                } catch (java.util.NoSuchElementException nsee) {
1646:                    // Should throw some sort of an error.
1647:
1648:                }
1649:            }
1650:
1651:            /**
1652:             * Set a bag of parameters for the transformation. Note that
1653:             * these will not be additive, they will replace the existing
1654:             * set of parameters.
1655:             *
1656:             * NEEDSDOC @param params
1657:             */
1658:            public void setParameters(Properties params) {
1659:
1660:                clearParameters();
1661:
1662:                Enumeration names = params.propertyNames();
1663:
1664:                while (names.hasMoreElements()) {
1665:                    String name = params.getProperty((String) names
1666:                            .nextElement());
1667:                    StringTokenizer tokenizer = new StringTokenizer(name, "{}",
1668:                            false);
1669:
1670:                    try {
1671:
1672:                        // The first string might be the namespace, or it might be 
1673:                        // the local name, if the namespace is null.
1674:                        String s1 = tokenizer.nextToken();
1675:                        String s2 = tokenizer.hasMoreTokens() ? tokenizer
1676:                                .nextToken() : null;
1677:
1678:                        if (null == s2)
1679:                            setParameter(s1, null, params.getProperty(name));
1680:                        else
1681:                            setParameter(s2, s1, params.getProperty(name));
1682:                    } catch (java.util.NoSuchElementException nsee) {
1683:
1684:                        // Should throw some sort of an error.
1685:                    }
1686:                }
1687:            }
1688:
1689:            /**
1690:             * Reset the parameters to a null list.
1691:             */
1692:            public void clearParameters() {
1693:
1694:                synchronized (m_reentryGuard) {
1695:                    VariableStack varstack = new VariableStack();
1696:
1697:                    m_xcontext.setVarStack(varstack);
1698:
1699:                    m_userParams = null;
1700:                }
1701:            }
1702:
1703:            /**
1704:             * Internal -- push the global variables from the Stylesheet onto
1705:             * the context's runtime variable stack.
1706:             * <p>If we encounter a variable
1707:             * that is already defined in the variable stack, we ignore it.  This
1708:             * is because the second variable definition will be at a lower import
1709:             * precedence.  Presumably, global"variables at the same import precedence
1710:             * with the same name will have been caught during the recompose process.
1711:             * <p>However, if we encounter a parameter that is already defined in the
1712:             * variable stack, we need to see if this is a parameter whose value was
1713:             * supplied by a setParameter call.  If so, we need to "receive" the one
1714:             * already in the stack, ignoring this one.  If it is just an earlier
1715:             * xsl:param or xsl:variable definition, we ignore it using the same
1716:             * reasoning as explained above for the variable.
1717:             *
1718:             * @param contextNode The root of the source tree, can't be null.
1719:             *
1720:             * @throws TransformerException
1721:             */
1722:            protected void pushGlobalVars(int contextNode)
1723:                    throws TransformerException {
1724:
1725:                XPathContext xctxt = m_xcontext;
1726:                VariableStack vs = xctxt.getVarStack();
1727:                StylesheetRoot sr = getStylesheet();
1728:                Vector vars = sr.getVariablesAndParamsComposed();
1729:
1730:                int i = vars.size();
1731:                vs.link(i);
1732:
1733:                while (--i >= 0) {
1734:                    ElemVariable v = (ElemVariable) vars.elementAt(i);
1735:
1736:                    // XObject xobj = v.getValue(this, contextNode);
1737:                    XObject xobj = new XUnresolvedVariable(v, contextNode,
1738:                            this , vs.getStackFrame(), 0, true);
1739:
1740:                    if (null == vs.elementAt(i))
1741:                        vs.setGlobalVariable(i, xobj);
1742:                }
1743:
1744:            }
1745:
1746:            /**
1747:             * Set an object that will be used to resolve URIs used in
1748:             * document(), etc.
1749:             * @param resolver An object that implements the URIResolver interface,
1750:             * or null.
1751:             */
1752:            public void setURIResolver(URIResolver resolver) {
1753:
1754:                synchronized (m_reentryGuard) {
1755:                    m_xcontext.getSourceTreeManager().setURIResolver(resolver);
1756:                }
1757:            }
1758:
1759:            /**
1760:             * Get an object that will be used to resolve URIs used in
1761:             * document(), etc.
1762:             *
1763:             * @return An object that implements the URIResolver interface,
1764:             * or null.
1765:             */
1766:            public URIResolver getURIResolver() {
1767:                return m_xcontext.getSourceTreeManager().getURIResolver();
1768:            }
1769:
1770:            // ======== End Transformer Implementation ========  
1771:
1772:            /**
1773:             * Set the content event handler.
1774:             *
1775:             * NEEDSDOC @param handler
1776:             * @throws java.lang.NullPointerException If the handler
1777:             *            is null.
1778:             * @see org.xml.sax.XMLReader#setContentHandler
1779:             */
1780:            public void setContentHandler(ContentHandler handler) {
1781:
1782:                if (handler == null) {
1783:                    throw new NullPointerException(XSLMessages.createMessage(
1784:                            XSLTErrorResources.ER_NULL_CONTENT_HANDLER, null)); //"Null content handler");
1785:                } else {
1786:                    m_outputContentHandler = handler;
1787:
1788:                    if (null == m_serializationHandler) {
1789:                        ToXMLSAXHandler h = new ToXMLSAXHandler();
1790:                        h.setContentHandler(handler);
1791:                        h.setTransformer(this );
1792:
1793:                        m_serializationHandler = h;
1794:                    } else
1795:                        m_serializationHandler.setContentHandler(handler);
1796:                }
1797:            }
1798:
1799:            /**
1800:             * Get the content event handler.
1801:             *
1802:             * @return The current content handler, or null if none was set.
1803:             * @see org.xml.sax.XMLReader#getContentHandler
1804:             */
1805:            public ContentHandler getContentHandler() {
1806:                return m_outputContentHandler;
1807:            }
1808:
1809:            /**
1810:             * Given a stylesheet element, create a result tree fragment from it's
1811:             * contents. The fragment will be built within the shared RTF DTM system
1812:             * used as a variable stack.
1813:             * @param templateParent The template element that holds the fragment.
1814:             * @return the NodeHandle for the root node of the resulting RTF.
1815:             *
1816:             * @throws TransformerException
1817:             * @xsl.usage advanced
1818:             */
1819:            public int transformToRTF(ElemTemplateElement templateParent)
1820:                    throws TransformerException {
1821:                // Retrieve a DTM to contain the RTF. At this writing, this may be a
1822:                // multi-document DTM (SAX2RTFDTM).
1823:                DTM dtmFrag = m_xcontext.getRTFDTM();
1824:                return transformToRTF(templateParent, dtmFrag);
1825:            }
1826:
1827:            /**
1828:             * Given a stylesheet element, create a result tree fragment from it's
1829:             * contents. The fragment will also use the shared DTM system, but will
1830:             * obtain its space from the global variable pool rather than the dynamic
1831:             * variable stack. This allows late binding of XUnresolvedVariables without
1832:             * the risk that their content will be discarded when the variable stack
1833:             * is popped.
1834:             * 
1835:             * @param templateParent The template element that holds the fragment.
1836:             * @return the NodeHandle for the root node of the resulting RTF.
1837:             *
1838:             * @throws TransformerException
1839:             * @xsl.usage advanced
1840:             */
1841:            public int transformToGlobalRTF(ElemTemplateElement templateParent)
1842:                    throws TransformerException {
1843:                // Retrieve a DTM to contain the RTF. At this writing, this may be a
1844:                // multi-document DTM (SAX2RTFDTM).
1845:                DTM dtmFrag = m_xcontext.getGlobalRTFDTM();
1846:                return transformToRTF(templateParent, dtmFrag);
1847:            }
1848:
1849:            /**
1850:             * Given a stylesheet element, create a result tree fragment from it's
1851:             * contents.
1852:             * @param templateParent The template element that holds the fragment.
1853:             * @param dtmFrag The DTM to write the RTF into
1854:             * @return the NodeHandle for the root node of the resulting RTF.
1855:             *
1856:             * @throws TransformerException
1857:             * @xsl.usage advanced
1858:             */
1859:            private int transformToRTF(ElemTemplateElement templateParent,
1860:                    DTM dtmFrag) throws TransformerException {
1861:
1862:                XPathContext xctxt = m_xcontext;
1863:
1864:                ContentHandler rtfHandler = dtmFrag.getContentHandler();
1865:
1866:                // Obtain the ResultTreeFrag's root node.
1867:                // NOTE: In SAX2RTFDTM, this value isn't available until after
1868:                // the startDocument has been issued, so assignment has been moved
1869:                // down a bit in the code.
1870:                int resultFragment; // not yet reliably = dtmFrag.getDocument();
1871:
1872:                // Save the current result tree handler.
1873:                SerializationHandler savedRTreeHandler = this .m_serializationHandler;
1874:
1875:                // And make a new handler for the RTF.
1876:                ToSAXHandler h = new ToXMLSAXHandler();
1877:                h.setContentHandler(rtfHandler);
1878:                h.setTransformer(this );
1879:
1880:                // Replace the old handler (which was already saved)
1881:                m_serializationHandler = h;
1882:
1883:                // use local variable for the current handler
1884:                SerializationHandler rth = m_serializationHandler;
1885:
1886:                try {
1887:                    rth.startDocument();
1888:
1889:                    // startDocument is "bottlenecked" in RTH. We need it acted upon immediately,
1890:                    // to set the DTM's state as in-progress, so that if the xsl:variable's body causes
1891:                    // further RTF activity we can keep that from bashing this DTM.
1892:                    rth.flushPending();
1893:
1894:                    try {
1895:
1896:                        // Do the transformation of the child elements.
1897:                        executeChildTemplates(templateParent, true);
1898:
1899:                        // Make sure everything is flushed!
1900:                        rth.flushPending();
1901:
1902:                        // Get the document ID. May not exist until the RTH has not only
1903:                        // received, but flushed, the startDocument, and may be invalid
1904:                        // again after the document has been closed (still debating that)
1905:                        // ... so waiting until just before the end seems simplest/safest. 
1906:                        resultFragment = dtmFrag.getDocument();
1907:                    } finally {
1908:                        rth.endDocument();
1909:                    }
1910:                } catch (org.xml.sax.SAXException se) {
1911:                    throw new TransformerException(se);
1912:                } finally {
1913:
1914:                    // Restore the previous result tree handler.
1915:                    this .m_serializationHandler = savedRTreeHandler;
1916:                }
1917:
1918:                return resultFragment;
1919:            }
1920:
1921:            /**
1922:             * Get the StringWriter pool, so that StringWriter
1923:             * objects may be reused.
1924:             *
1925:             * @return The string writer pool, not null.
1926:             * @xsl.usage internal
1927:             */
1928:            public ObjectPool getStringWriterPool() {
1929:                return m_stringWriterObjectPool;
1930:            }
1931:
1932:            /**
1933:             * Take the contents of a template element, process it, and
1934:             * convert it to a string.
1935:             *
1936:             * @param elem The parent element whose children will be output
1937:             * as a string.
1938:             *
1939:             * @return The stringized result of executing the elements children.
1940:             *
1941:             * @throws TransformerException
1942:             * @xsl.usage advanced
1943:             */
1944:            public String transformToString(ElemTemplateElement elem)
1945:                    throws TransformerException {
1946:                ElemTemplateElement firstChild = elem.getFirstChildElem();
1947:                if (null == firstChild)
1948:                    return "";
1949:                if (elem.hasTextLitOnly() && m_optimizer) {
1950:                    return ((ElemTextLiteral) firstChild).getNodeValue();
1951:                }
1952:
1953:                // Save the current result tree handler.
1954:                SerializationHandler savedRTreeHandler = this .m_serializationHandler;
1955:
1956:                // Create a Serializer object that will handle the SAX events 
1957:                // and build the ResultTreeFrag nodes.
1958:                StringWriter sw = (StringWriter) m_stringWriterObjectPool
1959:                        .getInstance();
1960:
1961:                m_serializationHandler = (ToTextStream) m_textResultHandlerObjectPool
1962:                        .getInstance();
1963:
1964:                if (null == m_serializationHandler) {
1965:                    // if we didn't get one from the pool, go make a new one
1966:
1967:                    Serializer serializer = org.apache.xml.serializer.SerializerFactory
1968:                            .getSerializer(m_textformat.getProperties());
1969:                    m_serializationHandler = (SerializationHandler) serializer;
1970:                }
1971:
1972:                m_serializationHandler.setTransformer(this );
1973:                m_serializationHandler.setWriter(sw);
1974:
1975:                String result;
1976:
1977:                try {
1978:                    /* Don't call startDocument, the SerializationHandler  will
1979:                     * generate its own internal startDocument call anyways
1980:                     */
1981:                    // this.m_serializationHandler.startDocument();
1982:                    // Do the transformation of the child elements.
1983:                    executeChildTemplates(elem, true);
1984:                    this .m_serializationHandler.endDocument();
1985:
1986:                    result = sw.toString();
1987:                } catch (org.xml.sax.SAXException se) {
1988:                    throw new TransformerException(se);
1989:                } finally {
1990:                    sw.getBuffer().setLength(0);
1991:
1992:                    try {
1993:                        sw.close();
1994:                    } catch (Exception ioe) {
1995:                    }
1996:
1997:                    m_stringWriterObjectPool.freeInstance(sw);
1998:                    m_serializationHandler.reset();
1999:                    m_textResultHandlerObjectPool
2000:                            .freeInstance(m_serializationHandler);
2001:
2002:                    // Restore the previous result tree handler.
2003:                    m_serializationHandler = savedRTreeHandler;
2004:                }
2005:
2006:                return result;
2007:            }
2008:
2009:            /**
2010:             * Given an element and mode, find the corresponding
2011:             * template and process the contents.
2012:             *
2013:             * @param xslInstruction The calling element.
2014:             * @param template The template to use if xsl:for-each, current template for apply-imports, or null.
2015:             * @param child The source context node.
2016:             * @throws TransformerException
2017:             * @return true if applied a template, false if not.
2018:             * @xsl.usage advanced
2019:             */
2020:            public boolean applyTemplateToNode(
2021:                    ElemTemplateElement xslInstruction, // xsl:apply-templates or xsl:for-each
2022:                    ElemTemplate template, int child)
2023:                    throws TransformerException {
2024:
2025:                DTM dtm = m_xcontext.getDTM(child);
2026:                short nodeType = dtm.getNodeType(child);
2027:                boolean isDefaultTextRule = false;
2028:                boolean isApplyImports = false;
2029:
2030:                isApplyImports = ((xslInstruction == null) ? false
2031:                        : xslInstruction.getXSLToken() == Constants.ELEMNAME_APPLY_IMPORTS);
2032:
2033:                if (null == template || isApplyImports) {
2034:                    int maxImportLevel, endImportLevel = 0;
2035:
2036:                    if (isApplyImports) {
2037:                        maxImportLevel = template.getStylesheetComposed()
2038:                                .getImportCountComposed() - 1;
2039:                        endImportLevel = template.getStylesheetComposed()
2040:                                .getEndImportCountComposed();
2041:                    } else {
2042:                        maxImportLevel = -1;
2043:                    }
2044:
2045:                    // If we're trying an xsl:apply-imports at the top level (ie there are no
2046:                    // imported stylesheets), we need to indicate that there is no matching template.
2047:                    // The above logic will calculate a maxImportLevel of -1 which indicates
2048:                    // that we should find any template.  This is because a value of -1 for
2049:                    // maxImportLevel has a special meaning.  But we don't want that.
2050:                    // We want to match -no- templates. See bugzilla bug 1170.
2051:                    if (isApplyImports && (maxImportLevel == -1)) {
2052:                        template = null;
2053:                    } else {
2054:
2055:                        // Find the XSL template that is the best match for the 
2056:                        // element.        
2057:                        XPathContext xctxt = m_xcontext;
2058:
2059:                        try {
2060:                            xctxt.pushNamespaceContext(xslInstruction);
2061:
2062:                            QName mode = this .getMode();
2063:
2064:                            if (isApplyImports)
2065:                                template = m_stylesheetRoot
2066:                                        .getTemplateComposed(xctxt, child,
2067:                                                mode, maxImportLevel,
2068:                                                endImportLevel,
2069:                                                m_quietConflictWarnings, dtm);
2070:                            else
2071:                                template = m_stylesheetRoot
2072:                                        .getTemplateComposed(xctxt, child,
2073:                                                mode, m_quietConflictWarnings,
2074:                                                dtm);
2075:
2076:                        } finally {
2077:                            xctxt.popNamespaceContext();
2078:                        }
2079:                    }
2080:
2081:                    // If that didn't locate a node, fall back to a default template rule.
2082:                    // See http://www.w3.org/TR/xslt#built-in-rule.
2083:                    if (null == template) {
2084:                        switch (nodeType) {
2085:                        case DTM.DOCUMENT_FRAGMENT_NODE:
2086:                        case DTM.ELEMENT_NODE:
2087:                            template = m_stylesheetRoot.getDefaultRule();
2088:                            break;
2089:                        case DTM.CDATA_SECTION_NODE:
2090:                        case DTM.TEXT_NODE:
2091:                        case DTM.ATTRIBUTE_NODE:
2092:                            template = m_stylesheetRoot.getDefaultTextRule();
2093:                            isDefaultTextRule = true;
2094:                            break;
2095:                        case DTM.DOCUMENT_NODE:
2096:                            template = m_stylesheetRoot.getDefaultRootRule();
2097:                            break;
2098:                        default:
2099:
2100:                            // No default rules for processing instructions and the like.
2101:                            return false;
2102:                        }
2103:                    }
2104:                }
2105:
2106:                // If we are processing the default text rule, then just clone 
2107:                // the value directly to the result tree.
2108:                try {
2109:                    pushElemTemplateElement(template);
2110:                    m_xcontext.pushCurrentNode(child);
2111:                    pushPairCurrentMatched(template, child);
2112:
2113:                    // Fix copy copy29 test.
2114:                    if (!isApplyImports) {
2115:                        DTMIterator cnl = new org.apache.xpath.NodeSetDTM(
2116:                                child, m_xcontext.getDTMManager());
2117:                        m_xcontext.pushContextNodeList(cnl);
2118:                    }
2119:
2120:                    if (isDefaultTextRule) {
2121:                        switch (nodeType) {
2122:                        case DTM.CDATA_SECTION_NODE:
2123:                        case DTM.TEXT_NODE:
2124:                            ClonerToResultTree.cloneToResultTree(child,
2125:                                    nodeType, dtm, getResultTreeHandler(),
2126:                                    false);
2127:                            break;
2128:                        case DTM.ATTRIBUTE_NODE:
2129:                            dtm.dispatchCharactersEvents(child,
2130:                                    getResultTreeHandler(), false);
2131:                            break;
2132:                        }
2133:                    } else {
2134:
2135:                        // Fire a trace event for the template.
2136:
2137:                        if (m_debug)
2138:                            getTraceManager().fireTraceEvent(template);
2139:                        // And execute the child templates.
2140:                        // 9/11/00: If template has been compiled, hand off to it
2141:                        // since much (most? all?) of the processing has been inlined.
2142:                        // (It would be nice if there was a single entry point that
2143:                        // worked for both... but the interpretive system works by
2144:                        // having the Tranformer execute the children, while the
2145:                        // compiled obviously has to run its own code. It's
2146:                        // also unclear that "execute" is really the right name for
2147:                        // that entry point.)
2148:                        m_xcontext.setSAXLocator(template);
2149:                        // m_xcontext.getVarStack().link();
2150:                        m_xcontext.getVarStack().link(template.m_frameSize);
2151:                        executeChildTemplates(template, true);
2152:
2153:                        if (m_debug)
2154:                            getTraceManager().fireTraceEndEvent(template);
2155:                    }
2156:                } catch (org.xml.sax.SAXException se) {
2157:                    throw new TransformerException(se);
2158:                } finally {
2159:                    if (!isDefaultTextRule)
2160:                        m_xcontext.getVarStack().unlink();
2161:                    m_xcontext.popCurrentNode();
2162:                    if (!isApplyImports) {
2163:                        m_xcontext.popContextNodeList();
2164:                    }
2165:                    popCurrentMatched();
2166:
2167:                    popElemTemplateElement();
2168:                }
2169:
2170:                return true;
2171:            }
2172:
2173:            /**
2174:             * Execute each of the children of a template element.  This method
2175:             * is only for extension use.
2176:             *
2177:             * @param elem The ElemTemplateElement that contains the children
2178:             * that should execute.
2179:             * NEEDSDOC @param context
2180:             * @param mode The current mode.
2181:             * @param handler The ContentHandler to where the result events
2182:             * should be fed.
2183:             *
2184:             * @throws TransformerException
2185:             * @xsl.usage advanced
2186:             */
2187:            public void executeChildTemplates(ElemTemplateElement elem,
2188:                    org.w3c.dom.Node context, QName mode, ContentHandler handler)
2189:                    throws TransformerException {
2190:
2191:                XPathContext xctxt = m_xcontext;
2192:
2193:                try {
2194:                    if (null != mode)
2195:                        pushMode(mode);
2196:                    xctxt.pushCurrentNode(xctxt.getDTMHandleFromNode(context));
2197:                    executeChildTemplates(elem, handler);
2198:                } finally {
2199:                    xctxt.popCurrentNode();
2200:
2201:                    // I'm not sure where or why this was here.  It is clearly in 
2202:                    // error though, without a corresponding pushMode().
2203:                    if (null != mode)
2204:                        popMode();
2205:                }
2206:            }
2207:
2208:            /**
2209:             * Execute each of the children of a template element.
2210:             *
2211:             * @param elem The ElemTemplateElement that contains the children
2212:             * that should execute.
2213:             * @param shouldAddAttrs true if xsl:attributes should be executed.
2214:             *
2215:             * @throws TransformerException
2216:             * @xsl.usage advanced
2217:             */
2218:            public void executeChildTemplates(ElemTemplateElement elem,
2219:                    boolean shouldAddAttrs) throws TransformerException {
2220:
2221:                // Does this element have any children?
2222:                ElemTemplateElement t = elem.getFirstChildElem();
2223:
2224:                if (null == t)
2225:                    return;
2226:
2227:                if (elem.hasTextLitOnly() && m_optimizer) {
2228:                    char[] chars = ((ElemTextLiteral) t).getChars();
2229:                    try {
2230:                        // Have to push stuff on for tooling...
2231:                        this .pushElemTemplateElement(t);
2232:                        m_serializationHandler.characters(chars, 0,
2233:                                chars.length);
2234:                    } catch (SAXException se) {
2235:                        throw new TransformerException(se);
2236:                    } finally {
2237:                        this .popElemTemplateElement();
2238:                    }
2239:                    return;
2240:                }
2241:
2242:                //    // Check for infinite loops if we have to.
2243:                //    boolean check = (m_stackGuard.m_recursionLimit > -1);
2244:                //
2245:                //    if (check)
2246:                //      getStackGuard().push(elem, xctxt.getCurrentNode());
2247:
2248:                XPathContext xctxt = m_xcontext;
2249:                xctxt.pushSAXLocatorNull();
2250:                int currentTemplateElementsTop = m_currentTemplateElements
2251:                        .size();
2252:                m_currentTemplateElements.push(null);
2253:
2254:                try {
2255:                    // Loop through the children of the template, calling execute on 
2256:                    // each of them.
2257:                    for (; t != null; t = t.getNextSiblingElem()) {
2258:                        if (!shouldAddAttrs
2259:                                && t.getXSLToken() == Constants.ELEMNAME_ATTRIBUTE)
2260:                            continue;
2261:
2262:                        xctxt.setSAXLocator(t);
2263:                        m_currentTemplateElements.setElementAt(t,
2264:                                currentTemplateElementsTop);
2265:                        t.execute(this );
2266:                    }
2267:                } catch (RuntimeException re) {
2268:                    TransformerException te = new TransformerException(re);
2269:                    te.setLocator(t);
2270:                    throw te;
2271:                } finally {
2272:                    m_currentTemplateElements.pop();
2273:                    xctxt.popSAXLocator();
2274:                }
2275:
2276:                // Check for infinite loops if we have to
2277:                //    if (check)
2278:                //      getStackGuard().pop();
2279:            }
2280:
2281:            /**
2282:             * Execute each of the children of a template element.
2283:             *
2284:             * @param elem The ElemTemplateElement that contains the children
2285:             * that should execute.
2286:             * @param handler The ContentHandler to where the result events
2287:             * should be fed.
2288:             *
2289:             * @throws TransformerException
2290:             * @xsl.usage advanced
2291:             */
2292:            public void executeChildTemplates(ElemTemplateElement elem,
2293:                    ContentHandler handler) throws TransformerException {
2294:
2295:                SerializationHandler xoh = this .getSerializationHandler();
2296:
2297:                // These may well not be the same!  In this case when calling
2298:                // the Redirect extension, it has already set the ContentHandler
2299:                // in the Transformer.
2300:                SerializationHandler savedHandler = xoh;
2301:
2302:                try {
2303:                    xoh.flushPending();
2304:
2305:                    // %REVIEW% Make sure current node is being pushed.
2306:                    LexicalHandler lex = null;
2307:                    if (handler instanceof  LexicalHandler) {
2308:                        lex = (LexicalHandler) handler;
2309:                    }
2310:                    m_serializationHandler = new ToXMLSAXHandler(handler, lex,
2311:                            savedHandler.getEncoding());
2312:                    m_serializationHandler.setTransformer(this );
2313:                    executeChildTemplates(elem, true);
2314:                } catch (TransformerException e) {
2315:                    throw e;
2316:                } catch (SAXException se) {
2317:                    throw new TransformerException(se);
2318:                } finally {
2319:                    m_serializationHandler = savedHandler;
2320:                }
2321:            }
2322:
2323:            /**
2324:             * Get the keys for the xsl:sort elements.
2325:             * Note: Should this go into ElemForEach?
2326:             *
2327:             * @param foreach Valid ElemForEach element, not null.
2328:             * @param sourceNodeContext The current node context in the source tree,
2329:             * needed to evaluate the Attribute Value Templates.
2330:             *
2331:             * @return A Vector of NodeSortKeys, or null.
2332:             *
2333:             * @throws TransformerException
2334:             * @xsl.usage advanced
2335:             */
2336:            public Vector processSortKeys(ElemForEach foreach,
2337:                    int sourceNodeContext) throws TransformerException {
2338:
2339:                Vector keys = null;
2340:                XPathContext xctxt = m_xcontext;
2341:                int nElems = foreach.getSortElemCount();
2342:
2343:                if (nElems > 0)
2344:                    keys = new Vector();
2345:
2346:                // March backwards, collecting the sort keys.
2347:                for (int i = 0; i < nElems; i++) {
2348:                    ElemSort sort = foreach.getSortElem(i);
2349:
2350:                    if (m_debug)
2351:                        getTraceManager().fireTraceEvent(sort);
2352:
2353:                    String langString = (null != sort.getLang()) ? sort
2354:                            .getLang().evaluate(xctxt, sourceNodeContext,
2355:                                    foreach) : null;
2356:                    String dataTypeString = sort.getDataType().evaluate(xctxt,
2357:                            sourceNodeContext, foreach);
2358:
2359:                    if (dataTypeString.indexOf(":") >= 0)
2360:                        System.out
2361:                                .println("TODO: Need to write the hooks for QNAME sort data type");
2362:                    else if (!(dataTypeString
2363:                            .equalsIgnoreCase(Constants.ATTRVAL_DATATYPE_TEXT))
2364:                            && !(dataTypeString
2365:                                    .equalsIgnoreCase(Constants.ATTRVAL_DATATYPE_NUMBER)))
2366:                        foreach.error(
2367:                                XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
2368:                                new Object[] { Constants.ATTRNAME_DATATYPE,
2369:                                        dataTypeString });
2370:
2371:                    boolean treatAsNumbers = ((null != dataTypeString) && dataTypeString
2372:                            .equals(Constants.ATTRVAL_DATATYPE_NUMBER)) ? true
2373:                            : false;
2374:                    String orderString = sort.getOrder().evaluate(xctxt,
2375:                            sourceNodeContext, foreach);
2376:
2377:                    if (!(orderString
2378:                            .equalsIgnoreCase(Constants.ATTRVAL_ORDER_ASCENDING))
2379:                            && !(orderString
2380:                                    .equalsIgnoreCase(Constants.ATTRVAL_ORDER_DESCENDING)))
2381:                        foreach.error(
2382:                                XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
2383:                                new Object[] { Constants.ATTRNAME_ORDER,
2384:                                        orderString });
2385:
2386:                    boolean descending = ((null != orderString) && orderString
2387:                            .equals(Constants.ATTRVAL_ORDER_DESCENDING)) ? true
2388:                            : false;
2389:                    AVT caseOrder = sort.getCaseOrder();
2390:                    boolean caseOrderUpper;
2391:
2392:                    if (null != caseOrder) {
2393:                        String caseOrderString = caseOrder.evaluate(xctxt,
2394:                                sourceNodeContext, foreach);
2395:
2396:                        if (!(caseOrderString
2397:                                .equalsIgnoreCase(Constants.ATTRVAL_CASEORDER_UPPER))
2398:                                && !(caseOrderString
2399:                                        .equalsIgnoreCase(Constants.ATTRVAL_CASEORDER_LOWER)))
2400:                            foreach
2401:                                    .error(
2402:                                            XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
2403:                                            new Object[] {
2404:                                                    Constants.ATTRNAME_CASEORDER,
2405:                                                    caseOrderString });
2406:
2407:                        caseOrderUpper = ((null != caseOrderString) && caseOrderString
2408:                                .equals(Constants.ATTRVAL_CASEORDER_UPPER)) ? true
2409:                                : false;
2410:                    } else {
2411:                        caseOrderUpper = false;
2412:                    }
2413:
2414:                    keys.addElement(new NodeSortKey(this , sort.getSelect(),
2415:                            treatAsNumbers, descending, langString,
2416:                            caseOrderUpper, foreach));
2417:                    if (m_debug)
2418:                        getTraceManager().fireTraceEndEvent(sort);
2419:                }
2420:
2421:                return keys;
2422:            }
2423:
2424:            //==========================================================
2425:            // SECTION: TransformState implementation
2426:            //==========================================================
2427:
2428:            /**
2429:             * Get the stack of ElemTemplateElements.
2430:             * 
2431:             * @return A copy of stack that contains the xsl element instructions, 
2432:             * the earliest called in index zero, and the latest called in index size()-1.
2433:             */
2434:            public Vector getElementCallstack() {
2435:                Vector elems = new Vector();
2436:                int nStackSize = m_currentTemplateElements.size();
2437:                for (int i = 0; i < nStackSize; i++) {
2438:                    ElemTemplateElement elem = (ElemTemplateElement) m_currentTemplateElements
2439:                            .elementAt(i);
2440:                    if (null != elem) {
2441:                        elems.addElement(elem);
2442:                    }
2443:                }
2444:                return elems;
2445:            }
2446:
2447:            /**
2448:             * Get the count of how many elements are 
2449:             * active.
2450:             * @return The number of active elements on 
2451:             * the currentTemplateElements stack.
2452:             */
2453:            public int getCurrentTemplateElementsCount() {
2454:                return m_currentTemplateElements.size();
2455:            }
2456:
2457:            /**
2458:             * Get the count of how many elements are 
2459:             * active.
2460:             * @return The number of active elements on 
2461:             * the currentTemplateElements stack.
2462:             */
2463:            public ObjectStack getCurrentTemplateElements() {
2464:                return m_currentTemplateElements;
2465:            }
2466:
2467:            /**
2468:             * Push the current template element.
2469:             *
2470:             * @param elem The current ElemTemplateElement (may be null, and then
2471:             * set via setCurrentElement).
2472:             */
2473:            public void pushElemTemplateElement(ElemTemplateElement elem) {
2474:                m_currentTemplateElements.push(elem);
2475:            }
2476:
2477:            /**
2478:             * Pop the current template element.
2479:             */
2480:            public void popElemTemplateElement() {
2481:                m_currentTemplateElements.pop();
2482:            }
2483:
2484:            /**
2485:             * Set the top of the current template elements
2486:             * stack.
2487:             *
2488:             * @param e The current ElemTemplateElement about to
2489:             * be executed.
2490:             */
2491:            public void setCurrentElement(ElemTemplateElement e) {
2492:                m_currentTemplateElements.setTop(e);
2493:            }
2494:
2495:            /**
2496:             * Retrieves the current ElemTemplateElement that is
2497:             * being executed.
2498:             *
2499:             * @return The current ElemTemplateElement that is executing,
2500:             * should not normally be null.
2501:             */
2502:            public ElemTemplateElement getCurrentElement() {
2503:                return (m_currentTemplateElements.size() > 0) ? (ElemTemplateElement) m_currentTemplateElements
2504:                        .peek()
2505:                        : null;
2506:            }
2507:
2508:            /**
2509:             * This method retrieves the current context node
2510:             * in the source tree.
2511:             *
2512:             * @return The current context node (should never be null?).
2513:             */
2514:            public int getCurrentNode() {
2515:                return m_xcontext.getCurrentNode();
2516:            }
2517:
2518:            /**
2519:             * Get the call stack of xsl:template elements.
2520:             * 
2521:             * @return A copy of stack that contains the xsl:template 
2522:             * (ElemTemplate) instructions, the earliest called in index 
2523:             * zero, and the latest called in index size()-1.
2524:             */
2525:            public Vector getTemplateCallstack() {
2526:                Vector elems = new Vector();
2527:                int nStackSize = m_currentTemplateElements.size();
2528:                for (int i = 0; i < nStackSize; i++) {
2529:                    ElemTemplateElement elem = (ElemTemplateElement) m_currentTemplateElements
2530:                            .elementAt(i);
2531:                    if (null != elem
2532:                            && (elem.getXSLToken() != Constants.ELEMNAME_TEMPLATE)) {
2533:                        elems.addElement(elem);
2534:                    }
2535:                }
2536:                return elems;
2537:            }
2538:
2539:            /**
2540:             * This method retrieves the xsl:template
2541:             * that is in effect, which may be a matched template
2542:             * or a named template.
2543:             *
2544:             * <p>Please note that the ElemTemplate returned may
2545:             * be a default template, and thus may not have a template
2546:             * defined in the stylesheet.</p>
2547:             *
2548:             * @return The current xsl:template, should not be null.
2549:             */
2550:            public ElemTemplate getCurrentTemplate() {
2551:
2552:                ElemTemplateElement elem = getCurrentElement();
2553:
2554:                while ((null != elem)
2555:                        && (elem.getXSLToken() != Constants.ELEMNAME_TEMPLATE)) {
2556:                    elem = elem.getParentElem();
2557:                }
2558:
2559:                return (ElemTemplate) elem;
2560:            }
2561:
2562:            /**
2563:             * Push both the current xsl:template or xsl:for-each onto the
2564:             * stack, along with the child node that was matched.
2565:             * (Note: should this only be used for xsl:templates?? -sb)
2566:             *
2567:             * @param template xsl:template or xsl:for-each.
2568:             * @param child The child that was matched.
2569:             */
2570:            public void pushPairCurrentMatched(ElemTemplateElement template,
2571:                    int child) {
2572:                m_currentMatchTemplates.push(template);
2573:                m_currentMatchedNodes.push(child);
2574:            }
2575:
2576:            /**
2577:             * Pop the elements that were pushed via pushPairCurrentMatched.
2578:             */
2579:            public void popCurrentMatched() {
2580:                m_currentMatchTemplates.pop();
2581:                m_currentMatchedNodes.pop();
2582:            }
2583:
2584:            /**
2585:             * This method retrieves the xsl:template
2586:             * that was matched.  Note that this may not be
2587:             * the same thing as the current template (which
2588:             * may be from getCurrentElement()), since a named
2589:             * template may be in effect.
2590:             *
2591:             * @return The pushed template that was pushed via pushPairCurrentMatched.
2592:             */
2593:            public ElemTemplate getMatchedTemplate() {
2594:                return (ElemTemplate) m_currentMatchTemplates.peek();
2595:            }
2596:
2597:            /**
2598:             * Retrieves the node in the source tree that matched
2599:             * the template obtained via getMatchedTemplate().
2600:             *
2601:             * @return The matched node that corresponds to the
2602:             * match attribute of the current xsl:template.
2603:             */
2604:            public int getMatchedNode() {
2605:                return m_currentMatchedNodes.peepTail();
2606:            }
2607:
2608:            /**
2609:             * Get the current context node list.
2610:             *
2611:             * @return A reset clone of the context node list.
2612:             */
2613:            public DTMIterator getContextNodeList() {
2614:
2615:                try {
2616:                    DTMIterator cnl = m_xcontext.getContextNodeList();
2617:
2618:                    return (cnl == null) ? null : (DTMIterator) cnl
2619:                            .cloneWithReset();
2620:                } catch (CloneNotSupportedException cnse) {
2621:
2622:                    // should never happen.
2623:                    return null;
2624:                }
2625:            }
2626:
2627:            /**
2628:             * Get the TrAX Transformer object in effect.
2629:             *
2630:             * @return This object.
2631:             */
2632:            public Transformer getTransformer() {
2633:                return this ;
2634:            }
2635:
2636:            //==========================================================
2637:            // SECTION: Accessor Functions
2638:            //==========================================================
2639:
2640:            /**
2641:             * Set the stylesheet for this processor.  If this is set, then the
2642:             * process calls that take only the input .xml will use
2643:             * this instead of looking for a stylesheet PI.  Also,
2644:             * setting the stylesheet is needed if you are going
2645:             * to use the processor as a SAX ContentHandler.
2646:             *
2647:             * @param stylesheetRoot A non-null StylesheetRoot object,
2648:             * or null if you wish to clear the stylesheet reference.
2649:             */
2650:            public void setStylesheet(StylesheetRoot stylesheetRoot) {
2651:                m_stylesheetRoot = stylesheetRoot;
2652:            }
2653:
2654:            /**
2655:             * Get the current stylesheet for this processor.
2656:             *
2657:             * @return The stylesheet that is associated with this
2658:             * transformer.
2659:             */
2660:            public final StylesheetRoot getStylesheet() {
2661:                return m_stylesheetRoot;
2662:            }
2663:
2664:            /**
2665:             * Get quietConflictWarnings property. If the quietConflictWarnings
2666:             * property is set to true, warnings about pattern conflicts won't be
2667:             * printed to the diagnostics stream.
2668:             *
2669:             * @return True if this transformer should not report
2670:             * template match conflicts.
2671:             */
2672:            public boolean getQuietConflictWarnings() {
2673:                return m_quietConflictWarnings;
2674:            }
2675:
2676:            /**
2677:             * If the quietConflictWarnings property is set to
2678:             * true, warnings about pattern conflicts won't be
2679:             * printed to the diagnostics stream.
2680:             * False by default.
2681:             * (Currently setting this property will have no effect.)
2682:             *
2683:             * @param b true if conflict warnings should be suppressed.
2684:             */
2685:            public void setQuietConflictWarnings(boolean b) {
2686:                m_quietConflictWarnings = b;
2687:            }
2688:
2689:            /**
2690:             * Set the execution context for XPath.
2691:             *
2692:             * @param xcontext A non-null reference to the XPathContext
2693:             * associated with this transformer.
2694:             * @xsl.usage internal
2695:             */
2696:            public void setXPathContext(XPathContext xcontext) {
2697:                m_xcontext = xcontext;
2698:            }
2699:
2700:            /**
2701:             * Get the XPath context associated with this transformer.
2702:             *
2703:             * @return The XPathContext reference, never null.
2704:             */
2705:            public final XPathContext getXPathContext() {
2706:                return m_xcontext;
2707:            }
2708:
2709:            /**
2710:             * Get the object used to guard the stack from
2711:             * recursion.
2712:             *
2713:             * @return The StackGuard object, which should never be null.
2714:             * @xsl.usage internal
2715:             */
2716:            public StackGuard getStackGuard() {
2717:                return m_stackGuard;
2718:            }
2719:
2720:            /**
2721:             * Get the recursion limit.
2722:             * Used for infinite loop check. If the value is -1, do not
2723:             * check for infinite loops. Anyone who wants to enable that
2724:             * check should change the value of this variable to be the
2725:             * level of recursion that they want to check. Be careful setting
2726:             * this variable, if the number is too low, it may report an
2727:             * infinite loop situation, when there is none.
2728:             * Post version 1.0.0, we'll make this a runtime feature.
2729:             *
2730:             * @return The limit on recursion, or -1 if no check is to be made.
2731:             */
2732:            public int getRecursionLimit() {
2733:                return m_stackGuard.getRecursionLimit();
2734:            }
2735:
2736:            /**
2737:             * Set the recursion limit.
2738:             * Used for infinite loop check. If the value is -1, do not
2739:             * check for infinite loops. Anyone who wants to enable that
2740:             * check should change the value of this variable to be the
2741:             * level of recursion that they want to check. Be careful setting
2742:             * this variable, if the number is too low, it may report an
2743:             * infinite loop situation, when there is none.
2744:             * Post version 1.0.0, we'll make this a runtime feature.
2745:             *
2746:             * @param limit A number that represents the limit of recursion,
2747:             * or -1 if no checking is to be done.
2748:             */
2749:            public void setRecursionLimit(int limit) {
2750:                m_stackGuard.setRecursionLimit(limit);
2751:            }
2752:
2753:            /**
2754:             * Get the SerializationHandler object.
2755:             *
2756:             * @return The current SerializationHandler, which may not
2757:             * be the main result tree manager.
2758:             */
2759:            public SerializationHandler getResultTreeHandler() {
2760:                return m_serializationHandler;
2761:            }
2762:
2763:            /**
2764:             * Get the SerializationHandler object.
2765:             *
2766:             * @return The current SerializationHandler, which may not
2767:             * be the main result tree manager.
2768:             */
2769:            public SerializationHandler getSerializationHandler() {
2770:                return m_serializationHandler;
2771:            }
2772:
2773:            /**
2774:             * Get the KeyManager object.
2775:             *
2776:             * @return A reference to the KeyManager object, which should
2777:             * never be null.
2778:             */
2779:            public KeyManager getKeyManager() {
2780:                return m_keyManager;
2781:            }
2782:
2783:            /**
2784:             * Check to see if this is a recursive attribute definition.
2785:             *
2786:             * @param attrSet A non-null ElemAttributeSet reference.
2787:             *
2788:             * @return true if the attribute set is recursive.
2789:             */
2790:            public boolean isRecursiveAttrSet(ElemAttributeSet attrSet) {
2791:
2792:                if (null == m_attrSetStack) {
2793:                    m_attrSetStack = new Stack();
2794:                }
2795:
2796:                if (!m_attrSetStack.empty()) {
2797:                    int loc = m_attrSetStack.search(attrSet);
2798:
2799:                    if (loc > -1) {
2800:                        return true;
2801:                    }
2802:                }
2803:
2804:                return false;
2805:            }
2806:
2807:            /**
2808:             * Push an executing attribute set, so we can check for
2809:             * recursive attribute definitions.
2810:             *
2811:             * @param attrSet A non-null ElemAttributeSet reference.
2812:             */
2813:            public void pushElemAttributeSet(ElemAttributeSet attrSet) {
2814:                m_attrSetStack.push(attrSet);
2815:            }
2816:
2817:            /**
2818:             * Pop the current executing attribute set.
2819:             */
2820:            public void popElemAttributeSet() {
2821:                m_attrSetStack.pop();
2822:            }
2823:
2824:            /**
2825:             * Get the table of counters, for optimized xsl:number support.
2826:             *
2827:             * @return The CountersTable, never null.
2828:             */
2829:            public CountersTable getCountersTable() {
2830:
2831:                if (null == m_countersTable)
2832:                    m_countersTable = new CountersTable();
2833:
2834:                return m_countersTable;
2835:            }
2836:
2837:            /**
2838:             * Tell if the current template rule is null, i.e. if we are
2839:             * directly within an apply-templates.  Used for xsl:apply-imports.
2840:             *
2841:             * @return True if the current template rule is null.
2842:             */
2843:            public boolean currentTemplateRuleIsNull() {
2844:                return ((!m_currentTemplateRuleIsNull.isEmpty()) && (m_currentTemplateRuleIsNull
2845:                        .peek() == true));
2846:            }
2847:
2848:            /**
2849:             * Push true if the current template rule is null, false
2850:             * otherwise.
2851:             *
2852:             * @param b True if the we are executing an xsl:for-each
2853:             * (or xsl:call-template?).
2854:             */
2855:            public void pushCurrentTemplateRuleIsNull(boolean b) {
2856:                m_currentTemplateRuleIsNull.push(b);
2857:            }
2858:
2859:            /**
2860:             * Push true if the current template rule is null, false
2861:             * otherwise.
2862:             */
2863:            public void popCurrentTemplateRuleIsNull() {
2864:                m_currentTemplateRuleIsNull.pop();
2865:            }
2866:
2867:            /**
2868:             * Push a funcion result for the currently active EXSLT
2869:             * <code>func:function</code>.
2870:             * 
2871:             * @param val the result of executing an EXSLT
2872:             * <code>func:result</code> instruction for the current
2873:             * <code>func:function</code>.
2874:             */
2875:            public void pushCurrentFuncResult(Object val) {
2876:                m_currentFuncResult.push(val);
2877:            }
2878:
2879:            /**
2880:             * Pops the result of the currently active EXSLT <code>func:function</code>.
2881:             * 
2882:             * @return the value of the <code>func:function</code>
2883:             */
2884:            public Object popCurrentFuncResult() {
2885:                return m_currentFuncResult.pop();
2886:            }
2887:
2888:            /**
2889:             * Determines whether an EXSLT <code>func:result</code> instruction has been
2890:             * executed for the currently active EXSLT <code>func:function</code>.
2891:             * 
2892:             * @return <code>true</code> if and only if a <code>func:result</code>
2893:             * instruction has been executed
2894:             */
2895:            public boolean currentFuncResultSeen() {
2896:                return !m_currentFuncResult.empty()
2897:                        && m_currentFuncResult.peek() != null;
2898:            }
2899:
2900:            /**
2901:             * Return the message manager.
2902:             *
2903:             * @return The message manager, never null.
2904:             */
2905:            public MsgMgr getMsgMgr() {
2906:
2907:                if (null == m_msgMgr)
2908:                    m_msgMgr = new MsgMgr(this );
2909:
2910:                return m_msgMgr;
2911:            }
2912:
2913:            /**
2914:             * Set the error event listener.
2915:             *
2916:             * @param listener The new error listener.
2917:             * @throws IllegalArgumentException if
2918:             */
2919:            public void setErrorListener(ErrorListener listener)
2920:                    throws IllegalArgumentException {
2921:
2922:                synchronized (m_reentryGuard) {
2923:                    if (listener == null)
2924:                        throw new IllegalArgumentException(
2925:                                XSLMessages
2926:                                        .createMessage(
2927:                                                XSLTErrorResources.ER_NULL_ERROR_HANDLER,
2928:                                                null)); //"Null error handler");
2929:
2930:                    m_errorHandler = listener;
2931:                }
2932:            }
2933:
2934:            /**
2935:             * Get the current error event handler.
2936:             *
2937:             * @return The current error handler, which should never be null.
2938:             */
2939:            public ErrorListener getErrorListener() {
2940:                return m_errorHandler;
2941:            }
2942:
2943:            /**
2944:             * Get an instance of the trace manager for this transformation.
2945:             * This object can be used to set trace listeners on various
2946:             * events during the transformation.
2947:             *
2948:             * @return A reference to the TraceManager, never null.
2949:             */
2950:            public TraceManager getTraceManager() {
2951:                return m_traceManager;
2952:            }
2953:
2954:            /**
2955:             * Look up the value of a feature.
2956:             *
2957:             * <p>The feature name is any fully-qualified URI.  It is
2958:             * possible for an TransformerFactory to recognize a feature name but
2959:             * to be unable to return its value; this is especially true
2960:             * in the case of an adapter for a SAX1 Parser, which has
2961:             * no way of knowing whether the underlying parser is
2962:             * validating, for example.</p>
2963:             *
2964:             * <h3>Open issues:</h3>
2965:             * <dl>
2966:             *    <dt><h4>Should getFeature be changed to hasFeature?</h4></dt>
2967:             *    <dd>Keith Visco writes: Should getFeature be changed to hasFeature?
2968:             *        It returns a boolean which indicated whether the "state"
2969:             *        of feature is "true or false". I assume this means whether
2970:             *        or not a feature is supported? I know SAX is using "getFeature",
2971:             *        but to me "hasFeature" is cleaner.</dd>
2972:             * </dl>
2973:             *
2974:             * @param name The feature name, which is a fully-qualified
2975:             *        URI.
2976:             * @return The current state of the feature (true or false).
2977:             * @throws org.xml.sax.SAXNotRecognizedException When the
2978:             *            TransformerFactory does not recognize the feature name.
2979:             * @throws org.xml.sax.SAXNotSupportedException When the
2980:             *            TransformerFactory recognizes the feature name but
2981:             *            cannot determine its value at this time.
2982:             *
2983:             * @throws SAXNotRecognizedException
2984:             * @throws SAXNotSupportedException
2985:             */
2986:            public boolean getFeature(String name)
2987:                    throws SAXNotRecognizedException, SAXNotSupportedException {
2988:
2989:                if ("http://xml.org/trax/features/sax/input".equals(name))
2990:                    return true;
2991:                else if ("http://xml.org/trax/features/dom/input".equals(name))
2992:                    return true;
2993:
2994:                throw new SAXNotRecognizedException(name);
2995:            }
2996:
2997:            // %TODO% Doc
2998:
2999:            /**
3000:             * NEEDSDOC Method getMode 
3001:             *
3002:             *
3003:             * NEEDSDOC (getMode) @return
3004:             */
3005:            public QName getMode() {
3006:                return m_modes.isEmpty() ? null : (QName) m_modes.peek();
3007:            }
3008:
3009:            // %TODO% Doc
3010:
3011:            /**
3012:             * NEEDSDOC Method pushMode 
3013:             *
3014:             *
3015:             * NEEDSDOC @param mode
3016:             */
3017:            public void pushMode(QName mode) {
3018:                m_modes.push(mode);
3019:            }
3020:
3021:            // %TODO% Doc
3022:
3023:            /**
3024:             * NEEDSDOC Method popMode 
3025:             *
3026:             */
3027:            public void popMode() {
3028:                m_modes.pop();
3029:            }
3030:
3031:            /**
3032:             * Called by SourceTreeHandler to start the transformation
3033:             *  in a separate thread
3034:             *
3035:             * NEEDSDOC @param priority
3036:             */
3037:            public void runTransformThread(int priority) {
3038:
3039:                // used in SourceTreeHandler
3040:                Thread t = ThreadControllerWrapper.runThread(this , priority);
3041:                this .setTransformThread(t);
3042:            }
3043:
3044:            /**
3045:             * Called by this.transform() if isParserEventsOnMain()==false.
3046:             *  Similar with runTransformThread(), but no priority is set
3047:             *  and setTransformThread is not set.
3048:             */
3049:            public void runTransformThread() {
3050:                ThreadControllerWrapper.runThread(this , -1);
3051:            }
3052:
3053:            /**
3054:             * Called by CoRoutineSAXParser. Launches the CoroutineSAXParser
3055:             * in a thread, and prepares it to invoke the parser from that thread
3056:             * upon request. 
3057:             *  
3058:             */
3059:            public static void runTransformThread(Runnable runnable) {
3060:                ThreadControllerWrapper.runThread(runnable, -1);
3061:            }
3062:
3063:            /**
3064:             * Used by SourceTreeHandler to wait until the transform
3065:             *   completes
3066:             *
3067:             * @throws SAXException
3068:             */
3069:            public void waitTransformThread() throws SAXException {
3070:
3071:                // This is called to make sure the task is done.
3072:                // It is possible that the thread has been reused -
3073:                // but for a different transformation. ( what if we 
3074:                // recycle the transformer ? Not a problem since this is
3075:                // still in use. )
3076:                Thread transformThread = this .getTransformThread();
3077:
3078:                if (null != transformThread) {
3079:                    try {
3080:                        ThreadControllerWrapper.waitThread(transformThread,
3081:                                this );
3082:
3083:                        if (!this .hasTransformThreadErrorCatcher()) {
3084:                            Exception e = this .getExceptionThrown();
3085:
3086:                            if (null != e) {
3087:                                e.printStackTrace();
3088:                                throw new org.xml.sax.SAXException(e);
3089:                            }
3090:                        }
3091:
3092:                        this .setTransformThread(null);
3093:                    } catch (InterruptedException ie) {
3094:                    }
3095:                }
3096:            }
3097:
3098:            /**
3099:             * Get the exception thrown by the secondary thread (normally
3100:             * the transform thread).
3101:             *
3102:             * @return The thrown exception, or null if no exception was
3103:             * thrown.
3104:             */
3105:            public Exception getExceptionThrown() {
3106:                return m_exceptionThrown;
3107:            }
3108:
3109:            /**
3110:             * Set the exception thrown by the secondary thread (normally
3111:             * the transform thread).
3112:             *
3113:             * @param e The thrown exception, or null if no exception was
3114:             * thrown.
3115:             */
3116:            public void setExceptionThrown(Exception e) {
3117:                m_exceptionThrown = e;
3118:            }
3119:
3120:            /**
3121:             * This is just a way to set the document for run().
3122:             *
3123:             * @param doc A non-null reference to the root of the
3124:             * tree to be transformed.
3125:             */
3126:            public void setSourceTreeDocForThread(int doc) {
3127:                m_doc = doc;
3128:            }
3129:
3130:            /**
3131:             * Set the input source for the source tree, which is needed if the
3132:             * parse thread is not the main thread, in order for the parse
3133:             * thread's run method to get to the input source.
3134:             *
3135:             * @param source The input source for the source tree.
3136:             */
3137:            public void setXMLSource(Source source) {
3138:                m_xmlSource = source;
3139:            }
3140:
3141:            /**
3142:             * Tell if the transform method is completed.
3143:             *
3144:             * @return True if transformNode has completed, or
3145:             * an exception was thrown.
3146:             */
3147:            public boolean isTransformDone() {
3148:
3149:                synchronized (this ) {
3150:                    return m_isTransformDone;
3151:                }
3152:            }
3153:
3154:            /**
3155:             * Set if the transform method is completed.
3156:             *
3157:             * @param done True if transformNode has completed, or
3158:             * an exception was thrown.
3159:             */
3160:            public void setIsTransformDone(boolean done) {
3161:
3162:                synchronized (this ) {
3163:                    m_isTransformDone = done;
3164:                }
3165:            }
3166:
3167:            /**
3168:             * From a secondary thread, post the exception, so that
3169:             * it can be picked up from the main thread.
3170:             *
3171:             * @param e The exception that was thrown.
3172:             */
3173:            void postExceptionFromThread(Exception e) {
3174:
3175:                // Commented out in response to problem reported by Nicola Brown <Nicola.Brown@jacobsrimell.com>
3176:                //    if(m_reportInPostExceptionFromThread)
3177:                //    {
3178:                //      // Consider re-throwing the exception if this flag is set.
3179:                //      e.printStackTrace();
3180:                //    }
3181:                // %REVIEW Need DTM equivelent?    
3182:                //    if (m_inputContentHandler instanceof SourceTreeHandler)
3183:                //    {
3184:                //      SourceTreeHandler sth = (SourceTreeHandler) m_inputContentHandler;
3185:                //
3186:                //      sth.setExceptionThrown(e);
3187:                //    }
3188:                //   ContentHandler ch = getContentHandler();
3189:
3190:                //    if(ch instanceof SourceTreeHandler)
3191:                //    {
3192:                //      SourceTreeHandler sth = (SourceTreeHandler) ch;
3193:                //      ((TransformerImpl)(sth.getTransformer())).postExceptionFromThread(e);
3194:                //    }
3195:                m_isTransformDone = true;
3196:                m_exceptionThrown = e;
3197:                ; // should have already been reported via the error handler?
3198:
3199:                synchronized (this ) {
3200:
3201:                    // See message from me on 3/27/2001 to Patrick Moore.
3202:                    //      String msg = e.getMessage();
3203:                    // System.out.println(e.getMessage());
3204:                    // Is this really needed?  -sb
3205:                    notifyAll();
3206:
3207:                    //      if (null == msg)
3208:                    //      {
3209:                    //
3210:                    //        // m_throwNewError = false;
3211:                    //        e.printStackTrace();
3212:                    //      }
3213:                    // throw new org.apache.xml.utils.WrappedRuntimeException(e);
3214:                }
3215:            }
3216:
3217:            /**
3218:             * Run the transform thread.
3219:             */
3220:            public void run() {
3221:
3222:                m_hasBeenReset = false;
3223:
3224:                try {
3225:
3226:                    // int n = ((SourceTreeHandler)getInputContentHandler()).getDTMRoot();
3227:                    // transformNode(n);
3228:                    try {
3229:                        m_isTransformDone = false;
3230:
3231:                        // Should no longer be needed...
3232:                        //          if(m_inputContentHandler instanceof TransformerHandlerImpl)
3233:                        //          {
3234:                        //            TransformerHandlerImpl thi = (TransformerHandlerImpl)m_inputContentHandler;
3235:                        //            thi.waitForInitialEvents();
3236:                        //          }
3237:
3238:                        transformNode(m_doc);
3239:
3240:                    } catch (Exception e) {
3241:                        // e.printStackTrace();
3242:
3243:                        // Strange that the other catch won't catch this...
3244:                        if (null != m_transformThread)
3245:                            postExceptionFromThread(e); // Assume we're on the main thread
3246:                        else
3247:                            throw new RuntimeException(e.getMessage());
3248:                    } finally {
3249:                        m_isTransformDone = true;
3250:
3251:                        if (m_inputContentHandler instanceof  TransformerHandlerImpl) {
3252:                            ((TransformerHandlerImpl) m_inputContentHandler)
3253:                                    .clearCoRoutine();
3254:                        }
3255:
3256:                        //        synchronized (this)
3257:                        //        {
3258:                        //          notifyAll();
3259:                        //        }
3260:                    }
3261:                } catch (Exception e) {
3262:
3263:                    // e.printStackTrace();
3264:                    if (null != m_transformThread)
3265:                        postExceptionFromThread(e);
3266:                    else
3267:                        throw new RuntimeException(e.getMessage()); // Assume we're on the main thread.
3268:                }
3269:            }
3270:
3271:            // Fragment re-execution interfaces for a tool.
3272:
3273:            /**
3274:             * This will get a snapshot of the current executing context 
3275:             *
3276:             *
3277:             * @return TransformSnapshot object, snapshot of executing context
3278:             * @deprecated This is an internal tooling API that nobody seems to be using
3279:             */
3280:            public TransformSnapshot getSnapshot() {
3281:                return new TransformSnapshotImpl(this );
3282:            }
3283:
3284:            /**
3285:             * This will execute the following XSLT instructions
3286:             * from the snapshot point, after the stylesheet execution
3287:             * context has been reset from the snapshot point. 
3288:             *
3289:             * @param ts The snapshot of where to start execution
3290:             *
3291:             * @throws TransformerException
3292:             * @deprecated This is an internal tooling API that nobody seems to be using
3293:             */
3294:            public void executeFromSnapshot(TransformSnapshot ts)
3295:                    throws TransformerException {
3296:
3297:                ElemTemplateElement template = getMatchedTemplate();
3298:                int child = getMatchedNode();
3299:
3300:                pushElemTemplateElement(template); //needed??
3301:                m_xcontext.pushCurrentNode(child); //needed??
3302:                this .executeChildTemplates(template, true); // getResultTreeHandler());
3303:            }
3304:
3305:            /**
3306:             * This will reset the stylesheet execution context
3307:             * from the snapshot point.
3308:             *
3309:             * @param ts The snapshot of where to start execution
3310:             * @deprecated This is an internal tooling API that nobody seems to be using
3311:             */
3312:            public void resetToStylesheet(TransformSnapshot ts) {
3313:                ((TransformSnapshotImpl) ts).apply(this );
3314:            }
3315:
3316:            /**
3317:             * NEEDSDOC Method stopTransformation 
3318:             *
3319:             */
3320:            public void stopTransformation() {
3321:            }
3322:
3323:            /**
3324:             * Test whether whitespace-only text nodes are visible in the logical
3325:             * view of <code>DTM</code>. Normally, this function
3326:             * will be called by the implementation of <code>DTM</code>;
3327:             * it is not normally called directly from
3328:             * user code.
3329:             *
3330:             * @param elementHandle int Handle of the element.
3331:             * @return one of NOTSTRIP, STRIP, or INHERIT.
3332:             */
3333:            public short getShouldStripSpace(int elementHandle, DTM dtm) {
3334:
3335:                try {
3336:                    org.apache.xalan.templates.WhiteSpaceInfo info = m_stylesheetRoot
3337:                            .getWhiteSpaceInfo(m_xcontext, elementHandle, dtm);
3338:
3339:                    if (null == info) {
3340:                        return DTMWSFilter.INHERIT;
3341:                    } else {
3342:
3343:                        // System.out.println("getShouldStripSpace: "+info.getShouldStripSpace());
3344:                        return info.getShouldStripSpace() ? DTMWSFilter.STRIP
3345:                                : DTMWSFilter.NOTSTRIP;
3346:                    }
3347:                } catch (TransformerException se) {
3348:                    return DTMWSFilter.INHERIT;
3349:                }
3350:            }
3351:
3352:            /**
3353:             * Initializer method.
3354:             *
3355:             * @param transformer non-null transformer instance
3356:             * @param realHandler Content Handler instance
3357:             */
3358:            public void init(ToXMLSAXHandler h, Transformer transformer,
3359:                    ContentHandler realHandler) {
3360:                h.setTransformer(transformer);
3361:                h.setContentHandler(realHandler);
3362:            }
3363:
3364:            public void setSerializationHandler(SerializationHandler xoh) {
3365:                m_serializationHandler = xoh;
3366:            }
3367:
3368:            /**
3369:             * Fire off characters, cdate events.
3370:             * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, char[], int, int)
3371:             */
3372:            public void fireGenerateEvent(int eventType, char[] ch, int start,
3373:                    int length) {
3374:
3375:                GenerateEvent ge = new GenerateEvent(this , eventType, ch,
3376:                        start, length);
3377:                m_traceManager.fireGenerateEvent(ge);
3378:            }
3379:
3380:            /**
3381:             * Fire off startElement, endElement events.
3382:             * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String, Attributes)
3383:             */
3384:            public void fireGenerateEvent(int eventType, String name,
3385:                    Attributes atts) {
3386:
3387:                GenerateEvent ge = new GenerateEvent(this , eventType, name,
3388:                        atts);
3389:                m_traceManager.fireGenerateEvent(ge);
3390:            }
3391:
3392:            /**
3393:             * Fire off processingInstruction events.
3394:             * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String, String)
3395:             */
3396:            public void fireGenerateEvent(int eventType, String name,
3397:                    String data) {
3398:                GenerateEvent ge = new GenerateEvent(this , eventType, name,
3399:                        data);
3400:                m_traceManager.fireGenerateEvent(ge);
3401:            }
3402:
3403:            /**
3404:             * Fire off comment and entity ref events.
3405:             * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String)
3406:             */
3407:            public void fireGenerateEvent(int eventType, String data) {
3408:                GenerateEvent ge = new GenerateEvent(this , eventType, data);
3409:                m_traceManager.fireGenerateEvent(ge);
3410:            }
3411:
3412:            /**
3413:             * Fire off startDocument, endDocument events.
3414:             * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int)
3415:             */
3416:            public void fireGenerateEvent(int eventType) {
3417:                GenerateEvent ge = new GenerateEvent(this , eventType);
3418:                m_traceManager.fireGenerateEvent(ge);
3419:            }
3420:
3421:            /**
3422:             * @see org.apache.xml.serializer.SerializerTrace#hasTraceListeners()
3423:             */
3424:            public boolean hasTraceListeners() {
3425:                return m_traceManager.hasTraceListeners();
3426:            }
3427:
3428:            public boolean getDebug() {
3429:                return m_debug;
3430:            }
3431:
3432:            public void setDebug(boolean b) {
3433:                m_debug = b;
3434:            }
3435:
3436:            /**
3437:             * @return Incremental flag
3438:             */
3439:            public boolean getIncremental() {
3440:                return m_incremental;
3441:            }
3442:
3443:            /**
3444:             * @return Optimization flag
3445:             */
3446:            public boolean getOptimize() {
3447:                return m_optimizer;
3448:            }
3449:
3450:            /**
3451:             * @return Source location flag
3452:             */
3453:            public boolean getSource_location() {
3454:                return m_source_location;
3455:            }
3456:
3457:        } // end TransformerImpl class
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.