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