blob: bf569967d88f882df1f3b3767c9ac64ab4f46ea1 [file] [log] [blame]
/*
* 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();
}