Update ooo320-m1
[ooovba.git] / configmgr / source / backend / backendfactory.cxx
blobeda39e38efc933d19122f01a23c7fa458a3348f9
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: backendfactory.cxx,v $
10 * $Revision: 1.12 $
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"
38 #endif
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>
50 namespace configmgr
52 // -------------------------------------------------------------------------
53 namespace backend
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,
80 k_BackendServiceNames
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;
121 if (xContext.is())
124 xContext->getValueByName(SINGLETON(K_DefaultBackendSingletonName))
125 >>= xResult;
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
139 throw;
142 return xResult;
144 // -------------------------------------------------------------------------
146 // -------------------------------------------------------------------------
147 // -------------------------------------------------------------------------
149 static
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();
155 return aResult;
157 // -------------------------------------------------------------------------
159 static
160 inline
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 // -------------------------------------------------------------------------
170 static
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 // -------------------------------------------------------------------------
191 static
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) );
204 return xResult;
206 // -------------------------------------------------------------------------
208 static
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);
220 return xResult;
222 // -------------------------------------------------------------------------
224 static
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
241 else
242 xResult.set(xRealBackend, uno::UNO_QUERY);
244 else
246 // look for a direct implementation of XBackend
247 xResult.set(xRealBackend, uno::UNO_QUERY);
248 if (!xResult.is())
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);
255 else
256 OSL_ENSURE( !xRealBackend.is(), "Configuration Backend implements no known backend interface" );
260 return xResult;
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;
275 if (!bOffline)
276 xResult = createOnlineBackend (aSettings,aArguments);
278 if (!xResult.is())
279 xResult = createOfflineBackend(aSettings,aArguments);
281 return xResult;
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");
301 return NULL;
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);
320 return xBackend;
322 // -------------------------------------------------------------------------
324 BackendFactory BackendFactory::instance(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & _xCtx)
326 return BackendFactory(_xCtx);
329 //-----------------------------------------------------------------------------
330 } // namespace
331 //-----------------------------------------------------------------------------
332 } // namespace