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: backendfactory.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_configmgr.hxx"
34 #include "backendfactory.hxx"
36 #ifndef CONFIGMGR_API_FACTORY_HXX_
37 #include "confapifactory.hxx"
39 #include "bootstrapcontext.hxx"
40 #include "bootstrap.hxx"
41 #include "backendaccess.hxx"
42 #include "serviceinfohelper.hxx"
43 #include "wrapexception.hxx"
46 #include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
47 #include <com/sun/star/configuration/backend/XBackend.hpp>
48 #include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
52 // -------------------------------------------------------------------------
55 // -------------------------------------------------------------------------
56 namespace uno
= ::com::sun::star::uno
;
57 namespace lang
= ::com::sun::star::lang
;
58 namespace backenduno
= ::com::sun::star::configuration::backend
;
59 // -------------------------------------------------------------------------
60 const sal_Char k_DefaultBackendWrapper
[] = "com.sun.star.comp.configuration.backend.SingleBackendAdapter";
61 const sal_Char k_DefaultBackendService
[] = "com.sun.star.comp.configuration.backend.LocalSingleBackend";
63 // -------------------------------------------------------------------------
64 const sal_Char k_DefaultBackendServiceAndImplName
[] = K_DefaultBackendServiceAndImplName
;
66 // -------------------------------------------------------------------------
67 const sal_Char k_GenericBackendServiceAndImplName
[] = "com.sun.star.configuration.backend.Backend" ;
69 // -------------------------------------------------------------------------
70 static sal_Char
const * const k_BackendServiceNames
[] =
72 k_DefaultBackendServiceAndImplName
,
73 k_GenericBackendServiceAndImplName
,
76 // -------------------------------------------------------------------------
77 static const ServiceRegistrationInfo k_DefaultBackendServiceInfo
=
79 k_DefaultBackendServiceAndImplName
,
82 // -------------------------------------------------------------------------
83 static const ServiceRegistrationInfo k_GenericBackendServiceInfo
=
85 k_GenericBackendServiceAndImplName
,
86 k_BackendServiceNames
+ 1
88 // -------------------------------------------------------------------------
89 static const SingletonRegistrationInfo k_DefaultBackendSingletonInfo
=
91 K_DefaultBackendSingletonName
,
92 k_DefaultBackendServiceAndImplName
,
93 k_DefaultBackendServiceAndImplName
,
94 & k_GenericBackendServiceInfo
96 // -------------------------------------------------------------------------
97 // -------------------------------------------------------------------------
98 const SingletonRegistrationInfo
* getDefaultBackendSingletonInfo()
100 return & k_DefaultBackendSingletonInfo
;
102 // -------------------------------------------------------------------------
104 const ServiceRegistrationInfo
* getDefaultBackendServiceInfo()
106 return & k_DefaultBackendServiceInfo
;
108 // -------------------------------------------------------------------------
109 // -------------------------------------------------------------------------
111 uno::Reference
<uno::XInterface
> SAL_CALL
112 getDefaultBackendSingleton( com::sun::star::uno::Reference
< com::sun::star::uno::XComponentContext
> const& xContext
)
114 OSL_ENSURE( xContext
.is(), "ERROR: NULL context has no singletons" );
116 UnoContextTunnel aTunnel
;
117 aTunnel
.passthru( xContext
);
119 uno::Reference
<uno::XInterface
> xResult
;
124 xContext
->getValueByName(SINGLETON(K_DefaultBackendSingletonName
))
127 catch (uno::Exception
& )
129 // to do: really use the tunneled failure when that is set properly
130 if ( aTunnel
.recoverFailure(true).hasValue() )
132 // have a failure, but can't recover it
133 // -> try to regenerate
134 instantiateDefaultBackend(xContext
);
136 OSL_ENSURE(false, "Cannot recreate configuration backend instantiation failure - using generic error");
138 // cannot recover any failure
144 // -------------------------------------------------------------------------
146 // -------------------------------------------------------------------------
147 // -------------------------------------------------------------------------
150 uno::Sequence
< uno::Any
> createInitArgs(ContextReader
const & _aContext
)
152 OSL_ASSERT(_aContext
.hasBootstrapContext());
153 uno::Sequence
< uno::Any
> aResult( 1 );
154 aResult
[0] <<= _aContext
.getBootstrapContext();
157 // -------------------------------------------------------------------------
161 uno::Reference
< uno::XInterface
> createService(ContextReader
const & _aCtx
, uno::Sequence
< uno::Any
> const & _aInitArgs
, rtl::OUString
const & _aSvc
)
163 uno::Reference
< lang::XMultiComponentFactory
> xFactory
= _aCtx
.getServiceManager();
164 OSL_ENSURE(xFactory
.is(),"ERROR: ComponentContext has no service manager\n");
165 if (!xFactory
.is()) throw uno::RuntimeException( rtl::OUString::createFromAscii("ERROR: ComponentContext has no service manager\n"), NULL
);
166 return xFactory
->createInstanceWithArgumentsAndContext( _aSvc
, _aInitArgs
, _aCtx
.getBaseContext());
168 // -------------------------------------------------------------------------
171 uno::Reference
< backenduno::XBackend
> wrapSingleBackend(ContextReader
const & _aSettings
, uno::Sequence
< uno::Any
> const & _aInitArgs
, uno::Reference
< backenduno::XMultiLayerStratum
> const & _xWrappedBackend
)
173 OSL_ASSERT(_aSettings
.hasUnoBackendWrapper() || _aSettings
.hasBootstrapContext());
175 rtl::OUString aWrapperSvc
= _aSettings
.hasUnoBackendWrapper() ?
176 _aSettings
.getUnoBackendWrapper() :
177 rtl::OUString::createFromAscii(k_DefaultBackendWrapper
);
179 OSL_ENSURE (aWrapperSvc
.getLength(), "ERROR: No wrapper service for wrapped configuration");
180 OSL_ENSURE (_xWrappedBackend
.is(), "ERROR: No backend to wrap for wrapped configuration");
182 sal_Int32
const nBaseArgsCount
= _aInitArgs
.getLength();
183 uno::Sequence
< uno::Any
> aExtendedArgs( _aInitArgs
);
184 aExtendedArgs
.realloc( nBaseArgsCount
+ 1 );
185 aExtendedArgs
[nBaseArgsCount
] <<= _xWrappedBackend
;
187 return uno::Reference
< backenduno::XBackend
>::query( createService(_aSettings
,aExtendedArgs
,aWrapperSvc
) );
189 // -------------------------------------------------------------------------
192 uno::Reference
< backenduno::XBackend
> createOfflineBackend(ContextReader
const & _aSettings
, uno::Sequence
< uno::Any
> const & _aInitArgs
)
194 OSL_ASSERT(_aSettings
.hasUnoBackendWrapper() || _aSettings
.hasBootstrapContext());
196 uno::Reference
< backenduno::XBackend
> xResult
;
197 if ( _aSettings
.hasUnoBackendWrapper() )
199 rtl::OUString
const aWrapperSvc
= _aSettings
.getUnoBackendWrapper();
201 xResult
= uno::Reference
< backenduno::XBackend
>::query( createService(_aSettings
,_aInitArgs
,aWrapperSvc
) );
206 // -------------------------------------------------------------------------
209 uno::Reference
< uno::XInterface
> createRealBackend(ContextReader
const & _aSettings
, uno::Sequence
< uno::Any
> const & _aInitArgs
)
211 OSL_ASSERT(_aSettings
.hasUnoBackendService() || _aSettings
.hasBootstrapContext());
213 rtl::OUString
const aBackendServiceName
= _aSettings
.hasUnoBackendService() ?
214 _aSettings
.getUnoBackendService() :
215 rtl::OUString::createFromAscii(k_DefaultBackendService
);
217 uno::Reference
< uno::XInterface
> xResult
=
218 createService(_aSettings
,_aInitArgs
,aBackendServiceName
);
222 // -------------------------------------------------------------------------
225 uno::Reference
< backenduno::XBackend
> createOnlineBackend(ContextReader
const & _aSettings
, uno::Sequence
< uno::Any
> const & _aInitArgs
)
227 OSL_ENSURE( _aSettings
.isUnoBackend(), "ERROR - BackendFactory: For legacy backends use createSessionBackend()");
229 uno::Reference
< backenduno::XBackend
> xResult
;
231 uno::Reference
< uno::XInterface
> xRealBackend
= createRealBackend(_aSettings
,_aInitArgs
);
233 if (_aSettings
.hasUnoBackendWrapper())
235 // try wrapping a single backend
236 uno::Reference
< backenduno::XMultiLayerStratum
> xSingleRealBackend( xRealBackend
, uno::UNO_QUERY
);
237 if (xSingleRealBackend
.is())
238 xResult
= wrapSingleBackend(_aSettings
,_aInitArgs
,xSingleRealBackend
);
240 // if we don't have one, try using it as unwrapped backend
242 xResult
.set(xRealBackend
, uno::UNO_QUERY
);
246 // look for a direct implementation of XBackend
247 xResult
.set(xRealBackend
, uno::UNO_QUERY
);
250 // try the default wrapper if we only have a single backend
251 uno::Reference
< backenduno::XMultiLayerStratum
> xSingleRealBackend( xRealBackend
, uno::UNO_QUERY
);
252 if (xSingleRealBackend
.is())
253 xResult
= wrapSingleBackend(_aSettings
,_aInitArgs
,xSingleRealBackend
);
256 OSL_ENSURE( !xRealBackend
.is(), "Configuration Backend implements no known backend interface" );
262 // -------------------------------------------------------------------------
264 static uno::Reference
< backenduno::XBackend
> createUnoBackend(com::sun::star::uno::Reference
< com::sun::star::uno::XComponentContext
> const& _xCtx
)
266 ContextReader
aSettings(_xCtx
);
267 OSL_ENSURE( aSettings
.isUnoBackend(), "ERROR - BackendFactory: Legacy backends are not supported any more");
269 uno::Sequence
< uno::Any
> aArguments
= createInitArgs(aSettings
);
271 sal_Bool bOffline
= aSettings
.hasOfflineSetting() ? aSettings
.getOfflineSetting() : !aSettings
.hasUnoBackendService();
273 uno::Reference
< backenduno::XBackend
> xResult
;
276 xResult
= createOnlineBackend (aSettings
,aArguments
);
279 xResult
= createOfflineBackend(aSettings
,aArguments
);
283 // -------------------------------------------------------------------------
284 // to do: tunnel and raise fully typed exception information (and use it in the get..Singleton wrappers)
285 #define TUNNEL_ALL_EXCEPTIONS() \
286 WRAP_CONFIGBACKEND_CREATION_EXCEPTIONS1( UnoContextTunnel::tunnelFailure, true )
288 // -------------------------------------------------------------------------
290 uno::Reference
<uno::XInterface
> SAL_CALL
instantiateDefaultBackend( com::sun::star::uno::Reference
< com::sun::star::uno::XComponentContext
> const& xTargetContext
)
292 com::sun::star::uno::Reference
< com::sun::star::uno::XComponentContext
> xContext
= UnoContextTunnel::recoverContext(xTargetContext
);
296 return uno::Reference
< uno::XInterface
>( createUnoBackend(xContext
), uno::UNO_QUERY
);
298 TUNNEL_ALL_EXCEPTIONS()
300 OSL_ASSERT(!"unreached");
303 // -------------------------------------------------------------------------
305 uno::Reference
< backenduno::XBackend
> BackendFactory::getUnoBackend()
307 return uno::Reference
< backenduno::XBackend
>::query( getDefaultBackendSingleton(m_xCtx
) );
309 // -------------------------------------------------------------------------
311 rtl::Reference
<IMergedDataProvider
> BackendFactory::createBackend()
313 rtl::Reference
< IMergedDataProvider
> xBackend
;
315 uno::Reference
< backenduno::XBackend
> xBackendService
= this->getUnoBackend();
317 if (xBackendService
.is())
318 xBackend
= new BackendAccess(xBackendService
, m_xCtx
);
322 // -------------------------------------------------------------------------
324 BackendFactory
BackendFactory::instance(com::sun::star::uno::Reference
< com::sun::star::uno::XComponentContext
> const & _xCtx
)
326 return BackendFactory(_xCtx
);
329 //-----------------------------------------------------------------------------
331 //-----------------------------------------------------------------------------