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 #include <stdio.h>
25 #include <vector>
26
27 #include "sal/main.h"
28 #include <osl/diagnose.h>
29 #include <osl/mutex.hxx>
30 #include <osl/conditn.hxx>
31 #include <osl/module.h>
32
33 #include <rtl/process.h>
34 #include <rtl/string.h>
35 #include <rtl/strbuf.hxx>
36 #include <rtl/ustrbuf.hxx>
37
38 #include <uno/environment.h>
39 #include <uno/mapping.hxx>
40
41 #include <cppuhelper/factory.hxx>
42 #include <cppuhelper/bootstrap.hxx>
43 #include <cppuhelper/servicefactory.hxx>
44 #include <cppuhelper/shlib.hxx>
45 #include <cppuhelper/implbase1.hxx>
46
47 #include <com/sun/star/lang/XMain.hpp>
48 #include <com/sun/star/lang/XInitialization.hpp>
49 #include <com/sun/star/lang/XComponent.hpp>
50 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
52 #include <com/sun/star/lang/XEventListener.hpp>
53 #include <com/sun/star/container/XSet.hpp>
54 #include <com/sun/star/loader/XImplementationLoader.hpp>
55 #include <com/sun/star/registry/XSimpleRegistry.hpp>
56 #include <com/sun/star/registry/XRegistryKey.hpp>
57 #include <com/sun/star/connection/XAcceptor.hpp>
58 #include <com/sun/star/connection/XConnection.hpp>
59 #include <com/sun/star/bridge/XBridgeFactory.hpp>
60 #include <com/sun/star/bridge/XBridge.hpp>
61 #include <osl/process.h>
62 #include <osl/thread.h>
63 #include <osl/file.hxx>
64
65 #ifdef SAL_UNX
66 #define SEPARATOR '/'
67 #else
68 #define SEPARATOR '\\'
69 #endif
70
71 using namespace std;
72 using namespace rtl;
73 using namespace osl;
74 using namespace cppu;
75 using namespace com::sun::star::uno;
76 using namespace com::sun::star::lang;
77 using namespace com::sun::star::loader;
78 using namespace com::sun::star::registry;
79 using namespace com::sun::star::connection;
80 using namespace com::sun::star::bridge;
81 using namespace com::sun::star::container;
82
83 namespace unoexe
84 {
85
isFileUrl(const OUString & fileName)86 static sal_Bool isFileUrl(const OUString& fileName)
87 {
88 if (fileName.indexOf(OUString::createFromAscii("file://")) == 0 )
89 return sal_True;
90 return sal_False;
91 }
92
convertToFileUrl(const OUString & fileName)93 static OUString convertToFileUrl(const OUString& fileName)
94 {
95 if ( isFileUrl(fileName) )
96 {
97 return fileName;
98 }
99
100 OUString uUrlFileName;
101 if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
102 {
103 OUString uWorkingDir;
104 if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) {
105 OSL_ASSERT(false);
106 }
107 if (FileBase::getAbsoluteFileURL(uWorkingDir, fileName, uUrlFileName)
108 != FileBase::E_None)
109 {
110 OSL_ASSERT(false);
111 }
112 } else
113 {
114 if (FileBase::getFileURLFromSystemPath(fileName, uUrlFileName)
115 != FileBase::E_None)
116 {
117 OSL_ASSERT(false);
118 }
119 }
120
121 return uUrlFileName;
122 }
123
124 static sal_Bool s_quiet = false;
125
126 //--------------------------------------------------------------------------------------------------
out(const sal_Char * pText)127 static inline void out( const sal_Char * pText )
128 {
129 if (! s_quiet)
130 fprintf( stderr, "%s", pText );
131 }
132 //--------------------------------------------------------------------------------------------------
out(const OUString & rText)133 static inline void out( const OUString & rText )
134 {
135 if (! s_quiet)
136 {
137 OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
138 fprintf( stderr, "%s", aText.getStr() );
139 }
140 }
141
142 //--------------------------------------------------------------------------------------------------
143 static const char arUsingText[] =
144 "\nusing:\n\n"
145 "uno [-c ComponentImplementationName -l LocationUrl | -s ServiceName]\n"
146 " [-ro ReadOnlyRegistry1] [-ro ReadOnlyRegistry2] ... [-rw ReadWriteRegistry]\n"
147 " [-u uno:(socket[,host=HostName][,port=nnn]|pipe[,name=PipeName]);<protocol>;Name\n"
148 " [--singleaccept] [--singleinstance]]\n"
149 " [--quiet]\n"
150 " [-- Argument1 Argument2 ...]\n";
151
152 //--------------------------------------------------------------------------------------------------
readOption(OUString * pValue,const sal_Char * pOpt,sal_Int32 * pnIndex,const OUString & aArg)153 static sal_Bool readOption( OUString * pValue, const sal_Char * pOpt,
154 sal_Int32 * pnIndex, const OUString & aArg)
155 {
156 const OUString dash = OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
157 if(aArg.indexOf(dash) != 0)
158 return sal_False;
159
160 OUString aOpt = OUString::createFromAscii( pOpt );
161
162 if (aArg.getLength() < aOpt.getLength())
163 return sal_False;
164
165 if (aOpt.equalsIgnoreAsciiCase( aArg.copy(1) ))
166 {
167 // take next argument
168 ++(*pnIndex);
169
170 rtl_getAppCommandArg(*pnIndex, &pValue->pData);
171 if (*pnIndex >= (sal_Int32)rtl_getAppCommandArgCount() || pValue->copy(1).equals(dash))
172 {
173 OUStringBuffer buf( 32 );
174 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("incomplete option \"-") );
175 buf.appendAscii( pOpt );
176 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" given!") );
177 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
178 }
179 else
180 {
181 #if OSL_DEBUG_LEVEL > 1
182 out( "\n> identified option -" );
183 out( pOpt );
184 out( " = " );
185 OString tmp = OUStringToOString(aArg, RTL_TEXTENCODING_ASCII_US);
186 out( tmp.getStr() );
187 #endif
188 ++(*pnIndex);
189 return sal_True;
190 }
191 }
192 else if (aArg.indexOf(aOpt) == 1)
193 {
194 *pValue = aArg.copy(1 + aOpt.getLength());
195 #if OSL_DEBUG_LEVEL > 1
196 out( "\n> identified option -" );
197 out( pOpt );
198 out( " = " );
199 OString tmp = OUStringToOString(aArg.copy(aOpt.getLength()), RTL_TEXTENCODING_ASCII_US);
200 out( tmp.getStr() );
201 #endif
202 ++(*pnIndex);
203
204 return sal_True;
205 }
206 return sal_False;
207 }
208 //--------------------------------------------------------------------------------------------------
readOption(sal_Bool * pbOpt,const sal_Char * pOpt,sal_Int32 * pnIndex,const OUString & aArg)209 static sal_Bool readOption( sal_Bool * pbOpt, const sal_Char * pOpt,
210 sal_Int32 * pnIndex, const OUString & aArg)
211 {
212 const OUString dashdash(RTL_CONSTASCII_USTRINGPARAM("--"));
213 OUString aOpt = OUString::createFromAscii(pOpt);
214
215 if(aArg.indexOf(dashdash) == 0 && aOpt.equals(aArg.copy(2)))
216 {
217 ++(*pnIndex);
218 *pbOpt = sal_True;
219 #if OSL_DEBUG_LEVEL > 1
220 out( "\n> identified option --" );
221 out( pOpt );
222 #endif
223 return sal_True;
224 }
225 return sal_False;
226 }
227
228
229 //##################################################################################################
230 //##################################################################################################
231 //##################################################################################################
232
233
234 //--------------------------------------------------------------------------------------------------
235 template< class T >
createInstance(Reference<T> & rxOut,const Reference<XComponentContext> & xContext,const OUString & rServiceName)236 void createInstance(
237 Reference< T > & rxOut,
238 const Reference< XComponentContext > & xContext,
239 const OUString & rServiceName )
240 {
241 Reference< XMultiComponentFactory > xMgr( xContext->getServiceManager() );
242 Reference< XInterface > x( xMgr->createInstanceWithContext( rServiceName, xContext ) );
243
244 if (! x.is())
245 {
246 static sal_Bool s_bSet = sal_False;
247 if (! s_bSet)
248 {
249 MutexGuard aGuard( Mutex::getGlobalMutex() );
250 if (! s_bSet)
251 {
252 Reference< XSet > xSet( xMgr, UNO_QUERY );
253 if (xSet.is())
254 {
255 Reference< XMultiServiceFactory > xSF( xMgr, UNO_QUERY );
256 // acceptor
257 xSet->insert( makeAny( loadSharedLibComponentFactory(
258 OUString( RTL_CONSTASCII_USTRINGPARAM(
259 "acceptor.uno" SAL_DLLEXTENSION) ),
260 OUString(),
261 OUString( RTL_CONSTASCII_USTRINGPARAM(
262 "com.sun.star.comp.io.Acceptor") ),
263 xSF, Reference< XRegistryKey >() ) ) );
264 // connector
265 xSet->insert( makeAny( loadSharedLibComponentFactory(
266 OUString( RTL_CONSTASCII_USTRINGPARAM(
267 "connector.uno" SAL_DLLEXTENSION) ),
268 OUString(),
269 OUString( RTL_CONSTASCII_USTRINGPARAM(
270 "com.sun.star.comp.io.Connector") ),
271 xSF, Reference< XRegistryKey >() ) ) );
272 // bridge factory
273 xSet->insert( makeAny( loadSharedLibComponentFactory(
274 OUString( RTL_CONSTASCII_USTRINGPARAM(
275 "binaryurp.uno" SAL_DLLEXTENSION) ),
276 OUString(),
277 OUString(
278 RTL_CONSTASCII_USTRINGPARAM(
279 "com.sun.star.comp.bridge.BridgeFactory") ),
280 xSF, Reference< XRegistryKey >() ) ) );
281 }
282 s_bSet = sal_True;
283 }
284 }
285 x = xMgr->createInstanceWithContext( rServiceName, xContext );
286 }
287
288 if (! x.is())
289 {
290 OUStringBuffer buf( 64 );
291 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
292 buf.append( rServiceName );
293 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
294 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
295 }
296
297 rxOut = Reference< T >::query( x );
298 if (! rxOut.is())
299 {
300 OUStringBuffer buf( 64 );
301 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
302 buf.append( rServiceName );
303 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
304 const Type & rType = ::getCppuType( (const Reference< T > *)0 );
305 buf.append( rType.getTypeName() );
306 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
307 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
308 }
309 }
310 //--------------------------------------------------------------------------------------------------
nestRegistries(const Reference<XSimpleRegistry> & xReadWrite,const Reference<XSimpleRegistry> & xReadOnly)311 static Reference< XSimpleRegistry > nestRegistries(
312 const Reference< XSimpleRegistry > & xReadWrite,
313 const Reference< XSimpleRegistry > & xReadOnly )
314 {
315 Reference< XSimpleRegistry > xReg( createNestedRegistry() );
316 if (! xReg.is())
317 {
318 throw RuntimeException(
319 OUString( RTL_CONSTASCII_USTRINGPARAM("no nested registry service!" ) ),
320 Reference< XInterface >() );
321 }
322
323 Reference< XInitialization > xInit( xReg, UNO_QUERY );
324 if (! xInit.is())
325 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("nested registry does not export interface \"com.sun.star.lang.XInitialization\"!" ) ), Reference< XInterface >() );
326
327 Sequence< Any > aArgs( 2 );
328 aArgs[0] <<= xReadWrite;
329 aArgs[1] <<= xReadOnly;
330 xInit->initialize( aArgs );
331
332 return xReg;
333 }
334 //--------------------------------------------------------------------------------------------------
openRegistry(const OUString & rURL,sal_Bool bReadOnly,sal_Bool bCreate)335 static Reference< XSimpleRegistry > openRegistry(
336 const OUString & rURL,
337 sal_Bool bReadOnly, sal_Bool bCreate )
338 {
339 Reference< XSimpleRegistry > xNewReg( createSimpleRegistry() );
340 if (! xNewReg.is())
341 {
342 throw RuntimeException(
343 OUString( RTL_CONSTASCII_USTRINGPARAM("no simple registry service!" ) ),
344 Reference< XInterface >() );
345 }
346
347 try
348 {
349 xNewReg->open( convertToFileUrl(rURL), bReadOnly, bCreate );
350 if (xNewReg->isValid())
351 return xNewReg;
352 else
353 xNewReg->close();
354 }
355 catch (Exception &)
356 {
357 }
358
359 out( "\n> warning: cannot open registry \"" );
360 out( rURL );
361 if (bReadOnly)
362 out( "\" for reading, ignoring!" );
363 else
364 out( "\" for reading and writing, ignoring!" );
365 return Reference< XSimpleRegistry >();
366 }
367 //--------------------------------------------------------------------------------------------------
loadComponent(const Reference<XComponentContext> & xContext,const OUString & rImplName,const OUString & rLocation)368 static Reference< XInterface > loadComponent(
369 const Reference< XComponentContext > & xContext,
370 const OUString & rImplName, const OUString & rLocation )
371 {
372 // determine loader to be used
373 sal_Int32 nDot = rLocation.lastIndexOf( '.' );
374 if (nDot > 0 && nDot < rLocation.getLength())
375 {
376 Reference< XImplementationLoader > xLoader;
377
378 OUString aExt( rLocation.copy( nDot +1 ) );
379
380 if (aExt.compareToAscii( "dll" ) == 0 ||
381 aExt.compareToAscii( "exe" ) == 0 ||
382 aExt.compareToAscii( "dylib" ) == 0 ||
383 aExt.compareToAscii( "so" ) == 0)
384 {
385 createInstance(
386 xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") ) );
387 }
388 else if (aExt.compareToAscii( "jar" ) == 0 ||
389 aExt.compareToAscii( "class" ) == 0)
390 {
391 createInstance(
392 xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") ) );
393 }
394 else
395 {
396 OUStringBuffer buf( 64 );
397 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unknown extension of \"") );
398 buf.append( rLocation );
399 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"! No loader available!") );
400 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
401 }
402
403 Reference< XInterface > xInstance;
404
405 // activate
406 Reference< XInterface > xFactory( xLoader->activate(
407 rImplName, OUString(), rLocation, Reference< XRegistryKey >() ) );
408 if (xFactory.is())
409 {
410 Reference< XSingleComponentFactory > xCFac( xFactory, UNO_QUERY );
411 if (xCFac.is())
412 {
413 xInstance = xCFac->createInstanceWithContext( xContext );
414 }
415 else
416 {
417 Reference< XSingleServiceFactory > xSFac( xFactory, UNO_QUERY );
418 if (xSFac.is())
419 {
420 out( "\n> warning: ignoring context for implementation \"" );
421 out( rImplName );
422 out( "\"!" );
423 xInstance = xSFac->createInstance();
424 }
425 }
426 }
427
428 if (! xInstance.is())
429 {
430 OUStringBuffer buf( 64 );
431 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("activating component \"") );
432 buf.append( rImplName );
433 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" from location \"") );
434 buf.append( rLocation );
435 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" failed!") );
436 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
437 }
438
439 return xInstance;
440 }
441 else
442 {
443 OUStringBuffer buf( 64 );
444 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("location \"") );
445 buf.append( rLocation );
446 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" has no extension! Cannot determine loader to be used!") );
447 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
448 }
449 }
450
451
452 //##################################################################################################
453 //##################################################################################################
454 //##################################################################################################
455
456
457 //==================================================================================================
458 class OInstanceProvider
459 : public WeakImplHelper1< XInstanceProvider >
460 {
461 Reference< XComponentContext > _xContext;
462
463 Mutex _aSingleInstanceMutex;
464 Reference< XInterface > _xSingleInstance;
465 sal_Bool _bSingleInstance;
466
467 OUString _aImplName;
468 OUString _aLocation;
469 OUString _aServiceName;
470 Sequence< Any > _aInitParams;
471
472 OUString _aInstanceName;
473
474 inline Reference< XInterface > createInstance();
475
476 public:
OInstanceProvider(const Reference<XComponentContext> & xContext,const OUString & rImplName,const OUString & rLocation,const OUString & rServiceName,const Sequence<Any> & rInitParams,sal_Bool bSingleInstance,const OUString & rInstanceName)477 OInstanceProvider( const Reference< XComponentContext > & xContext,
478 const OUString & rImplName, const OUString & rLocation,
479 const OUString & rServiceName, const Sequence< Any > & rInitParams,
480 sal_Bool bSingleInstance, const OUString & rInstanceName )
481 : _xContext( xContext )
482 , _bSingleInstance( bSingleInstance )
483 , _aImplName( rImplName )
484 , _aLocation( rLocation )
485 , _aServiceName( rServiceName )
486 , _aInitParams( rInitParams )
487 , _aInstanceName( rInstanceName )
488 {}
489
490 // XInstanceProvider
491 virtual Reference< XInterface > SAL_CALL getInstance( const OUString & rName );
492 };
493 //__________________________________________________________________________________________________
createInstance()494 inline Reference< XInterface > OInstanceProvider::createInstance()
495 {
496 Reference< XInterface > xRet;
497 if (_aImplName.getLength()) // manually via loader
498 xRet = loadComponent( _xContext, _aImplName, _aLocation );
499 else // via service manager
500 unoexe::createInstance( xRet, _xContext, _aServiceName );
501
502 // opt XInit
503 Reference< XInitialization > xInit( xRet, UNO_QUERY );
504 if (xInit.is())
505 xInit->initialize( _aInitParams );
506
507 return xRet;
508 }
509 //__________________________________________________________________________________________________
getInstance(const OUString & rName)510 Reference< XInterface > OInstanceProvider::getInstance( const OUString & rName )
511 {
512 try
513 {
514 if (_aInstanceName == rName)
515 {
516 Reference< XInterface > xRet;
517
518 if (_aImplName.getLength() == 0 && _aServiceName.getLength() == 0)
519 {
520 OSL_ASSERT(
521 rName.equalsAsciiL(
522 RTL_CONSTASCII_STRINGPARAM("uno.ComponentContext") ) );
523 xRet = _xContext;
524 }
525 else if (_bSingleInstance)
526 {
527 if (! _xSingleInstance.is())
528 {
529 MutexGuard aGuard( _aSingleInstanceMutex );
530 if (! _xSingleInstance.is())
531 {
532 _xSingleInstance = createInstance();
533 }
534 }
535 xRet = _xSingleInstance;
536 }
537 else
538 {
539 xRet = createInstance();
540 }
541
542 return xRet;
543 }
544 }
545 catch (Exception & rExc)
546 {
547 out( "\n> error: " );
548 out( rExc.Message );
549 }
550 OUStringBuffer buf( 64 );
551 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("no such element \"") );
552 buf.append( rName );
553 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
554 throw NoSuchElementException( buf.makeStringAndClear(), Reference< XInterface >() );
555 }
556
557 //==================================================================================================
558 struct ODisposingListener : public WeakImplHelper1< XEventListener >
559 {
560 Condition cDisposed;
561
562 // XEventListener
563 virtual void SAL_CALL disposing( const EventObject & rEvt );
564
565 //----------------------------------------------------------------------------------------------
566 static void waitFor( const Reference< XComponent > & xComp );
567 };
568 //__________________________________________________________________________________________________
disposing(const EventObject &)569 void ODisposingListener::disposing( const EventObject & )
570 {
571 cDisposed.set();
572 }
573 //--------------------------------------------------------------------------------------------------
waitFor(const Reference<XComponent> & xComp)574 void ODisposingListener::waitFor( const Reference< XComponent > & xComp )
575 {
576 ODisposingListener * pListener = new ODisposingListener();
577 Reference< XEventListener > xListener( pListener );
578
579 xComp->addEventListener( xListener );
580 pListener->cDisposed.wait();
581 }
582
583
584 //##################################################################################################
585 //##################################################################################################
586 //##################################################################################################
587
588
589 //##################################################################################################
590 } // namespace unoexe
591
592 using namespace unoexe;
593
594 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc,)
595 {
596 if (argc <= 1)
597 {
598 out( arUsingText );
599 return 0;
600 }
601
602 sal_Int32 nRet = 0;
603 Reference< XComponentContext > xContext;
604
605
606 try
607 {
608 OUString aImplName, aLocation, aServiceName, aUnoUrl;
609 vector< OUString > aReadOnlyRegistries;
610 Sequence< OUString > aParams;
611 sal_Bool bSingleAccept = sal_False;
612 sal_Bool bSingleInstance = sal_False;
613
614 //#### read command line arguments #########################################################
615
616 bool bOldRegistryMimic = false;
617 bool bNewRegistryMimic = false;
618 OUString aReadWriteRegistry;
619
620 sal_Int32 nPos = 0;
621 sal_Int32 nCount = (sal_Int32)rtl_getAppCommandArgCount();
622 // read up to arguments
623 while (nPos < nCount)
624 {
625 OUString arg;
626
627 rtl_getAppCommandArg(nPos, &arg.pData);
628
629 const OUString dashdash = OUString(RTL_CONSTASCII_USTRINGPARAM("--"));
630 if (dashdash == arg)
631 {
632 ++nPos;
633 break;
634 }
635
636 if (readOption( &aImplName, "c", &nPos, arg) ||
637 readOption( &aLocation, "l", &nPos, arg) ||
638 readOption( &aServiceName, "s", &nPos, arg) ||
639 readOption( &aUnoUrl, "u", &nPos, arg) ||
640 readOption( &s_quiet, "quiet", &nPos, arg) ||
641 readOption( &bSingleAccept, "singleaccept", &nPos, arg) ||
642 readOption( &bSingleInstance, "singleinstance", &nPos, arg))
643 {
644 continue;
645 }
646 OUString aRegistry;
647 if (readOption( &aRegistry, "ro", &nPos, arg))
648 {
649 aReadOnlyRegistries.push_back( aRegistry );
650 bNewRegistryMimic = true;
651 continue;
652 }
653 if (readOption( &aReadWriteRegistry, "rw", &nPos, arg))
654 {
655 bNewRegistryMimic = true;
656 continue;
657 }
658 if (readOption( &aRegistry, "r", &nPos, arg))
659 {
660 aReadOnlyRegistries.push_back( aRegistry );
661 aReadWriteRegistry = aRegistry;
662 out( "\n> warning: DEPRECATED use of option -r, use -ro or -rw!" );
663 bOldRegistryMimic = true;
664 continue;
665 }
666
667 // else illegal argument
668 OUStringBuffer buf( 64 );
669 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unexpected parameter \"") );
670 buf.append(arg);
671 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
672 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
673 }
674
675 if (bOldRegistryMimic) // last one was set to be read-write
676 {
677 aReadOnlyRegistries.pop_back();
678 if (bOldRegistryMimic && bNewRegistryMimic)
679 {
680 throw RuntimeException(
681 OUString( RTL_CONSTASCII_USTRINGPARAM("mixing with DEPRECATED registry options!") ),
682 Reference< XInterface >() );
683 }
684 }
685
686 if ((aImplName.getLength() != 0) && (aServiceName.getLength() != 0))
687 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component exOR service name!" ) ), Reference< XInterface >() );
688 if (aImplName.getLength() == 0 && aServiceName.getLength() == 0)
689 {
690 if (! aUnoUrl.endsWithIgnoreAsciiCaseAsciiL(
691 RTL_CONSTASCII_STRINGPARAM(";uno.ComponentContext") ))
692 throw RuntimeException(
693 OUString( RTL_CONSTASCII_USTRINGPARAM(
694 "expected UNO-URL with instance name "
695 "uno.ComponentContext!") ),
696 Reference<XInterface>() );
697 if (bSingleInstance)
698 throw RuntimeException(
699 OUString( RTL_CONSTASCII_USTRINGPARAM(
700 "unexpected option --singleinstance!") ),
701 Reference<XInterface>() );
702 }
703 if (aImplName.getLength() && !aLocation.getLength())
704 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component location!" ) ), Reference< XInterface >() );
705 if (aServiceName.getLength() && aLocation.getLength())
706 out( "\n> warning: service name given, will ignore location!" );
707
708 // read component params
709 aParams.realloc( nCount - nPos );
710 OUString * pParams = aParams.getArray();
711
712 sal_Int32 nOffset = nPos;
713 for ( ; nPos < nCount; ++nPos )
714 {
715 if (rtl_getAppCommandArg( nPos, &pParams[nPos -nOffset].pData )
716 != osl_Process_E_None)
717 {
718 OSL_ASSERT(false);
719 }
720 }
721
722 if (aReadOnlyRegistries.size() > 0 ||
723 aReadWriteRegistry.getLength() > 0)
724 {
725 //#### create registry #############################################
726
727 Reference< XSimpleRegistry > xRegistry;
728
729 // ReadOnly registries
730 for ( size_t nReg = 0; nReg < aReadOnlyRegistries.size(); ++nReg )
731 {
732 #if OSL_DEBUG_LEVEL > 1
733 out( "\n> trying to open ro registry: " );
734 out( OUStringToOString(
735 aReadOnlyRegistries[ nReg ],
736 RTL_TEXTENCODING_ASCII_US ).getStr() );
737 #endif
738 Reference< XSimpleRegistry > xNewReg(
739 openRegistry(
740 aReadOnlyRegistries[ nReg ], sal_True, sal_False ) );
741 if (xNewReg.is())
742 xRegistry = (xRegistry.is() ? nestRegistries(
743 xNewReg, xRegistry ) : xNewReg);
744 }
745 if (aReadWriteRegistry.getLength())
746 {
747 #if OSL_DEBUG_LEVEL > 1
748 out( "\n> trying to open rw registry: " );
749 out( OUStringToOString(
750 aReadWriteRegistry,
751 RTL_TEXTENCODING_ASCII_US ).getStr() );
752 #endif
753 // ReadWrite registry
754 Reference< XSimpleRegistry > xNewReg(
755 openRegistry( aReadWriteRegistry, sal_False, sal_True ) );
756 if (xNewReg.is())
757 xRegistry = (xRegistry.is()
758 ? nestRegistries( xNewReg, xRegistry )
759 : xNewReg);
760 }
761
762 OSL_ASSERT( xRegistry.is() );
763 xContext = bootstrap_InitialComponentContext( xRegistry );
764 }
765 else // defaulting
766 {
767 xContext = defaultBootstrap_InitialComponentContext();
768 }
769
770 //#### accept, instantiate, etc. ###########################################################
771
772 if (aUnoUrl.getLength()) // accepting connections
773 {
774 sal_Int32 nIndex = 0, nTokens = 0;
775 do { aUnoUrl.getToken( 0, ';', nIndex ); nTokens++; } while( nIndex != -1 );
776 if (nTokens != 3 || aUnoUrl.getLength() < 10 ||
777 !aUnoUrl.copy( 0, 4 ).equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("uno:") ) ))
778 {
779 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal uno url given!" ) ), Reference< XInterface >() );
780 }
781 nIndex = 0;
782 OUString aConnectDescr( aUnoUrl.getToken( 0, ';', nIndex ).copy( 4 ) ); // uno:CONNECTDESCR;iiop;InstanceName
783 OUString aInstanceName( aUnoUrl.getToken( 1, ';', nIndex ) );
784
785 Reference< XAcceptor > xAcceptor;
786 createInstance(
787 xAcceptor, xContext,
788 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor") ) );
789
790 // init params
791 Sequence< Any > aInitParams( aParams.getLength() );
792 const OUString * p = aParams.getConstArray();
793 Any * pInitParams = aInitParams.getArray();
794 for ( sal_Int32 i = aParams.getLength(); i--; )
795 {
796 pInitParams[i] = makeAny( p[i] );
797 }
798
799 // instance provider
800 Reference< XInstanceProvider > xInstanceProvider( new OInstanceProvider(
801 xContext, aImplName, aLocation, aServiceName, aInitParams,
802 bSingleInstance, aInstanceName ) );
803
804 nIndex = 0;
805 OUString aUnoUrlToken( aUnoUrl.getToken( 1, ';', nIndex ) );
806 for (;;)
807 {
808 // accepting
809 out( "\n> accepting " );
810 out( aConnectDescr );
811 out( "..." );
812 Reference< XConnection > xConnection( xAcceptor->accept( aConnectDescr ) );
813 out( "connection established." );
814
815 Reference< XBridgeFactory > xBridgeFactory;
816 createInstance(
817 xBridgeFactory, xContext,
818 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory") ) );
819
820 // bridge
821 Reference< XBridge > xBridge( xBridgeFactory->createBridge(
822 OUString(), aUnoUrlToken,
823 xConnection, xInstanceProvider ) );
824
825 if (bSingleAccept)
826 {
827 Reference< XComponent > xComp( xBridge, UNO_QUERY );
828 if (! xComp.is())
829 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("bridge factory does not export interface \"com.sun.star.lang.XComponent\"!" ) ), Reference< XInterface >() );
830 ODisposingListener::waitFor( xComp );
831 break;
832 }
833 }
834 }
835 else // no uno url
836 {
837 Reference< XInterface > xInstance;
838 if (aImplName.getLength()) // manually via loader
839 xInstance = loadComponent( xContext, aImplName, aLocation );
840 else // via service manager
841 createInstance( xInstance, xContext, aServiceName );
842
843 // execution
844 Reference< XMain > xMain( xInstance, UNO_QUERY );
845 if (xMain.is())
846 {
847 nRet = xMain->run( aParams );
848 }
849 else
850 {
851 Reference< XComponent > xComp( xInstance, UNO_QUERY );
852 if (xComp.is())
853 xComp->dispose();
854 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("component does not export interface interface \"com.sun.star.lang.XMain\"!" ) ), Reference< XInterface >() );
855 }
856 }
857 }
858 catch (Exception & rExc)
859 {
860 out( "\n> error: " );
861 out( rExc.Message );
862 out( "\n> dying..." );
863 nRet = 1;
864 }
865
866 // cleanup
867 Reference< XComponent > xComp( xContext, UNO_QUERY );
868 if (xComp.is())
869 xComp->dispose();
870
871 out( "\n" );
872 return nRet;
873 }
874