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