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