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

Generated by: LCOV version 1.10