[Libreoffice-commits] .: filter/source
Jan Holesovsky
kendy at kemper.freedesktop.org
Fri Feb 4 04:44:31 PST 2011
filter/source/xsltfilter/LibXSLTTransformer.cxx | 442 +++++++++
filter/source/xsltfilter/LibXSLTTransformer.hxx | 201 ++++
filter/source/xsltfilter/XSLTFilter.cxx | 1162 ++++++++++++------------
filter/source/xsltfilter/makefile.mk | 14
4 files changed, 1240 insertions(+), 579 deletions(-)
New commits:
commit cd9e87a248022a6a5b2f8fcd6dc5fca7432b7b38
Author: Peter Jentsch <pjotr at guineapics.de>
Date: Wed Feb 2 23:48:34 2011 +0100
Update of the libxslt based xsltfilter implementation.
* Uses the sax document handler adapter
* Uses libxslt by default
* Tries to evaluate the 2nd userdata parameter of the filter configuration as
the name of the transformation service to use. This should allow extension
authors to provide their own transformer implementation (which then could use
the old java based transformation service which in turn uses saxon and could
provide xslt 2.0 for the TEI people for example).
This is incomplete in the sense that the current filter configurations for the
MS Office 2003 filters needed to be changed to still use the Java based
filter, as long as there's no libxslt based extension function for the
embedded ole export available.
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx b/filter/source/xsltfilter/LibXSLTTransformer.cxx
new file mode 100644
index 0000000..ebf730f
--- /dev/null
+++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx
@@ -0,0 +1,442 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * [ Peter Jentsch <pjotr at guineapics.de> ]
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Peter Jentsch <pjotr at guineapics.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+
+#include <cstdio>
+#include <cstring>
+#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;
+
+#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";
+ 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";
+
+ 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);
+ 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,
+ this->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;
+ ListenerList* l = &m_listeners;
+ for (it = l->begin(); it != l->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..16396a3
--- /dev/null
+++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * [ Peter Jentsch <pjotr at guineapics.de> ]
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Peter Jentsch <pjotr at guineapics.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+// 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>
+
+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
+{
+
+ /*
+ * LibXSLTTransformer provides an transforming pipe service to XSLTFilter.
+ *
+ * It implements XActiveDataSource, XActiveDataSink and XActiveDataControl
+ * to consume data. It also notifies upstream of important events such as
+ * begin and end of the transformation and of any errors that occur during
+ * transformation.
+ *
+ * TODO: Error reporting leaves room for improvement, currently.
+ *
+ * The actual transformation is done by a worker thread.
+ *
+ * See Reader below.
+ */
+ 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();
+
+ };
+
+ /*
+ * Reader provides a worker thread to perform the actual transformation.
+ * It pipes the streams provided by a LibXSLTTransformer
+ * instance through libxslt.
+ */
+ 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;
+ static const sal_Int32 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 21983a1..a1545fa 100644
--- a/filter/source/xsltfilter/XSLTFilter.cxx
+++ b/filter/source/xsltfilter/XSLTFilter.cxx
@@ -39,6 +39,8 @@
#include <cppuhelper/implbase4.hxx>
#include <cppuhelper/implbase.hxx>
+#include <sax/tools/documenthandleradapter.hxx>
+
#include <osl/time.h>
#include <osl/conditn.h>
#include <tools/urlobj.hxx>
@@ -76,10 +78,12 @@
#include <xmloff/attrlist.hxx>
#include <fla.hxx>
+#include <LibXSLTTransformer.hxx>
using namespace ::rtl;
using namespace ::cppu;
using namespace ::osl;
+using namespace ::sax;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::uno;
@@ -89,587 +93,550 @@ 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>
+namespace XSLT
{
-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();
-}
+ /*
+ * FLABridge provides some obscure attribute mangling to wordml2000 import/export filters.
+ * In the long run, you might want to replace this with an XSLT extension function.
+ */
+ class FLABridge : public WeakImplHelper1< DocumentHandlerAdapter >
+ {
+ private:
+ const sal_Unicode *
+ eval(const sal_Unicode *expr, sal_Int32 exprLen);
+ FLA::Evaluator ev;
+ bool active;
-void FLABridge::endDocument() throw (SAXException,RuntimeException){
- OSL_ASSERT(m_rDocumentHandler.is());
- m_rDocumentHandler->endDocument();
+ public:
+ FLABridge(const Reference<XDocumentHandler>& m_rDocumentHandler);
-}
+ virtual void SAL_CALL
+ startElement(const OUString& str,
+ const Reference<XAttributeList>& attriblist)
+ throw (SAXException, RuntimeException);
+ };
-void FLABridge::startElement(const OUString& str, const Reference<XAttributeList>& attriblist)
- throw (SAXException, RuntimeException)
-{
- OSL_ASSERT(m_rDocumentHandler.is());
- if (active)
+ FLABridge::FLABridge(const Reference<XDocumentHandler>& _rDocumentHandler) : active(false)
{
-// 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))
+ DocumentHandlerAdapter::setDelegate(_rDocumentHandler);
+ }
+
+ void
+ FLABridge::startElement(const OUString& str,
+ const Reference<XAttributeList>& attriblist) throw (SAXException,
+ RuntimeException)
+ {
+ if (active)
{
- 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);
- }
+ // 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);
+ DocumentHandlerAdapter::startElement(str, newattriblist);
}
- else
+ else
{
- _newattriblist->AddAttribute(name, attriblist->getValueByIndex( sal::static_int_cast<sal_Int16>( i )));
+ if (str.compareToAscii("fla:fla.activate") == 0)
+ {
+ active = 1;
+ }
+ DocumentHandlerAdapter::startElement(str, attriblist);
}
- };
- const Reference<XAttributeList> newattriblist(_newattriblist);
- m_rDocumentHandler->startElement(str, newattriblist);
}
- else
+
+ /*
+ * XSLTFilter reads flat xml streams from the XML filter framework and passes
+ * them to an XSLT transformation service. XSLT transformation errors are
+ * reported to XSLTFilter.
+ *
+ * Currently, two implemations for the XSLT transformation service exist:
+ * a java based service (see XSLTransformer.java) and a libxslt based
+ * service (LibXSLTTransformer.cxx).
+ *
+ * The libxslt implementation will be used, if the value of the 2nd "UserData"
+ * parameter of the filter configuration is "libxslt"
+ */
+ class XSLTFilter : public WeakImplHelper4<XImportFilter, XExportFilter,
+ XStreamListener, ExtendedDocumentHandlerAdapter>
{
- if (str.compareToAscii("fla:fla.activate")==0)
- {
- active=1;
- }
- m_rDocumentHandler->startElement(str, attriblist);
+ private:
+ static const OUString LIBXSLT_HELPER_SERVICE_IMPL;
+
+ // the UNO ServiceFactory
+ Reference<XMultiServiceFactory> m_rServiceFactory;
+
+ // DocumentHandler interface of the css::xml::sax::Writer service
+ Reference<XOutputStream> m_rOutputStream;
+
+ Reference<XActiveDataControl> m_tcontrol;
+
+ oslCondition m_cTransformed;
+ sal_Bool m_bTerminated;
+ sal_Bool m_bError;
+
+ OUString m_aExportBaseUrl;
+
+ 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);
+ };
+
+ XSLTFilter::XSLTFilter(const Reference<XMultiServiceFactory> &r):
+m_rServiceFactory(r), m_bTerminated(sal_False), m_bError(sal_False)
+ {
+ m_cTransformed = osl_createCondition();
}
-}
-
-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
+ void
+ XSLTFilter::disposing(const EventObject&) throw (RuntimeException)
{
- Reference< XComponentContext > xContext;
- Reference< XPropertySet > xProps( m_rServiceFactory, UNO_QUERY_THROW );
- xContext.set( xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" )) ), UNO_QUERY_THROW );
- Reference< XMacroExpander > xMacroExpander( xContext->getValueByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander" )) ), UNO_QUERY_THROW );
- sExpandedUrl = xMacroExpander->expandMacros(sUrl);
- sal_Int32 nPos = sExpandedUrl.indexOf(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "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)
+ ::rtl::OUString
+ XSLTFilter::expandUrl(const ::rtl::OUString& sUrl)
{
- OString aMessage("XSLTFilter::error was called: ");
- aMessage += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
- OSL_ENSURE(sal_False, aMessage);
+ ::rtl::OUString sExpandedUrl;
+ try
+ {
+ Reference<XComponentContext> xContext;
+ Reference<XPropertySet> xProps(m_rServiceFactory,
+ UNO_QUERY_THROW);
+ xContext.set(xProps->getPropertyValue(::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))),
+ UNO_QUERY_THROW);
+ Reference<XMacroExpander>
+ xMacroExpander(
+ xContext->getValueByName(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander" ))),
+ UNO_QUERY_THROW);
+ sExpandedUrl = xMacroExpander->expandMacros(sUrl);
+ sal_Int32 nPos = sExpandedUrl.indexOf(::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.expand:" )));
+ if (nPos != -1)
+ sExpandedUrl = sExpandedUrl.copy(nPos + 20);
+ }
+ catch (Exception&)
+ {
+ }
+ return sExpandedUrl;
}
- 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( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.PathSubstitution" ))), UNO_QUERY);
- OUString aWorkingDir(subs->getSubstituteVariableValue(OUString(RTL_CONSTASCII_USTRINGPARAM("$(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++)
+ void
+ XSLTFilter::started() throw (RuntimeException)
{
- aName = aSourceData[i].Name;
- if (aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("InputStream")))
- aSourceData[i].Value >>= xInputStream;
- else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("FileName")))
- aSourceData[i].Value >>= aFileName;
- else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("URL")))
- aSourceData[i].Value >>= aURL;
+ osl_resetCondition(m_cTransformed);
}
- 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( RTL_CONSTASCII_USTRINGPARAM( "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( RTL_CONSTASCII_USTRINGPARAM( "StylesheetURL" ));
- nv.Value <<= expandUrl(udStyleSheet); args[0] <<= nv;
- nv.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SourceURL" ));
- nv.Value <<= aURL; args[1] <<= nv;
- nv.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SourceBaseURL" ));
- 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);
-
- OSL_ASSERT(xHandler.is());
- OSL_ASSERT(xInputStream.is());
- OSL_ASSERT(m_tcontrol.is());
- if (xHandler.is() && xInputStream.is() && m_tcontrol.is())
+ void
+ XSLTFilter::error(const Any& a) throw (RuntimeException)
{
- 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( RTL_CONSTASCII_USTRINGPARAM( "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)
+ Exception e;
+ if (a >>= e)
{
- // parse the transformed XML buffered in the pipe
- xSaxParser->parseStream(aInput);
- osl_waitCondition(m_cTransformed, 0);
- return sal_True;
- } else {
- return sal_False;
+ OString aMessage("XSLTFilter::error was called: ");
+ aMessage += OUStringToOString(e.Message,
+ RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMessage);
}
- }
-#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;
+ m_bError = sal_True;
+ osl_setCondition(m_cTransformed);
}
-}
-
-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++)
+ void
+ XSLTFilter::closed() throw (RuntimeException)
{
- aName = aSourceData[i].Name;
- if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Indent")))
- aSourceData[i].Value >>= bIndent;
- if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("DocType_Public")))
- aSourceData[i].Value >>= aDoctypePublic;
- if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("DocType_System")))
- aSourceData[i].Value >>= aDoctypeSystem;
- if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("OutputStream")))
- aSourceData[i].Value >>= m_rOutputStream;
- else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("URL" ) ))
- aSourceData[i].Value >>= sURL;
+ osl_setCondition(m_cTransformed);
}
-
- if (!m_rDocumentHandler.is()) {
- // get the document writer
- m_rDocumentHandler = Reference<XExtendedDocumentHandler>(
- m_rServiceFactory->createInstance(
- OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ))),
- UNO_QUERY);
+ void
+ XSLTFilter::terminated() throw (RuntimeException)
+ {
+ m_bTerminated = sal_True;
+ osl_setCondition(m_cTransformed);
}
- // create transformer
- Sequence< Any > args(4);
- NamedValue nv;
- nv.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "StylesheetURL" ));
- nv.Value <<= expandUrl(udStyleSheet); args[0] <<= nv;
- nv.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "TargetURL" ));
- nv.Value <<= sURL; args[1] <<= nv;
- nv.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DoctypeSystem" ));
- nv.Value <<= aDoctypeSystem; args[2] <<= nv;
- nv.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DoctypePublic" ));
- nv.Value <<= aDoctypePublic; args[3] <<= nv;
- nv.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "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( RTL_CONSTASCII_USTRINGPARAM( "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())
+ OUString
+ XSLTFilter::rel2abs(const OUString& s)
{
- // 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( RTL_CONSTASCII_USTRINGPARAM( "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;
+
+ Reference<XStringSubstitution>
+ subs(
+ m_rServiceFactory->createInstance(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.PathSubstitution" ))),
+ UNO_QUERY);
+ OUString aWorkingDir(subs->getSubstituteVariableValue(OUString(
+ RTL_CONSTASCII_USTRINGPARAM("$(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);
}
- else
+
+ sal_Bool
+ XSLTFilter::importer(const Sequence<PropertyValue>& aSourceData,
+ const Reference<XDocumentHandler>& xHandler, const Sequence<
+ OUString>& msUserData) throw (RuntimeException)
{
- return sal_False;
- }
-}
+ if (msUserData.getLength() < 5)
+ 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();
-}
+ 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;
-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();
+ // 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(
+ RTL_CONSTASCII_USTRINGPARAM( "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(RTL_CONSTASCII_USTRINGPARAM( "StylesheetURL" ));
+ nv.Value <<= expandUrl(udStyleSheet);
+ args[0] <<= nv;
+ nv.Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "SourceURL" ));
+ nv.Value <<= aURL;
+ args[1] <<= nv;
+ nv.Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "SourceBaseURL" ));
+ nv.Value <<= OUString(INetURLObject(aURL).getBase());
+ args[2] <<= nv;
+
+ OUString serviceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.documentconversion.LibXSLTTransformer"));
+ if (msUserData[1].getLength() != 0)
+ serviceName = msUserData[1];
+
+ m_tcontrol = Reference<XActiveDataControl> (m_rServiceFactory->createInstanceWithArguments(serviceName, 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(
+ RTL_CONSTASCII_USTRINGPARAM( "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;
-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);
-}
+ // 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;
+ }
-void XSLTFilter::endElement(const OUString& str)
- throw (SAXException, RuntimeException)
-{
- OSL_ASSERT(m_rDocumentHandler.is());
- m_rDocumentHandler->endElement(str);
-}
+ if (!getDelegate().is())
+ {
+ // get the document writer
+ setDelegate(Reference<XExtendedDocumentHandler> (
+ m_rServiceFactory->createInstance(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ))),
+ UNO_QUERY));
+ }
-void XSLTFilter::characters(const OUString& str)
- throw (SAXException, RuntimeException)
-{
- OSL_ASSERT(m_rDocumentHandler.is());
- m_rDocumentHandler->characters(str);
-}
+ // create transformer
+ Sequence<Any> args(4);
+ NamedValue nv;
+ nv.Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "StylesheetURL" ));
+ nv.Value <<= expandUrl(udStyleSheet);
+ args[0] <<= nv;
+ nv.Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "TargetURL" ));
+ nv.Value <<= sURL;
+ args[1] <<= nv;
+ nv.Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "DoctypeSystem" ));
+ nv.Value <<= aDoctypeSystem;
+ args[2] <<= nv;
+ nv.Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "DoctypePublic" ));
+ nv.Value <<= aDoctypePublic;
+ args[3] <<= nv;
+ nv.Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "TargetBaseURL" ));
+ INetURLObject ineturl(sURL);
+ ineturl.removeSegment();
+ m_aExportBaseUrl = ineturl.GetMainURL(INetURLObject::NO_DECODE);
+ nv.Value <<= m_aExportBaseUrl;
+ args[3] <<= nv;
+
+ OUString serviceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.documentconversion.LibXSLTTransformer"));
+ if (msUserData[1].getLength() != 0)
+ serviceName = msUserData[1];
+
+ m_tcontrol = Reference<XActiveDataControl> (m_rServiceFactory->createInstanceWithArguments(serviceName, args), UNO_QUERY);
+
+ OSL_ASSERT(m_rOutputStream.is());
+ OSL_ASSERT(m_tcontrol.is());
+ if (m_tcontrol.is() && m_rOutputStream.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(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.Pipe" ))),
+ UNO_QUERY);
+ Reference<XInputStream> pipein(pipeout, UNO_QUERY);
+
+ // connect sax writer to pipe
+ Reference<XActiveDataSource> xmlsource(getDelegate(),
+ 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;
+ }
+ }
-void XSLTFilter::ignorableWhitespace(const OUString& str)
- throw (SAXException, RuntimeException)
-{
- OSL_ASSERT(m_rDocumentHandler.is());
- if (!m_bPrettyPrint) return;
- m_rDocumentHandler->ignorableWhitespace(str);
-}
+ // 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)
+ {
+ ExtendedDocumentHandlerAdapter::startDocument();
+ m_tcontrol->start();
+ }
-void XSLTFilter::processingInstruction(const OUString& str, const OUString& str2)
- throw (SAXException, RuntimeException)
-{
- OSL_ASSERT(m_rDocumentHandler.is());
- m_rDocumentHandler->processingInstruction(str, str2);
-}
+ void
+ XSLTFilter::endDocument() throw (SAXException, RuntimeException)
+ {
+ ExtendedDocumentHandlerAdapter::endDocument();
+ // wait for the transformer to finish
+ osl_waitCondition(m_cTransformed, 0);
+ if (!m_bError && !m_bTerminated)
+ {
+ return;
+ }
+ else
+ {
+ throw RuntimeException();
+ }
-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"
+ // --------------------------------------
+ // Component management
+ // --------------------------------------
+#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)
-{
- return Reference< XInterface >(( OWeakObject *)new XSLTFilter(r));
-}
+ static Reference<XInterface> SAL_CALL
+ CreateTransformerInstance(const Reference<XMultiServiceFactory> &r)
+ {
+ return Reference<XInterface> ((OWeakObject *) new LibXSLTTransformer(r));
+ }
-static Sequence< OUString > getSupportedServiceNames()
-{
- static Sequence < OUString > *pNames = 0;
- if( ! pNames )
+ static Reference<XInterface> SAL_CALL
+ CreateFilterInstance(const Reference<XMultiServiceFactory> &r)
{
- MutexGuard guard( Mutex::getGlobalMutex() );
- if( !pNames )
- {
- static Sequence< OUString > seqNames(1);
- seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICE_NAME));
- pNames = &seqNames;
- }
+ return Reference<XInterface> ((OWeakObject *) new XSLTFilter(r));
}
- return *pNames;
-}
}
@@ -677,57 +644,98 @@ 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)
+ void SAL_CALL
+ component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,
+ uno_Environment ** /* ppEnv */)
{
- try
- {
- Reference< XRegistryKey > xNewKey(
- reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
- OUString( RTL_CONSTASCII_USTRINGPARAM( "/" 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!" );
- }
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
- return sal_False;
-}
-void * SAL_CALL component_getFactory(
- const sal_Char * pImplName, void * pServiceManager, void * /* pRegistryKey */ )
-{
- void * pRet = 0;
+ sal_Bool SAL_CALL
+ component_writeInfo(void * /* pServiceManager */, void * pRegistryKey)
+ {
+ sal_Bool bRetVal = sal_False;
+ if (pRegistryKey)
+ {
+ try
+ {
+ Reference<XRegistryKey> pXNewKey(
+ static_cast<XRegistryKey*> (pRegistryKey));
+ pXNewKey->createKey(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "/" FILTER_IMPL_NAME "/UNO/SERVICES/" FILTER_SERVICE_NAME )));
+ bRetVal = 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&)
+ {
+ OSL_ENSURE(sal_False, "InvalidRegistryException caught");
+ bRetVal = sal_False;
+ }
+ }
+ return bRetVal;
+ }
- if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
+ void *
+ SAL_CALL component_getFactory(const sal_Char * pImplName,
+ void * pServiceManager, void * /* pRegistryKey */)
{
- Reference< XSingleServiceFactory > xFactory( createSingleFactory(
- reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
- OUString::createFromAscii( pImplName ),
- CreateInstance, getSupportedServiceNames() ) );
-
- if (xFactory.is())
- {
- xFactory->acquire();
- pRet = xFactory.get();
- }
+ void * pRet = 0;
+
+ 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();
+ }
+
+ }
+ }
+ return pRet;
}
- return pRet;
-}
} // extern "C"
diff --git a/filter/source/xsltfilter/makefile.mk b/filter/source/xsltfilter/makefile.mk
index baefcff..58f3c9e 100644
--- a/filter/source/xsltfilter/makefile.mk
+++ b/filter/source/xsltfilter/makefile.mk
@@ -32,9 +32,17 @@ 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)
@@ -49,7 +57,9 @@ SHL1STDLIBS= \
$(CPPUHELPERLIB) \
$(CPPULIB) \
$(XMLOFFLIB) \
- $(SALLIB)
+ $(SALLIB) \
+ $(LIBXML2LIB) \
+ $(XSLTLIB)
.IF "$(SOLAR_JAVA)"!=""
More information about the Libreoffice-commits
mailing list