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