update dev300-m57
[ooovba.git] / cppuhelper / source / servicefactory.cxx
blob3128dd1fadda02224370a33d85660ff683d24e31
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: servicefactory.cxx,v $
10 * $Revision: 1.41 $
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
35 #include <stdio.h>
36 #endif
37 #include <vector>
39 #include "rtl/string.hxx"
40 #include "rtl/ustrbuf.hxx"
41 #include "rtl/bootstrap.hxx"
42 #include "osl/diagnose.h"
43 #include "osl/file.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;
71 namespace cppu
74 // private forward decl
75 void addFactories(
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 );
97 if (xFac.is())
99 return xFac->createInstanceWithContext( xContext );
101 else
103 Reference< lang::XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
104 if (xFac2.is())
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 )
117 SAL_THROW( () )
121 return Reference< registry::XSimpleRegistry >(
122 createInstance(
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 >() ) ),
130 UNO_QUERY );
132 catch (Exception & exc)
134 #if OSL_DEBUG_LEVEL > 0
135 OString cstr_msg(
136 OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
137 OSL_ENSURE( !"### exception occured:", cstr_msg.getStr() );
138 #else
139 (void) exc; // avoid warning about unused variable
140 #endif
143 return Reference< registry::XSimpleRegistry >();
146 Reference< registry::XSimpleRegistry > SAL_CALL createNestedRegistry(
147 OUString const & rBootstrapPath )
148 SAL_THROW( () )
152 return Reference< registry::XSimpleRegistry >(
153 createInstance(
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 >() ) ),
161 UNO_QUERY );
163 catch (Exception & exc)
165 #if OSL_DEBUG_LEVEL > 0
166 OString cstr_msg(
167 OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
168 OSL_ENSURE( !"### exception occured:", cstr_msg.getStr() );
169 #else
170 (void) exc; // avoid warning about unused variable
171 #endif
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;
203 OUString ac_policy;
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:///") ))
220 // no file url
221 OUString baseDir;
222 if ( ::osl_getProcessWorkingDir( &baseDir.pData )
223 != osl_Process_E_None )
225 OSL_ASSERT( false );
227 OUString fileURL;
228 if ( ::osl_getAbsoluteFileURL(
229 baseDir.pData, ac_policy.pData, &fileURL.pData )
230 != osl_File_E_None )
232 OSL_ASSERT( false );
234 ac_policy = fileURL;
237 entry.bLateInitService = false;
238 entry.name =
239 OUSTR("/implementations/com.sun.star.security.comp.stoc.FilePolicy/"
240 "file-name");
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
250 OUString ac_mode;
251 if (! bootstrap.getFrom( OUSTR("UNO_AC"), ac_mode ))
253 ac_mode = OUSTR("off"); // default
255 OUString ac_user;
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;
263 entry.name =
264 OUSTR("/services/com.sun.star.security.AccessController/"
265 "single-user-id");
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 >() );
277 else
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 >() );
290 OUString ac_service;
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
299 OUString ac_cache;
300 if (bootstrap.getFrom( OUSTR("UNO_AC_USERCACHE_SIZE"), ac_cache ))
302 // ac cache size
303 sal_Int32 n = ac_cache.toInt32();
304 if (0 < n)
306 entry.bLateInitService = false;
307 entry.name =
308 OUSTR("/services/com.sun.star.security.AccessController/"
309 "user-cache-size");
310 entry.value <<= n;
311 context_values.push_back( entry );
315 // - ac prop: mode
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 );
321 // - ac singleton
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(
336 createInstance(
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 >() ) ),
342 UNO_QUERY );
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",
364 addFactories(
365 ar, bootstrap_path,
366 xMgr, Reference< registry::XRegistryKey >() );
368 return xMgr;
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 );
380 if (! xSFInit.is())
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 );
398 // tdmgr singleton
399 entry.bLateInitService = true;
400 entry.name =
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() );
410 if (xKey.is())
412 xKey = xKey->openKey( OUSTR("/SINGLETONS") );
413 if (xKey.is())
415 entry.bLateInitService = true;
417 Sequence< Reference< registry::XRegistryKey > > keys(
418 xKey->openKeys() );
419 Reference< registry::XRegistryKey > const * pKeys =
420 keys.getConstArray();
421 for ( sal_Int32 nPos = keys.getLength(); nPos--; )
423 Reference< registry::XRegistryKey > const & xKey2 =
424 pKeys[ nPos ];
427 OUStringBuffer buf( 32 );
428 buf.appendAscii(
429 RTL_CONSTASCII_STRINGPARAM("/singletons/") );
430 buf.append(
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
440 OString aStr(
441 OUStringToOString(
442 xKey2->getKeyName().copy( 11 ),
443 RTL_TEXTENCODING_ASCII_US ) );
444 OString aStr2(
445 OUStringToOString(
446 rExc.Message, RTL_TEXTENCODING_ASCII_US ) );
447 fprintf(
448 stderr,
449 "### failed reading singleton [%s]"
450 " service name from registry: %s\n",
451 aStr.getStr(), aStr2.getStr() );
452 #else
453 (void) rExc; // avoid warning about unused variable
454 #endif
461 // ac, policy:
462 add_access_control_entries( &context_values, bootstrap );
464 // smgr singleton
465 entry.bLateInitService = false;
466 entry.name = OUSTR("/singletons/com.sun.star.lang.theServiceManager");
467 entry.value <<= xSF;
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() );
477 if (xProps.is())
479 xProps->setPropertyValue(
480 OUSTR("DefaultContext"), makeAny( xContext ) );
483 Reference< container::XHierarchicalNameAccess > xTDMgr;
485 // get tdmgr singleton
486 if (xContext->getValueByName(
487 OUSTR("/singletons/"
488 "com.sun.star.reflection.theTypeDescriptionManager") )
489 >>= xTDMgr)
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() );
504 // smgr
505 Reference< container::XSet > xSet( xSF, UNO_QUERY );
506 xSet->insert( makeAny( xFac ) );
507 OSL_ENSURE(
508 xSet->has( makeAny( xFac ) ),
509 "### failed registering registry td provider at smgr!" );
510 // tdmgr
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 );
517 OSL_ENSURE(
518 xSet->has( rdbtdp ),
519 "### failed inserting registry td provider to tdmgr!" );
521 // install callback
522 installTypeDescriptionManager( xTDMgr );
525 return xContext;
528 static Reference< lang::XMultiComponentFactory > createImplServiceFactory(
529 const OUString & rWriteRegistry,
530 const OUString & rReadRegistry,
531 sal_Bool bReadOnly,
532 const OUString & rBootstrapPath )
533 SAL_THROW( (Exception) )
535 Reference< lang::XMultiComponentFactory > xSF(
536 bootstrapInitialSF( rBootstrapPath ) );
538 Reference< registry::XSimpleRegistry > xRegistry;
540 // open a registry
541 sal_Bool bRegistryShouldBeValid = sal_False;
542 if (rWriteRegistry.getLength() && !rReadRegistry.getLength())
544 bRegistryShouldBeValid = sal_True;
545 xRegistry.set( createSimpleRegistry( rBootstrapPath ) );
546 if (xRegistry.is())
548 if (bReadOnly)
550 xRegistry->open( rWriteRegistry, sal_True, sal_False );
552 else
554 xRegistry->open( rWriteRegistry, sal_False, sal_True );
558 else if (rWriteRegistry.getLength() && rReadRegistry.getLength())
560 // default registry
561 bRegistryShouldBeValid = sal_True;
562 xRegistry.set( createNestedRegistry( rBootstrapPath ) );
564 Reference< registry::XSimpleRegistry > xWriteReg(
565 createSimpleRegistry( rBootstrapPath ) );
566 if (xWriteReg.is())
568 if (bReadOnly)
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 >() );
586 else
588 xWriteReg->open( rWriteRegistry, sal_False, sal_True );
592 Reference< registry::XSimpleRegistry > xReadReg(
593 createSimpleRegistry( rBootstrapPath ) );
594 if (xReadReg.is())
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 >() );
613 Bootstrap bootstrap;
614 Reference< XComponentContext > xContext(
615 bootstrapInitialContext(
616 xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
618 // initialize sf
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 );
625 return xSF;
628 Reference< lang::XMultiServiceFactory > SAL_CALL createRegistryServiceFactory(
629 const OUString & rWriteRegistry,
630 const OUString & rReadRegistry,
631 sal_Bool bReadOnly,
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) )
644 Bootstrap bootstrap;
646 Reference< lang::XMultiComponentFactory > xSF(
647 bootstrapInitialSF( rBootstrapPath ) );
648 Reference< XComponentContext > xContext(
649 bootstrapInitialContext(
650 xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
652 // initialize sf
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 );
660 return xContext;