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

Generated by: LCOV version 1.11