Bump for 3.6-28
[LibreOffice.git] / cpputools / source / unoexe / unoexe.cxx
blob0c218d1cc207dfb3eed31614a9b8b4a3e5006710
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <stdio.h>
30 #include <vector>
32 #include "sal/main.h"
33 #include <osl/diagnose.h>
34 #include <osl/mutex.hxx>
35 #include <osl/conditn.hxx>
36 #include <osl/module.h>
38 #include <rtl/process.h>
39 #include <rtl/string.h>
40 #include <rtl/strbuf.hxx>
41 #include <rtl/ustrbuf.hxx>
43 #include <uno/environment.h>
44 #include <uno/mapping.hxx>
46 #include <cppuhelper/factory.hxx>
47 #include <cppuhelper/bootstrap.hxx>
48 #include <cppuhelper/servicefactory.hxx>
49 #include <cppuhelper/shlib.hxx>
50 #include <cppuhelper/implbase1.hxx>
52 #include <com/sun/star/lang/XMain.hpp>
53 #include <com/sun/star/lang/XInitialization.hpp>
54 #include <com/sun/star/lang/XComponent.hpp>
55 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
56 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
57 #include <com/sun/star/lang/XEventListener.hpp>
58 #include <com/sun/star/container/XSet.hpp>
59 #include <com/sun/star/loader/XImplementationLoader.hpp>
60 #include <com/sun/star/registry/XSimpleRegistry.hpp>
61 #include <com/sun/star/registry/XRegistryKey.hpp>
62 #include <com/sun/star/connection/XAcceptor.hpp>
63 #include <com/sun/star/connection/XConnection.hpp>
64 #include <com/sun/star/bridge/XBridgeFactory.hpp>
65 #include <com/sun/star/bridge/XBridge.hpp>
66 #include <osl/process.h>
67 #include <osl/thread.h>
68 #include <osl/file.hxx>
70 #ifdef SAL_UNX
71 #define SEPARATOR '/'
72 #else
73 #define SEPARATOR '\\'
74 #endif
76 using namespace std;
77 using namespace osl;
78 using namespace cppu;
79 using namespace com::sun::star::uno;
80 using namespace com::sun::star::lang;
81 using namespace com::sun::star::loader;
82 using namespace com::sun::star::registry;
83 using namespace com::sun::star::connection;
84 using namespace com::sun::star::bridge;
85 using namespace com::sun::star::container;
87 using ::rtl::OUString;
88 using ::rtl::OString;
89 using ::rtl::OUStringToOString;
90 using ::rtl::OUStringBuffer;
92 namespace unoexe
95 static sal_Bool isFileUrl(const OUString& fileName)
97 if (fileName.indexOf(OUString(RTL_CONSTASCII_USTRINGPARAM("file://"))) == 0 )
98 return sal_True;
99 return sal_False;
102 static OUString convertToFileUrl(const OUString& fileName)
104 if ( isFileUrl(fileName) )
106 return fileName;
109 OUString uUrlFileName;
110 if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
112 OUString uWorkingDir;
113 if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) {
114 OSL_ASSERT(false);
116 if (FileBase::getAbsoluteFileURL(uWorkingDir, fileName, uUrlFileName)
117 != FileBase::E_None)
119 OSL_ASSERT(false);
121 } else
123 if (FileBase::getFileURLFromSystemPath(fileName, uUrlFileName)
124 != FileBase::E_None)
126 OSL_ASSERT(false);
130 return uUrlFileName;
133 static sal_Bool s_quiet = false;
135 //--------------------------------------------------------------------------------------------------
136 static inline void out( const sal_Char * pText )
138 if (! s_quiet)
139 fprintf( stderr, "%s", pText );
141 //--------------------------------------------------------------------------------------------------
142 static inline void out( const OUString & rText )
144 if (! s_quiet)
146 OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
147 fprintf( stderr, "%s", aText.getStr() );
151 //--------------------------------------------------------------------------------------------------
152 static const char arUsingText[] =
153 "\nusing:\n\n"
154 "uno [-c ComponentImplementationName -l LocationUrl | -s ServiceName]\n"
155 " [-ro ReadOnlyRegistry1] [-ro ReadOnlyRegistry2] ... [-rw ReadWriteRegistry]\n"
156 " [-u uno:(socket[,host=HostName][,port=nnn]|pipe[,name=PipeName]);<protocol>;Name\n"
157 " [--singleaccept] [--singleinstance]]\n"
158 " [--quiet]\n"
159 " [-- Argument1 Argument2 ...]\n";
161 //--------------------------------------------------------------------------------------------------
162 static sal_Bool readOption( OUString * pValue, const sal_Char * pOpt,
163 sal_uInt32 * pnIndex, const OUString & aArg)
164 throw (RuntimeException)
166 const OUString dash(RTL_CONSTASCII_USTRINGPARAM("-"));
167 if(aArg.indexOf(dash) != 0)
168 return sal_False;
170 OUString aOpt = OUString::createFromAscii( pOpt );
172 if (aArg.getLength() < aOpt.getLength())
173 return sal_False;
175 if (aOpt.equalsIgnoreAsciiCase( aArg.copy(1) ))
177 // take next argument
178 ++(*pnIndex);
180 rtl_getAppCommandArg(*pnIndex, &pValue->pData);
181 if (*pnIndex >= rtl_getAppCommandArgCount() || pValue->copy(1).equals(dash))
183 OUStringBuffer buf( 32 );
184 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("incomplete option \"-") );
185 buf.appendAscii( pOpt );
186 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" given!") );
187 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
189 else
191 #if OSL_DEBUG_LEVEL > 1
192 out( "\n> identified option -" );
193 out( pOpt );
194 out( " = " );
195 OString tmp = OUStringToOString(aArg, RTL_TEXTENCODING_ASCII_US);
196 out( tmp.getStr() );
197 #endif
198 ++(*pnIndex);
199 return sal_True;
202 else if (aArg.indexOf(aOpt) == 1)
204 *pValue = aArg.copy(1 + aOpt.getLength());
205 #if OSL_DEBUG_LEVEL > 1
206 out( "\n> identified option -" );
207 out( pOpt );
208 out( " = " );
209 OString tmp = OUStringToOString(aArg.copy(aOpt.getLength()), RTL_TEXTENCODING_ASCII_US);
210 out( tmp.getStr() );
211 #endif
212 ++(*pnIndex);
214 return sal_True;
216 return sal_False;
218 //--------------------------------------------------------------------------------------------------
219 static sal_Bool readOption( sal_Bool * pbOpt, const sal_Char * pOpt,
220 sal_uInt32 * pnIndex, const OUString & aArg)
222 const OUString dashdash(RTL_CONSTASCII_USTRINGPARAM("--"));
223 OUString aOpt = OUString::createFromAscii(pOpt);
225 if(aArg.indexOf(dashdash) == 0 && aOpt.equals(aArg.copy(2)))
227 ++(*pnIndex);
228 *pbOpt = sal_True;
229 #if OSL_DEBUG_LEVEL > 1
230 out( "\n> identified option --" );
231 out( pOpt );
232 #endif
233 return sal_True;
235 return sal_False;
239 //##################################################################################################
240 //##################################################################################################
241 //##################################################################################################
244 //--------------------------------------------------------------------------------------------------
245 template< class T >
246 void createInstance(
247 Reference< T > & rxOut,
248 const Reference< XComponentContext > & xContext,
249 const OUString & rServiceName )
250 throw (Exception)
252 Reference< XMultiComponentFactory > xMgr( xContext->getServiceManager() );
253 Reference< XInterface > x( xMgr->createInstanceWithContext( rServiceName, xContext ) );
255 if (! x.is())
257 static sal_Bool s_bSet = sal_False;
258 if (! s_bSet)
260 MutexGuard aGuard( Mutex::getGlobalMutex() );
261 if (! s_bSet)
263 Reference< XSet > xSet( xMgr, UNO_QUERY );
264 if (xSet.is())
266 Reference< XMultiServiceFactory > xSF( xMgr, UNO_QUERY );
267 // acceptor
268 xSet->insert( makeAny( loadSharedLibComponentFactory(
269 OUString( RTL_CONSTASCII_USTRINGPARAM(
270 "acceptor.uno" SAL_DLLEXTENSION) ),
271 OUString(),
272 OUString( RTL_CONSTASCII_USTRINGPARAM(
273 "com.sun.star.comp.io.Acceptor") ),
274 xSF, Reference< XRegistryKey >() ) ) );
275 // connector
276 xSet->insert( makeAny( loadSharedLibComponentFactory(
277 OUString( RTL_CONSTASCII_USTRINGPARAM(
278 "connector.uno" SAL_DLLEXTENSION) ),
279 OUString(),
280 OUString( RTL_CONSTASCII_USTRINGPARAM(
281 "com.sun.star.comp.io.Connector") ),
282 xSF, Reference< XRegistryKey >() ) ) );
283 // bridge factory
284 xSet->insert( makeAny( loadSharedLibComponentFactory(
285 OUString( RTL_CONSTASCII_USTRINGPARAM(
286 "binaryurp.uno" SAL_DLLEXTENSION) ),
287 OUString(),
288 OUString(
289 RTL_CONSTASCII_USTRINGPARAM(
290 "com.sun.star.comp.bridge.BridgeFactory") ),
291 xSF, Reference< XRegistryKey >() ) ) );
293 s_bSet = sal_True;
296 x = xMgr->createInstanceWithContext( rServiceName, xContext );
299 if (! x.is())
301 OUStringBuffer buf( 64 );
302 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
303 buf.append( rServiceName );
304 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
305 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
308 rxOut = Reference< T >::query( x );
309 if (! rxOut.is())
311 OUStringBuffer buf( 64 );
312 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
313 buf.append( rServiceName );
314 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
315 const Type & rType = ::getCppuType( (const Reference< T > *)0 );
316 buf.append( rType.getTypeName() );
317 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
318 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
321 //--------------------------------------------------------------------------------------------------
322 static Reference< XSimpleRegistry > nestRegistries(
323 const Reference< XSimpleRegistry > & xReadWrite,
324 const Reference< XSimpleRegistry > & xReadOnly )
325 throw (Exception)
327 Reference< XSimpleRegistry > xReg( createNestedRegistry() );
328 if (! xReg.is())
330 throw RuntimeException(
331 OUString( RTL_CONSTASCII_USTRINGPARAM("no nested registry service!" ) ),
332 Reference< XInterface >() );
335 Reference< XInitialization > xInit( xReg, UNO_QUERY );
336 if (! xInit.is())
337 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("nested registry does not export interface \"com.sun.star.lang.XInitialization\"!" ) ), Reference< XInterface >() );
339 Sequence< Any > aArgs( 2 );
340 aArgs[0] <<= xReadWrite;
341 aArgs[1] <<= xReadOnly;
342 xInit->initialize( aArgs );
344 return xReg;
346 //--------------------------------------------------------------------------------------------------
347 static Reference< XSimpleRegistry > openRegistry(
348 const OUString & rURL,
349 sal_Bool bReadOnly, sal_Bool bCreate )
350 throw (Exception)
352 Reference< XSimpleRegistry > xNewReg( createSimpleRegistry() );
353 if (! xNewReg.is())
355 throw RuntimeException(
356 OUString( RTL_CONSTASCII_USTRINGPARAM("no simple registry service!" ) ),
357 Reference< XInterface >() );
362 xNewReg->open( convertToFileUrl(rURL), bReadOnly, bCreate );
363 if (xNewReg->isValid())
364 return xNewReg;
365 else
366 xNewReg->close();
368 catch (Exception &)
372 out( "\n> warning: cannot open registry \"" );
373 out( rURL );
374 if (bReadOnly)
375 out( "\" for reading, ignoring!" );
376 else
377 out( "\" for reading and writing, ignoring!" );
378 return Reference< XSimpleRegistry >();
380 //--------------------------------------------------------------------------------------------------
381 static Reference< XInterface > loadComponent(
382 const Reference< XComponentContext > & xContext,
383 const OUString & rImplName, const OUString & rLocation )
384 throw (Exception)
386 // determine loader to be used
387 sal_Int32 nDot = rLocation.lastIndexOf( '.' );
388 if (nDot > 0 && nDot < rLocation.getLength())
390 Reference< XImplementationLoader > xLoader;
392 OUString aExt( rLocation.copy( nDot +1 ) );
394 if (aExt.compareToAscii( "dll" ) == 0 ||
395 aExt.compareToAscii( "exe" ) == 0 ||
396 aExt.compareToAscii( "dylib" ) == 0 ||
397 aExt.compareToAscii( "so" ) == 0)
399 createInstance(
400 xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") ) );
402 else if (aExt.compareToAscii( "jar" ) == 0 ||
403 aExt.compareToAscii( "class" ) == 0)
405 createInstance(
406 xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") ) );
408 else
410 OUStringBuffer buf( 64 );
411 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unknown extension of \"") );
412 buf.append( rLocation );
413 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"! No loader available!") );
414 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
417 Reference< XInterface > xInstance;
419 // activate
420 Reference< XInterface > xFactory( xLoader->activate(
421 rImplName, OUString(), rLocation, Reference< XRegistryKey >() ) );
422 if (xFactory.is())
424 Reference< XSingleComponentFactory > xCFac( xFactory, UNO_QUERY );
425 if (xCFac.is())
427 xInstance = xCFac->createInstanceWithContext( xContext );
429 else
431 Reference< XSingleServiceFactory > xSFac( xFactory, UNO_QUERY );
432 if (xSFac.is())
434 out( "\n> warning: ignroing context for implementation \"" );
435 out( rImplName );
436 out( "\"!" );
437 xInstance = xSFac->createInstance();
442 if (! xInstance.is())
444 OUStringBuffer buf( 64 );
445 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("activating component \"") );
446 buf.append( rImplName );
447 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" from location \"") );
448 buf.append( rLocation );
449 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" failed!") );
450 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
453 return xInstance;
455 else
457 OUStringBuffer buf( 64 );
458 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("location \"") );
459 buf.append( rLocation );
460 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" has no extension! Cannot determine loader to be used!") );
461 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
466 //##################################################################################################
467 //##################################################################################################
468 //##################################################################################################
471 //==================================================================================================
472 class OInstanceProvider
473 : public WeakImplHelper1< XInstanceProvider >
475 Reference< XComponentContext > _xContext;
477 Mutex _aSingleInstanceMutex;
478 Reference< XInterface > _xSingleInstance;
479 sal_Bool _bSingleInstance;
481 OUString _aImplName;
482 OUString _aLocation;
483 OUString _aServiceName;
484 Sequence< Any > _aInitParams;
486 OUString _aInstanceName;
488 inline Reference< XInterface > createInstance() throw (Exception);
490 public:
491 OInstanceProvider( const Reference< XComponentContext > & xContext,
492 const OUString & rImplName, const OUString & rLocation,
493 const OUString & rServiceName, const Sequence< Any > & rInitParams,
494 sal_Bool bSingleInstance, const OUString & rInstanceName )
495 : _xContext( xContext )
496 , _bSingleInstance( bSingleInstance )
497 , _aImplName( rImplName )
498 , _aLocation( rLocation )
499 , _aServiceName( rServiceName )
500 , _aInitParams( rInitParams )
501 , _aInstanceName( rInstanceName )
504 // XInstanceProvider
505 virtual Reference< XInterface > SAL_CALL getInstance( const OUString & rName )
506 throw (NoSuchElementException, RuntimeException);
508 //__________________________________________________________________________________________________
509 inline Reference< XInterface > OInstanceProvider::createInstance()
510 throw (Exception)
512 Reference< XInterface > xRet;
513 if (!_aImplName.isEmpty()) // manually via loader
514 xRet = loadComponent( _xContext, _aImplName, _aLocation );
515 else // via service manager
516 unoexe::createInstance( xRet, _xContext, _aServiceName );
518 // opt XInit
519 Reference< XInitialization > xInit( xRet, UNO_QUERY );
520 if (xInit.is())
521 xInit->initialize( _aInitParams );
523 return xRet;
525 //__________________________________________________________________________________________________
526 Reference< XInterface > OInstanceProvider::getInstance( const OUString & rName )
527 throw (NoSuchElementException, RuntimeException)
531 if (_aInstanceName == rName)
533 Reference< XInterface > xRet;
535 if (_aImplName.isEmpty() && _aServiceName.isEmpty())
537 OSL_ASSERT( rName == "uno.ComponentContext" );
538 xRet = _xContext;
540 else if (_bSingleInstance)
542 if (! _xSingleInstance.is())
544 MutexGuard aGuard( _aSingleInstanceMutex );
545 if (! _xSingleInstance.is())
547 _xSingleInstance = createInstance();
550 xRet = _xSingleInstance;
552 else
554 xRet = createInstance();
557 return xRet;
560 catch (Exception & rExc)
562 out( "\n> error: " );
563 out( rExc.Message );
565 OUStringBuffer buf( 64 );
566 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("no such element \"") );
567 buf.append( rName );
568 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
569 throw NoSuchElementException( buf.makeStringAndClear(), Reference< XInterface >() );
572 //==================================================================================================
573 struct ODisposingListener : public WeakImplHelper1< XEventListener >
575 Condition cDisposed;
577 // XEventListener
578 virtual void SAL_CALL disposing( const EventObject & rEvt )
579 throw (RuntimeException);
581 //----------------------------------------------------------------------------------------------
582 static void waitFor( const Reference< XComponent > & xComp );
584 //__________________________________________________________________________________________________
585 void ODisposingListener::disposing( const EventObject & )
586 throw (RuntimeException)
588 cDisposed.set();
590 //--------------------------------------------------------------------------------------------------
591 void ODisposingListener::waitFor( const Reference< XComponent > & xComp )
593 ODisposingListener * pListener = new ODisposingListener();
594 Reference< XEventListener > xListener( pListener );
596 xComp->addEventListener( xListener );
597 pListener->cDisposed.wait();
601 //##################################################################################################
602 //##################################################################################################
603 //##################################################################################################
606 //##################################################################################################
607 } // namespace unoexe
609 using namespace unoexe;
611 SAL_IMPLEMENT_MAIN()
613 sal_uInt32 nCount = rtl_getAppCommandArgCount();
614 if (nCount == 0)
616 out( arUsingText );
617 return 0;
620 sal_Int32 nRet = 0;
621 Reference< XComponentContext > xContext;
626 OUString aImplName, aLocation, aServiceName, aUnoUrl;
627 vector< OUString > aReadOnlyRegistries;
628 Sequence< OUString > aParams;
629 sal_Bool bSingleAccept = sal_False;
630 sal_Bool bSingleInstance = sal_False;
632 //#### read command line arguments #########################################################
634 bool bOldRegistryMimic = false;
635 bool bNewRegistryMimic = false;
636 OUString aReadWriteRegistry;
638 sal_uInt32 nPos = 0;
639 // read up to arguments
640 while (nPos < nCount)
642 OUString arg;
644 rtl_getAppCommandArg(nPos, &arg.pData);
646 const OUString dashdash(RTL_CONSTASCII_USTRINGPARAM("--"));
647 if (dashdash == arg)
649 ++nPos;
650 break;
653 if (readOption( &aImplName, "c", &nPos, arg) ||
654 readOption( &aLocation, "l", &nPos, arg) ||
655 readOption( &aServiceName, "s", &nPos, arg) ||
656 readOption( &aUnoUrl, "u", &nPos, arg) ||
657 readOption( &s_quiet, "quiet", &nPos, arg) ||
658 readOption( &bSingleAccept, "singleaccept", &nPos, arg) ||
659 readOption( &bSingleInstance, "singleinstance", &nPos, arg))
661 continue;
663 OUString aRegistry;
664 if (readOption( &aRegistry, "ro", &nPos, arg))
666 aReadOnlyRegistries.push_back( aRegistry );
667 bNewRegistryMimic = true;
668 continue;
670 if (readOption( &aReadWriteRegistry, "rw", &nPos, arg))
672 bNewRegistryMimic = true;
673 continue;
675 if (readOption( &aRegistry, "r", &nPos, arg))
677 aReadOnlyRegistries.push_back( aRegistry );
678 aReadWriteRegistry = aRegistry;
679 out( "\n> warning: DEPRECATED use of option -r, use -ro or -rw!" );
680 bOldRegistryMimic = true;
681 continue;
684 // else illegal argument
685 OUStringBuffer buf( 64 );
686 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unexpected parameter \"") );
687 buf.append(arg);
688 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
689 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
692 if (bOldRegistryMimic) // last one was set to be read-write
694 aReadOnlyRegistries.pop_back();
695 if (bOldRegistryMimic && bNewRegistryMimic)
697 throw RuntimeException(
698 OUString( RTL_CONSTASCII_USTRINGPARAM("mixing with DEPRECATED registry options!") ),
699 Reference< XInterface >() );
703 if (!(aImplName.isEmpty() || aServiceName.isEmpty()))
704 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component exOR service name!" ) ), Reference< XInterface >() );
705 if (aImplName.isEmpty() && aServiceName.isEmpty())
707 if (! aUnoUrl.endsWithIgnoreAsciiCaseAsciiL(
708 RTL_CONSTASCII_STRINGPARAM(";uno.ComponentContext") ))
709 throw RuntimeException(
710 OUString( RTL_CONSTASCII_USTRINGPARAM(
711 "expected UNO-URL with instance name "
712 "uno.ComponentContext!") ),
713 Reference<XInterface>() );
714 if (bSingleInstance)
715 throw RuntimeException(
716 OUString( RTL_CONSTASCII_USTRINGPARAM(
717 "unexpected option --singleinstance!") ),
718 Reference<XInterface>() );
720 if (!aImplName.isEmpty() && aLocation.isEmpty())
721 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component location!" ) ), Reference< XInterface >() );
722 if (!aServiceName.isEmpty() && !aLocation.isEmpty())
723 out( "\n> warning: service name given, will ignore location!" );
725 // read component params
726 aParams.realloc( nCount - nPos );
727 OUString * pParams = aParams.getArray();
729 sal_uInt32 nOffset = nPos;
730 for ( ; nPos < nCount; ++nPos )
732 if (rtl_getAppCommandArg( nPos, &pParams[nPos -nOffset].pData )
733 != osl_Process_E_None)
735 OSL_ASSERT(false);
739 if ((!aReadOnlyRegistries.empty()) ||
740 aReadWriteRegistry.getLength() > 0)
742 //#### create registry #############################################
744 Reference< XSimpleRegistry > xRegistry;
746 // ReadOnly registries
747 for ( size_t nReg = 0; nReg < aReadOnlyRegistries.size(); ++nReg )
749 #if OSL_DEBUG_LEVEL > 1
750 out( "\n> trying to open ro registry: " );
751 out( OUStringToOString(
752 aReadOnlyRegistries[ nReg ],
753 RTL_TEXTENCODING_ASCII_US ).getStr() );
754 #endif
755 Reference< XSimpleRegistry > xNewReg(
756 openRegistry(
757 aReadOnlyRegistries[ nReg ], sal_True, sal_False ) );
758 if (xNewReg.is())
759 xRegistry = (xRegistry.is() ? nestRegistries(
760 xNewReg, xRegistry ) : xNewReg);
762 if (!aReadWriteRegistry.isEmpty())
764 #if OSL_DEBUG_LEVEL > 1
765 out( "\n> trying to open rw registry: " );
766 out( OUStringToOString(
767 aReadWriteRegistry,
768 RTL_TEXTENCODING_ASCII_US ).getStr() );
769 #endif
770 // ReadWrite registry
771 Reference< XSimpleRegistry > xNewReg(
772 openRegistry( aReadWriteRegistry, sal_False, sal_True ) );
773 if (xNewReg.is())
774 xRegistry = (xRegistry.is()
775 ? nestRegistries( xNewReg, xRegistry )
776 : xNewReg);
779 OSL_ASSERT( xRegistry.is() );
780 xContext = bootstrap_InitialComponentContext( xRegistry );
782 else // defaulting
784 xContext = defaultBootstrap_InitialComponentContext();
787 //#### accept, instanciate, etc. ###########################################################
789 if (!aUnoUrl.isEmpty()) // accepting connections
791 sal_Int32 nIndex = 0, nTokens = 0;
792 do { aUnoUrl.getToken( 0, ';', nIndex ); nTokens++; } while( nIndex != -1 );
793 if (nTokens != 3 || aUnoUrl.getLength() < 10 ||
794 !aUnoUrl.copy( 0, 4 ).equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("uno:") ) ))
796 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal uno url given!" ) ), Reference< XInterface >() );
798 nIndex = 0;
799 OUString aConnectDescr( aUnoUrl.getToken( 0, ';', nIndex ).copy( 4 ) ); // uno:CONNECTDESCR;iiop;InstanceName
800 OUString aInstanceName( aUnoUrl.getToken( 1, ';', nIndex ) );
802 Reference< XAcceptor > xAcceptor;
803 createInstance(
804 xAcceptor, xContext,
805 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor") ) );
807 // init params
808 Sequence< Any > aInitParams( aParams.getLength() );
809 const OUString * p = aParams.getConstArray();
810 Any * pInitParams = aInitParams.getArray();
811 for ( sal_Int32 i = aParams.getLength(); i--; )
813 pInitParams[i] = makeAny( p[i] );
816 // instance provider
817 Reference< XInstanceProvider > xInstanceProvider( new OInstanceProvider(
818 xContext, aImplName, aLocation, aServiceName, aInitParams,
819 bSingleInstance, aInstanceName ) );
821 nIndex = 0;
822 OUString aUnoUrlToken( aUnoUrl.getToken( 1, ';', nIndex ) );
823 for (;;)
825 // accepting
826 out( "\n> accepting " );
827 out( aConnectDescr );
828 out( "..." );
829 Reference< XConnection > xConnection( xAcceptor->accept( aConnectDescr ) );
830 out( "connection established." );
832 Reference< XBridgeFactory > xBridgeFactory;
833 createInstance(
834 xBridgeFactory, xContext,
835 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory") ) );
837 // bridge
838 Reference< XBridge > xBridge( xBridgeFactory->createBridge(
839 OUString(), aUnoUrlToken,
840 xConnection, xInstanceProvider ) );
842 if (bSingleAccept)
844 Reference< XComponent > xComp( xBridge, UNO_QUERY );
845 if (! xComp.is())
846 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("bridge factory does not export interface \"com.sun.star.lang.XComponent\"!" ) ), Reference< XInterface >() );
847 ODisposingListener::waitFor( xComp );
848 xComp->dispose();
849 // explicitly dispose the remote bridge so that it joins
850 // on all spawned threads before process exit (see
851 // binaryurp/source/bridge.cxx for details)
852 break;
856 else // no uno url
858 Reference< XInterface > xInstance;
859 if (!aImplName.isEmpty()) // manually via loader
860 xInstance = loadComponent( xContext, aImplName, aLocation );
861 else // via service manager
862 createInstance( xInstance, xContext, aServiceName );
864 // execution
865 Reference< XMain > xMain( xInstance, UNO_QUERY );
866 if (xMain.is())
868 nRet = xMain->run( aParams );
870 else
872 Reference< XComponent > xComp( xInstance, UNO_QUERY );
873 if (xComp.is())
874 xComp->dispose();
875 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("component does not export interface interface \"com.sun.star.lang.XMain\"!" ) ), Reference< XInterface >() );
879 catch (Exception & rExc)
881 out( "\n> error: " );
882 out( rExc.Message );
883 out( "\n> dying..." );
884 nRet = 1;
887 // cleanup
888 Reference< XComponent > xComp( xContext, UNO_QUERY );
889 if (xComp.is())
890 xComp->dispose();
892 out( "\n" );
893 return nRet;
898 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */