summaryrefslogtreecommitdiff
path: root/filter/source/xsltfilter/XSLTFilter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/xsltfilter/XSLTFilter.cxx')
-rw-r--r--filter/source/xsltfilter/XSLTFilter.cxx731
1 files changed, 731 insertions, 0 deletions
diff --git a/filter/source/xsltfilter/XSLTFilter.cxx b/filter/source/xsltfilter/XSLTFilter.cxx
new file mode 100644
index 000000000000..2ee532086ef5
--- /dev/null
+++ b/filter/source/xsltfilter/XSLTFilter.cxx
@@ -0,0 +1,731 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+
+#include <stdio.h>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include <osl/time.h>
+#include <osl/conditn.h>
+#include <tools/urlobj.hxx>
+#include <osl/module.h>
+#include <osl/file.hxx>
+#include <osl/process.h>
+
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Type.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#include <com/sun/star/xml/XImportFilter.hpp>
+#include <com/sun/star/xml/XExportFilter.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/io/XStreamListener.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/util/XStringSubstitution.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include <xmloff/attrlist.hxx>
+#include <fla.hxx>
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::util;
+
+namespace XSLT {
+
+
+class FLABridge : public WeakImplHelper1< XDocumentHandler>
+{
+private:
+ const Reference<XDocumentHandler>& m_rDocumentHandler;
+ const sal_Unicode *eval(const sal_Unicode *expr, sal_Int32 exprLen);
+ FLA::Evaluator ev;
+ bool active;
+
+public:
+ FLABridge(const Reference<XDocumentHandler>& m_rDocumentHandler);
+
+ // XDocumentHandler
+ virtual void SAL_CALL startDocument()
+ throw (SAXException,RuntimeException);
+ virtual void SAL_CALL endDocument()
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL startElement(const OUString& str, const Reference<XAttributeList>& attriblist)
+ throw (SAXException,RuntimeException);
+ virtual void SAL_CALL endElement(const OUString& str)
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL characters(const OUString& str)
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace(const OUString& str)
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL processingInstruction(const OUString& str, const OUString& str2)
+ throw (com::sun::star::xml::sax::SAXException,RuntimeException);
+ virtual void SAL_CALL setDocumentLocator(const Reference<XLocator>& doclocator)
+ throw (SAXException,RuntimeException);
+
+};
+
+FLABridge::FLABridge(const Reference<XDocumentHandler>& _rDocumentHandler) : m_rDocumentHandler(_rDocumentHandler), active(false)
+{
+}
+
+void FLABridge::startDocument() throw (SAXException,RuntimeException){
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->startDocument();
+}
+
+void FLABridge::endDocument() throw (SAXException,RuntimeException){
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->endDocument();
+
+}
+
+
+void FLABridge::startElement(const OUString& str, const Reference<XAttributeList>& attriblist)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ if (active)
+ {
+// SvXMLAttributeList* _attriblist=SvXMLAttributeList::getImplementation(attriblist);
+ const int len=attriblist->getLength();
+ SvXMLAttributeList *_newattriblist= new SvXMLAttributeList();
+ for(int i=0;i<len;i++)
+ {
+ const OUString& name=attriblist->getNameByIndex( sal::static_int_cast<sal_Int16>( i ) );
+ sal_Int32 pos;
+ static const OUString _value_(".value", 6, RTL_TEXTENCODING_ASCII_US);
+ if ((pos=name.lastIndexOf(L'.'))!=-1 && name.match(_value_, pos))
+ {
+ const OUString newName(name, pos);
+ const OUString& value=attriblist->getValueByIndex( sal::static_int_cast<sal_Int16>( i ) );
+ const OUString newValue(ev.eval(value.getStr(), value.getLength()));
+ if (newValue.getLength()>0)
+ {
+ _newattriblist->AddAttribute(newName, newValue);
+ }
+ }
+ else
+ {
+ _newattriblist->AddAttribute(name, attriblist->getValueByIndex( sal::static_int_cast<sal_Int16>( i )));
+ }
+ };
+ const Reference<XAttributeList> newattriblist(_newattriblist);
+ m_rDocumentHandler->startElement(str, newattriblist);
+ }
+ else
+ {
+ if (str.compareToAscii("fla:fla.activate")==0)
+ {
+ active=1;
+ }
+ m_rDocumentHandler->startElement(str, attriblist);
+ }
+}
+
+void FLABridge::endElement(const OUString& str)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->endElement(str);
+}
+
+void FLABridge::characters(const OUString& str)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->characters(str);
+}
+
+void FLABridge::ignorableWhitespace(const OUString& str)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->ignorableWhitespace(str);
+}
+
+void FLABridge::processingInstruction(const OUString& str, const OUString& str2)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->processingInstruction(str, str2);
+}
+
+void FLABridge::setDocumentLocator(const Reference<XLocator>& doclocator)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->setDocumentLocator(doclocator);
+}
+
+
+
+class XSLTFilter : public WeakImplHelper4< XImportFilter, XExportFilter, XDocumentHandler, XStreamListener>
+{
+private:
+ // the UNO ServiceFactory
+ Reference< XMultiServiceFactory > m_rServiceFactory;
+
+ // DocumentHandler interface of the css::xml::sax::Writer service
+ Reference < XExtendedDocumentHandler > m_rDocumentHandler;
+ Reference < XOutputStream > m_rOutputStream;
+
+ // controls pretty-printing
+ sal_Bool m_bPrettyPrint;
+
+ Reference< XActiveDataControl > m_tcontrol;
+ oslCondition m_cTransformed;
+ sal_Bool m_bTerminated;
+ sal_Bool m_bError;
+
+ OUString m_aExportBaseUrl;
+ OUString m_aOldBaseUrl;
+
+ OUString rel2abs(const OUString&);
+ OUString expandUrl(const OUString&);
+
+public:
+
+ // ctor...
+ XSLTFilter( const Reference< XMultiServiceFactory > &r );
+
+ // XStreamListener
+ virtual void SAL_CALL error(const Any& a) throw (RuntimeException);
+ virtual void SAL_CALL closed() throw (RuntimeException);
+ virtual void SAL_CALL terminated() throw (RuntimeException);
+ virtual void SAL_CALL started() throw (RuntimeException);
+ virtual void SAL_CALL disposing(const EventObject& e) throw (RuntimeException);
+
+
+ // XImportFilter
+ virtual sal_Bool SAL_CALL importer(
+ const Sequence<PropertyValue>& aSourceData,
+ const Reference<XDocumentHandler>& xHandler,
+ const Sequence<OUString>& msUserData)
+ throw(RuntimeException);
+
+ // XExportFilter
+ virtual sal_Bool SAL_CALL exporter(
+ const Sequence<PropertyValue>& aSourceData,
+ const Sequence<OUString>& msUserData)
+ throw(RuntimeException);
+
+ // XDocumentHandler
+ virtual void SAL_CALL startDocument()
+ throw (SAXException,RuntimeException);
+ virtual void SAL_CALL endDocument()
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL startElement(const OUString& str, const Reference<XAttributeList>& attriblist)
+ throw (SAXException,RuntimeException);
+ virtual void SAL_CALL endElement(const OUString& str)
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL characters(const OUString& str)
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace(const OUString& str)
+ throw (SAXException, RuntimeException);
+ virtual void SAL_CALL processingInstruction(const OUString& str, const OUString& str2)
+ throw (com::sun::star::xml::sax::SAXException,RuntimeException);
+ virtual void SAL_CALL setDocumentLocator(const Reference<XLocator>& doclocator)
+ throw (SAXException,RuntimeException);
+};
+
+XSLTFilter::XSLTFilter( const Reference< XMultiServiceFactory > &r )
+ : m_rServiceFactory(r)
+ , m_bPrettyPrint(sal_True)
+ , m_bTerminated(sal_False)
+ , m_bError(sal_False)
+{
+ m_cTransformed = osl_createCondition();
+}
+
+void XSLTFilter::disposing(const EventObject& ) throw (RuntimeException)
+{
+}
+
+::rtl::OUString XSLTFilter::expandUrl( const ::rtl::OUString& sUrl )
+{
+ ::rtl::OUString sExpandedUrl;
+ try
+ {
+ Reference< XComponentContext > xContext;
+ Reference< XPropertySet > xProps( m_rServiceFactory, UNO_QUERY_THROW );
+ xContext.set( xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "DefaultContext" ) ), UNO_QUERY_THROW );
+ Reference< XMacroExpander > xMacroExpander( xContext->getValueByName( ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), UNO_QUERY_THROW );
+ sExpandedUrl = xMacroExpander->expandMacros(sUrl);
+ sal_Int32 nPos = sExpandedUrl.indexOf(::rtl::OUString::createFromAscii("vnd.sun.star.expand:"));
+ if ( nPos != -1 )
+ sExpandedUrl = sExpandedUrl.copy(nPos+20);
+ }
+ catch (Exception&) {}
+ return sExpandedUrl;
+}
+
+void XSLTFilter::started() throw (RuntimeException)
+{
+ osl_resetCondition(m_cTransformed);
+}
+void XSLTFilter::error(const Any& a) throw (RuntimeException)
+{
+ Exception e;
+ if ( a >>= e)
+ {
+ OString aMessage("XSLTFilter::error was called: ");
+ aMessage += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMessage);
+ }
+ m_bError = sal_True;
+ osl_setCondition(m_cTransformed);
+}
+void XSLTFilter::closed() throw (RuntimeException)
+{
+ osl_setCondition(m_cTransformed);
+}
+void XSLTFilter::terminated() throw (RuntimeException)
+{
+ m_bTerminated = sal_True;
+ osl_setCondition(m_cTransformed);
+}
+
+OUString XSLTFilter::rel2abs(const OUString& s)
+{
+
+ Reference< XStringSubstitution > subs(m_rServiceFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.util.PathSubstitution")), UNO_QUERY);
+ OUString aWorkingDir = subs->getSubstituteVariableValue(OUString::createFromAscii("$(progurl)"));
+ INetURLObject aObj( aWorkingDir );
+ aObj.setFinalSlash();
+ bool bWasAbsolute;
+ INetURLObject aURL = aObj.smartRel2Abs(
+ s, bWasAbsolute, false, INetURLObject::WAS_ENCODED, RTL_TEXTENCODING_UTF8, true );
+ return aURL.GetMainURL(INetURLObject::NO_DECODE);
+}
+
+
+
+sal_Bool XSLTFilter::importer(
+ const Sequence<PropertyValue>& aSourceData,
+ const Reference<XDocumentHandler>& xHandler,
+ const Sequence<OUString>& msUserData)
+ throw (RuntimeException)
+{
+ if ( msUserData.getLength() < 5 )
+ return sal_False;
+
+ OUString udImport = msUserData[2];
+ OUString udStyleSheet = rel2abs(msUserData[4]);
+
+ // get information from media descriptor
+ // the imput stream that represents the imported file
+ // is most important here since we need to supply it to
+ // the sax parser that drives the supplied document handler
+ sal_Int32 nLength = aSourceData.getLength();
+ OUString aName, aFileName, aURL;
+ Reference< XInputStream > xInputStream;
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ aName = aSourceData[i].Name;
+ if (aName.equalsAscii("InputStream"))
+ aSourceData[i].Value >>= xInputStream;
+ else if ( aName.equalsAscii("FileName"))
+ aSourceData[i].Value >>= aFileName;
+ else if ( aName.equalsAscii("URL"))
+ aSourceData[i].Value >>= aURL;
+ }
+ OSL_ASSERT(xInputStream.is());
+ if (!xInputStream.is()) return sal_False;
+
+ // create SAX parser that will read the document file
+ // and provide events to xHandler passed to this call
+ Reference < XParser > xSaxParser( m_rServiceFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.xml.sax.Parser")), UNO_QUERY );
+ OSL_ASSERT(xSaxParser.is());
+ if(!xSaxParser.is())return sal_False;
+
+ // create transformer
+ Sequence< Any > args(3);
+ NamedValue nv;
+
+ nv.Name = OUString::createFromAscii("StylesheetURL");
+ nv.Value <<= expandUrl(udStyleSheet); args[0] <<= nv;
+ nv.Name = OUString::createFromAscii("SourceURL");
+ nv.Value <<= aURL; args[1] <<= nv;
+ nv.Name = OUString::createFromAscii("SourceBaseURL");
+ nv.Value <<= OUString(INetURLObject(aURL).getBase());
+ args[2] <<= nv;
+
+ m_tcontrol = Reference< XActiveDataControl >(m_rServiceFactory->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.comp.JAXTHelper"), args), UNO_QUERY);
+
+ OSL_ASSERT(xHandler.is());
+ OSL_ASSERT(xInputStream.is());
+ OSL_ASSERT(m_tcontrol.is());
+ if (xHandler.is() && xInputStream.is() && m_tcontrol.is())
+ {
+ try
+ {
+ // we want to be notfied when the processing is done...
+ m_tcontrol->addListener(Reference< XStreamListener >(this));
+
+ // connect input to transformer
+ Reference< XActiveDataSink > tsink(m_tcontrol, UNO_QUERY);
+ tsink->setInputStream(xInputStream);
+
+ // create pipe
+ Reference< XOutputStream > pipeout(m_rServiceFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.io.Pipe")), UNO_QUERY);
+ Reference< XInputStream > pipein(pipeout, UNO_QUERY);
+
+ //connect transformer to pipe
+ Reference< XActiveDataSource > tsource(m_tcontrol, UNO_QUERY);
+ tsource->setOutputStream(pipeout);
+
+ // connect pipe to sax parser
+ InputSource aInput;
+ aInput.sSystemId = aURL;
+ aInput.sPublicId = aURL;
+ aInput.aInputStream = pipein;
+
+ // set doc handler
+ xSaxParser->setDocumentHandler(new FLABridge(xHandler));
+
+ // transform
+ m_tcontrol->start();
+ // osl_waitCondition(m_cTransformed, 0);
+ if (!m_bError && !m_bTerminated)
+ {
+ // parse the transformed XML buffered in the pipe
+ xSaxParser->parseStream(aInput);
+ osl_waitCondition(m_cTransformed, 0);
+ return sal_True;
+ } else {
+ return sal_False;
+ }
+ }
+#if OSL_DEBUG_LEVEL > 0
+ catch( Exception& exc)
+#else
+ catch( Exception& )
+#endif
+ {
+ // something went wrong
+ OSL_ENSURE(0, OUStringToOString(exc.Message, RTL_TEXTENCODING_ASCII_US).getStr());
+ return sal_False;
+ }
+ } else
+ {
+ return sal_False;
+ }
+}
+
+sal_Bool XSLTFilter::exporter(
+ const Sequence<PropertyValue>& aSourceData,
+ const Sequence<OUString>& msUserData)
+ throw (RuntimeException)
+{
+ if ( msUserData.getLength() < 6 )
+ return sal_False;
+
+ // get interesting values from user data
+ OUString udImport = msUserData[2];
+ OUString udStyleSheet = rel2abs(msUserData[5]);
+
+ // read source data
+ // we are especialy interested in the output stream
+ // since that is where our xml-writer will push the data
+ // from it's data-source interface
+ OUString aName, sURL;
+ sal_Bool bIndent = sal_False;
+ OUString aDoctypePublic;
+ OUString aDoctypeSystem;
+ // Reference<XOutputStream> rOutputStream;
+ sal_Int32 nLength = aSourceData.getLength();
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ aName = aSourceData[i].Name;
+ if ( aName.equalsAscii("Indent"))
+ aSourceData[i].Value >>= bIndent;
+ if ( aName.equalsAscii("DocType_Public"))
+ aSourceData[i].Value >>= aDoctypePublic;
+ if ( aName.equalsAscii("DocType_System"))
+ aSourceData[i].Value >>= aDoctypeSystem;
+ if ( aName.equalsAscii("OutputStream"))
+ aSourceData[i].Value >>= m_rOutputStream;
+ else if ( aName.equalsAscii("URL" ))
+ aSourceData[i].Value >>= sURL;
+ }
+
+ if (!m_rDocumentHandler.is()) {
+ // get the document writer
+ m_rDocumentHandler = Reference<XExtendedDocumentHandler>(
+ m_rServiceFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.xml.sax.Writer")),
+ UNO_QUERY);
+ }
+
+ // create transformer
+ Sequence< Any > args(4);
+ NamedValue nv;
+ nv.Name = OUString::createFromAscii("StylesheetURL");
+ nv.Value <<= expandUrl(udStyleSheet); args[0] <<= nv;
+ nv.Name = OUString::createFromAscii("TargetURL");
+ nv.Value <<= sURL; args[1] <<= nv;
+ nv.Name = OUString::createFromAscii("DoctypeSystem");
+ nv.Value <<= aDoctypeSystem; args[2] <<= nv;
+ nv.Name = OUString::createFromAscii("DoctypePublic");
+ nv.Value <<= aDoctypePublic; args[3] <<= nv;
+ nv.Name = OUString::createFromAscii("TargetBaseURL");
+ INetURLObject ineturl(sURL);
+ ineturl.removeSegment();
+ m_aExportBaseUrl = ineturl.GetMainURL(INetURLObject::NO_DECODE);
+ nv.Value <<= m_aExportBaseUrl;
+ args[3] <<= nv;
+
+ m_tcontrol = Reference< XActiveDataControl >(m_rServiceFactory->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.comp.JAXTHelper"), args), UNO_QUERY);
+
+ OSL_ASSERT(m_rDocumentHandler.is());
+ OSL_ASSERT(m_rOutputStream.is());
+ OSL_ASSERT(m_tcontrol.is());
+ if (m_tcontrol.is() && m_rOutputStream.is() && m_rDocumentHandler.is())
+ {
+ // we want to be notfied when the processing is done...
+ m_tcontrol->addListener(Reference< XStreamListener >(this));
+
+ // create pipe
+ Reference< XOutputStream > pipeout(m_rServiceFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.io.Pipe")), UNO_QUERY);
+ Reference< XInputStream > pipein(pipeout, UNO_QUERY);
+
+ // connect sax writer to pipe
+ Reference< XActiveDataSource > xmlsource(m_rDocumentHandler, UNO_QUERY);
+ xmlsource->setOutputStream(pipeout);
+
+ // connect pipe to transformer
+ Reference< XActiveDataSink > tsink(m_tcontrol, UNO_QUERY);
+ tsink->setInputStream(pipein);
+
+ // connect transformer to output
+ Reference< XActiveDataSource > tsource(m_tcontrol, UNO_QUERY);
+ tsource->setOutputStream(m_rOutputStream);
+
+ // we will start receiving events after returning 'true'.
+ // we will start the transformation as soon as we receive the startDocument
+ // event.
+ return sal_True;
+ }
+ else
+ {
+ return sal_False;
+ }
+}
+
+// for the DocumentHandler implementation, we just proxy the the
+// events to the XML writer that we created upon the output stream
+// that was provided by the XMLFilterAdapter
+void XSLTFilter::startDocument() throw (SAXException,RuntimeException){
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->startDocument();
+ m_tcontrol->start();
+}
+
+void XSLTFilter::endDocument() throw (SAXException, RuntimeException){
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->endDocument();
+ // wait for the transformer to finish
+ osl_waitCondition(m_cTransformed, 0);
+ if (!m_bError && !m_bTerminated)
+ {
+ return;
+ } else {
+ throw RuntimeException();
+ }
+
+}
+
+void XSLTFilter::startElement(const OUString& str, const Reference<XAttributeList>& attriblist)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+// SvXMLAttributeList* _attriblist=SvXMLAttributeList::getImplementation(attriblist);
+ m_rDocumentHandler->startElement(str, attriblist);
+}
+
+void XSLTFilter::endElement(const OUString& str)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->endElement(str);
+}
+
+void XSLTFilter::characters(const OUString& str)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->characters(str);
+}
+
+void XSLTFilter::ignorableWhitespace(const OUString& str)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ if (!m_bPrettyPrint) return;
+ m_rDocumentHandler->ignorableWhitespace(str);
+}
+
+void XSLTFilter::processingInstruction(const OUString& str, const OUString& str2)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->processingInstruction(str, str2);
+}
+
+void XSLTFilter::setDocumentLocator(const Reference<XLocator>& doclocator)
+ throw (SAXException, RuntimeException)
+{
+ OSL_ASSERT(m_rDocumentHandler.is());
+ m_rDocumentHandler->setDocumentLocator(doclocator);
+}
+
+// --------------------------------------
+// Component management
+// --------------------------------------
+#define SERVICE_NAME "com.sun.star.documentconversion.XSLTFilter"
+#define IMPLEMENTATION_NAME "com.sun.star.comp.documentconversion.XSLTFilter"
+
+static Reference< XInterface > SAL_CALL CreateInstance( const Reference< XMultiServiceFactory > &r)
+{
+ return Reference< XInterface >(( OWeakObject *)new XSLTFilter(r));
+}
+
+static Sequence< OUString > getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString::createFromAscii(SERVICE_NAME);
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+}
+
+using namespace XSLT;
+
+extern "C"
+{
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+sal_Bool SAL_CALL component_writeInfo(void * /* pServiceManager */, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ Reference< XRegistryKey > xNewKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
+ OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) );
+
+ const Sequence< OUString > & rSNL = getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ xNewKey->createKey( pArray[nPos] );
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /* pRegistryKey */ )
+{
+ void * pRet = 0;
+
+ if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
+ {
+ Reference< XSingleServiceFactory > xFactory( createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString::createFromAscii( pImplName ),
+ CreateInstance, getSupportedServiceNames() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+ return pRet;
+}
+
+} // extern "C"