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/theMacroExpander.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 : class XSLTFilter : public WeakImplHelper4<XImportFilter, XExportFilter,
104 : XStreamListener, ExtendedDocumentHandlerAdapter>
105 : {
106 : private:
107 :
108 : // the UNO ServiceFactory
109 : css::uno::Reference<XComponentContext> m_xContext;
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 OUString& rTransformer, const Sequence<Any>& rArgs);
128 :
129 : public:
130 :
131 : // ctor...
132 : XSLTFilter(const css::uno::Reference<XComponentContext> &r);
133 :
134 : virtual ~XSLTFilter();
135 :
136 : // XStreamListener
137 : virtual void SAL_CALL
138 : error(const Any& a) throw (RuntimeException, std::exception) SAL_OVERRIDE;
139 : virtual void SAL_CALL
140 : closed() throw (RuntimeException, std::exception) SAL_OVERRIDE;
141 : virtual void SAL_CALL
142 : terminated() throw (RuntimeException, std::exception) SAL_OVERRIDE;
143 : virtual void SAL_CALL
144 : started() throw (RuntimeException, std::exception) SAL_OVERRIDE;
145 : virtual void SAL_CALL
146 : disposing(const EventObject& e) throw (RuntimeException, std::exception) SAL_OVERRIDE;
147 :
148 : // XImportFilter
149 : virtual sal_Bool SAL_CALL
150 : importer(const Sequence<PropertyValue>& aSourceData, const css::uno::Reference<
151 : XDocumentHandler>& xHandler,
152 : const Sequence<OUString>& msUserData) throw (RuntimeException, std::exception) SAL_OVERRIDE;
153 :
154 : // XExportFilter
155 : virtual sal_Bool SAL_CALL
156 : exporter(const Sequence<PropertyValue>& aSourceData, const Sequence<
157 : OUString>& msUserData) throw (RuntimeException, std::exception) SAL_OVERRIDE;
158 :
159 : // XDocumentHandler
160 : virtual void SAL_CALL
161 : startDocument() throw (SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
162 : virtual void SAL_CALL
163 : endDocument() throw (SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
164 : };
165 :
166 0 : XSLTFilter::XSLTFilter(const css::uno::Reference<XComponentContext> &r):
167 0 : m_xContext(r), m_bTerminated(sal_False), m_bError(sal_False)
168 : {
169 0 : m_cTransformed = osl_createCondition();
170 0 : }
171 :
172 0 : XSLTFilter::~XSLTFilter()
173 : {
174 0 : osl_destroyCondition(m_cTransformed);
175 0 : }
176 :
177 : void
178 0 : XSLTFilter::disposing(const EventObject&) throw (RuntimeException, std::exception)
179 : {
180 0 : }
181 :
182 : OUString
183 0 : XSLTFilter::expandUrl(const OUString& sUrl)
184 : {
185 0 : OUString sExpandedUrl;
186 : try
187 : {
188 : css::uno::Reference<XMacroExpander>
189 0 : xMacroExpander = theMacroExpander::get(m_xContext);
190 0 : sExpandedUrl = xMacroExpander->expandMacros(sUrl);
191 0 : sal_Int32 nPos = sExpandedUrl.indexOf( "vnd.sun.star.expand:" );
192 0 : if (nPos != -1)
193 0 : sExpandedUrl = sExpandedUrl.copy(nPos + 20);
194 : }
195 0 : catch (const Exception&)
196 : {
197 : }
198 0 : return sExpandedUrl;
199 : }
200 :
201 : css::uno::Reference<xslt::XXSLTTransformer>
202 0 : XSLTFilter::impl_createTransformer(const OUString& rTransformer, const Sequence<Any>& rArgs)
203 : {
204 0 : css::uno::Reference<xslt::XXSLTTransformer> xTransformer;
205 :
206 : // check if the filter needs XSLT-2.0-capable transformer
207 : // COMPATIBILITY: libreoffice 3.5/3.6 used to save the impl.
208 : // name of the XSLT 2.0 transformation service there, so check
209 : // for that too (it is sufficient to check that there is _a_
210 : // service name there)
211 0 : if (rTransformer.toBoolean() || rTransformer.startsWith("com.sun."))
212 : {
213 : try
214 : {
215 0 : xTransformer = xslt::XSLT2Transformer::create(m_xContext, 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 0 : xTransformer = xslt::XSLTTransformer::create(m_xContext, rArgs);
231 : }
232 :
233 0 : return xTransformer;
234 : }
235 :
236 : void
237 0 : XSLTFilter::started() throw (RuntimeException, std::exception)
238 : {
239 0 : osl_resetCondition(m_cTransformed);
240 0 : }
241 : void
242 0 : XSLTFilter::error(const Any& a) throw (RuntimeException, std::exception)
243 : {
244 0 : Exception e;
245 0 : if (a >>= e)
246 : {
247 : SAL_WARN("filter.xslt", "XSLTFilter::error was called: " << e.Message);
248 : }
249 0 : m_bError = sal_True;
250 0 : osl_setCondition(m_cTransformed);
251 0 : }
252 : void
253 0 : XSLTFilter::closed() throw (RuntimeException, std::exception)
254 : {
255 0 : osl_setCondition(m_cTransformed);
256 0 : }
257 : void
258 0 : XSLTFilter::terminated() throw (RuntimeException, std::exception)
259 : {
260 0 : m_bTerminated = sal_True;
261 0 : osl_setCondition(m_cTransformed);
262 0 : }
263 :
264 : OUString
265 0 : XSLTFilter::rel2abs(const OUString& s)
266 : {
267 :
268 : css::uno::Reference<XStringSubstitution>
269 0 : subs(css::util::PathSubstitution::create(m_xContext));
270 0 : OUString aWorkingDir(subs->getSubstituteVariableValue(OUString( "$(progurl)")));
271 0 : INetURLObject aObj(aWorkingDir);
272 0 : aObj.setFinalSlash();
273 : bool bWasAbsolute;
274 : INetURLObject aURL = aObj.smartRel2Abs(s, bWasAbsolute, false,
275 0 : INetURLObject::WAS_ENCODED, RTL_TEXTENCODING_UTF8, true);
276 0 : return aURL.GetMainURL(INetURLObject::NO_DECODE);
277 : }
278 :
279 : sal_Bool
280 0 : XSLTFilter::importer(const Sequence<PropertyValue>& aSourceData,
281 : const css::uno::Reference<XDocumentHandler>& xHandler, const Sequence<
282 : OUString>& msUserData) throw (RuntimeException, std::exception)
283 : {
284 0 : if (msUserData.getLength() < 5)
285 0 : return sal_False;
286 :
287 0 : OUString udStyleSheet = rel2abs(msUserData[4]);
288 :
289 : // get information from media descriptor
290 : // the imput stream that represents the imported file
291 : // is most important here since we need to supply it to
292 : // the sax parser that drives the supplied document handler
293 0 : sal_Int32 nLength = aSourceData.getLength();
294 0 : OUString aName, aFileName, aURL;
295 0 : css::uno::Reference<XInputStream> xInputStream;
296 0 : css::uno::Reference<XInteractionHandler> xInterActionHandler;
297 0 : for (sal_Int32 i = 0; i < nLength; i++)
298 : {
299 0 : aName = aSourceData[i].Name;
300 0 : Any value = aSourceData[i].Value;
301 0 : if ( aName == "InputStream" )
302 0 : value >>= xInputStream;
303 0 : else if ( aName == "FileName" )
304 0 : value >>= aFileName;
305 0 : else if ( aName == "URL" )
306 0 : value >>= aURL;
307 0 : else if ( aName == "InteractionHandler" )
308 0 : value >>= xInterActionHandler;
309 0 : }
310 : OSL_ASSERT(xInputStream.is());
311 0 : if (!xInputStream.is())
312 0 : return sal_False;
313 :
314 : // create SAX parser that will read the document file
315 : // and provide events to xHandler passed to this call
316 0 : css::uno::Reference<XParser> xSaxParser = Parser::create(m_xContext);
317 :
318 : // create transformer
319 0 : Sequence<Any> args(3);
320 0 : NamedValue nv;
321 :
322 0 : nv.Name = "StylesheetURL";
323 0 : nv.Value <<= expandUrl(udStyleSheet);
324 0 : args[0] <<= nv;
325 0 : nv.Name = "SourceURL";
326 0 : nv.Value <<= aURL;
327 0 : args[1] <<= nv;
328 0 : nv.Name = "SourceBaseURL";
329 0 : nv.Value <<= OUString(INetURLObject(aURL).getBase());
330 0 : args[2] <<= nv;
331 :
332 0 : m_tcontrol = impl_createTransformer(msUserData[1], args);
333 :
334 : OSL_ASSERT(xHandler.is());
335 : OSL_ASSERT(xInputStream.is());
336 : OSL_ASSERT(m_tcontrol.is());
337 0 : if (xHandler.is() && xInputStream.is() && m_tcontrol.is())
338 : {
339 : try
340 : {
341 : // we want to be notfied when the processing is done...
342 0 : m_tcontrol->addListener(css::uno::Reference<XStreamListener> (
343 0 : this));
344 :
345 : // connect input to transformer
346 0 : css::uno::Reference<XActiveDataSink> tsink(m_tcontrol, UNO_QUERY);
347 0 : tsink->setInputStream(xInputStream);
348 :
349 : // create pipe
350 : css::uno::Reference<XOutputStream> pipeout(
351 : Pipe::create(m_xContext),
352 0 : UNO_QUERY);
353 0 : css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
354 :
355 : //connect transformer to pipe
356 : css::uno::Reference<XActiveDataSource> tsource(m_tcontrol,
357 0 : UNO_QUERY);
358 0 : tsource->setOutputStream(pipeout);
359 :
360 : // connect pipe to sax parser
361 0 : InputSource aInput;
362 0 : aInput.sSystemId = aURL;
363 0 : aInput.sPublicId = aURL;
364 0 : aInput.aInputStream = pipein;
365 :
366 : // set doc handler
367 0 : xSaxParser->setDocumentHandler(xHandler);
368 :
369 : // transform
370 0 : m_tcontrol->start();
371 0 : TimeValue timeout = { TRANSFORMATION_TIMEOUT_SEC, 0};
372 0 : oslConditionResult result(osl_waitCondition(m_cTransformed, &timeout));
373 0 : while (osl_cond_result_timeout == result) {
374 0 : if (xInterActionHandler.is()) {
375 0 : Sequence<Any> excArgs(0);
376 : ::com::sun::star::ucb::InteractiveAugmentedIOException exc(
377 : OUString("Timeout!"),
378 : static_cast< OWeakObject * >( this ),
379 : InteractionClassification_ERROR,
380 : ::com::sun::star::ucb::IOErrorCode_GENERAL,
381 0 : excArgs);
382 0 : Any r;
383 0 : r <<= exc;
384 0 : ::comphelper::OInteractionRequest* pRequest = new ::comphelper::OInteractionRequest(r);
385 0 : css::uno::Reference< XInteractionRequest > xRequest(pRequest);
386 0 : ::comphelper::OInteractionRetry* pRetry = new ::comphelper::OInteractionRetry;
387 0 : ::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort;
388 0 : pRequest->addContinuation(pRetry);
389 0 : pRequest->addContinuation(pAbort);
390 0 : xInterActionHandler->handle(xRequest);
391 0 : if (pAbort->wasSelected()) {
392 0 : m_bError = sal_True;
393 0 : osl_setCondition(m_cTransformed);
394 0 : }
395 : }
396 0 : result = osl_waitCondition(m_cTransformed, &timeout);
397 : };
398 0 : if (!m_bError) {
399 0 : xSaxParser->parseStream(aInput);
400 : }
401 0 : m_tcontrol->terminate();
402 0 : return !m_bError;
403 : }
404 : #if OSL_DEBUG_LEVEL > 0
405 : catch( const Exception& exc)
406 : #else
407 0 : catch (const Exception&)
408 : #endif
409 : {
410 : // something went wrong
411 : OSL_FAIL(OUStringToOString(exc.Message, RTL_TEXTENCODING_ASCII_US).getStr());
412 0 : return sal_False;
413 : }
414 : }
415 : else
416 : {
417 0 : return sal_False;
418 0 : }
419 : }
420 :
421 : sal_Bool
422 0 : XSLTFilter::exporter(const Sequence<PropertyValue>& aSourceData,
423 : const Sequence<OUString>& msUserData) throw (RuntimeException, std::exception)
424 : {
425 0 : if (msUserData.getLength() < 6)
426 0 : return sal_False;
427 :
428 : // get interesting values from user data
429 0 : OUString udStyleSheet = rel2abs(msUserData[5]);
430 :
431 : // read source data
432 : // we are especialy interested in the output stream
433 : // since that is where our xml-writer will push the data
434 : // from it's data-source interface
435 0 : OUString aName, sURL;
436 0 : sal_Bool bIndent = sal_False;
437 0 : OUString aDoctypePublic;
438 : // css::uno::Reference<XOutputStream> rOutputStream;
439 0 : sal_Int32 nLength = aSourceData.getLength();
440 0 : for (sal_Int32 i = 0; i < nLength; i++)
441 : {
442 0 : aName = aSourceData[i].Name;
443 0 : if ( aName == "Indent" )
444 0 : aSourceData[i].Value >>= bIndent;
445 0 : if ( aName == "DocType_Public" )
446 0 : aSourceData[i].Value >>= aDoctypePublic;
447 0 : if ( aName == "OutputStream" )
448 0 : aSourceData[i].Value >>= m_rOutputStream;
449 0 : else if ( aName == "URL" )
450 0 : aSourceData[i].Value >>= sURL;
451 : }
452 :
453 0 : if (!getDelegate().is())
454 : {
455 : // get the document writer
456 : setDelegate(css::uno::Reference<XExtendedDocumentHandler>(
457 : Writer::create(m_xContext),
458 0 : UNO_QUERY_THROW));
459 : }
460 :
461 : // create transformer
462 0 : Sequence<Any> args(4);
463 0 : NamedValue nv;
464 0 : nv.Name = "StylesheetURL";
465 0 : nv.Value <<= expandUrl(udStyleSheet);
466 0 : args[0] <<= nv;
467 0 : nv.Name = "TargetURL";
468 0 : nv.Value <<= sURL;
469 0 : args[1] <<= nv;
470 0 : nv.Name = "DoctypePublic";
471 0 : nv.Value <<= aDoctypePublic;
472 0 : args[2] <<= nv;
473 0 : nv.Name = "TargetBaseURL";
474 0 : INetURLObject ineturl(sURL);
475 0 : ineturl.removeSegment();
476 0 : m_aExportBaseUrl = ineturl.GetMainURL(INetURLObject::NO_DECODE);
477 0 : nv.Value <<= m_aExportBaseUrl;
478 0 : args[3] <<= nv;
479 :
480 0 : m_tcontrol = impl_createTransformer(msUserData[1], args);
481 :
482 : OSL_ASSERT(m_rOutputStream.is());
483 : OSL_ASSERT(m_tcontrol.is());
484 0 : if (m_tcontrol.is() && m_rOutputStream.is())
485 : {
486 : // we want to be notfied when the processing is done...
487 0 : m_tcontrol->addListener(css::uno::Reference<XStreamListener> (this));
488 :
489 : // create pipe
490 : css::uno::Reference<XOutputStream> pipeout(
491 : Pipe::create(m_xContext),
492 0 : UNO_QUERY);
493 0 : css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
494 :
495 : // connect sax writer to pipe
496 0 : css::uno::Reference<XActiveDataSource> xmlsource(getDelegate(),
497 0 : UNO_QUERY);
498 0 : xmlsource->setOutputStream(pipeout);
499 :
500 : // connect pipe to transformer
501 0 : css::uno::Reference<XActiveDataSink> tsink(m_tcontrol, UNO_QUERY);
502 0 : tsink->setInputStream(pipein);
503 :
504 : // connect transformer to output
505 0 : css::uno::Reference<XActiveDataSource> tsource(m_tcontrol, UNO_QUERY);
506 0 : tsource->setOutputStream(m_rOutputStream);
507 :
508 : // we will start receiving events after returning 'true'.
509 : // we will start the transformation as soon as we receive the startDocument
510 : // event.
511 0 : return sal_True;
512 : }
513 : else
514 : {
515 0 : return sal_False;
516 0 : }
517 : }
518 :
519 : // for the DocumentHandler implementation, we just proxy the the
520 : // events to the XML writer that we created upon the output stream
521 : // that was provided by the XMLFilterAdapter
522 : void
523 0 : XSLTFilter::startDocument() throw (SAXException, RuntimeException, std::exception)
524 : {
525 0 : ExtendedDocumentHandlerAdapter::startDocument();
526 0 : m_tcontrol->start();
527 0 : }
528 :
529 : void
530 0 : XSLTFilter::endDocument() throw (SAXException, RuntimeException, std::exception)
531 : {
532 0 : ExtendedDocumentHandlerAdapter::endDocument();
533 : // wait for the transformer to finish
534 0 : osl_waitCondition(m_cTransformed, 0);
535 0 : m_tcontrol->terminate();
536 0 : if (!m_bError && !m_bTerminated)
537 : {
538 0 : return;
539 : }
540 : else
541 : {
542 0 : throw RuntimeException();
543 : }
544 :
545 : }
546 :
547 :
548 :
549 : // Component management
550 :
551 : #define FILTER_SERVICE_NAME "com.sun.star.documentconversion.XSLTFilter"
552 : #define FILTER_IMPL_NAME "com.sun.star.comp.documentconversion.XSLTFilter"
553 : #define TRANSFORMER_SERVICE_NAME "com.sun.star.xml.xslt.XSLTTransformer"
554 : #define TRANSFORMER_IMPL_NAME "com.sun.star.comp.documentconversion.LibXSLTTransformer"
555 :
556 : static css::uno::Reference<XInterface> SAL_CALL
557 0 : CreateTransformerInstance(const css::uno::Reference<XMultiServiceFactory> &r)
558 : {
559 0 : return css::uno::Reference<XInterface> ((OWeakObject *) new LibXSLTTransformer( comphelper::getComponentContext(r) ));
560 : }
561 :
562 : static css::uno::Reference<XInterface> SAL_CALL
563 0 : CreateFilterInstance(const css::uno::Reference<XMultiServiceFactory> &r)
564 : {
565 0 : return css::uno::Reference<XInterface> ((OWeakObject *) new XSLTFilter( comphelper::getComponentContext(r) ));
566 : }
567 :
568 : }
569 :
570 : using namespace XSLT;
571 :
572 : extern "C"
573 : {
574 0 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL xsltfilter_component_getFactory(const sal_Char * pImplName,
575 : void * pServiceManager, void * /* pRegistryKey */)
576 : {
577 0 : void * pRet = 0;
578 :
579 0 : if (pServiceManager)
580 : {
581 0 : if (rtl_str_compare(pImplName, FILTER_IMPL_NAME) == 0)
582 : {
583 0 : Sequence<OUString> serviceNames(1);
584 0 : serviceNames.getArray()[0] = FILTER_SERVICE_NAME;
585 :
586 : css::uno::Reference<XSingleServiceFactory>
587 : xFactory(
588 : createSingleFactory(
589 : reinterpret_cast<XMultiServiceFactory *> (pServiceManager),
590 : OUString::createFromAscii(
591 : pImplName),
592 : CreateFilterInstance,
593 0 : serviceNames));
594 :
595 0 : if (xFactory.is())
596 : {
597 0 : xFactory->acquire();
598 0 : pRet = xFactory.get();
599 0 : }
600 : }
601 0 : else if (rtl_str_compare(pImplName, TRANSFORMER_IMPL_NAME) == 0)
602 : {
603 0 : Sequence<OUString> serviceNames(1);
604 0 : serviceNames.getArray()[0] = TRANSFORMER_SERVICE_NAME;
605 : css::uno::Reference<XSingleServiceFactory>
606 : xFactory(
607 : createSingleFactory(
608 : reinterpret_cast<XMultiServiceFactory *> (pServiceManager),
609 : OUString::createFromAscii(
610 : pImplName),
611 : CreateTransformerInstance,
612 0 : serviceNames));
613 :
614 0 : if (xFactory.is())
615 : {
616 0 : xFactory->acquire();
617 0 : pRet = xFactory.get();
618 0 : }
619 :
620 : }
621 : }
622 0 : return pRet;
623 : }
624 :
625 : } // extern "C"
626 :
627 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|