1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <vector>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "rtl/string.hxx"
34*cdf0e10cSrcweir #include "rtl/bootstrap.hxx"
35*cdf0e10cSrcweir #include "osl/diagnose.h"
36*cdf0e10cSrcweir #include "osl/file.h"
37*cdf0e10cSrcweir #include "osl/module.h"
38*cdf0e10cSrcweir #include "osl/process.h"
39*cdf0e10cSrcweir #include "cppuhelper/shlib.hxx"
40*cdf0e10cSrcweir #include "cppuhelper/factory.hxx"
41*cdf0e10cSrcweir #include "cppuhelper/component_context.hxx"
42*cdf0e10cSrcweir #include "cppuhelper/servicefactory.hxx"
43*cdf0e10cSrcweir #include "cppuhelper/bootstrap.hxx"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include "com/sun/star/uno/DeploymentException.hpp"
46*cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp"
47*cdf0e10cSrcweir #include "com/sun/star/lang/XInitialization.hpp"
48*cdf0e10cSrcweir #include "com/sun/star/lang/XSingleServiceFactory.hpp"
49*cdf0e10cSrcweir #include "com/sun/star/lang/XSingleComponentFactory.hpp"
50*cdf0e10cSrcweir #include "com/sun/star/beans/XPropertySet.hpp"
51*cdf0e10cSrcweir #include "com/sun/star/container/XSet.hpp"
52*cdf0e10cSrcweir #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
53*cdf0e10cSrcweir #include "com/sun/star/registry/XSimpleRegistry.hpp"
54*cdf0e10cSrcweir #include "com/sun/star/registry/XImplementationRegistration.hpp"
55*cdf0e10cSrcweir #include "com/sun/star/security/XAccessController.hpp"
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir using namespace ::rtl;
61*cdf0e10cSrcweir using namespace ::osl;
62*cdf0e10cSrcweir using namespace ::com::sun::star;
63*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
64*cdf0e10cSrcweir namespace css = com::sun::star;
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir namespace cppu
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir // private forward decl
70*cdf0e10cSrcweir void addFactories(
71*cdf0e10cSrcweir     char const * const * ppNames /* lib, implname, ..., 0 */,
72*cdf0e10cSrcweir     OUString const & bootstrapPath,
73*cdf0e10cSrcweir     Reference< lang::XMultiComponentFactory > const & xMgr,
74*cdf0e10cSrcweir     Reference< registry::XRegistryKey > const & xKey )
75*cdf0e10cSrcweir     SAL_THROW( (Exception) );
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir Reference< security::XAccessController >
78*cdf0e10cSrcweir createDefaultAccessController() SAL_THROW( () );
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir Reference< lang::XSingleComponentFactory >
81*cdf0e10cSrcweir create_boostrap_macro_expander_factory() SAL_THROW( () );
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir OUString const & get_this_libpath();
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir static Reference< XInterface > SAL_CALL createInstance(
87*cdf0e10cSrcweir     Reference< XInterface > const & xFactory,
88*cdf0e10cSrcweir     Reference< XComponentContext > const & xContext =
89*cdf0e10cSrcweir     Reference< XComponentContext >() )
90*cdf0e10cSrcweir {
91*cdf0e10cSrcweir     Reference< lang::XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
92*cdf0e10cSrcweir     if (xFac.is())
93*cdf0e10cSrcweir     {
94*cdf0e10cSrcweir         return xFac->createInstanceWithContext( xContext );
95*cdf0e10cSrcweir     }
96*cdf0e10cSrcweir     else
97*cdf0e10cSrcweir     {
98*cdf0e10cSrcweir         Reference< lang::XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
99*cdf0e10cSrcweir         if (xFac2.is())
100*cdf0e10cSrcweir         {
101*cdf0e10cSrcweir             OSL_ENSURE( !xContext.is(), "### ignoring context!" );
102*cdf0e10cSrcweir             return xFac2->createInstance();
103*cdf0e10cSrcweir         }
104*cdf0e10cSrcweir     }
105*cdf0e10cSrcweir     throw RuntimeException(
106*cdf0e10cSrcweir         OUSTR("no factory object given!"),
107*cdf0e10cSrcweir         Reference< XInterface >() );
108*cdf0e10cSrcweir }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir Reference< registry::XSimpleRegistry > SAL_CALL createSimpleRegistry(
111*cdf0e10cSrcweir     OUString const & rBootstrapPath )
112*cdf0e10cSrcweir     SAL_THROW( () )
113*cdf0e10cSrcweir {
114*cdf0e10cSrcweir     try
115*cdf0e10cSrcweir     {
116*cdf0e10cSrcweir         return Reference< registry::XSimpleRegistry >(
117*cdf0e10cSrcweir             createInstance(
118*cdf0e10cSrcweir                 loadSharedLibComponentFactory(
119*cdf0e10cSrcweir                     OUSTR("bootstrap.uno" SAL_DLLEXTENSION),
120*cdf0e10cSrcweir                     0 == rBootstrapPath.getLength()
121*cdf0e10cSrcweir                     ? get_this_libpath() : rBootstrapPath,
122*cdf0e10cSrcweir                     OUSTR("com.sun.star.comp.stoc.SimpleRegistry"),
123*cdf0e10cSrcweir                     Reference< lang::XMultiServiceFactory >(),
124*cdf0e10cSrcweir                     Reference< registry::XRegistryKey >() ) ),
125*cdf0e10cSrcweir             UNO_QUERY );
126*cdf0e10cSrcweir     }
127*cdf0e10cSrcweir     catch (Exception & exc)
128*cdf0e10cSrcweir     {
129*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
130*cdf0e10cSrcweir         OString cstr_msg(
131*cdf0e10cSrcweir             OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
132*cdf0e10cSrcweir         OSL_ENSURE( !"### exception occured:", cstr_msg.getStr() );
133*cdf0e10cSrcweir #else
134*cdf0e10cSrcweir         (void) exc; // avoid warning about unused variable
135*cdf0e10cSrcweir #endif
136*cdf0e10cSrcweir     }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir     return Reference< registry::XSimpleRegistry >();
139*cdf0e10cSrcweir }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir Reference< registry::XSimpleRegistry > SAL_CALL createNestedRegistry(
142*cdf0e10cSrcweir     OUString const & rBootstrapPath )
143*cdf0e10cSrcweir     SAL_THROW( () )
144*cdf0e10cSrcweir {
145*cdf0e10cSrcweir     try
146*cdf0e10cSrcweir     {
147*cdf0e10cSrcweir         return Reference< registry::XSimpleRegistry >(
148*cdf0e10cSrcweir             createInstance(
149*cdf0e10cSrcweir                 loadSharedLibComponentFactory(
150*cdf0e10cSrcweir                     OUSTR("bootstrap.uno" SAL_DLLEXTENSION),
151*cdf0e10cSrcweir                     0 == rBootstrapPath.getLength()
152*cdf0e10cSrcweir                     ? get_this_libpath() : rBootstrapPath,
153*cdf0e10cSrcweir                     OUSTR("com.sun.star.comp.stoc.NestedRegistry"),
154*cdf0e10cSrcweir                     Reference< lang::XMultiServiceFactory >(),
155*cdf0e10cSrcweir                     Reference< registry::XRegistryKey >() ) ),
156*cdf0e10cSrcweir             UNO_QUERY );
157*cdf0e10cSrcweir     }
158*cdf0e10cSrcweir     catch (Exception & exc)
159*cdf0e10cSrcweir     {
160*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
161*cdf0e10cSrcweir         OString cstr_msg(
162*cdf0e10cSrcweir             OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
163*cdf0e10cSrcweir         OSL_ENSURE( !"### exception occured:", cstr_msg.getStr() );
164*cdf0e10cSrcweir #else
165*cdf0e10cSrcweir         (void) exc; // avoid warning about unused variable
166*cdf0e10cSrcweir #endif
167*cdf0e10cSrcweir     }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir     return Reference< registry::XSimpleRegistry >();
170*cdf0e10cSrcweir }
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir /** bootstrap variables:
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir     UNO_AC=<mode> [mandatory]
176*cdf0e10cSrcweir       -- mode := { on, off, dynamic-only, single-user, single-default-user }
177*cdf0e10cSrcweir     UNO_AC_SERVICE=<service_name> [optional]
178*cdf0e10cSrcweir       -- override ac singleton service name
179*cdf0e10cSrcweir     UNO_AC_SINGLEUSER=<user-id|nothing> [optional]
180*cdf0e10cSrcweir       -- run with this user id or with default user policy (<nothing>)
181*cdf0e10cSrcweir          set UNO_AC=single-[default-]user
182*cdf0e10cSrcweir     UNO_AC_USERCACHE_SIZE=<cache_size>
183*cdf0e10cSrcweir       -- number of user permission sets to be cached
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir     UNO_AC_POLICYSERVICE=<service_name> [optional]
186*cdf0e10cSrcweir       -- override policy singleton service name
187*cdf0e10cSrcweir     UNO_AC_POLICYFILE=<file_url> [optional]
188*cdf0e10cSrcweir       -- read policy out of simple text file
189*cdf0e10cSrcweir */
190*cdf0e10cSrcweir static void add_access_control_entries(
191*cdf0e10cSrcweir     ::std::vector< ContextEntry_Init > * values,
192*cdf0e10cSrcweir     Bootstrap const & bootstrap )
193*cdf0e10cSrcweir     SAL_THROW( (Exception) )
194*cdf0e10cSrcweir {
195*cdf0e10cSrcweir     ContextEntry_Init entry;
196*cdf0e10cSrcweir     ::std::vector< ContextEntry_Init > & context_values = *values;
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir     OUString ac_policy;
199*cdf0e10cSrcweir     if (bootstrap.getFrom( OUSTR("UNO_AC_POLICYSERVICE"), ac_policy ))
200*cdf0e10cSrcweir     {
201*cdf0e10cSrcweir         // overridden service name
202*cdf0e10cSrcweir         // - policy singleton
203*cdf0e10cSrcweir         entry.bLateInitService = true;
204*cdf0e10cSrcweir         entry.name = OUSTR("/singletons/com.sun.star.security.thePolicy");
205*cdf0e10cSrcweir         entry.value <<= ac_policy;
206*cdf0e10cSrcweir         context_values.push_back( entry );
207*cdf0e10cSrcweir     }
208*cdf0e10cSrcweir     else if (bootstrap.getFrom( OUSTR("UNO_AC_POLICYFILE"), ac_policy ))
209*cdf0e10cSrcweir     {
210*cdf0e10cSrcweir         // check for file policy
211*cdf0e10cSrcweir         // - file policy prop: file-name
212*cdf0e10cSrcweir         if (0 != ac_policy.compareToAscii(
213*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM("file:///") ))
214*cdf0e10cSrcweir         {
215*cdf0e10cSrcweir             // no file url
216*cdf0e10cSrcweir             OUString baseDir;
217*cdf0e10cSrcweir             if ( ::osl_getProcessWorkingDir( &baseDir.pData )
218*cdf0e10cSrcweir                  != osl_Process_E_None )
219*cdf0e10cSrcweir             {
220*cdf0e10cSrcweir                 OSL_ASSERT( false );
221*cdf0e10cSrcweir             }
222*cdf0e10cSrcweir             OUString fileURL;
223*cdf0e10cSrcweir             if ( ::osl_getAbsoluteFileURL(
224*cdf0e10cSrcweir                      baseDir.pData, ac_policy.pData, &fileURL.pData )
225*cdf0e10cSrcweir                  != osl_File_E_None )
226*cdf0e10cSrcweir             {
227*cdf0e10cSrcweir                 OSL_ASSERT( false );
228*cdf0e10cSrcweir             }
229*cdf0e10cSrcweir             ac_policy = fileURL;
230*cdf0e10cSrcweir         }
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir         entry.bLateInitService = false;
233*cdf0e10cSrcweir         entry.name =
234*cdf0e10cSrcweir             OUSTR("/implementations/com.sun.star.security.comp.stoc.FilePolicy/"
235*cdf0e10cSrcweir                   "file-name");
236*cdf0e10cSrcweir         entry.value <<= ac_policy;
237*cdf0e10cSrcweir         context_values.push_back( entry );
238*cdf0e10cSrcweir         // - policy singleton
239*cdf0e10cSrcweir         entry.bLateInitService = true;
240*cdf0e10cSrcweir         entry.name = OUSTR("/singletons/com.sun.star.security.thePolicy");
241*cdf0e10cSrcweir         entry.value <<= OUSTR("com.sun.star.security.comp.stoc.FilePolicy");
242*cdf0e10cSrcweir         context_values.push_back( entry );
243*cdf0e10cSrcweir     } // else policy singleton comes from storage
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir     OUString ac_mode;
246*cdf0e10cSrcweir     if (! bootstrap.getFrom( OUSTR("UNO_AC"), ac_mode ))
247*cdf0e10cSrcweir     {
248*cdf0e10cSrcweir         ac_mode = OUSTR("off"); // default
249*cdf0e10cSrcweir     }
250*cdf0e10cSrcweir     OUString ac_user;
251*cdf0e10cSrcweir     if (bootstrap.getFrom( OUSTR("UNO_AC_SINGLEUSER"), ac_user ))
252*cdf0e10cSrcweir     {
253*cdf0e10cSrcweir         // ac in single-user mode
254*cdf0e10cSrcweir         if (ac_user.getLength())
255*cdf0e10cSrcweir         {
256*cdf0e10cSrcweir             // - ac prop: single-user-id
257*cdf0e10cSrcweir             entry.bLateInitService = false;
258*cdf0e10cSrcweir             entry.name =
259*cdf0e10cSrcweir                 OUSTR("/services/com.sun.star.security.AccessController/"
260*cdf0e10cSrcweir                       "single-user-id");
261*cdf0e10cSrcweir             entry.value <<= ac_user;
262*cdf0e10cSrcweir             context_values.push_back( entry );
263*cdf0e10cSrcweir             if (! ac_mode.equalsAsciiL(
264*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("single-user") ))
265*cdf0e10cSrcweir             {
266*cdf0e10cSrcweir                 throw SecurityException(
267*cdf0e10cSrcweir                     OUSTR("set UNO_AC=single-user "
268*cdf0e10cSrcweir                           "if you set UNO_AC_SINGLEUSER=<user-id>!"),
269*cdf0e10cSrcweir                     Reference< XInterface >() );
270*cdf0e10cSrcweir             }
271*cdf0e10cSrcweir         }
272*cdf0e10cSrcweir         else
273*cdf0e10cSrcweir         {
274*cdf0e10cSrcweir             if (! ac_mode.equalsAsciiL(
275*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("single-default-user") ))
276*cdf0e10cSrcweir             {
277*cdf0e10cSrcweir                 throw SecurityException(
278*cdf0e10cSrcweir                     OUSTR("set UNO_AC=single-default-user "
279*cdf0e10cSrcweir                           "if you set UNO_AC_SINGLEUSER=<nothing>!"),
280*cdf0e10cSrcweir                     Reference< XInterface >() );
281*cdf0e10cSrcweir             }
282*cdf0e10cSrcweir         }
283*cdf0e10cSrcweir     }
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir     OUString ac_service;
286*cdf0e10cSrcweir     if (! bootstrap.getFrom( OUSTR("UNO_AC_SERVICE"), ac_service ))
287*cdf0e10cSrcweir     {
288*cdf0e10cSrcweir         // override service name
289*cdf0e10cSrcweir         ac_service = OUSTR("com.sun.star.security.AccessController"); // default
290*cdf0e10cSrcweir //          ac = OUSTR("com.sun.star.security.comp.stoc.AccessController");
291*cdf0e10cSrcweir     }
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir     // - ac prop: user-cache-size
294*cdf0e10cSrcweir     OUString ac_cache;
295*cdf0e10cSrcweir     if (bootstrap.getFrom( OUSTR("UNO_AC_USERCACHE_SIZE"), ac_cache ))
296*cdf0e10cSrcweir     {
297*cdf0e10cSrcweir         // ac cache size
298*cdf0e10cSrcweir         sal_Int32 n = ac_cache.toInt32();
299*cdf0e10cSrcweir         if (0 < n)
300*cdf0e10cSrcweir         {
301*cdf0e10cSrcweir             entry.bLateInitService = false;
302*cdf0e10cSrcweir             entry.name =
303*cdf0e10cSrcweir                 OUSTR("/services/com.sun.star.security.AccessController/"
304*cdf0e10cSrcweir                       "user-cache-size");
305*cdf0e10cSrcweir             entry.value <<= n;
306*cdf0e10cSrcweir             context_values.push_back( entry );
307*cdf0e10cSrcweir         }
308*cdf0e10cSrcweir     }
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir     // - ac prop: mode
311*cdf0e10cSrcweir     // { "off", "on", "dynamic-only", "single-user", "single-default-user" }
312*cdf0e10cSrcweir     entry.bLateInitService = false;
313*cdf0e10cSrcweir     entry.name = OUSTR("/services/com.sun.star.security.AccessController/mode");
314*cdf0e10cSrcweir     entry.value <<= ac_mode;
315*cdf0e10cSrcweir     context_values.push_back( entry );
316*cdf0e10cSrcweir     // - ac singleton
317*cdf0e10cSrcweir     entry.bLateInitService = true;
318*cdf0e10cSrcweir     entry.name = OUSTR("/singletons/com.sun.star.security.theAccessController");
319*cdf0e10cSrcweir     entry.value <<= ac_service;
320*cdf0e10cSrcweir     context_values.push_back( entry );
321*cdf0e10cSrcweir }
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir Reference< lang::XMultiComponentFactory > bootstrapInitialSF(
324*cdf0e10cSrcweir     OUString const & rBootstrapPath )
325*cdf0e10cSrcweir     SAL_THROW( (Exception) )
326*cdf0e10cSrcweir {
327*cdf0e10cSrcweir     OUString const & bootstrap_path =
328*cdf0e10cSrcweir         0 == rBootstrapPath.getLength() ? get_this_libpath() : rBootstrapPath;
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir     Reference< lang::XMultiComponentFactory > xMgr(
331*cdf0e10cSrcweir         createInstance(
332*cdf0e10cSrcweir             loadSharedLibComponentFactory(
333*cdf0e10cSrcweir                 OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrap_path,
334*cdf0e10cSrcweir                 OUSTR("com.sun.star.comp.stoc.ORegistryServiceManager"),
335*cdf0e10cSrcweir                 Reference< lang::XMultiServiceFactory >(),
336*cdf0e10cSrcweir                 Reference< registry::XRegistryKey >() ) ),
337*cdf0e10cSrcweir         UNO_QUERY );
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir     // add initial bootstrap services
340*cdf0e10cSrcweir     static char const * ar[] = {
341*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
342*cdf0e10cSrcweir         "com.sun.star.comp.stoc.OServiceManagerWrapper",
343*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
344*cdf0e10cSrcweir         "com.sun.star.comp.stoc.DLLComponentLoader",
345*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
346*cdf0e10cSrcweir         "com.sun.star.comp.stoc.SimpleRegistry",
347*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
348*cdf0e10cSrcweir         "com.sun.star.comp.stoc.NestedRegistry",
349*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
350*cdf0e10cSrcweir         "com.sun.star.comp.stoc.TypeDescriptionManager",
351*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
352*cdf0e10cSrcweir         "com.sun.star.comp.stoc.ImplementationRegistration",
353*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
354*cdf0e10cSrcweir         "com.sun.star.security.comp.stoc.AccessController",
355*cdf0e10cSrcweir         "bootstrap.uno" SAL_DLLEXTENSION,
356*cdf0e10cSrcweir         "com.sun.star.security.comp.stoc.FilePolicy",
357*cdf0e10cSrcweir         0
358*cdf0e10cSrcweir     };
359*cdf0e10cSrcweir     addFactories(
360*cdf0e10cSrcweir         ar, bootstrap_path,
361*cdf0e10cSrcweir         xMgr, Reference< registry::XRegistryKey >() );
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir     return xMgr;
364*cdf0e10cSrcweir }
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir // returns context with UNinitialized smgr
367*cdf0e10cSrcweir Reference< XComponentContext > bootstrapInitialContext(
368*cdf0e10cSrcweir     Reference< lang::XMultiComponentFactory > const & xSF,
369*cdf0e10cSrcweir     Reference< registry::XSimpleRegistry > const & types_xRegistry,
370*cdf0e10cSrcweir     Reference< registry::XSimpleRegistry > const & services_xRegistry,
371*cdf0e10cSrcweir     OUString const & rBootstrapPath, Bootstrap const & bootstrap )
372*cdf0e10cSrcweir     SAL_THROW( (Exception) )
373*cdf0e10cSrcweir {
374*cdf0e10cSrcweir     Reference< lang::XInitialization > xSFInit( xSF, UNO_QUERY );
375*cdf0e10cSrcweir     if (! xSFInit.is())
376*cdf0e10cSrcweir     {
377*cdf0e10cSrcweir         throw RuntimeException(
378*cdf0e10cSrcweir             OUSTR("servicemanager does not support XInitialization!"),
379*cdf0e10cSrcweir             Reference< XInterface >() );
380*cdf0e10cSrcweir     }
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir     // basic context values
383*cdf0e10cSrcweir     ContextEntry_Init entry;
384*cdf0e10cSrcweir     ::std::vector< ContextEntry_Init > context_values;
385*cdf0e10cSrcweir     context_values.reserve( 14 );
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir     // macro expander singleton for loader
388*cdf0e10cSrcweir     entry.bLateInitService = true;
389*cdf0e10cSrcweir     entry.name = OUSTR("/singletons/com.sun.star.util.theMacroExpander");
390*cdf0e10cSrcweir     entry.value <<= create_boostrap_macro_expander_factory();
391*cdf0e10cSrcweir     context_values.push_back( entry );
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     // tdmgr singleton
394*cdf0e10cSrcweir     entry.bLateInitService = true;
395*cdf0e10cSrcweir     entry.name =
396*cdf0e10cSrcweir         OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
397*cdf0e10cSrcweir     entry.value <<= OUSTR("com.sun.star.comp.stoc.TypeDescriptionManager");
398*cdf0e10cSrcweir     context_values.push_back( entry );
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir     // read out singleton infos from registry
401*cdf0e10cSrcweir     if (services_xRegistry.is())
402*cdf0e10cSrcweir     {
403*cdf0e10cSrcweir         Reference< registry::XRegistryKey > xKey(
404*cdf0e10cSrcweir             services_xRegistry->getRootKey() );
405*cdf0e10cSrcweir         if (xKey.is())
406*cdf0e10cSrcweir         {
407*cdf0e10cSrcweir             xKey = xKey->openKey( OUSTR("/SINGLETONS") );
408*cdf0e10cSrcweir             if (xKey.is())
409*cdf0e10cSrcweir             {
410*cdf0e10cSrcweir                 entry.bLateInitService = true;
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir                 Sequence< Reference< registry::XRegistryKey > > keys(
413*cdf0e10cSrcweir                     xKey->openKeys() );
414*cdf0e10cSrcweir                 Reference< registry::XRegistryKey > const * pKeys =
415*cdf0e10cSrcweir                     keys.getConstArray();
416*cdf0e10cSrcweir                 for ( sal_Int32 nPos = keys.getLength(); nPos--; )
417*cdf0e10cSrcweir                 {
418*cdf0e10cSrcweir                     css::uno::Sequence< rtl::OUString > impls(
419*cdf0e10cSrcweir                         css::uno::Reference< css::registry::XRegistryKey >(
420*cdf0e10cSrcweir                             pKeys[nPos]->openKey(
421*cdf0e10cSrcweir                                 rtl::OUString(
422*cdf0e10cSrcweir                                     RTL_CONSTASCII_USTRINGPARAM(
423*cdf0e10cSrcweir                                         "REGISTERED_BY"))),
424*cdf0e10cSrcweir                             css::uno::UNO_SET_THROW)->getAsciiListValue());
425*cdf0e10cSrcweir                     switch (impls.getLength()) {
426*cdf0e10cSrcweir                     case 0:
427*cdf0e10cSrcweir                         throw css::uno::DeploymentException(
428*cdf0e10cSrcweir                             (pKeys[nPos]->getKeyName() +
429*cdf0e10cSrcweir                              rtl::OUString(
430*cdf0e10cSrcweir                                  RTL_CONSTASCII_USTRINGPARAM(
431*cdf0e10cSrcweir                                      "/REGISTERED_BY is empty"))),
432*cdf0e10cSrcweir                             css::uno::Reference< css::uno::XInterface >());
433*cdf0e10cSrcweir                     case 1:
434*cdf0e10cSrcweir                         break;
435*cdf0e10cSrcweir                     default:
436*cdf0e10cSrcweir                         OSL_TRACE(
437*cdf0e10cSrcweir                             ("arbitrarily chosing \"%s\" among multiple"
438*cdf0e10cSrcweir                              " implementations for \"%s\""),
439*cdf0e10cSrcweir                             rtl::OUStringToOString(
440*cdf0e10cSrcweir                                 impls[0], RTL_TEXTENCODING_UTF8).getStr(),
441*cdf0e10cSrcweir                             rtl::OUStringToOString(
442*cdf0e10cSrcweir                                 pKeys[nPos]->getKeyName(),
443*cdf0e10cSrcweir                                 RTL_TEXTENCODING_UTF8).getStr());
444*cdf0e10cSrcweir                         break;
445*cdf0e10cSrcweir                     }
446*cdf0e10cSrcweir                     context_values.push_back(
447*cdf0e10cSrcweir                         ContextEntry_Init(
448*cdf0e10cSrcweir                             (rtl::OUString(
449*cdf0e10cSrcweir                                 RTL_CONSTASCII_USTRINGPARAM("/singletons/")) +
450*cdf0e10cSrcweir                              pKeys[nPos]->getKeyName().copy(
451*cdf0e10cSrcweir                                  RTL_CONSTASCII_LENGTH("/SINGLETONS/"))),
452*cdf0e10cSrcweir                             css::uno::makeAny(impls[0]),
453*cdf0e10cSrcweir                             true));
454*cdf0e10cSrcweir                 }
455*cdf0e10cSrcweir             }
456*cdf0e10cSrcweir         }
457*cdf0e10cSrcweir     }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir     // ac, policy:
460*cdf0e10cSrcweir     add_access_control_entries( &context_values, bootstrap );
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir     // smgr singleton
463*cdf0e10cSrcweir     entry.bLateInitService = false;
464*cdf0e10cSrcweir     entry.name = OUSTR("/singletons/com.sun.star.lang.theServiceManager");
465*cdf0e10cSrcweir     entry.value <<= xSF;
466*cdf0e10cSrcweir     context_values.push_back( entry );
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir     Reference< XComponentContext > xContext(
469*cdf0e10cSrcweir         createComponentContext(
470*cdf0e10cSrcweir             &context_values[ 0 ], context_values.size(),
471*cdf0e10cSrcweir             Reference< XComponentContext >() ) );
472*cdf0e10cSrcweir     // set default context
473*cdf0e10cSrcweir     Reference< beans::XPropertySet > xProps( xSF, UNO_QUERY );
474*cdf0e10cSrcweir     OSL_ASSERT( xProps.is() );
475*cdf0e10cSrcweir     if (xProps.is())
476*cdf0e10cSrcweir     {
477*cdf0e10cSrcweir         xProps->setPropertyValue(
478*cdf0e10cSrcweir             OUSTR("DefaultContext"), makeAny( xContext ) );
479*cdf0e10cSrcweir     }
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir     Reference< container::XHierarchicalNameAccess > xTDMgr;
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir     // get tdmgr singleton
484*cdf0e10cSrcweir     if (xContext->getValueByName(
485*cdf0e10cSrcweir             OUSTR("/singletons/"
486*cdf0e10cSrcweir                   "com.sun.star.reflection.theTypeDescriptionManager") )
487*cdf0e10cSrcweir         >>= xTDMgr)
488*cdf0e10cSrcweir     {
489*cdf0e10cSrcweir         if (types_xRegistry.is()) // insert rdb provider?
490*cdf0e10cSrcweir         {
491*cdf0e10cSrcweir             // add registry td provider factory to smgr and instance to tdmgr
492*cdf0e10cSrcweir             Reference< lang::XSingleComponentFactory > xFac(
493*cdf0e10cSrcweir                 loadSharedLibComponentFactory(
494*cdf0e10cSrcweir                     OUSTR("bootstrap.uno" SAL_DLLEXTENSION),
495*cdf0e10cSrcweir                     0 == rBootstrapPath.getLength()
496*cdf0e10cSrcweir                     ? get_this_libpath() : rBootstrapPath,
497*cdf0e10cSrcweir                 OUSTR("com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"),
498*cdf0e10cSrcweir                 Reference< lang::XMultiServiceFactory >( xSF, UNO_QUERY ),
499*cdf0e10cSrcweir                 Reference< registry::XRegistryKey >() ), UNO_QUERY );
500*cdf0e10cSrcweir             OSL_ASSERT( xFac.is() );
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir             // smgr
503*cdf0e10cSrcweir             Reference< container::XSet > xSet( xSF, UNO_QUERY );
504*cdf0e10cSrcweir             xSet->insert( makeAny( xFac ) );
505*cdf0e10cSrcweir             OSL_ENSURE(
506*cdf0e10cSrcweir                 xSet->has( makeAny( xFac ) ),
507*cdf0e10cSrcweir                 "### failed registering registry td provider at smgr!" );
508*cdf0e10cSrcweir             // tdmgr
509*cdf0e10cSrcweir             xSet.set( xTDMgr, UNO_QUERY );
510*cdf0e10cSrcweir             OSL_ASSERT( xSet.is() );
511*cdf0e10cSrcweir             Any types_RDB( makeAny( types_xRegistry ) );
512*cdf0e10cSrcweir             Any rdbtdp( makeAny( xFac->createInstanceWithArgumentsAndContext(
513*cdf0e10cSrcweir                 Sequence< Any >( &types_RDB, 1 ), xContext ) ) );
514*cdf0e10cSrcweir             xSet->insert( rdbtdp );
515*cdf0e10cSrcweir             OSL_ENSURE(
516*cdf0e10cSrcweir                 xSet->has( rdbtdp ),
517*cdf0e10cSrcweir                 "### failed inserting registry td provider to tdmgr!" );
518*cdf0e10cSrcweir         }
519*cdf0e10cSrcweir         // install callback
520*cdf0e10cSrcweir         installTypeDescriptionManager( xTDMgr );
521*cdf0e10cSrcweir     }
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir     return xContext;
524*cdf0e10cSrcweir }
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir static Reference< lang::XMultiComponentFactory > createImplServiceFactory(
527*cdf0e10cSrcweir     const OUString & rWriteRegistry,
528*cdf0e10cSrcweir     const OUString & rReadRegistry,
529*cdf0e10cSrcweir     sal_Bool bReadOnly,
530*cdf0e10cSrcweir     const OUString & rBootstrapPath )
531*cdf0e10cSrcweir     SAL_THROW( (Exception) )
532*cdf0e10cSrcweir {
533*cdf0e10cSrcweir     Reference< lang::XMultiComponentFactory > xSF(
534*cdf0e10cSrcweir         bootstrapInitialSF( rBootstrapPath ) );
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir     Reference< registry::XSimpleRegistry > xRegistry;
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir     // open a registry
539*cdf0e10cSrcweir     sal_Bool bRegistryShouldBeValid = sal_False;
540*cdf0e10cSrcweir     if (rWriteRegistry.getLength() && !rReadRegistry.getLength())
541*cdf0e10cSrcweir     {
542*cdf0e10cSrcweir         bRegistryShouldBeValid = sal_True;
543*cdf0e10cSrcweir         xRegistry.set( createSimpleRegistry( rBootstrapPath ) );
544*cdf0e10cSrcweir         if (xRegistry.is())
545*cdf0e10cSrcweir         {
546*cdf0e10cSrcweir             if (bReadOnly)
547*cdf0e10cSrcweir             {
548*cdf0e10cSrcweir                 xRegistry->open( rWriteRegistry, sal_True, sal_False );
549*cdf0e10cSrcweir             }
550*cdf0e10cSrcweir             else
551*cdf0e10cSrcweir             {
552*cdf0e10cSrcweir                 xRegistry->open( rWriteRegistry, sal_False, sal_True );
553*cdf0e10cSrcweir             }
554*cdf0e10cSrcweir         }
555*cdf0e10cSrcweir     }
556*cdf0e10cSrcweir     else if (rWriteRegistry.getLength() && rReadRegistry.getLength())
557*cdf0e10cSrcweir     {
558*cdf0e10cSrcweir         // default registry
559*cdf0e10cSrcweir         bRegistryShouldBeValid = sal_True;
560*cdf0e10cSrcweir         xRegistry.set( createNestedRegistry( rBootstrapPath ) );
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir         Reference< registry::XSimpleRegistry > xWriteReg(
563*cdf0e10cSrcweir             createSimpleRegistry( rBootstrapPath ) );
564*cdf0e10cSrcweir         if (xWriteReg.is())
565*cdf0e10cSrcweir         {
566*cdf0e10cSrcweir             if (bReadOnly)
567*cdf0e10cSrcweir             {
568*cdf0e10cSrcweir                 try
569*cdf0e10cSrcweir                 {
570*cdf0e10cSrcweir                     xWriteReg->open( rWriteRegistry, sal_True, sal_False );
571*cdf0e10cSrcweir                 }
572*cdf0e10cSrcweir                 catch (registry::InvalidRegistryException &)
573*cdf0e10cSrcweir                 {
574*cdf0e10cSrcweir                 }
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir                 if (! xWriteReg->isValid())
577*cdf0e10cSrcweir                 {
578*cdf0e10cSrcweir                     throw RuntimeException(
579*cdf0e10cSrcweir                         OUSTR("specified first registry "
580*cdf0e10cSrcweir                               "could not be open readonly!"),
581*cdf0e10cSrcweir                         Reference< XInterface >() );
582*cdf0e10cSrcweir                 }
583*cdf0e10cSrcweir             }
584*cdf0e10cSrcweir             else
585*cdf0e10cSrcweir             {
586*cdf0e10cSrcweir                 xWriteReg->open( rWriteRegistry, sal_False, sal_True );
587*cdf0e10cSrcweir             }
588*cdf0e10cSrcweir         }
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir         Reference< registry::XSimpleRegistry > xReadReg(
591*cdf0e10cSrcweir             createSimpleRegistry( rBootstrapPath ) );
592*cdf0e10cSrcweir         if (xReadReg.is())
593*cdf0e10cSrcweir         {
594*cdf0e10cSrcweir             xReadReg->open( rReadRegistry, sal_True, sal_False );
595*cdf0e10cSrcweir         }
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir         Reference< lang::XInitialization > xInit( xRegistry, UNO_QUERY );
598*cdf0e10cSrcweir         Sequence< Any > aInitSeq( 2 );
599*cdf0e10cSrcweir         aInitSeq[ 0 ] <<= xWriteReg;
600*cdf0e10cSrcweir         aInitSeq[ 1 ] <<= xReadReg;
601*cdf0e10cSrcweir         xInit->initialize( aInitSeq );
602*cdf0e10cSrcweir     }
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir     if (bRegistryShouldBeValid && (!xRegistry.is() || !xRegistry->isValid()))
605*cdf0e10cSrcweir     {
606*cdf0e10cSrcweir         throw RuntimeException(
607*cdf0e10cSrcweir             OUSTR("specified registry could not be initialized"),
608*cdf0e10cSrcweir             Reference< XInterface >() );
609*cdf0e10cSrcweir     }
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir     Bootstrap bootstrap;
612*cdf0e10cSrcweir     Reference< XComponentContext > xContext(
613*cdf0e10cSrcweir         bootstrapInitialContext(
614*cdf0e10cSrcweir             xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir     // initialize sf
617*cdf0e10cSrcweir     Reference< lang::XInitialization > xInit( xSF, UNO_QUERY );
618*cdf0e10cSrcweir     OSL_ASSERT( xInit.is() );
619*cdf0e10cSrcweir     Sequence< Any > aSFInit( 1 );
620*cdf0e10cSrcweir     aSFInit[ 0 ] <<= xRegistry;
621*cdf0e10cSrcweir     xInit->initialize( aSFInit );
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir     return xSF;
624*cdf0e10cSrcweir }
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir Reference< lang::XMultiServiceFactory > SAL_CALL createRegistryServiceFactory(
627*cdf0e10cSrcweir     const OUString & rWriteRegistry,
628*cdf0e10cSrcweir     const OUString & rReadRegistry,
629*cdf0e10cSrcweir     sal_Bool bReadOnly,
630*cdf0e10cSrcweir     const OUString & rBootstrapPath )
631*cdf0e10cSrcweir     SAL_THROW( (Exception) )
632*cdf0e10cSrcweir {
633*cdf0e10cSrcweir     return Reference< lang::XMultiServiceFactory >( createImplServiceFactory(
634*cdf0e10cSrcweir         rWriteRegistry, rReadRegistry, bReadOnly, rBootstrapPath ), UNO_QUERY );
635*cdf0e10cSrcweir }
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir Reference< XComponentContext > SAL_CALL bootstrap_InitialComponentContext(
638*cdf0e10cSrcweir     Reference< registry::XSimpleRegistry > const & xRegistry,
639*cdf0e10cSrcweir     OUString const & rBootstrapPath )
640*cdf0e10cSrcweir     SAL_THROW( (Exception) )
641*cdf0e10cSrcweir {
642*cdf0e10cSrcweir     Bootstrap bootstrap;
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir     Reference< lang::XMultiComponentFactory > xSF(
645*cdf0e10cSrcweir         bootstrapInitialSF( rBootstrapPath ) );
646*cdf0e10cSrcweir     Reference< XComponentContext > xContext(
647*cdf0e10cSrcweir         bootstrapInitialContext(
648*cdf0e10cSrcweir             xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir     // initialize sf
651*cdf0e10cSrcweir     Reference< lang::XInitialization > xInit( xSF, UNO_QUERY );
652*cdf0e10cSrcweir     OSL_ASSERT( xInit.is() );
653*cdf0e10cSrcweir     Sequence< Any > aSFInit( 2 );
654*cdf0e10cSrcweir     aSFInit[ 0 ] <<= xRegistry;
655*cdf0e10cSrcweir     aSFInit[ 1 ] <<= xContext; // default context
656*cdf0e10cSrcweir     xInit->initialize( aSFInit );
657*cdf0e10cSrcweir 
658*cdf0e10cSrcweir     return xContext;
659*cdf0e10cSrcweir }
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir }
662