Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


Hi Jan, 

I'm attaching a patch I somehow managed to patiently pull out of git :-)

As I'm new to C++, libxslt, git and a few other things involved in
creating the patch I feel it must be full of warts and cause random
crashes, but it seems to work and might be useful anyway.

Basically, the patch provides an alternative service implementation
to be used by XSLTFilter.cxx. Use of the libxslt implementation can be
triggered by adding "libxslt" as second parameter to the "UserData"
configuration of an xslt filter. This second parameter is currently
unused for xslt filters. 

To completely remove the java dependency for xslt filters, the
xsltvalidation service would also need to be replaced by an
implementation based on libxslt. 

Also, the Office 2003 XML export filters use a saxon extension
implemented in Java, which needs to be replaced by a libxslt extension
if Office 2003 XML export should be supported without Java, too. 

The flat xml export could be implemented as a pure C++ xml Filter
indendendently of the xslt filter, as proposed in the SDK examples, I
suppose, and I'd like to do that next. 

I personally like the idea to make the implementation to use
configurable, instead of completely removing the Java based xslt filter
implementation. 

Cheers, 

Peter



 
Am Donnerstag, den 30.12.2010, 02:07 +0100 schrieb Jan Holesovsky:
Hi Peter,

On 2010-12-29 at 14:29 +0100, Peter Jentsch wrote:

I've gotten so far as to have a working implementation of XSLTFilter
which uses libxml2/libxslt to do the XSL transformation. It's still
missing some details like passing parameters to the xslt script, but it
works for the flat xml export and for xhtml export as well. Using this
implementation would remove the java dependency from xslt filter
processing,

Wow, cool! :-)  Can you please post the patch here, so that we can have
a look?  This sounds great.

Regards,
Kendy

_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice



From f3e5ff4c1ec9ecc01f92263f6fbe9a3f35dcfb16 Mon Sep 17 00:00:00 2001
From: Peter Jentsch <pjotr@guineapics.de>
Date: Sun, 2 Jan 2011 14:02:18 +0100
Subject: [PATCH 1/2] Added support for libxslt in xsltfilter

libxslt will be used to perform xsl transformations if either Java is
not available/configured at compile time or the 2nd, currently unused
"UserData" parameter of the xslt filter is "libxslt" (w/o the quotes)
---
 filter/source/xsltfilter/LibXSLTTransformer.cxx |  282 +++++++++++++++++++++++
 filter/source/xsltfilter/LibXSLTTransformer.hxx |  145 ++++++++++++
 filter/source/xsltfilter/XSLTFilter.cxx         |  129 +++++++----
 filter/source/xsltfilter/makefile.mk            |   16 ++-
 4 files changed, 526 insertions(+), 46 deletions(-)
 create mode 100644 filter/source/xsltfilter/LibXSLTTransformer.cxx
 create mode 100644 filter/source/xsltfilter/LibXSLTTransformer.hxx

diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx 
b/filter/source/xsltfilter/LibXSLTTransformer.cxx
new file mode 100644
index 0000000..da51908
--- /dev/null
+++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx
@@ -0,0 +1,282 @@
+ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+ // MARKER(update_precomp.py): autogen include statement, do not remove
+ #include "precompiled_filter.hxx"
+
+ #include <stdio.h>
+ #include <list>
+ #include <map>
+ #include <iostream>
+ #include <libxml/parser.h>
+ #include <libxml/tree.h>
+ #include <libxml/xmlIO.h>
+ #include <libxslt/transform.h>
+ #include <libxslt/xsltutils.h>
+ #include <libxslt/variables.h>
+
+ #include <cppuhelper/factory.hxx>
+ #include <cppuhelper/servicefactory.hxx>
+ #include <cppuhelper/implbase4.hxx>
+ #include <cppuhelper/implbase.hxx>
+ #include <osl/module.h>
+ #include <osl/file.hxx>
+ #include <osl/process.h>
+ #include <com/sun/star/lang/XComponent.hpp>
+ #include <com/sun/star/lang/XInitialization.hpp>
+ #include <com/sun/star/uno/Any.hxx>
+ #include <com/sun/star/beans/NamedValue.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 <LibXSLTTransformer.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 ::std::list;
+ using ::std::map;
+ using ::std::pair;
+
+ namespace XSLT {
+     const char* const LibXSLTTransformer::PARAM_SOURCE_URL = "sourceURL";
+     const char* const LibXSLTTransformer::PARAM_SOURCE_BASE_URL = "sourceBaseURL";
+     const char* const LibXSLTTransformer::PARAM_TARGET_URL = "targetURL";
+     const char* const LibXSLTTransformer::PARAM_TARGET_BASE_URL = "targetBaseURL";
+     const char* const LibXSLTTransformer::PARAM_DOCTYPE_SYSTEM = "sytemType";
+     const char* const LibXSLTTransformer::PARAM_DOCTYPE_PUBLIC = "publicType";
+     struct ParserInputBufferCallback {
+         static int on_read(void * context, char * buffer, int len) {
+             Reader * tmp = static_cast<Reader*>(context);
+             return tmp->read(buffer, len);
+         }
+         static int on_close(void * context) {
+             Reader * tmp = static_cast<Reader*>(context);
+             return tmp->closeInput();
+         }
+     };
+     struct ParserOutputBufferCallback {
+         static int on_write(void * context, const char * buffer, int len) {
+             Reader * tmp = static_cast<Reader*>(context);
+             return tmp->write(buffer, len);
+         }
+         static int on_close(void * context) {
+             Reader * tmp = static_cast<Reader*>(context);
+             return tmp->closeOutput();
+         }
+     };
+     Reader::Reader(LibXSLTTransformer* transformer):
+         m_transformer(transformer),
+         m_terminated(false),
+         m_readBuf(INPUT_BUFFER_SIZE),
+         m_writeBuf(OUTPUT_BUFFER_SIZE) {
+         LIBXML_TEST_VERSION;
+     };
+
+     int
+     Reader::read(char * buffer, int len) {
+         //        const char *ptr = (const char *) context;
+         if (buffer == NULL || len < 0) return(-1);
+         sal_Int32 n;
+         Reference<XInputStream> xis = this->m_transformer->getInputStream();
+         n = xis.get()->readBytes(m_readBuf, len);
+         if (n > 0) {
+             memcpy(buffer, m_readBuf.getArray(), n);
+         }
+         return n;
+     }
+     int Reader::write(const char * buffer, int len) {
+         if (buffer == NULL || len < 0) return -1;
+         if (len > 0) {
+             Reference<XOutputStream> xos = m_transformer->getOutputStream();
+             sal_Int32 writeLen = len;
+             sal_Int32 bufLen = ::std::min(writeLen, OUTPUT_BUFFER_SIZE);
+             const sal_uInt8* memPtr = reinterpret_cast< const sal_uInt8* >( buffer );
+             while( writeLen > 0 ) {
+                 sal_Int32 n = ::std::min(writeLen, bufLen);
+                 m_writeBuf.realloc( n );
+                 memcpy( m_writeBuf.getArray(), memPtr, static_cast< size_t >( n ) );
+                 xos.get()->writeBytes(m_writeBuf);
+                 memPtr += n;
+                 writeLen -= n;
+             }
+         }
+         return len;
+     }
+     int Reader::closeInput() {
+         return 0;
+     }
+     int Reader::closeOutput() {
+         Reference<XOutputStream>  xos = m_transformer->getOutputStream();
+         if (xos.is()) {
+             xos.get()->flush();
+             xos.get()->closeOutput();
+         }
+         m_transformer->done();
+         return 0;
+     }
+     void Reader::run() {
+         OSL_ASSERT(m_transformer != NULL);
+         OSL_ASSERT(m_transformer->getInputStream().is());
+         OSL_ASSERT(m_transformer->getOutputStream().is());
+         OSL_ASSERT(m_transformer->getStyleSheetURL());
+         ::std::map<const char*, OString>::iterator pit;
+         ::std::map<const char*, OString> pmap = m_transformer->getParameters();
+         const char* params[pmap.size()*2 + 1]; // build parameters
+         int paramIndex = 0;
+         for (pit = pmap.begin(); pit != pmap.end(); pit++) {
+             params[paramIndex++] = (*pit).first;
+             params[paramIndex++] = (*pit).second.getStr();
+         }
+         params[paramIndex] = NULL;
+         xmlDocPtr doc = xmlReadIO(&ParserInputBufferCallback::on_read,
+                                   &ParserInputBufferCallback::on_close,
+                                   static_cast<void*>(this),
+                                   NULL,
+                                   NULL,
+                                   0);
+         xsltStylesheetPtr styleSheet = xsltParseStylesheetFile((const xmlChar *) 
m_transformer->getStyleSheetURL().getStr());
+         xmlDocPtr result = NULL;
+         xsltTransformContextPtr tcontext = NULL;
+         if (styleSheet) {
+             tcontext = xsltNewTransformContext(styleSheet, doc);
+             xsltQuoteUserParams(tcontext, params);
+             result = xsltApplyStylesheetUser(styleSheet, doc, 0, 0, 0, tcontext);
+         }
+         if (result) {
+             xmlCharEncodingHandlerPtr encoder = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8);
+             xmlOutputBufferPtr outBuf = xmlAllocOutputBuffer(encoder);
+             outBuf->context = static_cast<void *>(this);
+             outBuf->writecallback = &ParserOutputBufferCallback::on_write;
+             outBuf->closecallback = &ParserOutputBufferCallback::on_close;
+             xsltSaveResultTo(outBuf, result, styleSheet);
+         } else {
+             xmlErrorPtr lastErr = xmlGetLastError();
+             OUString msg;
+             if (lastErr) {
+                 msg = OUString::createFromAscii(lastErr->message);
+             } else {
+                 msg = OUString::createFromAscii("Unknown XSLT transformation error");
+             }
+             m_transformer->error(msg);
+         }
+         closeOutput();
+         xsltFreeStylesheet(styleSheet);
+         xsltFreeTransformContext(tcontext);
+         xmlFreeDoc(doc);
+         xmlFreeDoc(result);
+     };
+     void Reader::onTerminated() {
+         m_terminated = true;
+     };
+     Reader::~Reader() {}
+     LibXSLTTransformer::LibXSLTTransformer( const Reference< XMultiServiceFactory > &r )
+         : m_rServiceFactory(r) {
+     }
+     void LibXSLTTransformer::setInputStream(const Reference<XInputStream>& inputStream)
+         throw (RuntimeException) {
+         m_rInputStream = inputStream;
+     }
+     Reference<XInputStream> LibXSLTTransformer::getInputStream()
+         throw (RuntimeException) {
+         return m_rInputStream;
+     }
+     void LibXSLTTransformer::setOutputStream(const Reference<XOutputStream>& outputStream)
+         throw (RuntimeException) {
+         m_rOutputStream = outputStream;
+     }
+     Reference<XOutputStream> LibXSLTTransformer::getOutputStream()
+         throw (RuntimeException) {
+         return m_rOutputStream;
+     }
+     void LibXSLTTransformer::addListener(const Reference<XStreamListener>& listener)
+         throw (RuntimeException) {
+         m_listeners.insert(m_listeners.begin(), listener);
+     }
+     void LibXSLTTransformer::removeListener(const Reference<XStreamListener>& listener)
+         throw (RuntimeException) {
+         m_listeners.remove(listener);
+     }
+     void LibXSLTTransformer::start()
+         throw (RuntimeException) {
+         ListenerList::iterator it;
+         for (it=m_listeners.begin(); it != m_listeners.end(); it++) {
+             Reference<XStreamListener> xl = *it;
+             xl.get()->started();
+         }
+         Reader* r = new Reader(this);
+         r->create();
+     }
+
+     void LibXSLTTransformer::error(const OUString& msg) {
+         ListenerList l = m_listeners;
+         Any arg;
+         arg <<= Exception(msg, *this);
+         for (ListenerList::iterator it=l.begin(); it != l.end(); it++) {
+             Reference<XStreamListener> xl = *it;
+             if (xl.is()) {
+                 xl.get()->error(arg);
+             }
+         }
+     }
+     void LibXSLTTransformer::done() {
+         ListenerList l = m_listeners;
+         for (ListenerList::iterator it=l.begin(); it != l.end(); it++) {
+             Reference<XStreamListener> xl = *it;
+             if (xl.is()) {
+                 xl.get()->closed();
+             }
+         }
+     }
+     void LibXSLTTransformer::terminate()
+         throw (RuntimeException) {
+         m_parameters.clear();
+     }
+     void LibXSLTTransformer::initialize(const Sequence<Any>& params)
+         throw (RuntimeException) {
+         xmlSubstituteEntitiesDefault(0);
+         m_parameters.clear();
+         for (int i = 0; i < params.getLength(); i++) {
+             NamedValue nv;
+             params[i] >>= nv;
+             OString nameUTF8 = OUStringToOString(nv.Name, RTL_TEXTENCODING_UTF8);
+             OUString value;
+             OString valueUTF8;
+             if (nv.Value >>= value) {
+                 valueUTF8 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
+             } else {
+                 // ignore non-string parameters
+                 continue;
+             }
+             if (nameUTF8.equals("StylesheetURL")) {
+                 m_styleSheetURL = valueUTF8;
+             } else if (nameUTF8.equals("SourceURL")) {
+                 m_parameters.insert(pair<const char*, OString>(PARAM_SOURCE_URL, valueUTF8));
+             } else if (nameUTF8.equals("SourceBaseURL")) {
+                 m_parameters.insert(pair<const char*, OString>(PARAM_SOURCE_BASE_URL, valueUTF8));
+             } else if (nameUTF8.equals("TargetURL")) {
+                 m_parameters.insert(pair<const char*, OString>(PARAM_TARGET_URL, valueUTF8));
+             } else if (nameUTF8.equals("TargetBaseURL")) {
+                 m_parameters.insert(pair<const char*, OString>(PARAM_TARGET_BASE_URL, valueUTF8));
+             } else if (nameUTF8.equals("DoctypeSystem")) {
+                 m_parameters.insert(pair<const char*, OString>(PARAM_DOCTYPE_SYSTEM, valueUTF8));
+             } else if (nameUTF8.equals("DoctypePublic")) {
+                 m_parameters.insert(pair<const char*, OString>(PARAM_DOCTYPE_PUBLIC, valueUTF8));
+             }
+         }
+     }
+     const OString LibXSLTTransformer::getStyleSheetURL() {
+         return m_styleSheetURL;
+     }
+     ::std::map<const char*, OString> LibXSLTTransformer::getParameters() {
+         return m_parameters;
+     }
+ }
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.hxx 
b/filter/source/xsltfilter/LibXSLTTransformer.hxx
new file mode 100644
index 0000000..376075e
--- /dev/null
+++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx
@@ -0,0 +1,145 @@
+ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+ // MARKER(update_precomp.py): autogen include statement, do not remove
+ #ifndef __LIBXSLTTRANSFORMER_HXX__
+ #define __LIBXSLTTRANSFORMER_HXX__
+ #include "precompiled_filter.hxx"
+
+ #include <stdio.h>
+
+ #include <list>
+ #include <map>
+
+ #include <libxml/parser.h>
+ #include <libxml/tree.h>
+ #include <libxml/xmlIO.h>
+ #include <libxslt/transform.h>
+
+ #include <cppuhelper/factory.hxx>
+ #include <cppuhelper/servicefactory.hxx>
+ #include <cppuhelper/implbase4.hxx>
+ #include <cppuhelper/implbase.hxx>
+
+ #include <osl/thread.hxx>
+
+ #include <com/sun/star/uno/Any.hxx>
+
+ #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/lang/XInitialization.hpp>
+ #include <com/sun/star/beans/NamedValue.hpp>
+
+ #define _INPUT_BUFFER_SIZE 1024
+ #define _OUTPUT_BUFFER_SIZE 1024
+
+ 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 ::std::list;
+ using ::std::map;
+
+ namespace XSLT {
+
+
+     class LibXSLTTransformer : public WeakImplHelper4< XActiveDataSink, XActiveDataSource, 
XActiveDataControl, XInitialization>
+     {
+     private:
+         static const char* const PARAM_SOURCE_URL;
+         static const char* const PARAM_SOURCE_BASE_URL;
+         static const char* const PARAM_TARGET_URL;
+         static const char* const PARAM_TARGET_BASE_URL;
+         static const char* const PARAM_DOCTYPE_SYSTEM;
+         static const char* const PARAM_DOCTYPE_PUBLIC;
+
+         // the UNO ServiceFactory
+         Reference< XMultiServiceFactory > m_rServiceFactory;
+
+         Reference< XInputStream> m_rInputStream;
+
+         Reference < XOutputStream > m_rOutputStream;
+
+         typedef ::std::list<Reference< XStreamListener > > ListenerList;
+
+         ListenerList m_listeners;
+
+         OString m_styleSheetURL;
+
+         ::std::map<const char *, OString> m_parameters;
+
+     public:
+
+         // ctor...
+         LibXSLTTransformer( const Reference< XMultiServiceFactory > &r );
+
+
+
+
+         // XActiveDataSink
+         virtual void SAL_CALL setInputStream(const Reference<XInputStream>& inputStream)
+             throw (RuntimeException);
+         virtual Reference<XInputStream> SAL_CALL getInputStream()
+             throw (RuntimeException);
+         // XActiveDataSource
+         virtual void SAL_CALL setOutputStream(const Reference<XOutputStream>& outputStream)
+             throw (RuntimeException);
+         virtual Reference<XOutputStream> SAL_CALL getOutputStream()
+             throw (RuntimeException);
+         // XActiveDataControl
+         virtual void SAL_CALL addListener(const Reference<XStreamListener>& listener)
+             throw (RuntimeException);
+         virtual void SAL_CALL removeListener(const Reference<XStreamListener>& listener)
+             throw (RuntimeException);
+         virtual void SAL_CALL start()
+             throw (RuntimeException);
+         virtual void SAL_CALL terminate()
+             throw (RuntimeException);
+         virtual void SAL_CALL initialize(const Sequence<Any>& params)
+             throw (RuntimeException);
+
+         void SAL_CALL done();
+
+         void SAL_CALL error(const OUString& msg);
+
+         const OString SAL_CALL getStyleSheetURL();
+
+         ::std::map<const char*, OString> SAL_CALL getParameters();
+
+     };
+
+     class Reader: public osl::Thread
+     {
+     public:
+         Reader(LibXSLTTransformer* transformer);
+         int SAL_CALL read(char * buffer, int len);
+         int SAL_CALL write(const char * buffer, int len);
+         int SAL_CALL closeInput();
+         int SAL_CALL closeOutput();
+
+     protected:
+         virtual ~Reader();
+
+     private:
+         static const sal_Int32 OUTPUT_BUFFER_SIZE = _OUTPUT_BUFFER_SIZE;
+         static const sal_Int32 INPUT_BUFFER_SIZE = _INPUT_BUFFER_SIZE;
+         LibXSLTTransformer* m_transformer;
+         sal_Bool m_terminated;
+         Sequence<sal_Int8> m_readBuf;
+         Sequence<sal_Int8> m_writeBuf;
+         virtual void SAL_CALL run();
+         virtual void SAL_CALL onTerminated();
+     };
+
+ }
+
+
+ #endif // __LIBXSLTTRANSFORMER_HXX__
+
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/xsltfilter/XSLTFilter.cxx b/filter/source/xsltfilter/XSLTFilter.cxx
index b2c2858..2e3f5af 100644
--- a/filter/source/xsltfilter/XSLTFilter.cxx
+++ b/filter/source/xsltfilter/XSLTFilter.cxx
@@ -76,6 +76,13 @@
 
 #include <xmloff/attrlist.hxx>
 #include <fla.hxx>
+#include <LibXSLTTransformer.hxx>
+
+#ifdef SOLAR_JAVA
+#define USE_LIBXSLT_DEFAULT sal_False
+#else
+#define USE_LIBXSLT_DEFAULT sal_True
+#endif
 
 using namespace ::rtl;
 using namespace ::cppu;
@@ -221,6 +228,9 @@ void FLABridge::setDocumentLocator(const Reference<XLocator>& doclocator)
 class XSLTFilter : public WeakImplHelper4< XImportFilter, XExportFilter, XDocumentHandler, 
XStreamListener>
 {
 private:
+    static const OUString JAXT_HELPER_SERVICE_IMPL;
+    static const OUString LIBXSLT_HELPER_SERVICE_IMPL;
+
     // the UNO ServiceFactory
     Reference< XMultiServiceFactory > m_rServiceFactory;
 
@@ -232,12 +242,12 @@ private:
     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&);
@@ -287,6 +297,9 @@ public:
         throw (SAXException,RuntimeException);
 };
 
+const OUString XSLTFilter::JAXT_HELPER_SERVICE_IMPL = 
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.JAXTHelper"));
+const OUString XSLTFilter::LIBXSLT_HELPER_SERVICE_IMPL = 
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.documentconversion.LibXSLTTransformer"));
+
 XSLTFilter::XSLTFilter( const Reference< XMultiServiceFactory > &r )
     : m_rServiceFactory(r)
     , m_bPrettyPrint(sal_True)
@@ -411,8 +424,17 @@ sal_Bool XSLTFilter::importer(
     nv.Value <<= OUString(INetURLObject(aURL).getBase());
     args[2] <<= nv;
 
-    m_tcontrol = Reference< XActiveDataControl >(m_rServiceFactory->createInstanceWithArguments(
-        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.JAXTHelper" )), args), 
UNO_QUERY);
+    sal_Bool useLibXSLT = USE_LIBXSLT_DEFAULT;
+    if (!useLibXSLT) {
+        useLibXSLT = msUserData[1].equalsIgnoreAsciiCaseAscii("libxslt");
+    }
+    if (useLibXSLT) {
+        m_tcontrol = Reference< XActiveDataControl 
(m_rServiceFactory->createInstanceWithArguments(
+        LIBXSLT_HELPER_SERVICE_IMPL, args), UNO_QUERY);
+    } else {
+        m_tcontrol = Reference< XActiveDataControl 
(m_rServiceFactory->createInstanceWithArguments(
+        JAXT_HELPER_SERVICE_IMPL, args), UNO_QUERY);
+    }
 
     OSL_ASSERT(xHandler.is());
     OSL_ASSERT(xInputStream.is());
@@ -538,8 +560,17 @@ sal_Bool XSLTFilter::exporter(
     nv.Value <<= m_aExportBaseUrl;
     args[3] <<= nv;
 
-    m_tcontrol = Reference< XActiveDataControl >(m_rServiceFactory->createInstanceWithArguments(
-        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.JAXTHelper" )), args), 
UNO_QUERY);
+    sal_Bool useLibXSLT = USE_LIBXSLT_DEFAULT;
+    if (!useLibXSLT) {
+        useLibXSLT = msUserData[1].equalsIgnoreAsciiCaseAscii("libxslt");
+    }
+    if (useLibXSLT) {
+        m_tcontrol = Reference< XActiveDataControl 
(m_rServiceFactory->createInstanceWithArguments(
+        LIBXSLT_HELPER_SERVICE_IMPL, args), UNO_QUERY);
+    } else {
+        m_tcontrol = Reference< XActiveDataControl 
(m_rServiceFactory->createInstanceWithArguments(
+        JAXT_HELPER_SERVICE_IMPL, args), UNO_QUERY);
+    }
 
     OSL_ASSERT(m_rDocumentHandler.is());
     OSL_ASSERT(m_rOutputStream.is());
@@ -647,28 +678,19 @@ void XSLTFilter::setDocumentLocator(const Reference<XLocator>& doclocator)
 // --------------------------------------
 // Component management
 // --------------------------------------
-#define SERVICE_NAME "com.sun.star.documentconversion.XSLTFilter"
-#define IMPLEMENTATION_NAME "com.sun.star.comp.documentconversion.XSLTFilter"
+#define FILTER_SERVICE_NAME "com.sun.star.documentconversion.XSLTFilter"
+#define FILTER_IMPL_NAME "com.sun.star.comp.documentconversion.XSLTFilter"
+#define TRANSFORMER_SERVICE_NAME "com.sun.star.documentconversion.LibXSLTTransformer"
+#define TRANSFORMER_IMPL_NAME "com.sun.star.comp.documentconversion.LibXSLTTransformer"
 
-static Reference< XInterface > SAL_CALL CreateInstance( const Reference< XMultiServiceFactory > &r)
+static Reference< XInterface > SAL_CALL CreateTransformerInstance( const Reference< 
XMultiServiceFactory > &r)
 {
-    return Reference< XInterface >(( OWeakObject *)new XSLTFilter(r));
+    return Reference< XInterface >(( OWeakObject *)new LibXSLTTransformer(r));
 }
 
-static Sequence< OUString > getSupportedServiceNames()
+static Reference< XInterface > SAL_CALL CreateFilterInstance( const Reference< 
XMultiServiceFactory > &r)
 {
-    static Sequence < OUString > *pNames = 0;
-    if( ! pNames )
-    {
-        MutexGuard guard( Mutex::getGlobalMutex() );
-        if( !pNames )
-        {
-            static Sequence< OUString > seqNames(1);
-                seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICE_NAME));
-            pNames = &seqNames;
-        }
-    }
-    return *pNames;
+    return Reference< XInterface >(( OWeakObject *)new XSLTFilter(r));
 }
 
 }
@@ -685,27 +707,26 @@ void SAL_CALL component_getImplementationEnvironment(
 
 sal_Bool SAL_CALL component_writeInfo(void * /* pServiceManager */, void * pRegistryKey )
 {
+    sal_Bool bRetVal = sal_False;
     if (pRegistryKey)
     {
         try
         {
-            Reference< XRegistryKey > xNewKey(
-                reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
-                    OUString( RTL_CONSTASCII_USTRINGPARAM( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" 
)) ) );
+            Reference< XRegistryKey > pXNewKey( static_cast< XRegistryKey* >( pRegistryKey ) );
+            pXNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "/" FILTER_IMPL_NAME 
"/UNO/SERVICES/" FILTER_SERVICE_NAME ) ) );
+            bRetVal = sal_True;
 
-            const Sequence< OUString > & rSNL = getSupportedServiceNames();
-            const OUString * pArray = rSNL.getConstArray();
-            for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
-                xNewKey->createKey( pArray[nPos] );
-
-            return sal_True;
+            pXNewKey=  static_cast< XRegistryKey* >( pRegistryKey );
+            pXNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "/" TRANSFORMER_IMPL_NAME 
"/UNO/SERVICES/" TRANSFORMER_SERVICE_NAME ) ) );
+            bRetVal = sal_True;
         }
-        catch (InvalidRegistryException &)
+        catch( InvalidRegistryException& )
         {
-            OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+            OSL_ENSURE(sal_False, "InvalidRegistryException caught");
+            bRetVal = sal_False;
         }
     }
-    return sal_False;
+    return bRetVal;
 }
 
 void * SAL_CALL component_getFactory(
@@ -713,17 +734,37 @@ void * SAL_CALL component_getFactory(
 {
     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 (pServiceManager) {
+        if (rtl_str_compare( pImplName, FILTER_IMPL_NAME ) == 0) {
+            Sequence< OUString > serviceNames( 1 );
+            serviceNames.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( 
FILTER_SERVICE_NAME ) );
+
+            Reference< XSingleServiceFactory > xFactory(
+                                                        createSingleFactory(
+                                                                            reinterpret_cast< 
XMultiServiceFactory * >( pServiceManager ),
+                                                                            
OUString::createFromAscii( pImplName ),
+                                                                            CreateFilterInstance, 
serviceNames ) );
+
+            if (xFactory.is())
+                {
+                    xFactory->acquire();
+                    pRet = xFactory.get();
+                }
+        } else if (rtl_str_compare( pImplName, TRANSFORMER_IMPL_NAME ) == 0) {
+            Sequence< OUString > serviceNames( 1 );
+            serviceNames.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( 
TRANSFORMER_SERVICE_NAME ) );
+            Reference< XSingleServiceFactory > xFactory(
+                                                        createSingleFactory(
+                                                                            reinterpret_cast< 
XMultiServiceFactory * >( pServiceManager ),
+                                                                            
OUString::createFromAscii( pImplName ),
+                                                                            
CreateTransformerInstance, serviceNames ) );
+
+            if (xFactory.is())
+                {
+                    xFactory->acquire();
+                    pRet = xFactory.get();
+                }
 
-        if (xFactory.is())
-        {
-            xFactory->acquire();
-            pRet = xFactory.get();
         }
     }
     return pRet;
diff --git a/filter/source/xsltfilter/makefile.mk b/filter/source/xsltfilter/makefile.mk
index a5e2713..ee23cfd 100644
--- a/filter/source/xsltfilter/makefile.mk
+++ b/filter/source/xsltfilter/makefile.mk
@@ -33,9 +33,19 @@ LIBTARGET=NO
 
 # --- Settings -----------------------------------------------------
 CLASSDIR!:=$(CLASSDIR)$/$(TARGET)
+
 .INCLUDE: settings.mk
 
-SLOFILES=$(SLO)$/XSLTFilter.obj $(SLO)$/fla.obj
+.IF "$(SYSTEM_LIBXSLT)" == "YES"
+CFLAGS+= $(LIBXSLT_CFLAGS)
+.ELSE
+LIBXSLTINCDIR=external$/libxslt
+CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXSLTINCDIR)
+.ENDIF
+
+
+
+SLOFILES=$(SLO)$/XSLTFilter.obj $(SLO)$/LibXSLTTransformer.obj $(SLO)$/fla.obj
 LIBNAME=xsltfilter
 SHL1TARGETDEPN=makefile.mk
 SHL1OBJS=$(SLOFILES)
@@ -50,7 +60,9 @@ SHL1STDLIBS= \
     $(CPPUHELPERLIB)    \
     $(CPPULIB)          \
     $(XMLOFFLIB) \
-    $(SALLIB)
+    $(SALLIB) \
+    $(LIBXML2LIB) \
+    $(XSLTLIB)
 
 .IF "$(SOLAR_JAVA)"!=""
 
-- 
1.7.1


From 74d639d3158a38afdfc3b0ce1d7e0c384724fb93 Mon Sep 17 00:00:00 2001
From: Peter Jentsch <pjotr@guineapics.de>
Date: Mon, 3 Jan 2011 20:38:17 +0100
Subject: [PATCH 2/2] Fixed constant definitions for LibXSLTFilter buffers

---
 filter/source/xsltfilter/LibXSLTTransformer.cxx |   29 ++++++++++++++++++++++-
 filter/source/xsltfilter/LibXSLTTransformer.hxx |    7 +----
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx 
b/filter/source/xsltfilter/LibXSLTTransformer.cxx
index da51908..2d40381 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.cxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx
@@ -45,6 +45,9 @@
  using ::std::map;
  using ::std::pair;
 
+ #define _INPUT_BUFFER_SIZE 4096
+ #define _OUTPUT_BUFFER_SIZE 4096
+
  namespace XSLT {
      const char* const LibXSLTTransformer::PARAM_SOURCE_URL = "sourceURL";
      const char* const LibXSLTTransformer::PARAM_SOURCE_BASE_URL = "sourceBaseURL";
@@ -52,6 +55,11 @@
      const char* const LibXSLTTransformer::PARAM_TARGET_BASE_URL = "targetBaseURL";
      const char* const LibXSLTTransformer::PARAM_DOCTYPE_SYSTEM = "sytemType";
      const char* const LibXSLTTransformer::PARAM_DOCTYPE_PUBLIC = "publicType";
+
+     const sal_Int32 Reader::OUTPUT_BUFFER_SIZE = _OUTPUT_BUFFER_SIZE;
+
+     const sal_Int32 Reader::INPUT_BUFFER_SIZE = _INPUT_BUFFER_SIZE;
+
      struct ParserInputBufferCallback {
          static int on_read(void * context, char * buffer, int len) {
              Reader * tmp = static_cast<Reader*>(context);
@@ -72,6 +80,7 @@
              return tmp->closeOutput();
          }
      };
+
      Reader::Reader(LibXSLTTransformer* transformer):
          m_transformer(transformer),
          m_terminated(false),
@@ -92,12 +101,13 @@
          }
          return n;
      }
+
      int Reader::write(const char * buffer, int len) {
          if (buffer == NULL || len < 0) return -1;
          if (len > 0) {
              Reference<XOutputStream> xos = m_transformer->getOutputStream();
              sal_Int32 writeLen = len;
-             sal_Int32 bufLen = ::std::min(writeLen, OUTPUT_BUFFER_SIZE);
+             sal_Int32 bufLen = ::std::min(writeLen, this->OUTPUT_BUFFER_SIZE);
              const sal_uInt8* memPtr = reinterpret_cast< const sal_uInt8* >( buffer );
              while( writeLen > 0 ) {
                  sal_Int32 n = ::std::min(writeLen, bufLen);
@@ -110,9 +120,11 @@
          }
          return len;
      }
+
      int Reader::closeInput() {
          return 0;
      }
+
      int Reader::closeOutput() {
          Reference<XOutputStream>  xos = m_transformer->getOutputStream();
          if (xos.is()) {
@@ -122,6 +134,7 @@
          m_transformer->done();
          return 0;
      }
+
      void Reader::run() {
          OSL_ASSERT(m_transformer != NULL);
          OSL_ASSERT(m_transformer->getInputStream().is());
@@ -150,6 +163,7 @@
              xsltQuoteUserParams(tcontext, params);
              result = xsltApplyStylesheetUser(styleSheet, doc, 0, 0, 0, tcontext);
          }
+
          if (result) {
              xmlCharEncodingHandlerPtr encoder = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8);
              xmlOutputBufferPtr outBuf = xmlAllocOutputBuffer(encoder);
@@ -173,37 +187,47 @@
          xmlFreeDoc(doc);
          xmlFreeDoc(result);
      };
+
      void Reader::onTerminated() {
          m_terminated = true;
      };
+
      Reader::~Reader() {}
+
      LibXSLTTransformer::LibXSLTTransformer( const Reference< XMultiServiceFactory > &r )
          : m_rServiceFactory(r) {
      }
+
      void LibXSLTTransformer::setInputStream(const Reference<XInputStream>& inputStream)
          throw (RuntimeException) {
          m_rInputStream = inputStream;
      }
+
      Reference<XInputStream> LibXSLTTransformer::getInputStream()
          throw (RuntimeException) {
          return m_rInputStream;
      }
+
      void LibXSLTTransformer::setOutputStream(const Reference<XOutputStream>& outputStream)
          throw (RuntimeException) {
          m_rOutputStream = outputStream;
      }
+
      Reference<XOutputStream> LibXSLTTransformer::getOutputStream()
          throw (RuntimeException) {
          return m_rOutputStream;
      }
+
      void LibXSLTTransformer::addListener(const Reference<XStreamListener>& listener)
          throw (RuntimeException) {
          m_listeners.insert(m_listeners.begin(), listener);
      }
+
      void LibXSLTTransformer::removeListener(const Reference<XStreamListener>& listener)
          throw (RuntimeException) {
          m_listeners.remove(listener);
      }
+
      void LibXSLTTransformer::start()
          throw (RuntimeException) {
          ListenerList::iterator it;
@@ -226,6 +250,7 @@
              }
          }
      }
+
      void LibXSLTTransformer::done() {
          ListenerList l = m_listeners;
          for (ListenerList::iterator it=l.begin(); it != l.end(); it++) {
@@ -235,10 +260,12 @@
              }
          }
      }
+
      void LibXSLTTransformer::terminate()
          throw (RuntimeException) {
          m_parameters.clear();
      }
+
      void LibXSLTTransformer::initialize(const Sequence<Any>& params)
          throw (RuntimeException) {
          xmlSubstituteEntitiesDefault(0);
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.hxx 
b/filter/source/xsltfilter/LibXSLTTransformer.hxx
index 376075e..64073c0 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.hxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx
@@ -32,9 +32,6 @@
  #include <com/sun/star/lang/XInitialization.hpp>
  #include <com/sun/star/beans/NamedValue.hpp>
 
- #define _INPUT_BUFFER_SIZE 1024
- #define _OUTPUT_BUFFER_SIZE 1024
-
  using namespace ::rtl;
  using namespace ::cppu;
  using namespace ::osl;
@@ -127,8 +124,8 @@
          virtual ~Reader();
 
      private:
-         static const sal_Int32 OUTPUT_BUFFER_SIZE = _OUTPUT_BUFFER_SIZE;
-         static const sal_Int32 INPUT_BUFFER_SIZE = _INPUT_BUFFER_SIZE;
+         static const sal_Int32 OUTPUT_BUFFER_SIZE;
+         static const sal_Int32 INPUT_BUFFER_SIZE;
          LibXSLTTransformer* m_transformer;
          sal_Bool m_terminated;
          Sequence<sal_Int8> m_readBuf;
-- 
1.7.1


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.