1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 **************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_filter.hxx"
24
25 #include <stdio.h>
26
27 #include <cppuhelper/factory.hxx>
28 #include <cppuhelper/servicefactory.hxx>
29 #include <cppuhelper/implbase4.hxx>
30 #include <cppuhelper/implbase.hxx>
31
32 #include <osl/time.h>
33 #include <osl/conditn.h>
34 #include <tools/urlobj.hxx>
35 #include <osl/module.h>
36 #include <osl/file.hxx>
37 #include <osl/process.h>
38
39 #include <com/sun/star/lang/XComponent.hpp>
40
41 #include <com/sun/star/uno/Any.hxx>
42 #include <com/sun/star/uno/Type.hxx>
43
44 #include <com/sun/star/beans/PropertyValue.hpp>
45
46 #include <com/sun/star/xml/sax/XParser.hpp>
47 #include <com/sun/star/xml/sax/InputSource.hpp>
48 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
49 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
50 #include <com/sun/star/xml/sax/SAXException.hpp>
51 #include <com/sun/star/xml/XImportFilter.hpp>
52 #include <com/sun/star/xml/XExportFilter.hpp>
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 #include <com/sun/star/util/XMacroExpander.hpp>
55
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/uno/Any.hxx>
63 #include <com/sun/star/lang/EventObject.hpp>
64 #include <com/sun/star/util/XStringSubstitution.hpp>
65 #include <com/sun/star/beans/NamedValue.hpp>
66
67
68 #include "uof2splitter.hxx"
69 #include "uof2storage.hxx"
70 #include "uof2merge.hxx"
71
72 using namespace ::rtl;
73 using namespace ::cppu;
74 using namespace ::osl;
75 using namespace ::com::sun::star::beans;
76 using namespace ::com::sun::star::io;
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::lang;
79 using namespace ::com::sun::star::registry;
80 using namespace ::com::sun::star::xml;
81 using namespace ::com::sun::star::xml::sax;
82 using namespace ::com::sun::star::util;
83
84 namespace XSLT {
85
86
87 class XSLTFilter : public WeakImplHelper4< XImportFilter, XExportFilter, XDocumentHandler, XStreamListener>
88 {
89 public:
90
91 // ctor...
92 XSLTFilter( const Reference< XMultiServiceFactory > &r );
93
94 // XStreamListener
95 virtual void SAL_CALL error(const Any& a) throw (RuntimeException);
96 virtual void SAL_CALL closed() throw (RuntimeException);
97 virtual void SAL_CALL terminated() throw (RuntimeException);
98 virtual void SAL_CALL started() throw (RuntimeException);
99 virtual void SAL_CALL disposing(const EventObject& e) throw (RuntimeException);
100
101
102 // XImportFilter
103 virtual sal_Bool SAL_CALL importer(
104 const Sequence<PropertyValue>& aSourceData,
105 const Reference<XDocumentHandler>& xHandler,
106 const Sequence<OUString>& msUserData)
107 throw(RuntimeException);
108
109 // XExportFilter
110 virtual sal_Bool SAL_CALL exporter(
111 const Sequence<PropertyValue>& aSourceData,
112 const Sequence<OUString>& msUserData)
113 throw(RuntimeException);
114
115 // XDocumentHandler
116 virtual void SAL_CALL startDocument()
117 throw (SAXException,RuntimeException);
118 virtual void SAL_CALL endDocument()
119 throw (SAXException, RuntimeException);
120 virtual void SAL_CALL startElement(const OUString& str, const Reference<XAttributeList>& attriblist)
121 throw (SAXException,RuntimeException);
122 virtual void SAL_CALL endElement(const OUString& str)
123 throw (SAXException, RuntimeException);
124 virtual void SAL_CALL characters(const OUString& str)
125 throw (SAXException, RuntimeException);
126 virtual void SAL_CALL ignorableWhitespace(const OUString& str)
127 throw (SAXException, RuntimeException);
128 virtual void SAL_CALL processingInstruction(const OUString& str, const OUString& str2)
129 throw (com::sun::star::xml::sax::SAXException,RuntimeException);
130 virtual void SAL_CALL setDocumentLocator(const Reference<XLocator>& doclocator)
131 throw (SAXException,RuntimeException);
132
133 private:
134 // the UNO ServiceFactory
135 Reference< XMultiServiceFactory > m_rServiceFactory;
136
137 // DocumentHandler interface of the css::xml::sax::Writer service
138 Reference < XExtendedDocumentHandler > m_rDocumentHandler;
139 Reference < XOutputStream > m_rOutputStream;
140
141 // controls pretty-printing
142 sal_Bool m_bPrettyPrint;
143
144 Reference< XActiveDataControl > m_tcontrol;
145 oslCondition m_cTransformed;
146
147 sal_Bool m_bTerminated;
148 sal_Bool m_bError;
149
150 OUString m_aExportBaseUrl;
151 OUString m_aOldBaseUrl;
152
153 OUString rel2abs(const OUString&);
154 OUString expandUrl(const OUString&);
155
156 // for support of UOF v2.0
157 Reference< XActiveDataControl > m_splitControl;
158 Reference< XStream > m_rStream;
159
160 bool isUOF2ExportStyleSheet( const OUString& rExportStyleSheet );
161
162 };
163
XSLTFilter(const Reference<XMultiServiceFactory> & r)164 XSLTFilter::XSLTFilter( const Reference< XMultiServiceFactory > &r )
165 : m_rServiceFactory( r )
166 , m_rDocumentHandler()
167 , m_rOutputStream()
168 , m_bPrettyPrint( sal_True )
169 , m_tcontrol()
170 , m_cTransformed()
171 , m_bTerminated( sal_False )
172 , m_bError( sal_False )
173 , m_aExportBaseUrl()
174 , m_aOldBaseUrl()
175 , m_splitControl()
176 , m_rStream()
177 {
178 m_cTransformed = osl_createCondition();
179 }
180
disposing(const EventObject &)181 void XSLTFilter::disposing(const EventObject& ) throw (RuntimeException)
182 {
183 }
184
expandUrl(const::rtl::OUString & sUrl)185 ::rtl::OUString XSLTFilter::expandUrl( const ::rtl::OUString& sUrl )
186 {
187 ::rtl::OUString sExpandedUrl;
188 try
189 {
190 Reference< XComponentContext > xContext;
191 Reference< XPropertySet > xProps( m_rServiceFactory, UNO_QUERY_THROW );
192 xContext.set( xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "DefaultContext" ) ), UNO_QUERY_THROW );
193 Reference< XMacroExpander > xMacroExpander( xContext->getValueByName( ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), UNO_QUERY_THROW );
194 sExpandedUrl = xMacroExpander->expandMacros(sUrl);
195 sal_Int32 nPos = sExpandedUrl.indexOf(::rtl::OUString::createFromAscii("vnd.sun.star.expand:"));
196 if ( nPos != -1 )
197 sExpandedUrl = sExpandedUrl.copy(nPos+20);
198 }
199 catch (Exception&) {}
200 return sExpandedUrl;
201 }
202
started()203 void XSLTFilter::started() throw (RuntimeException)
204 {
205 osl_resetCondition(m_cTransformed);
206 }
error(const Any & a)207 void XSLTFilter::error(const Any& a) throw (RuntimeException)
208 {
209 Exception e;
210 if ( a >>= e)
211 {
212 OString aMessage("XSLTFilter::error was called: ");
213 aMessage += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
214 OSL_ENSURE(sal_False, aMessage);
215 }
216 m_bError = sal_True;
217 osl_setCondition(m_cTransformed);
218 }
closed()219 void XSLTFilter::closed() throw (RuntimeException)
220 {
221 osl_setCondition(m_cTransformed);
222 }
terminated()223 void XSLTFilter::terminated() throw (RuntimeException)
224 {
225 m_bTerminated = sal_True;
226 osl_setCondition(m_cTransformed);
227 }
228
rel2abs(const OUString & s)229 OUString XSLTFilter::rel2abs(const OUString& s)
230 {
231
232 Reference< XStringSubstitution > subs(m_rServiceFactory->createInstance(
233 OUString::createFromAscii("com.sun.star.util.PathSubstitution")), UNO_QUERY);
234 OUString aWorkingDir = subs->getSubstituteVariableValue(OUString::createFromAscii("$(progurl)"));
235 INetURLObject aObj( aWorkingDir );
236 aObj.setFinalSlash();
237 bool bWasAbsolute;
238 INetURLObject aURL = aObj.smartRel2Abs(
239 s, bWasAbsolute, false, INetURLObject::WAS_ENCODED, RTL_TEXTENCODING_UTF8, true );
240 return aURL.GetMainURL(INetURLObject::NO_DECODE);
241 }
242
243
244
importer(const Sequence<PropertyValue> & aSourceData,const Reference<XDocumentHandler> & xHandler,const Sequence<OUString> & msUserData)245 sal_Bool XSLTFilter::importer(
246 const Sequence<PropertyValue>& aSourceData,
247 const Reference<XDocumentHandler>& xHandler,
248 const Sequence<OUString>& msUserData)
249 throw (RuntimeException)
250 {
251 if ( msUserData.getLength() < 5 )
252 return sal_False;
253
254 const OUString udStyleSheet = rel2abs( msUserData[4] );
255
256 // get information from media descriptor
257 // the imput stream that represents the imported file
258 // is most important here since we need to supply it to
259 // the sax parser that drives the supplied document handler
260 const sal_Int32 nLength = aSourceData.getLength();
261 OUString aFileName;
262 OUString aURL;
263 Reference< XInputStream > xInputStream;
264 for ( sal_Int32 i = 0 ; i < nLength; i++)
265 {
266 const OUString aName = aSourceData[i].Name;
267 if ( aName.equalsAscii( "InputStream" ) )
268 aSourceData[i].Value >>= xInputStream;
269 else if ( aName.equalsAscii( "FileName" ) )
270 aSourceData[i].Value >>= aFileName;
271 else if ( aName.equalsAscii( "URL" ) )
272 aSourceData[i].Value >>= aURL;
273 }
274 OSL_ASSERT(xInputStream.is());
275 if ( !xInputStream.is() )
276 return sal_False;
277
278 // create SAX parser that will read the document file
279 // and provide events to xHandler passed to this call
280 Reference < XParser > xSaxParser( m_rServiceFactory->createInstance(
281 OUString::createFromAscii("com.sun.star.xml.sax.Parser")), UNO_QUERY );
282 OSL_ASSERT(xSaxParser.is());
283 if( !xSaxParser.is() )
284 return sal_False;
285
286 // create transformer
287 Sequence< Any > args(3);
288 NamedValue nv;
289
290 nv.Name = OUString::createFromAscii("StylesheetURL");
291 nv.Value <<= expandUrl(udStyleSheet); args[0] <<= nv;
292 nv.Name = OUString::createFromAscii("SourceURL");
293 nv.Value <<= aURL; args[1] <<= nv;
294 nv.Name = OUString::createFromAscii("SourceBaseURL");
295 nv.Value <<= OUString(INetURLObject(aURL).getBase());
296 args[2] <<= nv;
297
298 m_tcontrol = Reference< XActiveDataControl >(m_rServiceFactory->createInstanceWithArguments(
299 OUString::createFromAscii("com.sun.star.comp.JAXTHelper"), args), UNO_QUERY);
300
301 OSL_ASSERT(xHandler.is());
302 OSL_ASSERT(xInputStream.is());
303 OSL_ASSERT(m_tcontrol.is());
304 if (xHandler.is() && xInputStream.is() && m_tcontrol.is())
305 {
306 try
307 {
308 // we want to be notified when the processing is done...
309 m_tcontrol->addListener(Reference< XStreamListener >(this));
310
311 // connect input to transformer
312 Reference< XActiveDataSink > tsink(m_tcontrol, UNO_QUERY);
313 //UOF v2 import
314 UOF2Storage aUOF2Storage( m_rServiceFactory, xInputStream );
315 if ( aUOF2Storage.isValidUOF2Doc() )
316 {
317 UOF2Merge aUOF2Merge( aUOF2Storage, m_rServiceFactory );
318 aUOF2Merge.merge();
319 tsink->setInputStream( aUOF2Merge.getMergedInStream() );
320 }
321 else
322 {
323 tsink->setInputStream( xInputStream );
324 }
325
326 // create pipe
327 Reference< XOutputStream > pipeout(m_rServiceFactory->createInstance(
328 OUString::createFromAscii("com.sun.star.io.Pipe")), UNO_QUERY);
329 Reference< XInputStream > pipein(pipeout, UNO_QUERY);
330
331 //connect transformer to pipe
332 Reference< XActiveDataSource > tsource(m_tcontrol, UNO_QUERY);
333 tsource->setOutputStream(pipeout);
334
335 // connect pipe to sax parser
336 InputSource aInput;
337 aInput.sSystemId = aURL;
338 aInput.sPublicId = aURL;
339 aInput.aInputStream = pipein;
340
341 // set doc handler
342 xSaxParser->setDocumentHandler(xHandler);
343
344 // transform
345 m_tcontrol->start();
346 // osl_waitCondition(m_cTransformed, 0);
347 if (!m_bError && !m_bTerminated)
348 {
349 // parse the transformed XML buffered in the pipe
350 xSaxParser->parseStream(aInput);
351 osl_waitCondition(m_cTransformed, 0);
352 return sal_True;
353 } else {
354 return sal_False;
355 }
356 }
357 #if OSL_DEBUG_LEVEL > 0
358 catch( Exception& exc)
359 #else
360 catch( Exception& )
361 #endif
362 {
363 // something went wrong
364 OSL_ENSURE(0, OUStringToOString(exc.Message, RTL_TEXTENCODING_ASCII_US).getStr());
365 return sal_False;
366 }
367 } else
368 {
369 return sal_False;
370 }
371 }
372
isUOF2ExportStyleSheet(const OUString & rExportStyleSheet)373 bool XSLTFilter::isUOF2ExportStyleSheet( const OUString& rExportStyleSheet )
374 {
375 bool bIsUOFDocumentType = false;
376
377 if ( rExportStyleSheet.endsWithAsciiL( "uof.xsl", 7 ) )
378 {
379 bIsUOFDocumentType = true;
380 }
381
382 return bIsUOFDocumentType;
383 }
384
exporter(const Sequence<PropertyValue> & aSourceData,const Sequence<OUString> & msUserData)385 sal_Bool XSLTFilter::exporter(
386 const Sequence<PropertyValue>& aSourceData,
387 const Sequence<OUString>& msUserData)
388 throw (RuntimeException)
389 {
390 if ( msUserData.getLength() < 6 )
391 return sal_False;
392
393 // get interesting values from user data
394 const OUString udStyleSheet = rel2abs( msUserData[5] );
395
396 // read source data
397 // we are especially interested in the output stream
398 // since that is where our xml-writer will push the data
399 // from it's data-source interface
400 OUString sURL;
401 sal_Bool bIndent = sal_False;
402 OUString aDoctypePublic;
403 OUString aDoctypeSystem;
404 {
405 const sal_Int32 nLength = aSourceData.getLength();
406 for ( sal_Int32 i = 0; i < nLength; i++ )
407 {
408 const OUString aName = aSourceData[i].Name;
409 if ( aName.equalsAscii( "Indent" ) )
410 aSourceData[i].Value >>= bIndent;
411 if ( aName.equalsAscii( "DocType_Public" ) )
412 aSourceData[i].Value >>= aDoctypePublic;
413 if ( aName.equalsAscii( "DocType_System" ) )
414 aSourceData[i].Value >>= aDoctypeSystem;
415 if ( aName.equalsAscii( "OutputStream" ) )
416 aSourceData[i].Value >>= m_rOutputStream;
417 else if ( aName.equalsAscii( "URL" ) )
418 aSourceData[i].Value >>= sURL;
419 //UOF v2.0 export, get Stream for constructing UOF2Storage
420 if ( aName.equalsAscii( "StreamForOutput" ) )
421 aSourceData[i].Value >>= m_rStream;
422 }
423 }
424
425 if (!m_rDocumentHandler.is())
426 {
427 // get the document writer
428 m_rDocumentHandler = Reference<XExtendedDocumentHandler>(
429 m_rServiceFactory->createInstance(
430 OUString::createFromAscii("com.sun.star.xml.sax.Writer") ),
431 UNO_QUERY);
432 }
433
434 // create transformer
435 Sequence< Any > args(4);
436 NamedValue nv;
437 nv.Name = OUString::createFromAscii("StylesheetURL");
438 nv.Value <<= expandUrl(udStyleSheet); args[0] <<= nv;
439 nv.Name = OUString::createFromAscii("TargetURL");
440 nv.Value <<= sURL; args[1] <<= nv;
441 nv.Name = OUString::createFromAscii("DoctypeSystem");
442 nv.Value <<= aDoctypeSystem; args[2] <<= nv;
443 nv.Name = OUString::createFromAscii("DoctypePublic");
444 nv.Value <<= aDoctypePublic; args[3] <<= nv;
445 nv.Name = OUString::createFromAscii("TargetBaseURL");
446 INetURLObject ineturl(sURL);
447 ineturl.removeSegment();
448 m_aExportBaseUrl = ineturl.GetMainURL(INetURLObject::NO_DECODE);
449 nv.Value <<= m_aExportBaseUrl;
450 args[3] <<= nv;
451
452 m_tcontrol = Reference< XActiveDataControl >(m_rServiceFactory->createInstanceWithArguments(
453 OUString::createFromAscii("com.sun.star.comp.JAXTHelper"), args), UNO_QUERY);
454
455 OSL_ASSERT(m_rDocumentHandler.is());
456 OSL_ASSERT(m_rOutputStream.is());
457 OSL_ASSERT(m_tcontrol.is());
458 if (m_tcontrol.is() && m_rOutputStream.is() && m_rDocumentHandler.is())
459 {
460 // we want to be notified when the processing is done...
461 m_tcontrol->addListener(Reference< XStreamListener >(this));
462
463 // create pipe
464 Reference< XOutputStream > pipeout(m_rServiceFactory->createInstance(
465 OUString::createFromAscii("com.sun.star.io.Pipe")), UNO_QUERY);
466 Reference< XInputStream > pipein(pipeout, UNO_QUERY);
467
468 // connect sax writer to pipe
469 Reference< XActiveDataSource > xmlsource(m_rDocumentHandler, UNO_QUERY);
470 xmlsource->setOutputStream(pipeout);
471
472 // connect pipe to transformer
473 Reference< XActiveDataSink > tsink(m_tcontrol, UNO_QUERY);
474 tsink->setInputStream(pipein);
475
476 // connect transformer to output
477 Reference< XActiveDataSource > tsource( m_tcontrol, UNO_QUERY );
478 if ( isUOF2ExportStyleSheet( udStyleSheet ) )
479 {
480 // special handling for UOF 2
481
482 if ( !m_rStream.is() )
483 {
484 return sal_False;
485 }
486
487 //creating pipe2
488 Reference< XOutputStream > x_Pipeout(
489 m_rServiceFactory->createInstance(
490 OUString::createFromAscii( "com.sun.star.io.Pipe" ) ), UNO_QUERY );
491 Reference< XInputStream > x_Pipein( x_Pipeout, UNO_QUERY );
492
493 // connect transformer to pipe2
494 tsource->setOutputStream( x_Pipeout );
495
496 UOF2Splitter* pSplitter = new UOF2Splitter( m_rServiceFactory, sURL );
497 m_splitControl =
498 Reference< XActiveDataControl >(
499 static_cast< cppu::OWeakObject* >( pSplitter ), UNO_QUERY );
500 // connect pipe2 to splitter
501 Reference< XActiveDataSink > splitsink( m_splitControl, UNO_QUERY );
502 splitsink->setInputStream( x_Pipein );
503 // connect splitter to output
504 Reference< XActiveDataStreamer > splitout( m_splitControl, UNO_QUERY );
505 splitout->setStream( m_rStream );
506 m_rOutputStream = m_rStream->getOutputStream();
507 }
508 else
509 {
510 tsource->setOutputStream( m_rOutputStream );
511 }
512
513 // we will start receiving events after returning 'true'.
514 // we will start the transformation as soon as we receive the startDocument event.
515 return sal_True;
516 }
517 else
518 {
519 return sal_False;
520 }
521 }
522
523 // for the DocumentHandler implementation, we just proxy the the
524 // events to the XML writer that we created upon the output stream
525 // that was provided by the XMLFilterAdapter
startDocument()526 void XSLTFilter::startDocument() throw (SAXException,RuntimeException){
527 OSL_ASSERT(m_rDocumentHandler.is());
528 m_rDocumentHandler->startDocument();
529 m_tcontrol->start();
530 }
531
endDocument()532 void XSLTFilter::endDocument() throw (SAXException, RuntimeException){
533 OSL_ASSERT(m_rDocumentHandler.is());
534 m_rDocumentHandler->endDocument();
535
536 // m_splitControl only set for UOF 2
537 if ( m_splitControl.is() )
538 {
539 //when the inputStream(outputStream of filter) was closed, start to parse it.
540 m_splitControl->start();
541 }
542
543 // wait for the transformer to finish
544 osl_waitCondition(m_cTransformed, 0);
545 if (!m_bError && !m_bTerminated)
546 {
547 return;
548 } else {
549 throw RuntimeException();
550 }
551
552 }
553
startElement(const OUString & str,const Reference<XAttributeList> & attriblist)554 void XSLTFilter::startElement(const OUString& str, const Reference<XAttributeList>& attriblist)
555 throw (SAXException, RuntimeException)
556 {
557 OSL_ASSERT(m_rDocumentHandler.is());
558 // SvXMLAttributeList* _attriblist=SvXMLAttributeList::getImplementation(attriblist);
559 m_rDocumentHandler->startElement(str, attriblist);
560 }
561
endElement(const OUString & str)562 void XSLTFilter::endElement(const OUString& str)
563 throw (SAXException, RuntimeException)
564 {
565 OSL_ASSERT(m_rDocumentHandler.is());
566 m_rDocumentHandler->endElement(str);
567 }
568
characters(const OUString & str)569 void XSLTFilter::characters(const OUString& str)
570 throw (SAXException, RuntimeException)
571 {
572 OSL_ASSERT(m_rDocumentHandler.is());
573 m_rDocumentHandler->characters(str);
574 }
575
ignorableWhitespace(const OUString & str)576 void XSLTFilter::ignorableWhitespace(const OUString& str)
577 throw (SAXException, RuntimeException)
578 {
579 OSL_ASSERT(m_rDocumentHandler.is());
580 if (!m_bPrettyPrint) return;
581 m_rDocumentHandler->ignorableWhitespace(str);
582 }
583
processingInstruction(const OUString & str,const OUString & str2)584 void XSLTFilter::processingInstruction(const OUString& str, const OUString& str2)
585 throw (SAXException, RuntimeException)
586 {
587 OSL_ASSERT(m_rDocumentHandler.is());
588 m_rDocumentHandler->processingInstruction(str, str2);
589 }
590
setDocumentLocator(const Reference<XLocator> & doclocator)591 void XSLTFilter::setDocumentLocator(const Reference<XLocator>& doclocator)
592 throw (SAXException, RuntimeException)
593 {
594 OSL_ASSERT(m_rDocumentHandler.is());
595 m_rDocumentHandler->setDocumentLocator(doclocator);
596 }
597
598 // --------------------------------------
599 // Component management
600 // --------------------------------------
601 #define SERVICE_NAME "com.sun.star.documentconversion.XSLTFilter"
602 #define IMPLEMENTATION_NAME "com.sun.star.comp.documentconversion.XSLTFilter"
603
CreateInstance(const Reference<XMultiServiceFactory> & r)604 static Reference< XInterface > SAL_CALL CreateInstance( const Reference< XMultiServiceFactory > &r)
605 {
606 return Reference< XInterface >(( OWeakObject *)new XSLTFilter(r));
607 }
608
getSupportedServiceNames()609 static Sequence< OUString > getSupportedServiceNames()
610 {
611 static Sequence < OUString > *pNames = 0;
612 if( ! pNames )
613 {
614 MutexGuard guard( Mutex::getGlobalMutex() );
615 if( !pNames )
616 {
617 static Sequence< OUString > seqNames(1);
618 seqNames.getArray()[0] = OUString::createFromAscii(SERVICE_NAME);
619 pNames = &seqNames;
620 }
621 }
622 return *pNames;
623 }
624
625 }
626
627 using namespace XSLT;
628
629 extern "C"
630 {
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)631 void SAL_CALL component_getImplementationEnvironment(
632 const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
633 {
634 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
635 }
636
component_writeInfo(void *,void * pRegistryKey)637 sal_Bool SAL_CALL component_writeInfo(void * /* pServiceManager */, void * pRegistryKey )
638 {
639 if (pRegistryKey)
640 {
641 try
642 {
643 Reference< XRegistryKey > xNewKey(
644 reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
645 OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) );
646
647 const Sequence< OUString > & rSNL = getSupportedServiceNames();
648 const OUString * pArray = rSNL.getConstArray();
649 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
650 xNewKey->createKey( pArray[nPos] );
651
652 return sal_True;
653 }
654 catch (InvalidRegistryException &)
655 {
656 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
657 }
658 }
659 return sal_False;
660 }
661
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void *)662 void * SAL_CALL component_getFactory(
663 const sal_Char * pImplName, void * pServiceManager, void * /* pRegistryKey */ )
664 {
665 void * pRet = 0;
666
667 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
668 {
669 Reference< XSingleServiceFactory > xFactory( createSingleFactory(
670 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
671 OUString::createFromAscii( pImplName ),
672 CreateInstance, getSupportedServiceNames() ) );
673
674 if (xFactory.is())
675 {
676 xFactory->acquire();
677 pRet = xFactory.get();
678 }
679 }
680 return pRet;
681 }
682
683 } // extern "C"
684