27#include <osl/diagnose.h>
29#include <osl/conditn.hxx>
38#include <com/sun/star/lang/EventObject.hpp>
39#include <com/sun/star/lang/XServiceInfo.hpp>
41#include <com/sun/star/uno/Any.hxx>
43#include <com/sun/star/beans/PropertyValue.hpp>
45#include <com/sun/star/xml/sax/Parser.hpp>
46#include <com/sun/star/xml/sax/InputSource.hpp>
47#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
48#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
49#include <com/sun/star/xml/sax/XFastParser.hpp>
50#include <com/sun/star/xml/sax/Writer.hpp>
51#include <com/sun/star/xml/XImportFilter.hpp>
52#include <com/sun/star/xml/XImportFilter2.hpp>
53#include <com/sun/star/xml/XExportFilter.hpp>
55#include <com/sun/star/util/theMacroExpander.hpp>
57#include <com/sun/star/io/Pipe.hpp>
58#include <com/sun/star/io/XInputStream.hpp>
59#include <com/sun/star/io/XOutputStream.hpp>
60#include <com/sun/star/io/XActiveDataSource.hpp>
61#include <com/sun/star/io/XSeekable.hpp>
62#include <com/sun/star/io/XStreamListener.hpp>
63#include <com/sun/star/util/PathSubstitution.hpp>
64#include <com/sun/star/util/XStringSubstitution.hpp>
65#include <com/sun/star/beans/NamedValue.hpp>
66#include <com/sun/star/task/XInteractionHandler.hpp>
67#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
68#include <com/sun/star/xml/xslt/XSLTTransformer.hpp>
71#define TRANSFORMATION_TIMEOUT_SEC 60
73using namespace ::
cppu;
91 class XSLTFilterStreamListener :
public WeakImplHelper<XStreamListener>
94 XSLTFilterStreamListener(XSLTFilter& rParent) :
m_rParent(rParent) {}
98 error(
const Any&
a)
override;
101 virtual void SAL_CALL
102 terminated()
override;
103 virtual void SAL_CALL
105 virtual void SAL_CALL
106 disposing(
const EventObject& e)
override;
121 class XSLTFilter :
public WeakImplHelper<XImportFilter, XImportFilter2, XExportFilter,
122 ExtendedDocumentHandlerAdapter, XServiceInfo>
124 friend class XSLTFilterStreamListener;
142 rel2abs(
const OUString&);
144 expandUrl(
const OUString&);
146 css::uno::Reference<xslt::XXSLTTransformer> impl_createTransformer(
const OUString& rTransformer,
const Sequence<Any>& rArgs);
151 explicit XSLTFilter(css::uno::Reference<XComponentContext> x);
160 importer(
const Sequence<PropertyValue>& aSourceData,
const css::uno::Reference<
161 XDocumentHandler>& xHandler,
162 const Sequence<OUString>& msUserData)
override;
166 importer(
const Sequence<PropertyValue>& aSourceData,
const css::uno::Reference<
167 XFastParser>& xFastParser,
168 const Sequence<OUString>& msUserData)
override;
172 exporter(
const Sequence<PropertyValue>& aSourceData,
const Sequence<
173 OUString>& msUserData)
override;
176 virtual void SAL_CALL
177 startDocument()
override;
178 virtual void SAL_CALL
179 endDocument()
override;
184 XSLTFilter::XSLTFilter(css::uno::Reference<XComponentContext> x):
189 XSLTFilterStreamListener::disposing(
const EventObject&)
194 sal_Bool XSLTFilter::supportsService(
const OUString& sServiceName)
198 OUString XSLTFilter::getImplementationName()
200 return "com.sun.star.comp.documentconversion.XSLTFilter";
202 css::uno::Sequence< OUString > XSLTFilter::getSupportedServiceNames()
204 return {
"com.sun.star.documentconversion.XSLTFilter" };
208 XSLTFilter::expandUrl(
const OUString& sUrl)
210 OUString sPreparedURL(sUrl);
211 if (sPreparedURL.startsWithIgnoreAsciiCase(
"vnd.sun.star.expand:", &sPreparedURL))
213 sPreparedURL = rtl::Uri::decode(sPreparedURL, rtl_UriDecodeWithCharset,
214 RTL_TEXTENCODING_UTF8);
215 css::uno::Reference<XMacroExpander>
216 xMacroExpander = theMacroExpander::get(
m_xContext);
217 sPreparedURL = xMacroExpander->expandMacros(sPreparedURL);
222 css::uno::Reference<xslt::XXSLTTransformer>
223 XSLTFilter::impl_createTransformer(
const OUString& rTransformer,
const Sequence<Any>& rArgs)
225 css::uno::Reference<xslt::XXSLTTransformer> xTransformer;
232 if (rTransformer.toBoolean() || rTransformer.startsWith(
"com.sun."))
237 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
238 "com.sun.star.xml.xslt.XSLT2Transformer", rArgs,
m_xContext),
239 css::uno::UNO_QUERY_THROW);
241 catch (
const Exception&)
245 SAL_WARN(
"filter.xslt",
"could not create XSLT 2.0 transformer");
251 xTransformer = xslt::XSLTTransformer::create(
m_xContext, rArgs);
258 XSLTFilterStreamListener::started()
263 XSLTFilterStreamListener::error(
const Any& a)
270 XSLTFilterStreamListener::closed()
275 XSLTFilterStreamListener::terminated()
282 XSLTFilter::rel2abs(
const OUString& s)
285 css::uno::Reference<XStringSubstitution>
286 subs(css::util::PathSubstitution::create(
m_xContext));
287 OUString aWorkingDir(subs->getSubstituteVariableValue(
"$(progurl)" ));
289 aObj.setFinalSlash();
297 XSLTFilter::importer(
const Sequence<PropertyValue>& aSourceData,
298 const css::uno::Reference<XDocumentHandler>& xHandler,
const Sequence<
299 OUString>& msUserData)
301 if (msUserData.getLength() < 5)
304 OUString udStyleSheet = rel2abs(msUserData[4]);
311 css::uno::Reference<XInputStream> xInputStream;
312 css::uno::Reference<XInteractionHandler> xInterActionHandler;
313 for (
const auto& sourceDataItem : aSourceData)
315 aName = sourceDataItem.Name;
317 if ( aName ==
"InputStream" )
318 value >>= xInputStream;
319 else if ( aName ==
"URL" )
321 else if ( aName ==
"InteractionHandler" )
322 value >>= xInterActionHandler;
324 OSL_ASSERT(xInputStream.is());
325 if (!xInputStream.is())
329 Sequence<Any>
args{
Any(NamedValue(
"StylesheetURL",
Any(expandUrl(udStyleSheet)))),
330 Any(NamedValue(
"SourceURL",
Any(aURL))),
332 m_tcontrol = impl_createTransformer(msUserData[1], args);
334 OSL_ASSERT(xHandler.is());
335 OSL_ASSERT(xInputStream.is());
337 if (xHandler.is() && xInputStream.is() &&
m_tcontrol.is())
341 css::uno::Reference<css::io::XSeekable> xSeek(xInputStream, UNO_QUERY);
346 m_tcontrol->addListener(
new XSLTFilterStreamListener(*
this));
352 css::uno::Reference<XOutputStream> pipeout =
354 css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
361 aInput.sSystemId =
aURL;
362 aInput.sPublicId =
aURL;
363 aInput.aInputStream = pipein;
365 css::uno::Reference< css::xml::sax::XFastParser > xFastParser(
366 xHandler, css::uno::UNO_QUERY );
372 while (osl::Condition::result_timeout == result) {
373 if (xInterActionHandler.is()) {
374 Sequence<Any> excArgs(0);
375 css::ucb::InteractiveAugmentedIOException exc(
378 InteractionClassification_ERROR,
379 css::ucb::IOErrorCode_GENERAL,
386 pRequest->addContinuation(pRetry);
387 pRequest->addContinuation(pAbort);
388 xInterActionHandler->handle(pRequest);
389 if (pAbort->wasSelected()) {
397 if( xFastParser.is() )
398 xFastParser->parseStream( aInput );
403 css::uno::Reference<XParser> xSaxParser = Parser::create(
m_xContext);
405 xSaxParser->setDocumentHandler(xHandler);
406 xSaxParser->parseStream( aInput );
412 catch(
const Exception& )
426 XSLTFilter::importer(
const Sequence<PropertyValue>& aSourceData,
427 const css::uno::Reference<XFastParser>& xFastParser,
const Sequence<
428 OUString>& msUserData)
430 if (msUserData.getLength() < 5)
433 OUString udStyleSheet = rel2abs(msUserData[4]);
439 sal_Int32
nLength = aSourceData.getLength();
441 css::uno::Reference<XInputStream> xInputStream;
442 css::uno::Reference<XInteractionHandler> xInterActionHandler;
445 aName = aSourceData[
i].Name;
447 if ( aName ==
"InputStream" )
448 value >>= xInputStream;
449 else if ( aName ==
"URL" )
451 else if ( aName ==
"InteractionHandler" )
452 value >>= xInterActionHandler;
454 OSL_ASSERT(xInputStream.is());
455 if (!xInputStream.is())
459 Sequence<Any>
args{
Any(NamedValue(
"StylesheetURL",
Any(expandUrl(udStyleSheet)))),
460 Any(NamedValue(
"SourceURL",
Any(aURL))),
462 m_tcontrol = impl_createTransformer(msUserData[1], args);
464 assert(xFastParser.is());
465 OSL_ASSERT(xInputStream.is());
467 if (xFastParser.is() && xInputStream.is() &&
m_tcontrol.is())
471 css::uno::Reference<css::io::XSeekable> xSeek(xInputStream, UNO_QUERY);
476 m_tcontrol->addListener(
new XSLTFilterStreamListener(*
this));
482 css::uno::Reference<XOutputStream> pipeout =
484 css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
491 aInput.sSystemId =
aURL;
492 aInput.sPublicId =
aURL;
493 aInput.aInputStream = pipein;
499 while (osl::Condition::result_timeout == result) {
500 if (xInterActionHandler.is()) {
501 Sequence<Any> excArgs(0);
502 css::ucb::InteractiveAugmentedIOException exc(
505 InteractionClassification_ERROR,
506 css::ucb::IOErrorCode_GENERAL,
513 pRequest->addContinuation(pRetry);
514 pRequest->addContinuation(pAbort);
515 xInterActionHandler->handle(pRequest);
516 if (pAbort->wasSelected()) {
524 xFastParser->parseStream( aInput );
528 catch(
const Exception& )
542 XSLTFilter::exporter(
const Sequence<PropertyValue>& aSourceData,
543 const Sequence<OUString>& msUserData)
545 if (msUserData.getLength() < 6)
549 OUString udStyleSheet = rel2abs(msUserData[5]);
555 OUString
aName, sURL;
556 OUString aDoctypePublic;
558 sal_Int32
nLength = aSourceData.getLength();
561 aName = aSourceData[
i].Name;
562 if ( aName ==
"DocType_Public" )
563 aSourceData[
i].Value >>= aDoctypePublic;
564 else if ( aName ==
"OutputStream" )
566 else if ( aName ==
"URL" )
567 aSourceData[
i].Value >>= sURL;
570 if (!getDelegate().is())
573 setDelegate(css::uno::Reference<XExtendedDocumentHandler>(
580 ineturl.removeSegment();
582 Sequence<Any>
args{
Any(NamedValue(
"StylesheetURL",
Any(expandUrl(udStyleSheet)))),
583 Any(NamedValue(
"TargetURL",
Any(sURL))),
584 Any(NamedValue(
"DoctypePublic",
Any(aDoctypePublic))),
586 m_tcontrol = impl_createTransformer(msUserData[1], args);
593 m_tcontrol->addListener(
new XSLTFilterStreamListener(*
this));
596 css::uno::Reference<XOutputStream> pipeout =
598 css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
601 css::uno::Reference<XActiveDataSource> xmlsource(getDelegate(),
603 xmlsource->setOutputStream(pipeout);
626 XSLTFilter::startDocument()
628 ExtendedDocumentHandlerAdapter::startDocument();
633 XSLTFilter::endDocument()
635 ExtendedDocumentHandlerAdapter::endDocument();
648extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
650 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any>
const&)
652 return cppu::acquire(
new XSLT::XSLTFilter(context));
osl::Condition m_cTransformed
css::uno::Reference< XComponentContext > m_xContext
#define TRANSFORMATION_TIMEOUT_SEC
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * filter_XSLTFilter_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
css::uno::Reference< xslt::XXSLTTransformer > m_tcontrol
OUString m_aExportBaseUrl
css::uno::Reference< XOutputStream > m_rOutputStream
OString exceptionToString(const css::uno::Any &caught)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define SAL_WARN(area, stream)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)