diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx b/filter/source/xsltfilter/LibXSLTTransformer.cxx index 18f18dcab596..ec9e37441100 100644 --- a/filter/source/xsltfilter/LibXSLTTransformer.cxx +++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx @@ -51,6 +51,7 @@ #include #include #include + #include #include #include @@ -135,10 +136,10 @@ namespace XSLT } }; /** - * ExtFuncOleCB forwards XPath extension function calls registers with libxslt to the OleHandler instance that actually + * ExtFuncOleCB forwards XPath extension function calls registered with libxslt to the OleHandler instance that actually * provides the implementation for those functions. * - * The OLE extension module currently supplies to functions + * The OLE extension module currently supplies two functions * insertByName: registers an OLE object to be later inserted into the output tree. * getByName: reads a previously registered OLE object and returns a base64 encoded string representation. */ @@ -390,7 +391,7 @@ namespace XSLT LibXSLTTransformer::LibXSLTTransformer( const Reference &r) : - m_rServiceFactory(r) + m_rServiceFactory(r), m_Reader(NULL) { } @@ -447,8 +448,9 @@ namespace XSLT Reference xl = *it; xl.get()->started(); } - Reader* r = new Reader(this); - r->create(); + OSL_ENSURE(m_Reader == NULL, "Somebody forgot to call terminate *and* holds a reference to this LibXSLTTransformer instance"); + m_Reader = new Reader(this); + m_Reader->create(); } void @@ -484,6 +486,8 @@ namespace XSLT void LibXSLTTransformer::terminate() throw (RuntimeException) { + m_Reader->terminate(); + delete(m_Reader); m_parameters.clear(); } diff --git a/filter/source/xsltfilter/LibXSLTTransformer.hxx b/filter/source/xsltfilter/LibXSLTTransformer.hxx index 2554558d0485..ccd1dbb6ed0a 100644 --- a/filter/source/xsltfilter/LibXSLTTransformer.hxx +++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx @@ -116,6 +116,16 @@ namespace XSLT ::std::map m_parameters; + osl::Thread* m_Reader; + + protected: + virtual ~LibXSLTTransformer() { + if (m_Reader) { + m_Reader->terminate(); + } + delete(m_Reader); + } + public: // ctor... diff --git a/filter/source/xsltfilter/XSLTFilter.cxx b/filter/source/xsltfilter/XSLTFilter.cxx index 0bf8c1771a3e..e44be63d443b 100644 --- a/filter/source/xsltfilter/XSLTFilter.cxx +++ b/filter/source/xsltfilter/XSLTFilter.cxx @@ -44,14 +44,13 @@ #include #include #include -#include -#include -#include + +#include #include +#include #include -#include #include @@ -63,6 +62,7 @@ #include #include #include + #include #include @@ -71,15 +71,19 @@ #include #include #include -#include -#include #include #include +#include +#include +#include #include + #include #include +#define TRANSFORMATION_TIMEOUT_SEC 60 + using namespace ::rtl; using namespace ::cppu; using namespace ::osl; @@ -92,12 +96,12 @@ using namespace ::com::sun::star::registry; using namespace ::com::sun::star::xml; using namespace ::com::sun::star::xml::sax; using namespace ::com::sun::star::util; +using namespace ::com::sun::star::task; namespace XSLT { - /* - * FLABridge provides some obscure attribute mangling to wordml2000 import/export filters. + * FLABridge provides some obscure attribute mangling to wordml2003 import/export filters. * In the long run, you might want to replace this with an XSLT extension function. */ class FLABridge : public WeakImplHelper1< DocumentHandlerAdapter > @@ -180,22 +184,23 @@ namespace XSLT } /* - * XSLTFilter reads flat xml streams from the XML filter framework and passes + * XSLTFilter reads flat XML streams from the XML filter framework and passes * them to an XSLT transformation service. XSLT transformation errors are * reported to XSLTFilter. * - * Currently, two implemations for the XSLT transformation service exist: + * Currently, two implementations for the XSLT transformation service exist: * a java based service (see XSLTransformer.java) and a libxslt based * service (LibXSLTTransformer.cxx). * - * The libxslt implementation will be used, if the value of the 2nd "UserData" - * parameter of the filter configuration is "libxslt" + * The libxslt implementation will be used by default. + * + * If the value of the 2nd "UserData" parameter of the filter configuration is + * not empty, the service name given there will be used. */ class XSLTFilter : public WeakImplHelper4 { private: - static const OUString LIBXSLT_HELPER_SERVICE_IMPL; // the UNO ServiceFactory Reference m_rServiceFactory; @@ -361,15 +366,19 @@ m_rServiceFactory(r), m_bTerminated(sal_False), m_bError(sal_False) sal_Int32 nLength = aSourceData.getLength(); OUString aName, aFileName, aURL; Reference xInputStream; + Reference xInterActionHandler; for (sal_Int32 i = 0; i < nLength; i++) { aName = aSourceData[i].Name; + Any value = aSourceData[i].Value; if (aName.equalsAscii("InputStream")) - aSourceData[i].Value >>= xInputStream; + value >>= xInputStream; else if (aName.equalsAscii("FileName")) - aSourceData[i].Value >>= aFileName; + value >>= aFileName; else if (aName.equalsAscii("URL")) - aSourceData[i].Value >>= aURL; + value >>= aURL; + else if (aName.equalsAscii("InteractionHandler")) + value >>= xInterActionHandler; } OSL_ASSERT(xInputStream.is()); if (!xInputStream.is()) @@ -447,18 +456,38 @@ m_rServiceFactory(r), m_bTerminated(sal_False), m_bError(sal_False) // transform m_tcontrol->start(); - // osl_waitCondition(m_cTransformed, 0); - if (!m_bError && !m_bTerminated) - { - // parse the transformed XML buffered in the pipe + TimeValue timeout = { TRANSFORMATION_TIMEOUT_SEC, 0}; + oslConditionResult result(osl_waitCondition(m_cTransformed, &timeout)); + while (osl_cond_result_timeout == result) { + if (xInterActionHandler.is()) { + Sequence excArgs(0); + ::com::sun::star::ucb::InteractiveAugmentedIOException exc( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Timeout!")), + static_cast< OWeakObject * >( this ), + InteractionClassification_ERROR, + ::com::sun::star::ucb::IOErrorCode_GENERAL, + excArgs); + Any r; + r <<= exc; + ::comphelper::OInteractionRequest* pRequest = new ::comphelper::OInteractionRequest(r); + Reference< XInteractionRequest > xRequest(pRequest); + ::comphelper::OInteractionRetry* pRetry = new ::comphelper::OInteractionRetry; + ::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort; + pRequest->addContinuation(pRetry); + pRequest->addContinuation(pAbort); + xInterActionHandler->handle(xRequest); + if (pAbort->wasSelected()) { + m_bError = sal_True; + osl_setCondition(m_cTransformed); + } + } + result = osl_waitCondition(m_cTransformed, &timeout); + }; + if (!m_bError) { xSaxParser->parseStream(aInput); - osl_waitCondition(m_cTransformed, 0); - return sal_True; - } - else - { - return sal_False; - } + } + m_tcontrol->terminate(); + return !m_bError; } #if OSL_DEBUG_LEVEL > 0 catch( Exception& exc) @@ -607,6 +636,7 @@ m_rServiceFactory(r), m_bTerminated(sal_False), m_bError(sal_False) ExtendedDocumentHandlerAdapter::endDocument(); // wait for the transformer to finish osl_waitCondition(m_cTransformed, 0); + m_tcontrol->terminate(); if (!m_bError && !m_bTerminated) { return; @@ -618,6 +648,7 @@ m_rServiceFactory(r), m_bTerminated(sal_False), m_bError(sal_False) } + // -------------------------------------- // Component management // -------------------------------------- diff --git a/filter/source/xsltfilter/makefile.mk b/filter/source/xsltfilter/makefile.mk index 473c98f34588..50faea7fe6aa 100644 --- a/filter/source/xsltfilter/makefile.mk +++ b/filter/source/xsltfilter/makefile.mk @@ -54,9 +54,11 @@ SHL1DEF=$(MISC)$/$(SHL1TARGET).def DEF1NAME=$(SHL1TARGET) SHL1STDLIBS= \ - $(TOOLSLIB) \ - $(CPPUHELPERLIB) \ - $(CPPULIB) \ + $(TOOLSLIB) \ + $(CPPUHELPERLIB) \ + $(UCBHELPERLIB) \ + $(COMPHELPERLIB) \ + $(CPPULIB) \ $(XMLOFFLIB) \ $(SALLIB) \ $(LIBXML2LIB) \