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: bootstrapcontext.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 "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"
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 // ---------------------------------------------------------------------------
58 static void testComplete()
60 uno::Reference
< uno::XInterface
> test
= * new ComponentContext(uno::Reference
< uno::XComponentContext
>,uno::Sequence
< beans::NamedValue
>(),true);
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
)
72 // ---------------------------------------------------------------------------
74 ComponentContext::~ComponentContext()
76 if (m_hBootstrapData
) rtl_bootstrap_args_close(m_hBootstrapData
);
78 // ---------------------------------------------------------------------------
80 void ComponentContext::initialize( const rtl::OUString
& _aURL
)
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);
93 OSL_ENSURE(rBHelper
.bDisposed
,"ComponentContext::initialize - Context unexpectedly missing");
94 throw lang::DisposedException(OUSTR("Parent context has been disposed early"),*this);
97 // ---------------------------------------------------------------------------
100 void SAL_CALL
ComponentContext::disposing()
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
;
120 if (m_hBootstrapData
)
122 rtl_bootstrap_get_iniName_from_handle(m_hBootstrapData
,&aResult
.pData
);
126 OSL_TRACE( "configmgr: No bootstrap data URL set");
131 // ---------------------------------------------------------------------------
133 uno::Reference
< lang::XMultiComponentFactory
> SAL_CALL
134 ComponentContext::getServiceManager( )
135 throw (uno::RuntimeException
)
139 if (!m_xServiceManager
.is())
141 uno::Reference
< uno::XComponentContext
> xBase
= basecontext();
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
),
154 // patch DefaultContext property of new one
155 uno::Reference
< beans::XPropertySet
> xProps( m_xServiceManager
, uno::UNO_QUERY
);
156 OSL_ASSERT( xProps
.is() );
159 uno::Reference
< XComponentContext
> xThis( this );
160 xProps
->setPropertyValue( OUSTR("DefaultContext"), uno::makeAny( xThis
) );
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
;
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();
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
);
202 uno::Any aCtxValue
= xBase
->getValueByName( _aName
);
204 if (aCtxValue
.hasValue())
212 // ---------------------------------------------------------------------------
214 bool ComponentContext::lookupInBootstrap( uno::Any
& _rValue
, const rtl::OUString
& _aName
) const
217 rtl::OUString sResult
;
218 if ( rtl_bootstrap_get_from_handle( m_hBootstrapData
, _aName
.pData
, &sResult
.pData
, 0) )
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
;
238 Tunnel(uno::Reference
< uno::XComponentContext
> const & xTunneledContext
, uno::Reference
< uno::XCurrentContext
> const & xOldContext
)
239 : m_xTunneledContext(xTunneledContext
)
240 , m_xOldContext(xOldContext
)
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
);
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
);
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
)
289 if (sal_Int64 nSomething
= xTunnel
->getSomething(getTunnelId()))
291 return reinterpret_cast<uno::Any
*>(nSomething
);
296 // ---------------------------------------------------------------------------
298 UnoContextTunnel::UnoContextTunnel()
299 : m_xOldContext( uno::getCurrentContext() )
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
);
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
)
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");
363 // ---------------------------------------------------------------------------
365 uno::Any
UnoContextTunnel::recoverFailure(bool bRaise
)
367 if (uno::Any
* pFail
= UnoContextTunnel::Tunnel::getFailure(m_xActiveTunnel
))
371 if (pFail
->hasValue())
372 cppu::throwException(*pFail
);
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
))
393 if (bRaise
&& aException
.hasValue())
394 cppu::throwException(aException
);
405 // ---------------------------------------------------------------------------
406 // ---------------------------------------------------------------------------
407 void DisposingForwarder::disposing( lang::EventObject
const & /*rSource*/ )
408 throw (uno::RuntimeException
)
410 m_xTarget
->dispose();
413 // ---------------------------------------------------------------------------
414 // ---------------------------------------------------------------------------
415 } // namespace config