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