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 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 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 //-------------------------------------------------------------------------------------------------- 127 static inline void out( const sal_Char * pText ) 128 { 129 if (! s_quiet) 130 fprintf( stderr, "%s", pText ); 131 } 132 //-------------------------------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------------------------------- 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 > 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 //-------------------------------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------------------------------- 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: 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 569 void ODisposingListener::disposing( const EventObject & ) 570 { 571 cDisposed.set(); 572 } 573 //-------------------------------------------------------------------------------------------------- 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