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