Update ooo320-m1
[ooovba.git] / remotebridges / source / bridge / remote_bridge.cxx
blobcde002a31cc815577827b498eede5f1a7c6bd125
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: remote_bridge.cxx,v $
10 * $Revision: 1.11 $
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 ************************************************************************/
30 #include <stdio.h>
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 ),
57 m_pContext( 0 ),
58 m_pEnvRemote(0 )
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()
68 if( m_pContext )
70 m_pContext->aBase.release( (uno_Context *) m_pContext );
72 if( m_pEnvRemote )
74 m_pEnvRemote->release( m_pEnvRemote );
76 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
79 void ORemoteBridge::objectMappedSuccesfully()
81 MutexGuard guard( m_mutex );
83 if( m_pEnvRemote )
85 m_pEnvRemote->release( m_pEnvRemote );
86 m_pEnvRemote = 0;
90 Any ORemoteBridge::queryInterface( const Type & aType ) throw(RuntimeException)
92 Any a = ::cppu::queryInterface(
93 aType ,
94 SAL_STATIC_CAST( XInitialization * , this ) ,
95 SAL_STATIC_CAST( XBridge * , this ),
96 SAL_STATIC_CAST( XTypeProvider * , this ) );
97 if( a.hasValue() )
99 return a;
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 >(),
116 0 );
119 OUString swName;
120 OUString swProtocol;
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 > (),
133 2 );
136 remote_Connection *pConnection = new OConnectionWrapper( rConnection );
137 remote_InstanceProvider *pProvider = 0;
138 if( rProvider.is( ))
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;
152 else
154 m_sName = sName;
157 m_pContext = remote_createContext( pConnection,
158 sName.pData,
159 m_sDescription.pData,
160 swProtocol.pData,
161 pProvider );
162 if( ! m_pContext )
164 throw BridgeExistsException();
167 m_pContext->addDisposingListener( m_pContext ,
168 (remote_DisposingListener *) this );
170 // environment will be released by the first succesfull mapping
171 OUString sRemoteEnv;
172 if( swProtocol.indexOf( ',') == -1 )
174 sRemoteEnv = swProtocol;
176 else
178 sRemoteEnv = swProtocol.copy( 0 , swProtocol.indexOf( ',' ) );
180 m_sProtocol = sRemoteEnv;
181 uno_getEnvironment( &m_pEnvRemote ,
182 sRemoteEnv.pData ,
183 m_pContext );
184 if( ! m_pEnvRemote )
186 m_pContext->removeDisposingListener( m_pContext ,
187 (remote_DisposingListener*) this );
188 m_pContext->aBase.release( (uno_Context * ) m_pContext );
189 m_pContext = 0;
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 );
211 if( pContext )
213 // get the appropriate remote environment
214 uno_Environment *pEnvRemote = 0;
215 uno_getEnvironment( &pEnvRemote , m_sProtocol.pData , pContext );
217 if( ! pEnvRemote )
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;
228 uno_Any exception;
229 uno_Any *pException = &exception;
231 pContext->getRemoteInstance(
232 pEnvRemote,
233 &pRemoteI,
234 sInstanceName.pData,
235 type.getTypeLibType(),
236 &pException );
237 pContext->aBase.release( (uno_Context*) pContext );
238 pContext = 0;
240 uno_Environment *pEnvCpp =0;
241 OUString sCppuName( RTL_CONSTASCII_USTRINGPARAM( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) );
242 uno_getEnvironment( &pEnvCpp ,
243 sCppuName.pData ,
244 0 );
245 Mapping map( pEnvRemote , pEnvCpp );
247 pEnvCpp->release( pEnvCpp );
248 pEnvRemote->release( pEnvRemote );
250 if( pException )
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 );
267 throw myException;
269 else if( pRemoteI )
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();
278 else
280 throw RuntimeException(
281 OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed." ) ),
282 Reference< XInterface > () );
285 return rReturn;
289 ::rtl::OUString SAL_CALL ORemoteBridge::getName( )
290 throw(::com::sun::star::uno::RuntimeException)
292 return m_sName;
295 ::rtl::OUString SAL_CALL ORemoteBridge::getDescription( )
296 throw(::com::sun::star::uno::RuntimeException)
298 return m_sDescription;
301 // XTypeProvider
302 Sequence< Type > SAL_CALL ORemoteBridge::getTypes(void) throw( RuntimeException )
304 static OTypeCollection *pCollection = 0;
305 if( ! pCollection )
307 MutexGuard guard( Mutex::getGlobalMutex() );
308 if( ! pCollection )
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;
325 if( ! pId )
327 MutexGuard guard( Mutex::getGlobalMutex() );
328 if( ! pId )
330 static OImplementationId id( sal_False );
331 pId = &id;
334 return (*pId).getImplementationId();
337 void ORemoteBridge::disposing()
339 MutexGuard guard( m_mutex );
340 if( m_pContext )
342 m_pContext->removeDisposingListener( m_pContext , ( remote_DisposingListener * )this);
343 if( ! m_pEnvRemote )
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 );
352 else
354 // within disposing from the context, no further dispose necessary !
358 if( m_pEnvRemote )
360 m_pEnvRemote->dispose( m_pEnvRemote );
361 m_pEnvRemote->release( m_pEnvRemote );
362 m_pEnvRemote = 0;
365 m_pContext->aBase.release( (uno_Context*)m_pContext );
366 m_pContext = 0;
371 //----------------------
372 // static methods
373 //----------------------
374 void ORemoteBridge::thisAcquire( remote_DisposingListener *p )
376 ORemoteBridge *m = (ORemoteBridge * ) p;
377 m->acquire();
380 void ORemoteBridge::thisRelease( remote_DisposingListener *p )
382 ORemoteBridge *m = (ORemoteBridge * ) p;
383 m->release();
386 void ORemoteBridge::thisDisposing( remote_DisposingListener * p,
387 rtl_uString * )
389 ORemoteBridge *m = (ORemoteBridge * ) p;
390 m->dispose();
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;
404 if( ! pImplName )
406 MutexGuard guard( Mutex::getGlobalMutex() );
407 if( ! pImplName )
409 static OUString implName(
410 RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
411 pImplName = &implName;
414 return *pImplName;
417 Sequence< OUString > getSupportedServiceNames()
419 static Sequence < OUString > *pNames = 0;
420 if( ! pNames )
422 MutexGuard guard( Mutex::getGlobalMutex() );
423 if( !pNames )
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" );
430 pNames = &seqNames;
433 return *pNames;
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
446 { 0, 0, 0, 0, 0, 0 }
449 extern "C"
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 );