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: remote_bridge.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 ************************************************************************/
32 #include "remote_bridge.hxx"
33 #include "bridge_connection.hxx"
34 #include <cppuhelper/implementationentry.hxx>
36 #include <com/sun/star/lang/IllegalArgumentException.hpp>
37 #include <com/sun/star/bridge/BridgeExistsException.hpp>
39 #define IMPLEMENTATION_NAME "com.sun.star.comp.remotebridges.Bridge.various"
42 using namespace ::rtl
;
43 using namespace ::cppu
;
44 using namespace ::osl
;
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::lang
;
47 using namespace ::com::sun::star::bridge
;
48 using namespace ::com::sun::star::registry
;
49 using namespace ::com::sun::star::connection
;
51 namespace remotebridges_bridge
53 rtl_StandardModuleCount g_moduleCount
= MODULE_COUNT_INIT
;
55 ORemoteBridge::ORemoteBridge() :
56 OComponentHelper( m_mutex
),
60 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
61 remote_DisposingListener::acquire
= thisAcquire
;
62 remote_DisposingListener::release
= thisRelease
;
63 remote_DisposingListener::disposing
= thisDisposing
;
66 ORemoteBridge::~ORemoteBridge()
70 m_pContext
->aBase
.release( (uno_Context
*) m_pContext
);
74 m_pEnvRemote
->release( m_pEnvRemote
);
76 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
79 void ORemoteBridge::objectMappedSuccesfully()
81 MutexGuard
guard( m_mutex
);
85 m_pEnvRemote
->release( m_pEnvRemote
);
90 Any
ORemoteBridge::queryInterface( const Type
& aType
) throw(RuntimeException
)
92 Any a
= ::cppu::queryInterface(
94 SAL_STATIC_CAST( XInitialization
* , this ) ,
95 SAL_STATIC_CAST( XBridge
* , this ),
96 SAL_STATIC_CAST( XTypeProvider
* , this ) );
102 return OComponentHelper::queryInterface( aType
);
106 void ORemoteBridge::initialize( const Sequence
< Any
>& aArguments
)
107 throw( Exception
, RuntimeException
)
110 MutexGuard
guard( m_mutex
);
112 if( 4 != aArguments
.getLength() )
114 throw IllegalArgumentException( rtl::OUString::createFromAscii("wrong number of arguments") ,
115 Reference
< XInterface
>(),
121 Reference
< XConnection
> rConnection
;
122 Reference
< XInstanceProvider
> rProvider
;
124 aArguments
.getConstArray()[0] >>= swName
;
125 aArguments
.getConstArray()[1] >>= swProtocol
;
126 aArguments
.getConstArray()[2] >>= rConnection
;
127 aArguments
.getConstArray()[3] >>= rProvider
;
129 if( ! rConnection
.is() )
131 throw IllegalArgumentException( rtl::OUString::createFromAscii("connection is missing") ,
132 Reference
< XInterface
> (),
136 remote_Connection
*pConnection
= new OConnectionWrapper( rConnection
);
137 remote_InstanceProvider
*pProvider
= 0;
140 pProvider
= new OInstanceProviderWrapper( rProvider
, this );
143 OUString sName
= swName
;
144 m_sDescription
= swProtocol
;
145 m_sDescription
+= OUString( RTL_CONSTASCII_USTRINGPARAM(":"));
146 m_sDescription
+= rConnection
->getDescription();
148 if( 0 == sName
.getLength() )
150 sName
= m_sDescription
;
157 m_pContext
= remote_createContext( pConnection
,
159 m_sDescription
.pData
,
164 throw BridgeExistsException();
167 m_pContext
->addDisposingListener( m_pContext
,
168 (remote_DisposingListener
*) this );
170 // environment will be released by the first succesfull mapping
172 if( swProtocol
.indexOf( ',') == -1 )
174 sRemoteEnv
= swProtocol
;
178 sRemoteEnv
= swProtocol
.copy( 0 , swProtocol
.indexOf( ',' ) );
180 m_sProtocol
= sRemoteEnv
;
181 uno_getEnvironment( &m_pEnvRemote
,
186 m_pContext
->removeDisposingListener( m_pContext
,
187 (remote_DisposingListener
*) this );
188 m_pContext
->aBase
.release( (uno_Context
* ) m_pContext
);
191 // forgotten exception when specifying the interface
192 throw RuntimeException( rtl::OUString::createFromAscii("couldn't create uno-remote-environment") ,
193 Reference
< XInterface
> () );
197 Reference
< XInterface
> ORemoteBridge::getInstance( const ::rtl::OUString
& sInstanceName
)
198 throw(::com::sun::star::uno::RuntimeException
)
200 Reference
< XInterface
> rReturn
;
202 remote_Context
*pContext
= 0;
204 MutexGuard
guard( m_mutex
);
205 if( m_pContext
&& m_pContext
->getRemoteInstance
)
207 pContext
= m_pContext
;
208 pContext
->aBase
.acquire( (uno_Context
*)pContext
);
213 // get the appropriate remote environment
214 uno_Environment
*pEnvRemote
= 0;
215 uno_getEnvironment( &pEnvRemote
, m_sProtocol
.pData
, pContext
);
219 pContext
->aBase
.release( (uno_Context
*) pContext
);
220 throw RuntimeException(
221 OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed" ) ),
222 Reference
< XInterface
> () );
225 Type type
= getCppuType( (Reference
< XInterface
> * ) 0 );
227 remote_Interface
*pRemoteI
= 0;
229 uno_Any
*pException
= &exception
;
231 pContext
->getRemoteInstance(
235 type
.getTypeLibType(),
237 pContext
->aBase
.release( (uno_Context
*) pContext
);
240 uno_Environment
*pEnvCpp
=0;
241 OUString
sCppuName( RTL_CONSTASCII_USTRINGPARAM( CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
242 uno_getEnvironment( &pEnvCpp
,
245 Mapping
map( pEnvRemote
, pEnvCpp
);
247 pEnvCpp
->release( pEnvCpp
);
248 pEnvRemote
->release( pEnvRemote
);
252 typelib_CompoundTypeDescription
* pCompType
= 0 ;
253 getCppuType( (Exception
*)0 ).getDescription( (typelib_TypeDescription
**) &pCompType
);
255 if( ! ((typelib_TypeDescription
*)pCompType
)->bComplete
)
257 typelib_typedescription_complete( (typelib_TypeDescription
**) &pCompType
);
259 XInterface
*pXInterface
= (XInterface
*) map
.mapInterface(
260 *(remote_Interface
**) ( ((char*)pException
->pData
)+pCompType
->pMemberOffsets
[1] ),
261 getCppuType( (Reference
< XInterface
> *)0 ) );
262 RuntimeException
myException(
263 *((rtl_uString
**)pException
->pData
),
264 Reference
< XInterface
> ( pXInterface
, SAL_NO_ACQUIRE
) );
265 uno_any_destruct( pException
, 0 );
271 // got an interface !
272 XInterface
* pCppI
= ( XInterface
* ) map
.mapInterface( pRemoteI
, type
);
273 rReturn
= Reference
<XInterface
> ( pCppI
, SAL_NO_ACQUIRE
);
274 pRemoteI
->release( pRemoteI
);
275 objectMappedSuccesfully();
280 throw RuntimeException(
281 OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed." ) ),
282 Reference
< XInterface
> () );
289 ::rtl::OUString SAL_CALL
ORemoteBridge::getName( )
290 throw(::com::sun::star::uno::RuntimeException
)
295 ::rtl::OUString SAL_CALL
ORemoteBridge::getDescription( )
296 throw(::com::sun::star::uno::RuntimeException
)
298 return m_sDescription
;
302 Sequence
< Type
> SAL_CALL
ORemoteBridge::getTypes(void) throw( RuntimeException
)
304 static OTypeCollection
*pCollection
= 0;
307 MutexGuard
guard( Mutex::getGlobalMutex() );
310 static OTypeCollection
collection(
311 getCppuType( (Reference
< XTypeProvider
> * )0),
312 getCppuType( (Reference
< XBridge
> * ) 0 ),
313 getCppuType( (Reference
< XInitialization
> * ) 0 ),
314 OComponentHelper::getTypes() );
315 pCollection
= &collection
;
319 return (*pCollection
).getTypes();
322 Sequence
< sal_Int8
> SAL_CALL
ORemoteBridge::getImplementationId( ) throw( RuntimeException
)
324 static OImplementationId
*pId
= 0;
327 MutexGuard
guard( Mutex::getGlobalMutex() );
330 static OImplementationId
id( sal_False
);
334 return (*pId
).getImplementationId();
337 void ORemoteBridge::disposing()
339 MutexGuard
guard( m_mutex
);
342 m_pContext
->removeDisposingListener( m_pContext
, ( remote_DisposingListener
* )this);
345 if( m_pContext
->m_pConnection
)
347 sal_Int32 nIndex
= 0;
348 OUString sProtocol
= OUString( m_pContext
->m_pProtocol
).getToken( 0 , ',' , nIndex
);
349 uno_getEnvironment( &m_pEnvRemote
, sProtocol
.pData
, m_pContext
);
350 OSL_ASSERT( m_pEnvRemote
);
354 // within disposing from the context, no further dispose necessary !
360 m_pEnvRemote
->dispose( m_pEnvRemote
);
361 m_pEnvRemote
->release( m_pEnvRemote
);
365 m_pContext
->aBase
.release( (uno_Context
*)m_pContext
);
371 //----------------------
373 //----------------------
374 void ORemoteBridge::thisAcquire( remote_DisposingListener
*p
)
376 ORemoteBridge
*m
= (ORemoteBridge
* ) p
;
380 void ORemoteBridge::thisRelease( remote_DisposingListener
*p
)
382 ORemoteBridge
*m
= (ORemoteBridge
* ) p
;
386 void ORemoteBridge::thisDisposing( remote_DisposingListener
* p
,
389 ORemoteBridge
*m
= (ORemoteBridge
* ) p
;
393 //---------------------------------
395 //---------------------------------
396 Reference
< XInterface
> SAL_CALL
CreateInstance( const Reference
< XComponentContext
> &)
398 return Reference
< XInterface
> ( ( OWeakObject
* ) new ORemoteBridge
);
401 OUString
getImplementationName()
403 static OUString
*pImplName
= 0;
406 MutexGuard
guard( Mutex::getGlobalMutex() );
409 static OUString
implName(
410 RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME
) );
411 pImplName
= &implName
;
417 Sequence
< OUString
> getSupportedServiceNames()
419 static Sequence
< OUString
> *pNames
= 0;
422 MutexGuard
guard( Mutex::getGlobalMutex() );
425 static Sequence
< OUString
> seqNames(3);
426 seqNames
.getArray()[0] = OUString::createFromAscii( "com.sun.star.bridge.Bridge" );
427 seqNames
.getArray()[1] = OUString::createFromAscii( "com.sun.star.bridge.IiopBridge" );
428 seqNames
.getArray()[2] = OUString::createFromAscii( "com.sun.star.bridge.UrpBridge" );
437 using namespace remotebridges_bridge
;
439 static struct ImplementationEntry g_entries
[] =
442 remotebridges_bridge::CreateInstance
, remotebridges_bridge::getImplementationName
,
443 remotebridges_bridge::getSupportedServiceNames
, createSingleComponentFactory
,
444 &g_moduleCount
.modCnt
, 0
451 sal_Bool SAL_CALL
component_canUnload( TimeValue
*pTime
)
453 return g_moduleCount
.canUnload( &g_moduleCount
, pTime
);
456 //==================================================================================================
457 void SAL_CALL
component_getImplementationEnvironment(
458 const sal_Char
** ppEnvTypeName
, uno_Environment
** )
460 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
462 //==================================================================================================
463 sal_Bool SAL_CALL
component_writeInfo(
464 void * pServiceManager
, void * pRegistryKey
)
466 return component_writeInfoHelper( pServiceManager
, pRegistryKey
, g_entries
);
468 //==================================================================================================
469 void * SAL_CALL
component_getFactory(
470 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
472 return component_getFactoryHelper( pImplName
, pServiceManager
, pRegistryKey
, g_entries
);