LCOV - code coverage report
Current view: top level - filter/source/xsltfilter - XSLTFilter.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 15 218 6.9 %
Date: 2014-11-03 Functions: 2 18 11.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <stdio.h>
      22             : 
      23             : #include <cppuhelper/factory.hxx>
      24             : #include <cppuhelper/implbase4.hxx>
      25             : 
      26             : #include <sax/tools/documenthandleradapter.hxx>
      27             : 
      28             : #include <osl/time.h>
      29             : #include <osl/conditn.h>
      30             : #include <rtl/strbuf.hxx>
      31             : #include <tools/urlobj.hxx>
      32             : 
      33             : #include <comphelper/interaction.hxx>
      34             : #include <comphelper/processfactory.hxx>
      35             : 
      36             : #include <com/sun/star/lang/XComponent.hpp>
      37             : #include <com/sun/star/lang/EventObject.hpp>
      38             : 
      39             : #include <com/sun/star/uno/Any.hxx>
      40             : 
      41             : #include <com/sun/star/beans/PropertyValue.hpp>
      42             : 
      43             : #include <com/sun/star/xml/sax/Parser.hpp>
      44             : #include <com/sun/star/xml/sax/InputSource.hpp>
      45             : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
      46             : #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
      47             : #include <com/sun/star/xml/sax/SAXException.hpp>
      48             : #include <com/sun/star/xml/sax/Writer.hpp>
      49             : #include <com/sun/star/xml/XImportFilter.hpp>
      50             : #include <com/sun/star/xml/XExportFilter.hpp>
      51             : 
      52             : #include <com/sun/star/util/theMacroExpander.hpp>
      53             : 
      54             : #include <com/sun/star/io/Pipe.hpp>
      55             : #include <com/sun/star/io/XInputStream.hpp>
      56             : #include <com/sun/star/io/XOutputStream.hpp>
      57             : #include <com/sun/star/io/XActiveDataSource.hpp>
      58             : #include <com/sun/star/io/XActiveDataSink.hpp>
      59             : #include <com/sun/star/io/XActiveDataControl.hpp>
      60             : #include <com/sun/star/io/XSeekable.hpp>
      61             : #include <com/sun/star/io/XStreamListener.hpp>
      62             : #include <com/sun/star/util/PathSubstitution.hpp>
      63             : #include <com/sun/star/util/XStringSubstitution.hpp>
      64             : #include <com/sun/star/beans/NamedValue.hpp>
      65             : #include <com/sun/star/task/XInteractionHandler.hpp>
      66             : #include <com/sun/star/task/XInteractionRequest.hpp>
      67             : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
      68             : #include <com/sun/star/xml/xslt/XSLT2Transformer.hpp>
      69             : #include <com/sun/star/xml/xslt/XSLTTransformer.hpp>
      70             : 
      71             : #include <xmloff/attrlist.hxx>
      72             : 
      73             : #include <LibXSLTTransformer.hxx>
      74             : 
      75             : #define TRANSFORMATION_TIMEOUT_SEC 60
      76             : 
      77             : using namespace ::cppu;
      78             : using namespace ::osl;
      79             : using namespace ::sax;
      80             : using namespace ::com::sun::star::beans;
      81             : using namespace ::com::sun::star::io;
      82             : using namespace ::com::sun::star::uno;
      83             : using namespace ::com::sun::star::lang;
      84             : using namespace ::com::sun::star::registry;
      85             : using namespace ::com::sun::star::xml;
      86             : using namespace ::com::sun::star::xml::sax;
      87             : using namespace ::com::sun::star::util;
      88             : using namespace ::com::sun::star::task;
      89             : 
      90             : namespace XSLT
      91             : {
      92             :     /*
      93             :      * XSLTFilter reads flat XML streams from the XML filter framework and passes
      94             :      * them to an XSLT transformation service. XSLT transformation errors are
      95             :      * reported to XSLTFilter.
      96             :      *
      97             :      * Currently, our transformation service is libxslt based, so it
      98             :      * only supports XSLT 1.0. There is a possibility to use XSLT 2.0
      99             :      * supporting service from an extension for a specific filter; the
     100             :      * service must support com.sun.star.xml.xslt.XSLT2Transformer.
     101             :      */
     102             :     class XSLTFilter : public WeakImplHelper4<XImportFilter, XExportFilter,
     103             :             XStreamListener, ExtendedDocumentHandlerAdapter>
     104             :     {
     105             :     private:
     106             : 
     107             :         // the UNO ServiceFactory
     108             :         css::uno::Reference<XComponentContext> m_xContext;
     109             : 
     110             :         // DocumentHandler interface of the css::xml::sax::Writer service
     111             :         css::uno::Reference<XOutputStream> m_rOutputStream;
     112             : 
     113             :         css::uno::Reference<xslt::XXSLTTransformer> m_tcontrol;
     114             : 
     115             :         oslCondition m_cTransformed;
     116             :         bool m_bTerminated;
     117             :         bool m_bError;
     118             : 
     119             :         OUString m_aExportBaseUrl;
     120             : 
     121             :         OUString
     122             :         rel2abs(const OUString&);
     123             :         OUString
     124             :         expandUrl(const OUString&);
     125             : 
     126             :         css::uno::Reference<xslt::XXSLTTransformer> impl_createTransformer(const OUString& rTransformer, const Sequence<Any>& rArgs);
     127             : 
     128             :     public:
     129             : 
     130             :         // ctor...
     131             :         XSLTFilter(const css::uno::Reference<XComponentContext> &r);
     132             : 
     133             :         virtual ~XSLTFilter();
     134             : 
     135             :         // XStreamListener
     136             :         virtual void SAL_CALL
     137             :         error(const Any& a) throw (RuntimeException, std::exception) SAL_OVERRIDE;
     138             :         virtual void SAL_CALL
     139             :         closed() throw (RuntimeException, std::exception) SAL_OVERRIDE;
     140             :         virtual void SAL_CALL
     141             :         terminated() throw (RuntimeException, std::exception) SAL_OVERRIDE;
     142             :         virtual void SAL_CALL
     143             :         started() throw (RuntimeException, std::exception) SAL_OVERRIDE;
     144             :         virtual void SAL_CALL
     145             :         disposing(const EventObject& e) throw (RuntimeException, std::exception) SAL_OVERRIDE;
     146             : 
     147             :         // XImportFilter
     148             :         virtual sal_Bool SAL_CALL
     149             :         importer(const Sequence<PropertyValue>& aSourceData, const css::uno::Reference<
     150             :                 XDocumentHandler>& xHandler,
     151             :                 const Sequence<OUString>& msUserData) throw (RuntimeException, std::exception) SAL_OVERRIDE;
     152             : 
     153             :         // XExportFilter
     154             :         virtual sal_Bool SAL_CALL
     155             :         exporter(const Sequence<PropertyValue>& aSourceData, const Sequence<
     156             :                 OUString>& msUserData) throw (RuntimeException, std::exception) SAL_OVERRIDE;
     157             : 
     158             :         // XDocumentHandler
     159             :         virtual void SAL_CALL
     160             :         startDocument() throw (SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     161             :         virtual void SAL_CALL
     162             :         endDocument() throw (SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     163             :     };
     164             : 
     165           0 :     XSLTFilter::XSLTFilter(const css::uno::Reference<XComponentContext> &r):
     166           0 :         m_xContext(r), m_bTerminated(false), m_bError(false)
     167             :     {
     168           0 :         m_cTransformed = osl_createCondition();
     169           0 :     }
     170             : 
     171           0 :     XSLTFilter::~XSLTFilter()
     172             :     {
     173           0 :         osl_destroyCondition(m_cTransformed);
     174           0 :     }
     175             : 
     176             :     void
     177           0 :     XSLTFilter::disposing(const EventObject&) throw (RuntimeException, std::exception)
     178             :     {
     179           0 :     }
     180             : 
     181             :     OUString
     182           0 :     XSLTFilter::expandUrl(const OUString& sUrl)
     183             :     {
     184           0 :         OUString sExpandedUrl;
     185             :         try
     186             :             {
     187             :                 css::uno::Reference<XMacroExpander>
     188           0 :                         xMacroExpander = theMacroExpander::get(m_xContext);
     189           0 :                 sExpandedUrl = xMacroExpander->expandMacros(sUrl);
     190           0 :                 sal_Int32 nPos = sExpandedUrl.indexOf( "vnd.sun.star.expand:" );
     191           0 :                 if (nPos != -1)
     192           0 :                     sExpandedUrl = sExpandedUrl.copy(nPos + 20);
     193             :             }
     194           0 :         catch (const Exception&)
     195             :             {
     196             :             }
     197           0 :         return sExpandedUrl;
     198             :     }
     199             : 
     200             :     css::uno::Reference<xslt::XXSLTTransformer>
     201           0 :     XSLTFilter::impl_createTransformer(const OUString& rTransformer, const Sequence<Any>& rArgs)
     202             :     {
     203           0 :         css::uno::Reference<xslt::XXSLTTransformer> xTransformer;
     204             : 
     205             :         // check if the filter needs XSLT-2.0-capable transformer
     206             :         // COMPATIBILITY: libreoffice 3.5/3.6 used to save the impl.
     207             :         // name of the XSLT 2.0 transformation service there, so check
     208             :         // for that too (it is sufficient to check that there is _a_
     209             :         // service name there)
     210           0 :         if (rTransformer.toBoolean() || rTransformer.startsWith("com.sun."))
     211             :         {
     212             :             try
     213             :             {
     214           0 :                 xTransformer = xslt::XSLT2Transformer::create(m_xContext, rArgs);
     215             :             }
     216           0 :             catch (const Exception&)
     217             :             {
     218             :                 // TODO: put a dialog telling about the need to install
     219             :                 // xslt2-transformer extension here
     220             :                 SAL_WARN("filter.xslt", "could not create XSLT 2.0 transformer");
     221           0 :                 throw;
     222             :             }
     223             :         }
     224             : 
     225             :         // instantiation of XSLT 2.0 transformer service failed, or the
     226             :         // filter does not need it
     227           0 :         if (!xTransformer.is())
     228             :         {
     229           0 :             xTransformer = xslt::XSLTTransformer::create(m_xContext, rArgs);
     230             :         }
     231             : 
     232           0 :         return xTransformer;
     233             :     }
     234             : 
     235             :     void
     236           0 :     XSLTFilter::started() throw (RuntimeException, std::exception)
     237             :     {
     238           0 :         osl_resetCondition(m_cTransformed);
     239           0 :     }
     240             :     void
     241           0 :     XSLTFilter::error(const Any& a) throw (RuntimeException, std::exception)
     242             :     {
     243           0 :         Exception e;
     244           0 :         if (a >>= e)
     245             :         {
     246             :             SAL_WARN("filter.xslt", "XSLTFilter::error was called: " << e.Message);
     247             :         }
     248           0 :         m_bError = true;
     249           0 :         osl_setCondition(m_cTransformed);
     250           0 :     }
     251             :     void
     252           0 :     XSLTFilter::closed() throw (RuntimeException, std::exception)
     253             :     {
     254           0 :         osl_setCondition(m_cTransformed);
     255           0 :     }
     256             :     void
     257           0 :     XSLTFilter::terminated() throw (RuntimeException, std::exception)
     258             :     {
     259           0 :         m_bTerminated = true;
     260           0 :         osl_setCondition(m_cTransformed);
     261           0 :     }
     262             : 
     263             :     OUString
     264           0 :     XSLTFilter::rel2abs(const OUString& s)
     265             :     {
     266             : 
     267             :         css::uno::Reference<XStringSubstitution>
     268           0 :                 subs(css::util::PathSubstitution::create(m_xContext));
     269           0 :         OUString aWorkingDir(subs->getSubstituteVariableValue(OUString( "$(progurl)")));
     270           0 :         INetURLObject aObj(aWorkingDir);
     271           0 :         aObj.setFinalSlash();
     272             :         bool bWasAbsolute;
     273             :         INetURLObject aURL = aObj.smartRel2Abs(s, bWasAbsolute, false,
     274           0 :                 INetURLObject::WAS_ENCODED, RTL_TEXTENCODING_UTF8, true);
     275           0 :         return aURL.GetMainURL(INetURLObject::NO_DECODE);
     276             :     }
     277             : 
     278             :     sal_Bool
     279           0 :     XSLTFilter::importer(const Sequence<PropertyValue>& aSourceData,
     280             :             const css::uno::Reference<XDocumentHandler>& xHandler, const Sequence<
     281             :                     OUString>& msUserData) throw (RuntimeException, std::exception)
     282             :     {
     283           0 :         if (msUserData.getLength() < 5)
     284           0 :             return sal_False;
     285             : 
     286           0 :         OUString udStyleSheet = rel2abs(msUserData[4]);
     287             : 
     288             :         // get information from media descriptor
     289             :         // the imput stream that represents the imported file
     290             :         // is most important here since we need to supply it to
     291             :         // the sax parser that drives the supplied document handler
     292           0 :         sal_Int32 nLength = aSourceData.getLength();
     293           0 :         OUString aName, aFileName, aURL;
     294           0 :         css::uno::Reference<XInputStream> xInputStream;
     295           0 :         css::uno::Reference<XInteractionHandler> xInterActionHandler;
     296           0 :         for (sal_Int32 i = 0; i < nLength; i++)
     297             :             {
     298           0 :                 aName = aSourceData[i].Name;
     299           0 :                 Any value = aSourceData[i].Value;
     300           0 :                 if ( aName == "InputStream" )
     301           0 :                     value >>= xInputStream;
     302           0 :                 else if ( aName == "FileName" )
     303           0 :                     value >>= aFileName;
     304           0 :                 else if ( aName == "URL" )
     305           0 :                     value >>= aURL;
     306           0 :                 else if ( aName == "InteractionHandler" )
     307           0 :                     value >>= xInterActionHandler;
     308           0 :             }
     309             :         OSL_ASSERT(xInputStream.is());
     310           0 :         if (!xInputStream.is())
     311           0 :             return sal_False;
     312             : 
     313             :         // create SAX parser that will read the document file
     314             :         // and provide events to xHandler passed to this call
     315           0 :         css::uno::Reference<XParser> xSaxParser = Parser::create(m_xContext);
     316             : 
     317             :         // create transformer
     318           0 :         Sequence<Any> args(3);
     319           0 :         NamedValue nv;
     320             : 
     321           0 :         nv.Name = "StylesheetURL";
     322           0 :         nv.Value <<= expandUrl(udStyleSheet);
     323           0 :         args[0] <<= nv;
     324           0 :         nv.Name = "SourceURL";
     325           0 :         nv.Value <<= aURL;
     326           0 :         args[1] <<= nv;
     327           0 :         nv.Name = "SourceBaseURL";
     328           0 :         nv.Value <<= OUString(INetURLObject(aURL).getBase());
     329           0 :         args[2] <<= nv;
     330             : 
     331           0 :         m_tcontrol = impl_createTransformer(msUserData[1], args);
     332             : 
     333             :         OSL_ASSERT(xHandler.is());
     334             :         OSL_ASSERT(xInputStream.is());
     335             :         OSL_ASSERT(m_tcontrol.is());
     336           0 :         if (xHandler.is() && xInputStream.is() && m_tcontrol.is())
     337             :             {
     338             :                 try
     339             :                     {
     340           0 :                         css::uno::Reference<css::io::XSeekable> xSeek(xInputStream, UNO_QUERY);
     341           0 :                         if (xSeek.is())
     342           0 :                             xSeek->seek(0);
     343             : 
     344             :                         // we want to be notfied when the processing is done...
     345           0 :                         m_tcontrol->addListener(css::uno::Reference<XStreamListener> (
     346           0 :                                 this));
     347             : 
     348             :                         // connect input to transformer
     349           0 :                         css::uno::Reference<XActiveDataSink> tsink(m_tcontrol, UNO_QUERY);
     350           0 :                         tsink->setInputStream(xInputStream);
     351             : 
     352             :                         // create pipe
     353             :                         css::uno::Reference<XOutputStream> pipeout(
     354             :                                         Pipe::create(m_xContext),
     355           0 :                                         UNO_QUERY);
     356           0 :                         css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
     357             : 
     358             :                         //connect transformer to pipe
     359             :                         css::uno::Reference<XActiveDataSource> tsource(m_tcontrol,
     360           0 :                                 UNO_QUERY);
     361           0 :                         tsource->setOutputStream(pipeout);
     362             : 
     363             :                         // connect pipe to sax parser
     364           0 :                         InputSource aInput;
     365           0 :                         aInput.sSystemId = aURL;
     366           0 :                         aInput.sPublicId = aURL;
     367           0 :                         aInput.aInputStream = pipein;
     368             : 
     369             :                         // set doc handler
     370           0 :                         xSaxParser->setDocumentHandler(xHandler);
     371             : 
     372             :                         // transform
     373           0 :                         m_tcontrol->start();
     374           0 :                         TimeValue timeout = { TRANSFORMATION_TIMEOUT_SEC, 0};
     375           0 :                         oslConditionResult result(osl_waitCondition(m_cTransformed, &timeout));
     376           0 :                         while (osl_cond_result_timeout == result) {
     377           0 :                                 if (xInterActionHandler.is()) {
     378           0 :                                         Sequence<Any> excArgs(0);
     379             :                                         ::com::sun::star::ucb::InteractiveAugmentedIOException exc(
     380             :                                                 OUString("Timeout!"),
     381             :                                                 static_cast< OWeakObject * >( this ),
     382             :                                                 InteractionClassification_ERROR,
     383             :                                                 ::com::sun::star::ucb::IOErrorCode_GENERAL,
     384           0 :                                                  excArgs);
     385           0 :                                         Any r;
     386           0 :                                         r <<= exc;
     387           0 :                                         ::comphelper::OInteractionRequest* pRequest = new ::comphelper::OInteractionRequest(r);
     388           0 :                                         css::uno::Reference< XInteractionRequest > xRequest(pRequest);
     389           0 :                                         ::comphelper::OInteractionRetry* pRetry = new ::comphelper::OInteractionRetry;
     390           0 :                                         ::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort;
     391           0 :                                         pRequest->addContinuation(pRetry);
     392           0 :                                         pRequest->addContinuation(pAbort);
     393           0 :                                         xInterActionHandler->handle(xRequest);
     394           0 :                                         if (pAbort->wasSelected()) {
     395           0 :                                                 m_bError = true;
     396           0 :                                                 osl_setCondition(m_cTransformed);
     397           0 :                                         }
     398             :                                 }
     399           0 :                                 result = osl_waitCondition(m_cTransformed, &timeout);
     400             :                         };
     401           0 :                         if (!m_bError) {
     402           0 :                                 xSaxParser->parseStream(aInput);
     403             :                         }
     404           0 :                         m_tcontrol->terminate();
     405           0 :                         return !m_bError;
     406             :                     }
     407             : #if OSL_DEBUG_LEVEL > 0
     408             :                 catch( const Exception& exc)
     409             : #else
     410           0 :                 catch (const Exception&)
     411             : #endif
     412             :                     {
     413             :                         // something went wrong
     414             :                         OSL_FAIL(OUStringToOString(exc.Message, RTL_TEXTENCODING_ASCII_US).getStr());
     415           0 :                         return sal_False;
     416             :                     }
     417             :             }
     418             :         else
     419             :             {
     420           0 :                 return sal_False;
     421           0 :             }
     422             :     }
     423             : 
     424             :     sal_Bool
     425           0 :     XSLTFilter::exporter(const Sequence<PropertyValue>& aSourceData,
     426             :             const Sequence<OUString>& msUserData) throw (RuntimeException, std::exception)
     427             :     {
     428           0 :         if (msUserData.getLength() < 6)
     429           0 :             return sal_False;
     430             : 
     431             :         // get interesting values from user data
     432           0 :         OUString udStyleSheet = rel2abs(msUserData[5]);
     433             : 
     434             :         // read source data
     435             :         // we are especialy interested in the output stream
     436             :         // since that is where our xml-writer will push the data
     437             :         // from it's data-source interface
     438           0 :         OUString aName, sURL;
     439           0 :         bool bIndent = false;
     440           0 :         OUString aDoctypePublic;
     441             :         // css::uno::Reference<XOutputStream> rOutputStream;
     442           0 :         sal_Int32 nLength = aSourceData.getLength();
     443           0 :         for (sal_Int32 i = 0; i < nLength; i++)
     444             :             {
     445           0 :                 aName = aSourceData[i].Name;
     446           0 :                 if ( aName == "Indent" )
     447           0 :                     aSourceData[i].Value >>= bIndent;
     448           0 :                 if ( aName == "DocType_Public" )
     449           0 :                     aSourceData[i].Value >>= aDoctypePublic;
     450           0 :                 if ( aName == "OutputStream" )
     451           0 :                     aSourceData[i].Value >>= m_rOutputStream;
     452           0 :                 else if ( aName == "URL" )
     453           0 :                     aSourceData[i].Value >>= sURL;
     454             :             }
     455             : 
     456           0 :         if (!getDelegate().is())
     457             :             {
     458             :                 // get the document writer
     459             :                 setDelegate(css::uno::Reference<XExtendedDocumentHandler>(
     460             :                                 Writer::create(m_xContext),
     461           0 :                                 UNO_QUERY_THROW));
     462             :             }
     463             : 
     464             :         // create transformer
     465           0 :         Sequence<Any> args(4);
     466           0 :         NamedValue nv;
     467           0 :         nv.Name = "StylesheetURL";
     468           0 :         nv.Value <<= expandUrl(udStyleSheet);
     469           0 :         args[0] <<= nv;
     470           0 :         nv.Name = "TargetURL";
     471           0 :         nv.Value <<= sURL;
     472           0 :         args[1] <<= nv;
     473           0 :         nv.Name = "DoctypePublic";
     474           0 :         nv.Value <<= aDoctypePublic;
     475           0 :         args[2] <<= nv;
     476           0 :         nv.Name = "TargetBaseURL";
     477           0 :         INetURLObject ineturl(sURL);
     478           0 :         ineturl.removeSegment();
     479           0 :         m_aExportBaseUrl = ineturl.GetMainURL(INetURLObject::NO_DECODE);
     480           0 :         nv.Value <<= m_aExportBaseUrl;
     481           0 :         args[3] <<= nv;
     482             : 
     483           0 :         m_tcontrol = impl_createTransformer(msUserData[1], args);
     484             : 
     485             :         OSL_ASSERT(m_rOutputStream.is());
     486             :         OSL_ASSERT(m_tcontrol.is());
     487           0 :         if (m_tcontrol.is() && m_rOutputStream.is())
     488             :             {
     489             :                 // we want to be notfied when the processing is done...
     490           0 :                 m_tcontrol->addListener(css::uno::Reference<XStreamListener> (this));
     491             : 
     492             :                 // create pipe
     493             :                 css::uno::Reference<XOutputStream> pipeout(
     494             :                                 Pipe::create(m_xContext),
     495           0 :                                 UNO_QUERY);
     496           0 :                 css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
     497             : 
     498             :                 // connect sax writer to pipe
     499           0 :                 css::uno::Reference<XActiveDataSource> xmlsource(getDelegate(),
     500           0 :                         UNO_QUERY);
     501           0 :                 xmlsource->setOutputStream(pipeout);
     502             : 
     503             :                 // connect pipe to transformer
     504           0 :                 css::uno::Reference<XActiveDataSink> tsink(m_tcontrol, UNO_QUERY);
     505           0 :                 tsink->setInputStream(pipein);
     506             : 
     507             :                 // connect transformer to output
     508           0 :                 css::uno::Reference<XActiveDataSource> tsource(m_tcontrol, UNO_QUERY);
     509           0 :                 tsource->setOutputStream(m_rOutputStream);
     510             : 
     511             :                 // we will start receiving events after returning 'true'.
     512             :                 // we will start the transformation as soon as we receive the startDocument
     513             :                 // event.
     514           0 :                 return sal_True;
     515             :             }
     516             :         else
     517             :             {
     518           0 :                 return sal_False;
     519           0 :             }
     520             :     }
     521             : 
     522             :     // for the DocumentHandler implementation, we just proxy the the
     523             :     // events to the XML writer that we created upon the output stream
     524             :     // that was provided by the XMLFilterAdapter
     525             :     void
     526           0 :     XSLTFilter::startDocument() throw (SAXException, RuntimeException, std::exception)
     527             :     {
     528           0 :         ExtendedDocumentHandlerAdapter::startDocument();
     529           0 :         m_tcontrol->start();
     530           0 :     }
     531             : 
     532             :     void
     533           0 :     XSLTFilter::endDocument() throw (SAXException, RuntimeException, std::exception)
     534             :     {
     535           0 :         ExtendedDocumentHandlerAdapter::endDocument();
     536             :         // wait for the transformer to finish
     537           0 :         osl_waitCondition(m_cTransformed, 0);
     538           0 :         m_tcontrol->terminate();
     539           0 :         if (!m_bError && !m_bTerminated)
     540             :             {
     541           0 :                 return;
     542             :             }
     543             :         else
     544             :             {
     545           0 :                 throw RuntimeException();
     546             :             }
     547             : 
     548             :     }
     549             : 
     550             : 
     551             : 
     552             :     // Component management
     553             : 
     554             : #define FILTER_SERVICE_NAME "com.sun.star.documentconversion.XSLTFilter"
     555             : #define FILTER_IMPL_NAME "com.sun.star.comp.documentconversion.XSLTFilter"
     556             : #define TRANSFORMER_SERVICE_NAME "com.sun.star.xml.xslt.XSLTTransformer"
     557             : #define TRANSFORMER_IMPL_NAME "com.sun.star.comp.documentconversion.LibXSLTTransformer"
     558             : 
     559             :     static css::uno::Reference<XInterface> SAL_CALL
     560           4 :     CreateTransformerInstance(const css::uno::Reference<XMultiServiceFactory> &r)
     561             :     {
     562           4 :         return css::uno::Reference<XInterface> ((OWeakObject *) new LibXSLTTransformer( comphelper::getComponentContext(r) ));
     563             :     }
     564             : 
     565             :     static css::uno::Reference<XInterface> SAL_CALL
     566           0 :     CreateFilterInstance(const css::uno::Reference<XMultiServiceFactory> &r)
     567             :     {
     568           0 :         return css::uno::Reference<XInterface> ((OWeakObject *) new XSLTFilter( comphelper::getComponentContext(r) ));
     569             :     }
     570             : 
     571             : }
     572             : 
     573             : using namespace XSLT;
     574             : 
     575             : extern "C"
     576             : {
     577           2 :     SAL_DLLPUBLIC_EXPORT void * SAL_CALL xsltfilter_component_getFactory(const sal_Char * pImplName,
     578             :             void * pServiceManager, void * /* pRegistryKey */)
     579             :     {
     580           2 :         void * pRet = 0;
     581             : 
     582           2 :         if (pServiceManager)
     583             :             {
     584           2 :                 if (rtl_str_compare(pImplName, FILTER_IMPL_NAME) == 0)
     585             :                     {
     586           0 :                         Sequence<OUString> serviceNames(1);
     587           0 :                         serviceNames.getArray()[0] = FILTER_SERVICE_NAME;
     588             : 
     589             :                         css::uno::Reference<XSingleServiceFactory>
     590             :                                 xFactory(
     591             :                                         createSingleFactory(
     592             :                                                 reinterpret_cast<XMultiServiceFactory *> (pServiceManager),
     593             :                                                 OUString::createFromAscii(
     594             :                                                         pImplName),
     595             :                                                 CreateFilterInstance,
     596           0 :                                                 serviceNames));
     597             : 
     598           0 :                         if (xFactory.is())
     599             :                             {
     600           0 :                                 xFactory->acquire();
     601           0 :                                 pRet = xFactory.get();
     602           0 :                             }
     603             :                     }
     604           2 :                 else if (rtl_str_compare(pImplName, TRANSFORMER_IMPL_NAME) == 0)
     605             :                     {
     606           2 :                         Sequence<OUString> serviceNames(1);
     607           2 :                         serviceNames.getArray()[0] = TRANSFORMER_SERVICE_NAME;
     608             :                         css::uno::Reference<XSingleServiceFactory>
     609             :                                 xFactory(
     610             :                                         createSingleFactory(
     611             :                                                 reinterpret_cast<XMultiServiceFactory *> (pServiceManager),
     612             :                                                 OUString::createFromAscii(
     613             :                                                         pImplName),
     614             :                                                 CreateTransformerInstance,
     615           4 :                                                 serviceNames));
     616             : 
     617           2 :                         if (xFactory.is())
     618             :                             {
     619           2 :                                 xFactory->acquire();
     620           2 :                                 pRet = xFactory.get();
     621           2 :                             }
     622             : 
     623             :                     }
     624             :             }
     625           2 :         return pRet;
     626             :     }
     627             : 
     628             : } // extern "C"
     629             : 
     630             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10