Update ooo320-m1
[ooovba.git] / configmgr / source / misc / bootstrapcontext.cxx
blob5bd281f97937ec50fea3bda1696f696afd398f45
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: bootstrapcontext.cxx,v $
10 * $Revision: 1.9 $
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 "bootstrapcontext.hxx"
35 #include "datalock.hxx"
36 #include <uno/current_context.hxx>
37 #include <cppuhelper/implbase2.hxx>
38 #include <cppuhelper/exc_hlp.hxx>
39 #include <cppuhelper/typeprovider.hxx>
40 #include <com/sun/star/uno/XComponentContext.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/lang/DisposedException.hpp>
43 #include "utility.hxx"
45 namespace configmgr
47 // ---------------------------------------------------------------------------
48 #define IMPL_ITEM_PREFIX_ "/implementations/com.sun.star.com.configuration.bootstrap.ComponentContext/"
49 #define IMPL_ITEM_PASSTHRU IMPL_ITEM_PREFIX_"isPassthrough"
50 #define IMPL_ITEM_BASECONTEXT IMPL_ITEM_PREFIX_"theBaseContext"
51 #define A_SERVICEMANAGER "com.sun.star.lang.theServiceManager"
52 // ---------------------------------------------------------------------------
54 #define OUSTR( text ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( text ) )
55 #define OU2ASCII( str ) ( rtl::OUStringToOString(str,RTL_TEXTENCODING_ASCII_US) .getStr() )
56 // ---------------------------------------------------------------------------
57 #if 0
58 static void testComplete()
60 uno::Reference< uno::XInterface > test = * new ComponentContext(uno::Reference< uno::XComponentContext >,uno::Sequence < beans::NamedValue >(),true);
62 #endif
63 // ---------------------------------------------------------------------------
65 ComponentContext::ComponentContext(uno::Reference< uno::XComponentContext > const & _xContext)
66 : cppu::WeakComponentImplHelper3 < uno::XComponentContext, uno::XCurrentContext, lang::XServiceInfo >(UnoApiLock::getLock())
67 , m_xContext(_xContext)
68 , m_hBootstrapData(NULL)
69 , m_xServiceManager()
72 // ---------------------------------------------------------------------------
74 ComponentContext::~ComponentContext()
76 if (m_hBootstrapData) rtl_bootstrap_args_close(m_hBootstrapData);
78 // ---------------------------------------------------------------------------
80 void ComponentContext::initialize( const rtl::OUString& _aURL )
82 UnoApiLock aLock;
84 OSL_ASSERT(!m_hBootstrapData);
85 m_hBootstrapData = rtl_bootstrap_args_open(_aURL.pData);
87 uno::Reference< lang::XComponent > xOwner(m_xContext, uno::UNO_QUERY);
89 if (xOwner.is()) DisposingForwarder::forward(xOwner,this);
91 if (!m_xContext.is())
93 OSL_ENSURE(rBHelper.bDisposed,"ComponentContext::initialize - Context unexpectedly missing");
94 throw lang::DisposedException(OUSTR("Parent context has been disposed early"),*this);
97 // ---------------------------------------------------------------------------
99 // ComponentHelper
100 void SAL_CALL ComponentContext::disposing()
102 UnoApiLock aLock;
104 m_xContext.clear();
106 if (m_hBootstrapData)
108 rtl_bootstrap_args_close(m_hBootstrapData);
109 m_hBootstrapData = NULL;
112 // ---------------------------------------------------------------------------
114 rtl::OUString ComponentContext::getBootstrapURL() const
116 rtl::OUString aResult;
118 UnoApiLock aLock;
120 if (m_hBootstrapData)
122 rtl_bootstrap_get_iniName_from_handle(m_hBootstrapData,&aResult.pData);
124 else
126 OSL_TRACE( "configmgr: No bootstrap data URL set");
129 return aResult;
131 // ---------------------------------------------------------------------------
133 uno::Reference< lang::XMultiComponentFactory > SAL_CALL
134 ComponentContext::getServiceManager( )
135 throw (uno::RuntimeException)
137 UnoApiLock aLock;
139 if (!m_xServiceManager.is())
141 uno::Reference< uno::XComponentContext > xBase = basecontext();
142 if (!xBase.is())
143 throw lang::DisposedException(OUSTR("Parent context has been disposed"),*this);
145 uno::Reference< lang::XMultiComponentFactory > xBaseServiceManager = xBase->getServiceManager();
146 OSL_ENSURE( xBaseServiceManager.is(), "Base context has no service manager");
148 if (xBaseServiceManager.is())
150 // create new smgr based on delegate's one
151 m_xServiceManager.set(
152 xBaseServiceManager->createInstanceWithContext( OUSTR("com.sun.star.comp.stoc.OServiceManagerWrapper"), xBase ),
153 uno::UNO_QUERY );
154 // patch DefaultContext property of new one
155 uno::Reference< beans::XPropertySet > xProps( m_xServiceManager, uno::UNO_QUERY );
156 OSL_ASSERT( xProps.is() );
157 if (xProps.is())
159 uno::Reference< XComponentContext > xThis( this );
160 xProps->setPropertyValue( OUSTR("DefaultContext"), uno::makeAny( xThis ) );
162 else
163 OSL_ENSURE(!m_xServiceManager.is(), "Cannot set Default Context of Service Manager Wrapper: no property set");
166 return m_xServiceManager;
168 // ---------------------------------------------------------------------------
171 // ---------------------------------------------------------------------------
173 sal_Bool ComponentContext::isPassthrough(uno::Reference< uno::XComponentContext > const & _xContext)
175 OSL_ENSURE(_xContext.is(),"Unexpected NULL context");
176 if (!_xContext.is()) return false;
178 sal_Bool bValue = false;
179 _xContext->getValueByName(OUSTR(IMPL_ITEM_PASSTHRU)) >>= bValue;
180 return bValue;
182 // ---------------------------------------------------------------------------
184 beans::NamedValue ComponentContext::makePassthroughMarker(sal_Bool bPassthrough)
186 return beans::NamedValue(OUSTR(IMPL_ITEM_PASSTHRU),uno::makeAny(bPassthrough));
188 // ---------------------------------------------------------------------------
190 bool ComponentContext::lookupInContext( uno::Any & _rValue, const rtl::OUString& _aName ) const
192 uno::Reference< uno::XComponentContext > xBase = basecontext();
193 if (!xBase.is())
194 throw lang::DisposedException(OUSTR("Parent context has been disposed"),const_cast<ComponentContext&>(*this));
196 if (_aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( IMPL_ITEM_BASECONTEXT )))
198 _rValue = uno::makeAny(xBase);
199 return true;
202 uno::Any aCtxValue = xBase->getValueByName( _aName );
204 if (aCtxValue.hasValue())
206 _rValue = aCtxValue;
207 return true;
209 else
210 return false;
212 // ---------------------------------------------------------------------------
214 bool ComponentContext::lookupInBootstrap( uno::Any & _rValue, const rtl::OUString& _aName ) const
216 UnoApiLock aLock;
217 rtl::OUString sResult;
218 if ( rtl_bootstrap_get_from_handle( m_hBootstrapData, _aName.pData, &sResult.pData, 0) )
220 _rValue <<= sResult;
221 return true;
223 else
224 return false;
226 // ---------------------------------------------------------------------------
227 // ---------------------------------------------------------------------------
229 static const char k_TunneledContext[] = "/services/com.sun.star.configuration.bootstrap.Context";
231 class UnoContextTunnel::Tunnel
232 : public ::cppu::WeakImplHelper2< uno::XCurrentContext, lang::XUnoTunnel >
234 uno::Reference< uno::XComponentContext > m_xTunneledContext;
235 uno::Reference< uno::XCurrentContext > m_xOldContext;
236 uno::Any m_aFailure;
237 public:
238 Tunnel(uno::Reference< uno::XComponentContext > const & xTunneledContext, uno::Reference< uno::XCurrentContext > const & xOldContext)
239 : m_xTunneledContext(xTunneledContext)
240 , m_xOldContext(xOldContext)
241 , m_aFailure()
244 virtual uno::Any SAL_CALL
245 getValueByName( const rtl::OUString& name )
246 throw (uno::RuntimeException)
248 if (name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(k_TunneledContext) ) )
250 return uno::makeAny(m_xTunneledContext);
252 else if (m_xOldContext.is())
254 return m_xOldContext->getValueByName(name);
256 else
258 return uno::Any();
262 virtual sal_Int64 SAL_CALL
263 getSomething( const uno::Sequence< sal_Int8 >& aIdentifier )
264 throw (uno::RuntimeException)
266 if (getTunnelId() == aIdentifier)
267 return reinterpret_cast<sal_Int64>(&m_aFailure);
268 else
269 return 0;
272 static uno::Any * getFailure(uno::Reference< lang::XUnoTunnel > const & xTunnel);
274 static uno::Sequence< sal_Int8 > getTunnelId();
276 // ---------------------------------------------------------------------------
278 uno::Sequence< sal_Int8 > UnoContextTunnel::Tunnel::getTunnelId()
280 static ::cppu::OImplementationId aTunnelId;
281 return aTunnelId.getImplementationId();
283 // ---------------------------------------------------------------------------
285 uno::Any * UnoContextTunnel::Tunnel::getFailure(uno::Reference< lang::XUnoTunnel > const & xTunnel)
287 if (xTunnel.is())
289 if (sal_Int64 nSomething = xTunnel->getSomething(getTunnelId()))
291 return reinterpret_cast<uno::Any *>(nSomething);
294 return NULL;
296 // ---------------------------------------------------------------------------
298 UnoContextTunnel::UnoContextTunnel()
299 : m_xOldContext( uno::getCurrentContext() )
300 , m_xActiveTunnel()
303 // ---------------------------------------------------------------------------
305 UnoContextTunnel::~UnoContextTunnel()
307 uno::setCurrentContext( m_xOldContext );
309 // ---------------------------------------------------------------------------
311 void UnoContextTunnel::passthru(uno::Reference< uno::XComponentContext > const & xContext)
313 OSL_ASSERT( xContext.is() );
314 if ( ComponentContext::isPassthrough(xContext) )
316 this ->tunnel(xContext);
318 else
320 this->tunnel(NULL);
323 // ---------------------------------------------------------------------------
325 void UnoContextTunnel::tunnel(uno::Reference< uno::XComponentContext > const & xContext)
327 Tunnel * pNewTunnel = new Tunnel(xContext,m_xOldContext);
328 m_xActiveTunnel = pNewTunnel;
329 uno::setCurrentContext( pNewTunnel );
331 // ---------------------------------------------------------------------------
333 uno::Reference< uno::XComponentContext > UnoContextTunnel::recoverContext(uno::Reference< uno::XComponentContext > const & xFallback )
337 uno::Reference< uno::XCurrentContext > const xCurrContext = uno::getCurrentContext();
339 if (xCurrContext.is())
341 rtl::OUString aName(RTL_CONSTASCII_USTRINGPARAM(k_TunneledContext));
342 uno::Reference< uno::XComponentContext > xResult;
343 if (xCurrContext->getValueByName(aName) >>= xResult)
345 if (xResult.is())
346 return xResult;
348 else
350 OSL_ASSERT( !xResult.is() );
351 OSL_ENSURE( !xCurrContext->getValueByName(aName).hasValue(),
352 "Value in context has wrong type");
356 catch (uno::Exception &)
358 OSL_ENSURE(false, "Unexpected: Exception from accessing current context");
361 return xFallback;
363 // ---------------------------------------------------------------------------
365 uno::Any UnoContextTunnel::recoverFailure(bool bRaise)
367 if (uno::Any * pFail = UnoContextTunnel::Tunnel::getFailure(m_xActiveTunnel))
369 if (bRaise)
371 if (pFail->hasValue())
372 cppu::throwException(*pFail);
373 else
374 throw;
376 return *pFail;
379 return uno::Any();
381 // ---------------------------------------------------------------------------
383 bool UnoContextTunnel::tunnelFailure(uno::Any const & aException, bool bRaise)
385 OSL_ASSERT( !aException.hasValue() || aException.getValueTypeClass() == uno::TypeClass_EXCEPTION );
387 uno::Reference< lang::XUnoTunnel > xTunnel( uno::getCurrentContext(), uno::UNO_QUERY );
389 if (uno::Any * pFail = Tunnel::getFailure(xTunnel))
391 *pFail = aException;
393 if (bRaise && aException.hasValue())
394 cppu::throwException(aException);
396 if (bRaise) throw;
397 return true;
399 else
401 if (bRaise) throw;
402 return false;
405 // ---------------------------------------------------------------------------
406 // ---------------------------------------------------------------------------
407 void DisposingForwarder::disposing( lang::EventObject const & /*rSource*/ )
408 throw (uno::RuntimeException)
410 m_xTarget->dispose();
411 m_xTarget.clear();
413 // ---------------------------------------------------------------------------
414 // ---------------------------------------------------------------------------
415 } // namespace config