1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: servicefactory.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppuhelper.hxx"
34 #if OSL_DEBUG_LEVEL > 0
39 #include "rtl/string.hxx"
40 #include "rtl/ustrbuf.hxx"
41 #include "rtl/bootstrap.hxx"
42 #include "osl/diagnose.h"
44 #include "osl/module.h"
45 #include "osl/process.h"
46 #include "cppuhelper/shlib.hxx"
47 #include "cppuhelper/factory.hxx"
48 #include "cppuhelper/component_context.hxx"
49 #include "cppuhelper/servicefactory.hxx"
50 #include "cppuhelper/bootstrap.hxx"
52 #include "com/sun/star/uno/XComponentContext.hpp"
53 #include "com/sun/star/lang/XInitialization.hpp"
54 #include "com/sun/star/lang/XSingleServiceFactory.hpp"
55 #include "com/sun/star/lang/XSingleComponentFactory.hpp"
56 #include "com/sun/star/beans/XPropertySet.hpp"
57 #include "com/sun/star/container/XSet.hpp"
58 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
59 #include "com/sun/star/registry/XSimpleRegistry.hpp"
60 #include "com/sun/star/registry/XImplementationRegistration.hpp"
61 #include "com/sun/star/security/XAccessController.hpp"
63 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
66 using namespace ::rtl
;
67 using namespace ::osl
;
68 using namespace ::com::sun::star
;
69 using namespace ::com::sun::star::uno
;
74 // private forward decl
76 char const * const * ppNames
/* lib, implname, ..., 0 */,
77 OUString
const & bootstrapPath
,
78 Reference
< lang::XMultiComponentFactory
> const & xMgr
,
79 Reference
< registry::XRegistryKey
> const & xKey
)
80 SAL_THROW( (Exception
) );
82 Reference
< security::XAccessController
>
83 createDefaultAccessController() SAL_THROW( () );
85 Reference
< lang::XSingleComponentFactory
>
86 create_boostrap_macro_expander_factory() SAL_THROW( () );
88 OUString
const & get_this_libpath();
91 static Reference
< XInterface
> SAL_CALL
createInstance(
92 Reference
< XInterface
> const & xFactory
,
93 Reference
< XComponentContext
> const & xContext
=
94 Reference
< XComponentContext
>() )
96 Reference
< lang::XSingleComponentFactory
> xFac( xFactory
, UNO_QUERY
);
99 return xFac
->createInstanceWithContext( xContext
);
103 Reference
< lang::XSingleServiceFactory
> xFac2( xFactory
, UNO_QUERY
);
106 OSL_ENSURE( !xContext
.is(), "### ignoring context!" );
107 return xFac2
->createInstance();
110 throw RuntimeException(
111 OUSTR("no factory object given!"),
112 Reference
< XInterface
>() );
115 Reference
< registry::XSimpleRegistry
> SAL_CALL
createSimpleRegistry(
116 OUString
const & rBootstrapPath
)
121 return Reference
< registry::XSimpleRegistry
>(
123 loadSharedLibComponentFactory(
124 OUSTR("bootstrap.uno" SAL_DLLEXTENSION
),
125 0 == rBootstrapPath
.getLength()
126 ? get_this_libpath() : rBootstrapPath
,
127 OUSTR("com.sun.star.comp.stoc.SimpleRegistry"),
128 Reference
< lang::XMultiServiceFactory
>(),
129 Reference
< registry::XRegistryKey
>() ) ),
132 catch (Exception
& exc
)
134 #if OSL_DEBUG_LEVEL > 0
136 OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
137 OSL_ENSURE( !"### exception occured:", cstr_msg
.getStr() );
139 (void) exc
; // avoid warning about unused variable
143 return Reference
< registry::XSimpleRegistry
>();
146 Reference
< registry::XSimpleRegistry
> SAL_CALL
createNestedRegistry(
147 OUString
const & rBootstrapPath
)
152 return Reference
< registry::XSimpleRegistry
>(
154 loadSharedLibComponentFactory(
155 OUSTR("bootstrap.uno" SAL_DLLEXTENSION
),
156 0 == rBootstrapPath
.getLength()
157 ? get_this_libpath() : rBootstrapPath
,
158 OUSTR("com.sun.star.comp.stoc.NestedRegistry"),
159 Reference
< lang::XMultiServiceFactory
>(),
160 Reference
< registry::XRegistryKey
>() ) ),
163 catch (Exception
& exc
)
165 #if OSL_DEBUG_LEVEL > 0
167 OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
168 OSL_ENSURE( !"### exception occured:", cstr_msg
.getStr() );
170 (void) exc
; // avoid warning about unused variable
174 return Reference
< registry::XSimpleRegistry
>();
178 /** bootstrap variables:
180 UNO_AC=<mode> [mandatory]
181 -- mode := { on, off, dynamic-only, single-user, single-default-user }
182 UNO_AC_SERVICE=<service_name> [optional]
183 -- override ac singleton service name
184 UNO_AC_SINGLEUSER=<user-id|nothing> [optional]
185 -- run with this user id or with default user policy (<nothing>)
186 set UNO_AC=single-[default-]user
187 UNO_AC_USERCACHE_SIZE=<cache_size>
188 -- number of user permission sets to be cached
190 UNO_AC_POLICYSERVICE=<service_name> [optional]
191 -- override policy singleton service name
192 UNO_AC_POLICYFILE=<file_url> [optional]
193 -- read policy out of simple text file
195 static void add_access_control_entries(
196 ::std::vector
< ContextEntry_Init
> * values
,
197 Bootstrap
const & bootstrap
)
198 SAL_THROW( (Exception
) )
200 ContextEntry_Init entry
;
201 ::std::vector
< ContextEntry_Init
> & context_values
= *values
;
204 if (bootstrap
.getFrom( OUSTR("UNO_AC_POLICYSERVICE"), ac_policy
))
206 // overridden service name
207 // - policy singleton
208 entry
.bLateInitService
= true;
209 entry
.name
= OUSTR("/singletons/com.sun.star.security.thePolicy");
210 entry
.value
<<= ac_policy
;
211 context_values
.push_back( entry
);
213 else if (bootstrap
.getFrom( OUSTR("UNO_AC_POLICYFILE"), ac_policy
))
215 // check for file policy
216 // - file policy prop: file-name
217 if (0 != ac_policy
.compareToAscii(
218 RTL_CONSTASCII_STRINGPARAM("file:///") ))
222 if ( ::osl_getProcessWorkingDir( &baseDir
.pData
)
223 != osl_Process_E_None
)
228 if ( ::osl_getAbsoluteFileURL(
229 baseDir
.pData
, ac_policy
.pData
, &fileURL
.pData
)
237 entry
.bLateInitService
= false;
239 OUSTR("/implementations/com.sun.star.security.comp.stoc.FilePolicy/"
241 entry
.value
<<= ac_policy
;
242 context_values
.push_back( entry
);
243 // - policy singleton
244 entry
.bLateInitService
= true;
245 entry
.name
= OUSTR("/singletons/com.sun.star.security.thePolicy");
246 entry
.value
<<= OUSTR("com.sun.star.security.comp.stoc.FilePolicy");
247 context_values
.push_back( entry
);
248 } // else policy singleton comes from storage
251 if (! bootstrap
.getFrom( OUSTR("UNO_AC"), ac_mode
))
253 ac_mode
= OUSTR("off"); // default
256 if (bootstrap
.getFrom( OUSTR("UNO_AC_SINGLEUSER"), ac_user
))
258 // ac in single-user mode
259 if (ac_user
.getLength())
261 // - ac prop: single-user-id
262 entry
.bLateInitService
= false;
264 OUSTR("/services/com.sun.star.security.AccessController/"
266 entry
.value
<<= ac_user
;
267 context_values
.push_back( entry
);
268 if (! ac_mode
.equalsAsciiL(
269 RTL_CONSTASCII_STRINGPARAM("single-user") ))
271 throw SecurityException(
272 OUSTR("set UNO_AC=single-user "
273 "if you set UNO_AC_SINGLEUSER=<user-id>!"),
274 Reference
< XInterface
>() );
279 if (! ac_mode
.equalsAsciiL(
280 RTL_CONSTASCII_STRINGPARAM("single-default-user") ))
282 throw SecurityException(
283 OUSTR("set UNO_AC=single-default-user "
284 "if you set UNO_AC_SINGLEUSER=<nothing>!"),
285 Reference
< XInterface
>() );
291 if (! bootstrap
.getFrom( OUSTR("UNO_AC_SERVICE"), ac_service
))
293 // override service name
294 ac_service
= OUSTR("com.sun.star.security.AccessController"); // default
295 // ac = OUSTR("com.sun.star.security.comp.stoc.AccessController");
298 // - ac prop: user-cache-size
300 if (bootstrap
.getFrom( OUSTR("UNO_AC_USERCACHE_SIZE"), ac_cache
))
303 sal_Int32 n
= ac_cache
.toInt32();
306 entry
.bLateInitService
= false;
308 OUSTR("/services/com.sun.star.security.AccessController/"
311 context_values
.push_back( entry
);
316 // { "off", "on", "dynamic-only", "single-user", "single-default-user" }
317 entry
.bLateInitService
= false;
318 entry
.name
= OUSTR("/services/com.sun.star.security.AccessController/mode");
319 entry
.value
<<= ac_mode
;
320 context_values
.push_back( entry
);
322 entry
.bLateInitService
= true;
323 entry
.name
= OUSTR("/singletons/com.sun.star.security.theAccessController");
324 entry
.value
<<= ac_service
;
325 context_values
.push_back( entry
);
328 Reference
< lang::XMultiComponentFactory
> bootstrapInitialSF(
329 OUString
const & rBootstrapPath
)
330 SAL_THROW( (Exception
) )
332 OUString
const & bootstrap_path
=
333 0 == rBootstrapPath
.getLength() ? get_this_libpath() : rBootstrapPath
;
335 Reference
< lang::XMultiComponentFactory
> xMgr(
337 loadSharedLibComponentFactory(
338 OUSTR("bootstrap.uno" SAL_DLLEXTENSION
), bootstrap_path
,
339 OUSTR("com.sun.star.comp.stoc.ORegistryServiceManager"),
340 Reference
< lang::XMultiServiceFactory
>(),
341 Reference
< registry::XRegistryKey
>() ) ),
344 // add initial bootstrap services
345 static char const * ar
[] = {
346 "bootstrap.uno" SAL_DLLEXTENSION
,
347 "com.sun.star.comp.stoc.OServiceManagerWrapper",
348 "bootstrap.uno" SAL_DLLEXTENSION
,
349 "com.sun.star.comp.stoc.DLLComponentLoader",
350 "bootstrap.uno" SAL_DLLEXTENSION
,
351 "com.sun.star.comp.stoc.SimpleRegistry",
352 "bootstrap.uno" SAL_DLLEXTENSION
,
353 "com.sun.star.comp.stoc.NestedRegistry",
354 "bootstrap.uno" SAL_DLLEXTENSION
,
355 "com.sun.star.comp.stoc.TypeDescriptionManager",
356 "bootstrap.uno" SAL_DLLEXTENSION
,
357 "com.sun.star.comp.stoc.ImplementationRegistration",
358 "bootstrap.uno" SAL_DLLEXTENSION
,
359 "com.sun.star.security.comp.stoc.AccessController",
360 "bootstrap.uno" SAL_DLLEXTENSION
,
361 "com.sun.star.security.comp.stoc.FilePolicy",
366 xMgr
, Reference
< registry::XRegistryKey
>() );
371 // returns context with UNinitialized smgr
372 Reference
< XComponentContext
> bootstrapInitialContext(
373 Reference
< lang::XMultiComponentFactory
> const & xSF
,
374 Reference
< registry::XSimpleRegistry
> const & types_xRegistry
,
375 Reference
< registry::XSimpleRegistry
> const & services_xRegistry
,
376 OUString
const & rBootstrapPath
, Bootstrap
const & bootstrap
)
377 SAL_THROW( (Exception
) )
379 Reference
< lang::XInitialization
> xSFInit( xSF
, UNO_QUERY
);
382 throw RuntimeException(
383 OUSTR("servicemanager does not support XInitialization!"),
384 Reference
< XInterface
>() );
387 // basic context values
388 ContextEntry_Init entry
;
389 ::std::vector
< ContextEntry_Init
> context_values
;
390 context_values
.reserve( 14 );
392 // macro expander singleton for loader
393 entry
.bLateInitService
= true;
394 entry
.name
= OUSTR("/singletons/com.sun.star.util.theMacroExpander");
395 entry
.value
<<= create_boostrap_macro_expander_factory();
396 context_values
.push_back( entry
);
399 entry
.bLateInitService
= true;
401 OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
402 entry
.value
<<= OUSTR("com.sun.star.comp.stoc.TypeDescriptionManager");
403 context_values
.push_back( entry
);
405 // read out singleton infos from registry
406 if (services_xRegistry
.is())
408 Reference
< registry::XRegistryKey
> xKey(
409 services_xRegistry
->getRootKey() );
412 xKey
= xKey
->openKey( OUSTR("/SINGLETONS") );
415 entry
.bLateInitService
= true;
417 Sequence
< Reference
< registry::XRegistryKey
> > keys(
419 Reference
< registry::XRegistryKey
> const * pKeys
=
420 keys
.getConstArray();
421 for ( sal_Int32 nPos
= keys
.getLength(); nPos
--; )
423 Reference
< registry::XRegistryKey
> const & xKey2
=
427 OUStringBuffer
buf( 32 );
429 RTL_CONSTASCII_STRINGPARAM("/singletons/") );
431 xKey2
->getKeyName().copy(
432 sizeof("/SINGLETONS") /* -\0 +'/' */ ) );
433 entry
.name
= buf
.makeStringAndClear();
434 entry
.value
<<= xKey2
->getStringValue();
435 context_values
.push_back( entry
);
437 catch (Exception
& rExc
)
439 #if OSL_DEBUG_LEVEL > 0
442 xKey2
->getKeyName().copy( 11 ),
443 RTL_TEXTENCODING_ASCII_US
) );
446 rExc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
449 "### failed reading singleton [%s]"
450 " service name from registry: %s\n",
451 aStr
.getStr(), aStr2
.getStr() );
453 (void) rExc
; // avoid warning about unused variable
462 add_access_control_entries( &context_values
, bootstrap
);
465 entry
.bLateInitService
= false;
466 entry
.name
= OUSTR("/singletons/com.sun.star.lang.theServiceManager");
468 context_values
.push_back( entry
);
470 Reference
< XComponentContext
> xContext(
471 createComponentContext(
472 &context_values
[ 0 ], context_values
.size(),
473 Reference
< XComponentContext
>() ) );
474 // set default context
475 Reference
< beans::XPropertySet
> xProps( xSF
, UNO_QUERY
);
476 OSL_ASSERT( xProps
.is() );
479 xProps
->setPropertyValue(
480 OUSTR("DefaultContext"), makeAny( xContext
) );
483 Reference
< container::XHierarchicalNameAccess
> xTDMgr
;
485 // get tdmgr singleton
486 if (xContext
->getValueByName(
488 "com.sun.star.reflection.theTypeDescriptionManager") )
491 if (types_xRegistry
.is()) // insert rdb provider?
493 // add registry td provider factory to smgr and instance to tdmgr
494 Reference
< lang::XSingleComponentFactory
> xFac(
495 loadSharedLibComponentFactory(
496 OUSTR("bootstrap.uno" SAL_DLLEXTENSION
),
497 0 == rBootstrapPath
.getLength()
498 ? get_this_libpath() : rBootstrapPath
,
499 OUSTR("com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"),
500 Reference
< lang::XMultiServiceFactory
>( xSF
, UNO_QUERY
),
501 Reference
< registry::XRegistryKey
>() ), UNO_QUERY
);
502 OSL_ASSERT( xFac
.is() );
505 Reference
< container::XSet
> xSet( xSF
, UNO_QUERY
);
506 xSet
->insert( makeAny( xFac
) );
508 xSet
->has( makeAny( xFac
) ),
509 "### failed registering registry td provider at smgr!" );
511 xSet
.set( xTDMgr
, UNO_QUERY
);
512 OSL_ASSERT( xSet
.is() );
513 Any
types_RDB( makeAny( types_xRegistry
) );
514 Any
rdbtdp( makeAny( xFac
->createInstanceWithArgumentsAndContext(
515 Sequence
< Any
>( &types_RDB
, 1 ), xContext
) ) );
516 xSet
->insert( rdbtdp
);
519 "### failed inserting registry td provider to tdmgr!" );
522 installTypeDescriptionManager( xTDMgr
);
528 static Reference
< lang::XMultiComponentFactory
> createImplServiceFactory(
529 const OUString
& rWriteRegistry
,
530 const OUString
& rReadRegistry
,
532 const OUString
& rBootstrapPath
)
533 SAL_THROW( (Exception
) )
535 Reference
< lang::XMultiComponentFactory
> xSF(
536 bootstrapInitialSF( rBootstrapPath
) );
538 Reference
< registry::XSimpleRegistry
> xRegistry
;
541 sal_Bool bRegistryShouldBeValid
= sal_False
;
542 if (rWriteRegistry
.getLength() && !rReadRegistry
.getLength())
544 bRegistryShouldBeValid
= sal_True
;
545 xRegistry
.set( createSimpleRegistry( rBootstrapPath
) );
550 xRegistry
->open( rWriteRegistry
, sal_True
, sal_False
);
554 xRegistry
->open( rWriteRegistry
, sal_False
, sal_True
);
558 else if (rWriteRegistry
.getLength() && rReadRegistry
.getLength())
561 bRegistryShouldBeValid
= sal_True
;
562 xRegistry
.set( createNestedRegistry( rBootstrapPath
) );
564 Reference
< registry::XSimpleRegistry
> xWriteReg(
565 createSimpleRegistry( rBootstrapPath
) );
572 xWriteReg
->open( rWriteRegistry
, sal_True
, sal_False
);
574 catch (registry::InvalidRegistryException
&)
578 if (! xWriteReg
->isValid())
580 throw RuntimeException(
581 OUSTR("specified first registry "
582 "could not be open readonly!"),
583 Reference
< XInterface
>() );
588 xWriteReg
->open( rWriteRegistry
, sal_False
, sal_True
);
592 Reference
< registry::XSimpleRegistry
> xReadReg(
593 createSimpleRegistry( rBootstrapPath
) );
596 xReadReg
->open( rReadRegistry
, sal_True
, sal_False
);
599 Reference
< lang::XInitialization
> xInit( xRegistry
, UNO_QUERY
);
600 Sequence
< Any
> aInitSeq( 2 );
601 aInitSeq
[ 0 ] <<= xWriteReg
;
602 aInitSeq
[ 1 ] <<= xReadReg
;
603 xInit
->initialize( aInitSeq
);
606 if (bRegistryShouldBeValid
&& (!xRegistry
.is() || !xRegistry
->isValid()))
608 throw RuntimeException(
609 OUSTR("specified registry could not be initialized"),
610 Reference
< XInterface
>() );
614 Reference
< XComponentContext
> xContext(
615 bootstrapInitialContext(
616 xSF
, xRegistry
, xRegistry
, rBootstrapPath
, bootstrap
) );
619 Reference
< lang::XInitialization
> xInit( xSF
, UNO_QUERY
);
620 OSL_ASSERT( xInit
.is() );
621 Sequence
< Any
> aSFInit( 1 );
622 aSFInit
[ 0 ] <<= xRegistry
;
623 xInit
->initialize( aSFInit
);
628 Reference
< lang::XMultiServiceFactory
> SAL_CALL
createRegistryServiceFactory(
629 const OUString
& rWriteRegistry
,
630 const OUString
& rReadRegistry
,
632 const OUString
& rBootstrapPath
)
633 SAL_THROW( (Exception
) )
635 return Reference
< lang::XMultiServiceFactory
>( createImplServiceFactory(
636 rWriteRegistry
, rReadRegistry
, bReadOnly
, rBootstrapPath
), UNO_QUERY
);
639 Reference
< XComponentContext
> SAL_CALL
bootstrap_InitialComponentContext(
640 Reference
< registry::XSimpleRegistry
> const & xRegistry
,
641 OUString
const & rBootstrapPath
)
642 SAL_THROW( (Exception
) )
646 Reference
< lang::XMultiComponentFactory
> xSF(
647 bootstrapInitialSF( rBootstrapPath
) );
648 Reference
< XComponentContext
> xContext(
649 bootstrapInitialContext(
650 xSF
, xRegistry
, xRegistry
, rBootstrapPath
, bootstrap
) );
653 Reference
< lang::XInitialization
> xInit( xSF
, UNO_QUERY
);
654 OSL_ASSERT( xInit
.is() );
655 Sequence
< Any
> aSFInit( 2 );
656 aSFInit
[ 0 ] <<= xRegistry
;
657 aSFInit
[ 1 ] <<= xContext
; // default context
658 xInit
->initialize( aSFInit
);