| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2001 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xalan" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 1999, International |
| * Business Machines, Inc., http://www.ibm.com. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| #include "XalanTransformer.hpp" |
| |
| |
| |
| #include <algorithm> |
| |
| |
| |
| #include <sax/SAXException.hpp> |
| |
| |
| |
| #include <XalanDOM/XalanDOMException.hpp> |
| |
| |
| |
| #include <PlatformSupport/DOMStringHelper.hpp> |
| #include <PlatformSupport/DOMStringPrintWriter.hpp> |
| #include <PlatformSupport/XalanOutputStreamPrintWriter.hpp> |
| |
| |
| |
| #include <XPath/XObjectFactoryDefault.hpp> |
| #include <XPath/XPathFactoryBlock.hpp> |
| #include <XPath/XPathFactoryDefault.hpp> |
| |
| |
| |
| #include <XSLT/StylesheetConstructionContextDefault.hpp> |
| #include <XSLT/StylesheetExecutionContextDefault.hpp> |
| #include <XSLT/StylesheetRoot.hpp> |
| #include <XSLT/XSLTEngineImpl.hpp> |
| #include <XSLT/XSLTInit.hpp> |
| #include <XSLT/XSLTProcessorEnvSupportDefault.hpp> |
| |
| |
| |
| #include <XalanSourceTree/XalanSourceTreeDOMSupport.hpp> |
| #include <XalanSourceTree/XalanSourceTreeParserLiaison.hpp> |
| |
| |
| |
| #include <XalanExtensions/XalanExtensions.hpp> |
| |
| |
| |
| //#define XALAN_USE_ICU |
| #if defined(XALAN_USE_ICU) |
| #include <ICUBridge/ICUBridge.hpp> |
| #include <ICUBridge/FunctionICUFormatNumber.hpp> |
| #include <ICUBridge/ICUBridgeCollationCompareFunctor.hpp> |
| #endif |
| |
| |
| |
| #include "XalanCompiledStylesheetDefault.hpp" |
| #include "XalanDefaultDocumentBuilder.hpp" |
| #include "XalanDefaultParsedSource.hpp" |
| #include "XalanTransformerOutputStream.hpp" |
| #include "XercesDOMParsedSource.hpp" |
| |
| |
| |
| const XSLTInit* XalanTransformer::s_xsltInit = 0; |
| |
| #if defined(XALAN_USE_ICU) |
| static const ICUBridgeCollationCompareFunctor* theICUFunctor = 0; |
| #endif |
| |
| |
| |
| XalanTransformer::XalanTransformer(): |
| m_compiledStylesheets(), |
| m_parsedSources(), |
| m_paramPairs(), |
| m_functionPairs(), |
| m_errorMessage(1, '\0'), |
| m_stylesheetExecutionContext(new StylesheetExecutionContextDefault) |
| { |
| #if defined(XALAN_USE_ICU) |
| m_stylesheetExecutionContext->installCollationCompareFunctor(theICUFunctor); |
| #endif |
| } |
| |
| |
| |
| XalanTransformer::~XalanTransformer() |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::for_each; |
| #endif |
| |
| // Clean up all entries in the compliledStylesheets vector. |
| for_each(m_compiledStylesheets.begin(), |
| m_compiledStylesheets.end(), |
| DeleteFunctor<XalanCompiledStylesheet>()); |
| |
| // Clean up all entries in the compliledStylesheets vector. |
| for_each(m_parsedSources.begin(), |
| m_parsedSources.end(), |
| DeleteFunctor<XalanParsedSource>()); |
| |
| for (FunctionParamPairVectorType::size_type i = 0; i < m_functionPairs.size(); ++i) |
| { |
| delete m_functionPairs[i].second; |
| } |
| |
| m_functionPairs.clear(); |
| |
| delete m_stylesheetExecutionContext; |
| } |
| |
| |
| |
| void |
| XalanTransformer::initialize() |
| { |
| // Initialize Xalan. |
| s_xsltInit = new XSLTInit; |
| |
| const XalanDOMString theXalanNamespace(StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("http://xml.apache.org/xalan"))); |
| |
| XalanTransformer::installExternalFunctionGlobal( |
| theXalanNamespace, |
| StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("difference")), |
| FunctionDifference()); |
| |
| XalanTransformer::installExternalFunctionGlobal( |
| theXalanNamespace, |
| StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("distinct")), |
| FunctionDistinct()); |
| |
| XalanTransformer::installExternalFunctionGlobal( |
| theXalanNamespace, |
| StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("evaluate")), |
| FunctionEvaluate()); |
| |
| XalanTransformer::installExternalFunctionGlobal( |
| theXalanNamespace, |
| StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("hasSameNodes")), |
| FunctionHasSameNodes()); |
| |
| XalanTransformer::installExternalFunctionGlobal( |
| theXalanNamespace, |
| StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("intersection")), |
| FunctionIntersection()); |
| |
| XalanTransformer::installExternalFunctionGlobal( |
| theXalanNamespace, |
| StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("nodeset")), |
| FunctionNodeSet()); |
| |
| #if defined(XALAN_USE_ICU) |
| theICUFunctor = new ICUBridgeCollationCompareFunctor; |
| |
| // Install the ICU version of format-number... |
| XPath::installFunction( |
| StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("format-number")), |
| FunctionICUFormatNumber()); |
| #endif |
| } |
| |
| |
| |
| void |
| XalanTransformer::terminate() |
| { |
| // Terminate Xalan and release memory. |
| #if defined(XALAN_CANNOT_DELETE_CONST) |
| (XSLTInit*) s_xsltInit; |
| #else |
| delete s_xsltInit; |
| #endif |
| |
| s_xsltInit = 0; |
| |
| #if defined(XALAN_USE_ICU) |
| #if defined(XALAN_CANNOT_DELETE_CONST) |
| delete (ICUBridgeCollationCompareFunctor*)theICUFunctor; |
| #else |
| delete theICUFunctor; |
| #endif |
| |
| theICUFunctor = 0; |
| #endif |
| } |
| |
| |
| |
| int |
| XalanTransformer::transform( |
| const XalanParsedSource& theParsedXML, |
| const XSLTInputSource& theStylesheetSource, |
| const XSLTResultTarget& theResultTarget) |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::for_each; |
| #endif |
| |
| int theResult = 0; |
| |
| // Clear the error message. |
| m_errorMessage.resize(1, '\0'); |
| |
| // Store error messages from problem listener. |
| XalanDOMString theErrorMessage; |
| |
| try |
| { |
| XalanDocument* const theSourceDocument = theParsedXML.getDocument(); |
| assert(theSourceDocument != 0); |
| |
| // Create the helper object that is necessary for running the processor... |
| XalanAutoPtr<XalanParsedSourceHelper> theHelper(theParsedXML.createHelper()); |
| assert(theHelper.get() != 0); |
| |
| DOMSupport& theDOMSupport = theHelper->getDOMSupport(); |
| |
| XMLParserLiaison& theParserLiaison = theHelper->getParserLiaison(); |
| |
| // Create some more support objects... |
| XSLTProcessorEnvSupportDefault theXSLTProcessorEnvSupport; |
| |
| XObjectFactoryDefault theXObjectFactory; |
| |
| XPathFactoryDefault theXPathFactory; |
| |
| // Create a processor... |
| XSLTEngineImpl theProcessor( |
| theParserLiaison, |
| theXSLTProcessorEnvSupport, |
| theDOMSupport, |
| theXObjectFactory, |
| theXPathFactory); |
| |
| theXSLTProcessorEnvSupport.setProcessor(&theProcessor); |
| |
| const XalanDOMString& theSourceURI = theParsedXML.getURI(); |
| |
| if (length(theSourceURI) > 0) |
| { |
| theXSLTProcessorEnvSupport.setSourceDocument(theSourceURI, theSourceDocument); |
| } |
| |
| // Create a problem listener and send output to a XalanDOMString. |
| DOMStringPrintWriter thePrintWriter(theErrorMessage); |
| |
| ProblemListenerDefault theProblemListener(&thePrintWriter); |
| |
| theProcessor.setProblemListener(&theProblemListener); |
| |
| theParserLiaison.setExecutionContext(*m_stylesheetExecutionContext); |
| |
| // Create a stylesheet construction context, |
| // using the stylesheet's factory support objects. |
| StylesheetConstructionContextDefault theStylesheetConstructionContext( |
| theProcessor, |
| theXSLTProcessorEnvSupport, |
| theXPathFactory); |
| |
| // Hack used to cast away const. |
| XSLTResultTarget tempResultTarget(theResultTarget); |
| |
| const EnsureReset theReset(*this); |
| |
| // Set up the stylesheet execution context. |
| m_stylesheetExecutionContext->setXPathEnvSupport(&theXSLTProcessorEnvSupport); |
| |
| m_stylesheetExecutionContext->setDOMSupport(&theDOMSupport); |
| |
| m_stylesheetExecutionContext->setXObjectFactory(&theXObjectFactory); |
| |
| m_stylesheetExecutionContext->setXSLTProcessor(&theProcessor); |
| |
| // Set the parameters if any. |
| for (ParamPairVectorType::size_type i = 0; i < m_paramPairs.size(); ++i) |
| { |
| theProcessor.setStylesheetParam( |
| m_paramPairs[i].first, |
| m_paramPairs[i].second); |
| } |
| |
| // Set the functions if any. |
| for (FunctionParamPairVectorType::size_type f = 0; f < m_functionPairs.size(); ++f) |
| { |
| theXSLTProcessorEnvSupport.installExternalFunctionLocal( |
| m_functionPairs[f].first.getNamespace(), |
| m_functionPairs[f].first.getLocalPart(), |
| *(m_functionPairs[f].second)); |
| } |
| |
| // Create an input source for the source document... |
| XSLTInputSource theDocumentInputSource(theSourceDocument); |
| |
| // Set the system ID, so relative URIs are resolved properly... |
| theDocumentInputSource.setSystemId(c_wstr(theSourceURI)); |
| |
| // Do the transformation... |
| theProcessor.process( |
| theDocumentInputSource, |
| theStylesheetSource, |
| tempResultTarget, |
| theStylesheetConstructionContext, |
| *m_stylesheetExecutionContext); |
| } |
| catch (XSLException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -1; |
| } |
| catch (SAXException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -2; |
| } |
| catch (XMLException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -3; |
| } |
| catch(const XalanDOMException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| XalanDOMString theMessage("XalanDOMException caught. The code is "); |
| |
| append(theMessage, LongToDOMString(long(e.getExceptionCode()))); |
| append(theMessage, XalanDOMString(".")); |
| |
| TranscodeToLocalCodePage(theMessage, m_errorMessage, true); |
| } |
| |
| theResult = -4; |
| } |
| |
| return theResult; |
| } |
| |
| |
| |
| int |
| XalanTransformer::transform( |
| const XalanParsedSource& theParsedXML, |
| const XalanCompiledStylesheet* theCompiledStylesheet, |
| const XSLTResultTarget& theResultTarget) |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::for_each; |
| #endif |
| |
| int theResult = 0; |
| |
| // Clear the error message. |
| m_errorMessage.resize(1, '\0'); |
| |
| // Store error messages from problem listener. |
| XalanDOMString theErrorMessage; |
| |
| try |
| { |
| XalanDocument* const theSourceDocument = theParsedXML.getDocument(); |
| assert(theSourceDocument != 0); |
| |
| // Create the helper object that is necessary for running the processor... |
| XalanAutoPtr<XalanParsedSourceHelper> theHelper(theParsedXML.createHelper()); |
| assert(theHelper.get() != 0); |
| |
| DOMSupport& theDOMSupport = theHelper->getDOMSupport(); |
| |
| XMLParserLiaison& theParserLiaison = theHelper->getParserLiaison(); |
| |
| // Create some more support objects... |
| XSLTProcessorEnvSupportDefault theXSLTProcessorEnvSupport; |
| |
| XObjectFactoryDefault theXObjectFactory; |
| |
| XPathFactoryDefault theXPathFactory; |
| |
| // Create a processor... |
| XSLTEngineImpl theProcessor( |
| theParserLiaison, |
| theXSLTProcessorEnvSupport, |
| theDOMSupport, |
| theXObjectFactory, |
| theXPathFactory); |
| |
| theXSLTProcessorEnvSupport.setProcessor(&theProcessor); |
| |
| const XalanDOMString& theSourceURI = theParsedXML.getURI(); |
| |
| if (length(theSourceURI) > 0) |
| { |
| theXSLTProcessorEnvSupport.setSourceDocument(theSourceURI, theSourceDocument); |
| } |
| |
| // Create a problem listener and send output to a XalanDOMString. |
| DOMStringPrintWriter thePrintWriter(theErrorMessage); |
| |
| ProblemListenerDefault theProblemListener(&thePrintWriter); |
| |
| theProcessor.setProblemListener(&theProblemListener); |
| |
| // Since the result target is not const in our |
| // internal intefaces, we'll pass in a local copy |
| // of the one provided... |
| XSLTResultTarget tempResultTarget(theResultTarget); |
| |
| const EnsureReset theReset(*this); |
| |
| // Set up the stylesheet execution context. |
| m_stylesheetExecutionContext->setXPathEnvSupport(&theXSLTProcessorEnvSupport); |
| |
| m_stylesheetExecutionContext->setDOMSupport(&theDOMSupport); |
| |
| m_stylesheetExecutionContext->setXObjectFactory(&theXObjectFactory); |
| |
| m_stylesheetExecutionContext->setXSLTProcessor(&theProcessor); |
| |
| // Set the compiled stylesheet. |
| m_stylesheetExecutionContext->setStylesheetRoot(theCompiledStylesheet->getStylesheetRoot()); |
| |
| // Set the parameters if any. |
| for (ParamPairVectorType::size_type i = 0; i < m_paramPairs.size(); ++i) |
| { |
| theProcessor.setStylesheetParam( |
| m_paramPairs[i].first, |
| m_paramPairs[i].second); |
| } |
| |
| // Set the functions if any. |
| for (FunctionParamPairVectorType::size_type f = 0; f < m_functionPairs.size(); ++f) |
| { |
| theXSLTProcessorEnvSupport.installExternalFunctionLocal( |
| m_functionPairs[f].first.getNamespace(), |
| m_functionPairs[f].first.getLocalPart(), |
| *(m_functionPairs[f].second)); |
| } |
| |
| // Create an input source for the source document... |
| XSLTInputSource theDocumentInputSource(theSourceDocument); |
| |
| // Set the system ID, so relative URIs are resolved properly... |
| theDocumentInputSource.setSystemId(c_wstr(theSourceURI)); |
| |
| // Do the transformation... |
| theProcessor.process( |
| theDocumentInputSource, |
| tempResultTarget, |
| *m_stylesheetExecutionContext); |
| } |
| catch (XSLException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -1; |
| } |
| catch (SAXException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -2; |
| } |
| catch (XMLException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -3; |
| } |
| catch(const XalanDOMException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| XalanDOMString theMessage("XalanDOMException caught. The code is "); |
| |
| append(theMessage, LongToDOMString(long(e.getExceptionCode()))); |
| append(theMessage, XalanDOMString(".")); |
| |
| TranscodeToLocalCodePage(theMessage, m_errorMessage, true); |
| } |
| |
| theResult = -4; |
| } |
| |
| return theResult; |
| } |
| |
| |
| |
| int |
| XalanTransformer::transform( |
| const XSLTInputSource& theInputSource, |
| const XalanCompiledStylesheet* theCompiledStylesheet, |
| const XSLTResultTarget& theResultTarget) |
| { |
| const XalanParsedSource* theParsedSource = 0; |
| |
| const int theResult = parseSource(theInputSource, theParsedSource); |
| |
| if (theResult != 0) |
| { |
| return theResult; |
| } |
| else |
| { |
| assert(theParsedSource != 0); |
| |
| // Make sure the parsed source is destroyed when |
| // the transformation is finished... |
| EnsureDestroyParsedSource theGuard(*this, theParsedSource); |
| |
| // Do the transformation... |
| return transform( |
| *theParsedSource, |
| theCompiledStylesheet, |
| theResultTarget); |
| } |
| } |
| |
| int |
| XalanTransformer::transform( |
| const XSLTInputSource& theInputSource, |
| const XSLTInputSource& theStylesheetSource, |
| const XSLTResultTarget& theResultTarget) |
| { |
| // Parse the source document. |
| const XalanParsedSource* theParsedSource = 0; |
| |
| const int theResult = parseSource(theInputSource, theParsedSource); |
| |
| if (theResult != 0) |
| { |
| return theResult; |
| } |
| else |
| { |
| assert(theParsedSource != 0); |
| |
| // Make sure the parsed source is destroyed when |
| // the transformation is finished... |
| EnsureDestroyParsedSource theGuard(*this, theParsedSource); |
| |
| // Do the transformation... |
| return transform( |
| *theParsedSource, |
| theStylesheetSource, |
| theResultTarget); |
| } |
| } |
| |
| |
| |
| int |
| XalanTransformer::transform( |
| const XSLTInputSource& theInputSource, |
| const XSLTResultTarget& theResultTarget) |
| { |
| // Do the transformation... |
| return transform( |
| theInputSource, |
| XSLTInputSource(), |
| theResultTarget); |
| } |
| |
| |
| |
| int |
| XalanTransformer::transform( |
| const XSLTInputSource& theInputSource, |
| const XSLTInputSource& theStylesheetSource, |
| void* theOutputHandle, |
| XalanOutputHandlerType theOutputHandler, |
| XalanFlushHandlerType theFlushHandler) |
| { |
| // Set to output target to the callback |
| XalanTransformerOutputStream theOutputStream(theOutputHandle, theOutputHandler, theFlushHandler); |
| |
| XalanOutputStreamPrintWriter thePrintWriter(theOutputStream); |
| |
| XSLTResultTarget theResultTarget(&thePrintWriter); |
| |
| // Do the transformation... |
| return transform( |
| theInputSource, |
| theStylesheetSource, |
| theResultTarget); |
| } |
| |
| |
| |
| int |
| XalanTransformer::transform( |
| const XalanParsedSource& theParsedSource, |
| const XalanCompiledStylesheet* theCompiledStylesheet, |
| void* theOutputHandle, |
| XalanOutputHandlerType theOutputHandler, |
| XalanFlushHandlerType theFlushHandler) |
| { |
| // Set to output target to the callback |
| XalanTransformerOutputStream theOutputStream(theOutputHandle, theOutputHandler, theFlushHandler); |
| |
| XalanOutputStreamPrintWriter thePrintWriter(theOutputStream); |
| |
| XSLTResultTarget theResultTarget(&thePrintWriter); |
| |
| // Do the transformation... |
| return transform( |
| theParsedSource, |
| theCompiledStylesheet, |
| theResultTarget); |
| } |
| |
| |
| |
| int |
| XalanTransformer::transform( |
| const XSLTInputSource& theInputSource, |
| void* theOutputHandle, |
| XalanOutputHandlerType theOutputHandler, |
| XalanFlushHandlerType theFlushHandler) |
| { |
| // Set to output target to the callback |
| XalanTransformerOutputStream theOutputStream(theOutputHandle, theOutputHandler, theFlushHandler); |
| |
| XalanOutputStreamPrintWriter thePrintWriter(theOutputStream); |
| |
| XSLTResultTarget theResultTarget(&thePrintWriter); |
| |
| // Do the transformation... |
| return transform( |
| theInputSource, |
| XSLTInputSource(), |
| theResultTarget); |
| } |
| |
| |
| |
| int |
| XalanTransformer::compileStylesheet( |
| const XSLTInputSource& theStylesheetSource, |
| const XalanCompiledStylesheet*& theCompiledStylesheet) |
| { |
| // Clear the error message. |
| m_errorMessage.resize(1, '\0'); |
| |
| // Store error messages from problem listener. |
| XalanDOMString theErrorMessage; |
| |
| int theResult = 0; |
| |
| try |
| { |
| // Create some support objects that are necessary for running the processor... |
| XalanSourceTreeDOMSupport theDOMSupport; |
| |
| XalanSourceTreeParserLiaison theParserLiaison(theDOMSupport); |
| |
| // Hook the two together... |
| theDOMSupport.setParserLiaison(&theParserLiaison); |
| |
| // Create some more support objects... |
| XSLTProcessorEnvSupportDefault theXSLTProcessorEnvSupport; |
| |
| XObjectFactoryDefault theXObjectFactory; |
| |
| XPathFactoryDefault theXPathFactory; |
| |
| // Create a processor... |
| XSLTEngineImpl theProcessor( |
| theParserLiaison, |
| theXSLTProcessorEnvSupport, |
| theDOMSupport, |
| theXObjectFactory, |
| theXPathFactory); |
| |
| // Create a problem listener and send output to a XalanDOMString. |
| DOMStringPrintWriter thePrintWriter(theErrorMessage); |
| |
| ProblemListenerDefault theProblemListener(&thePrintWriter); |
| |
| theProcessor.setProblemListener(&theProblemListener); |
| |
| // Create a new XalanCompiledStylesheet. |
| theCompiledStylesheet = |
| new XalanCompiledStylesheetDefault( |
| theStylesheetSource, |
| theXSLTProcessorEnvSupport, |
| theProcessor); |
| |
| // Store it in a vector. |
| m_compiledStylesheets.push_back(theCompiledStylesheet); |
| } |
| catch (XSLException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -1; |
| } |
| catch (SAXException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -2; |
| } |
| catch (XMLException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| } |
| |
| theResult = -3; |
| } |
| catch(const XalanDOMException& e) |
| { |
| if (length(theErrorMessage) != 0) |
| { |
| TranscodeToLocalCodePage(theErrorMessage, m_errorMessage, true); |
| } |
| else |
| { |
| XalanDOMString theMessage("XalanDOMException caught. The code is "); |
| |
| append(theMessage, LongToDOMString(long(e.getExceptionCode()))); |
| |
| append(theMessage, XalanDOMString(".")); |
| |
| TranscodeToLocalCodePage(theMessage, m_errorMessage, true); |
| } |
| |
| theResult = -4; |
| } |
| |
| return theResult; |
| } |
| |
| |
| |
| int |
| XalanTransformer::destroyStylesheet(const XalanCompiledStylesheet* theStylesheet) |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::find; |
| #endif |
| |
| const CompiledStylesheetPtrVectorType::iterator i = |
| find( |
| m_compiledStylesheets.begin(), |
| m_compiledStylesheets.end(), |
| theStylesheet); |
| |
| if (i == m_compiledStylesheets.end()) |
| { |
| const char* const theStylesheetErrorMessage = |
| "An invalid compiled stylesheet was provided."; |
| |
| const unsigned int theLength = |
| length(theStylesheetErrorMessage); |
| |
| m_errorMessage.resize(theLength + 1, '\0'); |
| |
| strncpy(&*m_errorMessage.begin(), theStylesheetErrorMessage, theLength); |
| |
| return -1; |
| } |
| else |
| { |
| m_compiledStylesheets.erase(i); |
| |
| #if defined(XALAN_CANNOT_DELETE_CONST) |
| delete (XalanCompiledStylesheet*) theStylesheet; |
| #else |
| delete theStylesheet; |
| #endif |
| |
| return 0; |
| } |
| } |
| |
| |
| |
| int |
| XalanTransformer::parseSource( |
| const XSLTInputSource& theInputSource, |
| const XalanParsedSource*& theParsedSource, |
| bool useXercesDOM) |
| { |
| // Clear the error message. |
| m_errorMessage.clear(); |
| m_errorMessage.push_back(0); |
| |
| int theResult = 0; |
| |
| try |
| { |
| if(useXercesDOM == true) |
| { |
| theParsedSource = new XercesDOMParsedSource(theInputSource); |
| } |
| else |
| { |
| theParsedSource = new XalanDefaultParsedSource(theInputSource); |
| } |
| |
| // Store it in a vector. |
| m_parsedSources.push_back(theParsedSource); |
| } |
| catch (XSLException& e) |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| |
| theResult = -1; |
| } |
| catch (SAXException& e) |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| |
| theResult = -2; |
| } |
| catch (XMLException& e) |
| { |
| TranscodeToLocalCodePage(e.getMessage(), m_errorMessage, true); |
| |
| theResult = -3; |
| } |
| catch(const XalanDOMException& e) |
| { |
| XalanDOMString theMessage("XalanDOMException caught. The code is "); |
| |
| append(theMessage, LongToDOMString(long(e.getExceptionCode()))); |
| |
| append(theMessage, XalanDOMString(".")); |
| |
| TranscodeToLocalCodePage(theMessage, m_errorMessage, true); |
| |
| theResult = -3; |
| } |
| |
| return theResult; |
| } |
| |
| |
| |
| int |
| XalanTransformer::destroyParsedSource(const XalanParsedSource* theParsedSource) |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::find; |
| #endif |
| |
| const ParsedSourcePtrVectorType::iterator i = |
| find( |
| m_parsedSources.begin(), |
| m_parsedSources.end(), |
| theParsedSource); |
| |
| if (i == m_parsedSources.end()) |
| { |
| const char* const theParsedSourceErrorMessage = |
| "An invalid parsed source was provided."; |
| |
| const unsigned int theLength = |
| length(theParsedSourceErrorMessage); |
| |
| m_errorMessage.resize(theLength + 1, '\0'); |
| |
| strncpy(&*m_errorMessage.begin(), theParsedSourceErrorMessage, theLength); |
| |
| return -1; |
| } |
| else |
| { |
| m_parsedSources.erase(i); |
| |
| #if defined(XALAN_CANNOT_DELETE_CONST) |
| delete (XalanCompiledStylesheet*) theParsedSource; |
| #else |
| delete theParsedSource; |
| #endif |
| |
| return 0; |
| } |
| } |
| |
| |
| |
| void |
| XalanTransformer::setStylesheetParam( |
| const XalanDOMString& key, |
| const XalanDOMString& expression) |
| { |
| // Store the stylesheet parameter in a vector. |
| m_paramPairs.push_back(ParamPairType(key, expression)); |
| } |
| |
| |
| |
| XalanDocumentBuilder* |
| XalanTransformer::createDocumentBuilder() |
| { |
| m_parsedSources.reserve(m_parsedSources.size() + 1); |
| |
| XalanDocumentBuilder* const theNewBuilder = new XalanDefaultDocumentBuilder; |
| |
| m_parsedSources.push_back(theNewBuilder); |
| |
| return theNewBuilder; |
| } |
| |
| |
| |
| void |
| XalanTransformer::destroyDocumentBuilder(XalanDocumentBuilder* theDocumentBuilder) |
| { |
| destroyParsedSource(theDocumentBuilder); |
| } |
| |
| |
| |
| void |
| XalanTransformer::installExternalFunction( |
| const XalanDOMString& theNamespace, |
| const XalanDOMString& functionName, |
| const Function& function) |
| { |
| m_functionPairs.push_back(FunctionPairType(XalanQNameByValue(theNamespace, functionName), function.clone())); |
| } |
| |
| |
| |
| void |
| XalanTransformer::installExternalFunctionGlobal( |
| const XalanDOMString& theNamespace, |
| const XalanDOMString& functionName, |
| const Function& function) |
| { |
| XSLTProcessorEnvSupportDefault::installExternalFunctionGlobal( |
| theNamespace, |
| functionName, |
| function); |
| } |
| |
| |
| |
| void |
| XalanTransformer::uninstallExternalFunction( |
| const XalanDOMString& theNamespace, |
| const XalanDOMString& functionName) |
| { |
| for (FunctionParamPairVectorType::size_type i = 0; i < m_functionPairs.size(); ++i) |
| { |
| if(XalanQNameByReference(theNamespace, functionName).equals(m_functionPairs[i].first)) |
| { |
| delete m_functionPairs[i].second; |
| |
| m_functionPairs.erase(m_functionPairs.begin() + i); |
| } |
| } |
| } |
| |
| |
| |
| void |
| XalanTransformer::uninstallExternalFunctionGlobal( |
| const XalanDOMString& theNamespace, |
| const XalanDOMString& functionName) |
| { |
| XSLTProcessorEnvSupportDefault::uninstallExternalFunctionGlobal( |
| theNamespace, |
| functionName); |
| } |
| |
| |
| |
| |
| const char* |
| XalanTransformer::getLastError() const |
| { |
| return &m_errorMessage[0]; |
| } |
| |
| |
| |
| void |
| XalanTransformer::reset() |
| { |
| try |
| { |
| // Reset objects. |
| m_stylesheetExecutionContext->setXPathEnvSupport(0); |
| |
| m_stylesheetExecutionContext->setDOMSupport(0); |
| |
| m_stylesheetExecutionContext->setXObjectFactory(0); |
| |
| m_stylesheetExecutionContext->setXSLTProcessor(0); |
| |
| m_stylesheetExecutionContext->reset(); |
| |
| // Clear the ParamPairVectorType. |
| m_paramPairs.clear(); |
| } |
| catch(...) |
| { |
| } |
| } |
| |
| |
| |
| |
| XalanTransformer::EnsureReset::~EnsureReset() |
| { |
| m_transformer.m_stylesheetExecutionContext->reset(); |
| |
| m_transformer.reset(); |
| } |