office-gobmx/remotebridges/source/bridge/remote_bridge.cxx

511 lines
17 KiB
C++
Raw Normal View History

2000-09-28 02:47:31 -05:00
/*************************************************************************
*
* $RCSfile: remote_bridge.cxx,v $
*
* $Revision: 1.7 $
2000-09-28 02:47:31 -05:00
*
* last change: $Author: jbu $ $Date: 2001-06-22 16:39:16 $
2000-09-28 02:47:31 -05:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#include <stdio.h>
#include "remote_bridge.hxx"
#include "bridge_connection.hxx"
#include <cppuhelper/implementationentry.hxx>
2000-09-28 02:47:31 -05:00
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/bridge/BridgeExistsException.hpp>
#define IMPLEMENTATION_NAME "com.sun.star.comp.remotebridges.Bridge.various"
using namespace ::rtl;
using namespace ::cppu;
using namespace ::osl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::bridge;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::connection;
namespace remotebridges_bridge
{
rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
2000-09-28 02:47:31 -05:00
ORemoteBridge::ORemoteBridge() :
OComponentHelper( m_mutex ),
m_pContext( 0 ),
m_pEnvRemote(0 )
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
2000-09-28 02:47:31 -05:00
remote_DisposingListener::acquire = thisAcquire;
remote_DisposingListener::release = thisRelease;
remote_DisposingListener::disposing = thisDisposing;
}
ORemoteBridge::~ORemoteBridge()
{
if( m_pContext )
{
m_pContext->aBase.release( (uno_Context *) m_pContext );
}
if( m_pEnvRemote )
{
m_pEnvRemote->release( m_pEnvRemote );
}
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
2000-09-28 02:47:31 -05:00
}
void ORemoteBridge::objectMappedSuccesfully()
{
MutexGuard guard( m_mutex );
if( m_pEnvRemote )
{
m_pEnvRemote->release( m_pEnvRemote );
m_pEnvRemote = 0;
}
}
Any ORemoteBridge::queryInterface( const Type & aType )
{
Any a = ::cppu::queryInterface(
aType ,
SAL_STATIC_CAST( XInitialization * , this ) ,
SAL_STATIC_CAST( XBridge * , this ),
SAL_STATIC_CAST( XTypeProvider * , this ) );
if( a.hasValue() )
{
return a;
}
return OComponentHelper::queryInterface( aType );
}
void ORemoteBridge::initialize( const Sequence< Any >& aArguments )
throw( Exception, RuntimeException)
{
MutexGuard guard( m_mutex );
if( 4 != aArguments.getLength() )
{
throw IllegalArgumentException( rtl::OUString::createFromAscii("wrong number of arguments") ,
Reference< XInterface >(),
0 );
}
OUString swName;
OUString swProtocol;
Reference < XConnection > rConnection;
Reference < XInstanceProvider > rProvider;
aArguments.getConstArray()[0] >>= swName;
aArguments.getConstArray()[1] >>= swProtocol;
aArguments.getConstArray()[2] >>= rConnection;
aArguments.getConstArray()[3] >>= rProvider;
if( ! rConnection.is() )
{
throw IllegalArgumentException( rtl::OUString::createFromAscii("connection is missing") ,
Reference < XInterface > (),
2 );
}
remote_Connection *pConnection = new OConnectionWrapper( rConnection );
remote_InstanceProvider *pProvider = 0;
if( rProvider.is( ))
{
pProvider = new OInstanceProviderWrapper( rProvider , this );
}
OUString sName = swName;
m_sDescription = swProtocol;
m_sDescription += OUString( RTL_CONSTASCII_USTRINGPARAM(":"));
m_sDescription += rConnection->getDescription();
if( 0 == sName.getLength() )
{
sName = m_sDescription;
}
else
{
m_sName = sName;
}
m_pContext = remote_createContext( pConnection,
sName.pData,
m_sDescription.pData,
swProtocol.pData,
pProvider );
if( ! m_pContext )
{
throw BridgeExistsException();
}
m_pContext->addDisposingListener( m_pContext ,
(remote_DisposingListener *) this );
// environment will be released by the first succesfull mapping
OUString sRemoteEnv;
if( swProtocol.indexOf( ',') == -1 )
{
sRemoteEnv = swProtocol;
}
else
{
sRemoteEnv = swProtocol.copy( 0 , swProtocol.indexOf( ',' ) );
}
m_sProtocol = sRemoteEnv;
uno_getEnvironment( &m_pEnvRemote ,
sRemoteEnv.pData ,
m_pContext );
if( ! m_pEnvRemote )
{
m_pContext->removeDisposingListener( m_pContext ,
(remote_DisposingListener*) this );
m_pContext->aBase.release( (uno_Context * ) m_pContext );
m_pContext = 0;
// forgotten exception when specifying the interface
throw RuntimeException( rtl::OUString::createFromAscii("couldn't create uno-remote-environment") ,
Reference < XInterface > () );
}
}
Reference< XInterface > ORemoteBridge::getInstance( const ::rtl::OUString& sInstanceName )
throw(::com::sun::star::uno::RuntimeException)
{
Reference < XInterface > rReturn;
remote_Context *pContext = 0;
{
MutexGuard guard( m_mutex );
if( m_pContext && m_pContext->getRemoteInstance )
{
pContext = m_pContext;
pContext->aBase.acquire( (uno_Context*)pContext );
}
}
if( pContext )
2000-09-28 02:47:31 -05:00
{
// get the appropriate remote environment
uno_Environment *pEnvRemote = 0;
uno_getEnvironment( &pEnvRemote , m_sProtocol.pData , pContext );
2000-09-28 02:47:31 -05:00
if( ! pEnvRemote )
{
pContext->aBase.release( (uno_Context*) pContext );
throw RuntimeException(
OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed" ) ),
Reference< XInterface > () );
2000-09-28 02:47:31 -05:00
}
Type type = getCppuType( (Reference < XInterface > * ) 0 );
remote_Interface *pRemoteI = 0;
uno_Any exception;
uno_Any *pException = &exception;
pContext->getRemoteInstance(
2000-09-28 02:47:31 -05:00
pEnvRemote,
&pRemoteI,
sInstanceName.pData,
type.getTypeLibType(),
&pException );
pContext->aBase.release( (uno_Context*) pContext );
pContext = 0;
uno_Environment *pEnvCpp =0;
OUString sCppuName( RTL_CONSTASCII_USTRINGPARAM( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) );
uno_getEnvironment( &pEnvCpp ,
sCppuName.pData ,
0 );
Mapping map( pEnvRemote , pEnvCpp );
pEnvCpp->release( pEnvCpp );
pEnvRemote->release( pEnvRemote );
2000-09-28 02:47:31 -05:00
if( pException )
{
typelib_CompoundTypeDescription * pCompType = 0 ;
getCppuType( (Exception*)0 ).getDescription( (typelib_TypeDescription **) &pCompType );
if( ! ((typelib_TypeDescription *)pCompType)->bComplete )
{
typelib_typedescription_complete( (typelib_TypeDescription**) &pCompType );
}
XInterface *pXInterface = (XInterface *) map.mapInterface(
*(remote_Interface**) ( ((char*)pException->pData)+pCompType->pMemberOffsets[1] ),
getCppuType( (Reference< XInterface > *)0 ) );
RuntimeException myException(
*((rtl_uString **)pException->pData),
Reference< XInterface > ( pXInterface , SAL_NO_ACQUIRE) );
uno_any_destruct( pException , 0 );
throw myException;
}
else if( pRemoteI )
2000-09-28 02:47:31 -05:00
{
// got an interface !
XInterface * pCppI = ( XInterface * ) map.mapInterface( pRemoteI, type );
rReturn = Reference<XInterface > ( pCppI, SAL_NO_ACQUIRE );
2000-09-28 02:47:31 -05:00
pRemoteI->release( pRemoteI );
objectMappedSuccesfully();
}
}
else
{
throw RuntimeException(
OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed." ) ),
Reference< XInterface > () );
}
2000-09-28 02:47:31 -05:00
return rReturn;
}
::rtl::OUString SAL_CALL ORemoteBridge::getName( )
throw(::com::sun::star::uno::RuntimeException)
{
return m_sName;
}
::rtl::OUString SAL_CALL ORemoteBridge::getDescription( )
throw(::com::sun::star::uno::RuntimeException)
{
return m_sDescription;
}
// XTypeProvider
Sequence< Type > SAL_CALL ORemoteBridge::getTypes(void) throw( RuntimeException )
{
static OTypeCollection *pCollection = 0;
if( ! pCollection )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pCollection )
{
static OTypeCollection collection(
getCppuType( (Reference< XTypeProvider> * )0),
getCppuType( (Reference< XBridge > * ) 0 ),
getCppuType( (Reference< XInitialization > * ) 0 ),
OComponentHelper::getTypes() );
pCollection = &collection;
}
}
return (*pCollection).getTypes();
}
Sequence< sal_Int8 > SAL_CALL ORemoteBridge::getImplementationId( ) throw( RuntimeException)
{
static OImplementationId *pId = 0;
if( ! pId )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pId )
{
static OImplementationId id( sal_False );
pId = &id;
}
}
return (*pId).getImplementationId();
}
void ORemoteBridge::disposing()
{
MutexGuard guard( m_mutex );
if( m_pContext )
{
m_pContext->removeDisposingListener( m_pContext , ( remote_DisposingListener * )this);
if( ! m_pEnvRemote )
{
if( m_pContext->m_pConnection )
{
2001-05-11 04:57:01 -05:00
sal_Int32 nIndex = 0;
OUString sProtocol = OUString( m_pContext->m_pProtocol ).getToken( 0 , ',' , nIndex );
2000-09-28 02:47:31 -05:00
uno_getEnvironment( &m_pEnvRemote , sProtocol.pData , m_pContext );
OSL_ASSERT( m_pEnvRemote );
}
else
{
// within disposing from the context, no further dispose necessary !
}
}
if( m_pEnvRemote )
{
m_pEnvRemote->dispose( m_pEnvRemote );
m_pEnvRemote->release( m_pEnvRemote );
m_pEnvRemote = 0;
}
m_pContext->aBase.release( (uno_Context*)m_pContext );
m_pContext = 0;
}
}
//----------------------
// static methods
//----------------------
void ORemoteBridge::thisAcquire( remote_DisposingListener *p )
{
ORemoteBridge *m = (ORemoteBridge * ) p;
m->acquire();
}
void ORemoteBridge::thisRelease( remote_DisposingListener *p )
{
ORemoteBridge *m = (ORemoteBridge * ) p;
m->release();
}
void ORemoteBridge::thisDisposing( remote_DisposingListener * p,
rtl_uString *pString )
{
ORemoteBridge *m = (ORemoteBridge * ) p;
m->dispose();
}
//---------------------------------
//
//---------------------------------
Reference< XInterface > SAL_CALL CreateInstance( const Reference< XComponentContext > &)
2000-09-28 02:47:31 -05:00
{
return Reference< XInterface > ( ( OWeakObject * ) new ORemoteBridge );
}
OUString getImplementationName()
{
static OUString *pImplName = 0;
if( ! pImplName )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pImplName )
{
static OUString implName(
RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
pImplName = &implName;
}
}
return *pImplName;
}
2000-09-28 02:47:31 -05:00
Sequence< OUString > getSupportedServiceNames()
{
static Sequence < OUString > *pNames = 0;
if( ! pNames )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( !pNames )
{
static Sequence< OUString > seqNames(3);
seqNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.bridge.Bridge" );
seqNames.getArray()[1] = OUString::createFromAscii( "com.sun.star.bridge.IiopBridge" );
seqNames.getArray()[2] = OUString::createFromAscii( "com.sun.star.bridge.UrpBridge" );
2000-09-28 02:47:31 -05:00
pNames = &seqNames;
}
}
return *pNames;
}
}
using namespace remotebridges_bridge;
static struct ImplementationEntry g_entries[] =
{
{
remotebridges_bridge::CreateInstance, remotebridges_bridge::getImplementationName,
remotebridges_bridge::getSupportedServiceNames, createSingleComponentFactory,
&g_moduleCount.modCnt , 0
},
{ 0, 0, 0, 0, 0, 0 }
};
2000-09-28 02:47:31 -05:00
extern "C"
{
sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
{
return g_moduleCount.canUnload( &g_moduleCount , pTime );
}
2000-09-28 02:47:31 -05:00
//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
void * pServiceManager, void * pRegistryKey )
{
return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
2000-09-28 02:47:31 -05:00
}
//==================================================================================================
void * SAL_CALL component_getFactory(
const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
2000-09-28 02:47:31 -05:00
}
}