diff options
Diffstat (limited to 'remotebridges')
23 files changed, 3406 insertions, 0 deletions
diff --git a/remotebridges/examples/exports.dxp b/remotebridges/examples/exports.dxp new file mode 100644 index 000000000000..9630d7e06768 --- /dev/null +++ b/remotebridges/examples/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/remotebridges/examples/makefile.mk b/remotebridges/examples/makefile.mk new file mode 100644 index 000000000000..64b948d66651 --- /dev/null +++ b/remotebridges/examples/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=remotebridges +TARGET=officeclientsample +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +SLOFILES = $(SLO)$/officeclient.obj + +SHL1TARGET= officeclientsample + +SHL1STDLIBS= \ + $(SALLIB) \ + $(VOSLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(SHL1TARGET) +SHL1LIBS= $(SLB)$/$(SHL1TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/remotebridges/examples/officeclient.cxx b/remotebridges/examples/officeclient.cxx new file mode 100644 index 000000000000..b6d5ea60c801 --- /dev/null +++ b/remotebridges/examples/officeclient.cxx @@ -0,0 +1,333 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <stdio.h> +#include <osl/mutex.hxx> +#include <cppuhelper/factory.hxx> + +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/uno/XNamingService.hpp> + +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +#include <com/sun/star/connection/XConnector.hpp> + +#include <com/sun/star/bridge/XUnoUrlResolver.hpp> + +#include <com/sun/star/lang/XMain.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#include <com/sun/star/frame/XComponentLoader.hpp> + +#include <com/sun/star/text/XTextDocument.hpp> + +#include <cppuhelper/implbase1.hxx> + +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::registry; +using namespace ::com::sun::star::connection; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::frame; + + + +namespace remotebridges_officeclient { + +class OfficeClientMain : public WeakImplHelper1< XMain > +{ +public: + OfficeClientMain( const Reference< XMultiServiceFactory > &r ) : + m_xSMgr( r ) + {} +public: // Methods + + + virtual sal_Int32 SAL_CALL run( const Sequence< OUString >& aArguments ) + throw(RuntimeException); + + +private: // helper methods + void testWriter( const Reference < XComponent > & rComponent ); + void registerServices(); + Reference< XMultiServiceFactory > m_xSMgr; +}; + +void OfficeClientMain::testWriter( const Reference< XComponent > & rComponent ) +{ + printf( "pasting some text into the writer document\n" ); + + Reference< XTextDocument > rTextDoc( rComponent , UNO_QUERY ); + Reference< XText > rText = rTextDoc->getText(); + Reference< XTextCursor > rCursor = rText->createTextCursor(); + Reference< XTextRange > rRange ( rCursor , UNO_QUERY ); + + rText->insertString( rRange, OUString::createFromAscii( "This text has been posted by the officeclient component" ), sal_False ); +} + +/******************** + * does necessary service registration ( this could be done also by a setup tool ) + *********************/ +void OfficeClientMain::registerServices( ) +{ + // register services. + // Note : this needs to be done only once and is in general done by the setup + Reference < XImplementationRegistration > rImplementationRegistration( + + m_xSMgr->createInstance( + OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" )), + UNO_QUERY ); + + if( ! rImplementationRegistration.is() ) + { + printf( "Couldn't create registration component\n" ); + exit(1); + } + + OUString aSharedLibrary[4]; + aSharedLibrary[0] = + OUString::createFromAscii( "connector.uno" SAL_DLLEXTENSION ); + aSharedLibrary[1] = + OUString::createFromAscii( "remotebridge.uno" SAL_DLLEXTENSION ); + aSharedLibrary[2] = + OUString::createFromAscii( "bridgefac.uno" SAL_DLLEXTENSION ); + aSharedLibrary[3] = + OUString::createFromAscii( "uuresolver.uno" SAL_DLLEXTENSION ); + + sal_Int32 i; + for( i = 0 ; i < 4 ; i ++ ) + { + + // build the system specific library name + OUString aDllName = aSharedLibrary[i]; + + try + { + // register the needed services in the servicemanager + rImplementationRegistration->registerImplementation( + OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ), + aDllName, + Reference< XSimpleRegistry > () ); + } + catch( Exception & ) + { + printf( "couldn't register dll %s\n" , + OUStringToOString( aDllName, RTL_TEXTENCODING_ASCII_US ).getStr() ); + } + } +} + +sal_Int32 OfficeClientMain::run( const Sequence< OUString > & aArguments ) throw ( RuntimeException ) +{ + printf( "Connecting ....\n" ); + + if( aArguments.getLength() == 1 ) + { + try { + registerServices(); + Reference < XInterface > r = + m_xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.bridge.UnoUrlResolver" ) ); + Reference < XUnoUrlResolver > rResolver( r , UNO_QUERY ); + r = rResolver->resolve( aArguments.getConstArray()[0] ); + + Reference< XNamingService > rNamingService( r, UNO_QUERY ); + if( rNamingService.is() ) + { + printf( "got the remote NamingService\n" ); + + r = rNamingService->getRegisteredObject(OUString::createFromAscii("StarOffice.ServiceManager")); + + Reference< XMultiServiceFactory > rRemoteSMgr( r , UNO_QUERY ); + + Reference < XComponentLoader > rLoader( + rRemoteSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop" ))), + UNO_QUERY ); + + if( rLoader.is() ) + { + + sal_Char *urls[] = { + "private:factory/swriter", + "private:factory/sdraw", + "private:factory/simpress", + "private:factory/scalc" + }; + + sal_Char *docu[]= { + "a new writer document ...\n", + "a new draw document ...\n", + "a new schedule document ...\n" , + "a new calc document ...\n" + }; + sal_Int32 i; + for( i = 0 ; i < 4 ; i ++ ) + { + printf( "press any key to open %s\n" , docu[i] ); + getchar(); + + Reference< XComponent > rComponent = + rLoader->loadComponentFromURL( + OUString::createFromAscii( urls[i] ) , + OUString( RTL_CONSTASCII_USTRINGPARAM("_blank")), + 0 , + Sequence < ::com::sun::star::beans::PropertyValue >() ); + + if( 0 == i ) + { + testWriter( rComponent ); + } + printf( "press any key to close the document\n" ); + getchar(); + rComponent->dispose(); + } + } + } + + } + catch( ConnectionSetupException &e ) + { + OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n", o.pData->buffer ); + printf( "couldn't access local resource ( possible security resons )\n" ); + } + catch( NoConnectException &e ) + { + OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n", o.pData->buffer ); + printf( "no server listening on the resource\n" ); + } + catch( IllegalArgumentException &e ) + { + OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n", o.pData->buffer ); + printf( "uno url invalid\n" ); + } + catch( RuntimeException & e ) + { + OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n", o.pData->buffer ); + printf( "a remote call was aborted\n" ); + } + } + else + { + printf( "usage: (uno officeclient-component --) uno-url\n" + "e.g.: uno:socket,host=localhost,port=2002;urp;StarOffice.NamingService\n" ); + return 1; + } + return 0; +} + +Reference< XInterface > SAL_CALL CreateInstance( const Reference< XMultiServiceFactory > &r) +{ + return Reference< XInterface > ( ( OWeakObject * ) new OfficeClientMain(r) ); +} + +Sequence< OUString > getSupportedServiceNames() +{ + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(2); + seqNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.bridge.example.OfficeClientExample" ); + pNames = &seqNames; + } + } + return *pNames; +} + +} + +using namespace remotebridges_officeclient; +#define IMPLEMENTATION_NAME "com.sun.star.comp.remotebridges.example.OfficeClientSample" + + +extern "C" +{ +//================================================================================================== +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 ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) ); + + const Sequence< OUString > & rSNL = getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + CreateInstance, getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} diff --git a/remotebridges/prj/build.lst b/remotebridges/prj/build.lst new file mode 100644 index 000000000000..30a376462d7c --- /dev/null +++ b/remotebridges/prj/build.lst @@ -0,0 +1,6 @@ +rb remotebridges : bridges rdbmaker NULL +rb remotebridges usr1 - all rb_mkout NULL +rb remotebridges\source\bridge nmake - all rb_iiop NULL +rb remotebridges\source\factory nmake - all rb_factory NULL +rb remotebridges\source\unourl_resolver nmake - all rb_urlresolv NULL +rb remotebridges\source\dynamicloader nmake - all rb_dynloader NULL diff --git a/remotebridges/prj/d.lst b/remotebridges/prj/d.lst new file mode 100644 index 000000000000..04b8bf4f7a61 --- /dev/null +++ b/remotebridges/prj/d.lst @@ -0,0 +1,17 @@ +..\%__SRC%\bin\bridgefa*.dll %_DEST%\bin%_EXT%\bridgefa*.dll +..\%__SRC%\bin\remotebr*.dll %_DEST%\bin%_EXT%\remotebr*.dll +..\%__SRC%\bin\dynamicl*.dll %_DEST%\bin%_EXT%\dynamicl*.dll +..\%__SRC%\bin\uuresolv*.dll %_DEST%\bin%_EXT%\uuresolv*.dll +..\%__SRC%\bin\brdgfctr.rdb %_DEST%\rdb%_EXT%\brdgfctr.rdb +..\%__SRC%\bin\remotebridge.rdb %_DEST%\rdb%_EXT%\remotebridge.rdb +..\%__SRC%\bin\dynamicloader.rdb %_DEST%\rdb%_EXT%\dynamicloader.rdb +..\%__SRC%\bin\uuresolver.rdb %_DEST%\rdb%_EXT%\uuresolver.rdb +..\source\factory\brdgfctr.xml %_DEST%\xml%_EXT%\bridgefac.uno.xml +..\source\bridge\remotebridge.xml %_DEST%\xml%_EXT%\remotebridge.uno.xml +..\source\dynamicloader\dynamicloader.xml %_DEST%\xml%_EXT%\dynamicloader.uno.xml +..\source\unourl_resolver\uuresolver.xml %_DEST%\xml%_EXT%\uuresolver.uno.xml +..\%__SRC%\lib\bridgefac.uno.so %_DEST%\lib%_EXT%\bridgefac.uno.so +..\%__SRC%\lib\remotebridge.uno.so %_DEST%\lib%_EXT%\remotebridge.uno.so +..\%__SRC%\lib\dynamicloader.uno.so %_DEST%\lib%_EXT%\dynamicloader.uno.so +..\%__SRC%\lib\uuresolver.uno.so %_DEST%\lib%_EXT%\uuresolver.uno.so +..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\* diff --git a/remotebridges/source/bridge/bridge_connection.cxx b/remotebridges/source/bridge/bridge_connection.cxx new file mode 100644 index 000000000000..063b30af14bf --- /dev/null +++ b/remotebridges/source/bridge/bridge_connection.cxx @@ -0,0 +1,139 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "bridge_connection.hxx" +#include "remote_bridge.hxx" +#include <rtl/byteseq.hxx> +#include <string.h> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::connection; + +namespace remotebridges_bridge +{ + OConnectionWrapper::OConnectionWrapper( const Reference < XConnection > &r ) : + m_r( r ), + m_nRef( 0 ) + { + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + acquire = thisAcquire; + release = thisRelease; + read = thisRead; + write = thisWrite; + flush = thisFlush; + close = thisClose; + } + + OConnectionWrapper::~OConnectionWrapper() + { + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + + void OConnectionWrapper::thisAcquire( remote_Connection *p) + { + OConnectionWrapper * m = ( OConnectionWrapper * ) p; + osl_incrementInterlockedCount( &(m->m_nRef ) ); + } + + void OConnectionWrapper::thisRelease( remote_Connection * p) + { + OConnectionWrapper * m = ( OConnectionWrapper * ) p; + if( ! osl_decrementInterlockedCount( &( m->m_nRef ) ) ) + { + delete m; + } + } + + sal_Int32 OConnectionWrapper::thisRead( remote_Connection *p , sal_Int8 *pDest , sal_Int32 nSize ) + { + // guard the C-Code + OConnectionWrapper * m = ( OConnectionWrapper * ) p; + try + { + // TODO possible optimization : give + Sequence<sal_Int8> seq = toUnoSequence( ::rtl::ByteSequence(nSize, ::rtl::BYTESEQ_NODEFAULT) ); + sal_Int32 nRead = m->m_r->read( seq , nSize ); + memcpy( pDest , seq.getConstArray() , nRead ); + return nRead; + } + catch ( Exception & ) + { + return 0; + } + catch (::std::bad_alloc &) + { + return 0; + } + } + + sal_Int32 OConnectionWrapper::thisWrite( remote_Connection *p , + const sal_Int8 *pSource , + sal_Int32 nSize ) + { + // guard the C-Code + OConnectionWrapper * m = ( OConnectionWrapper * ) p; + try + { + Sequence< sal_Int8 > seq( pSource , nSize ); + m->m_r->write( seq ); + return nSize; + } + catch ( Exception & ) + { + return 0; + } + } + + void OConnectionWrapper::thisFlush( remote_Connection *p ) + { + // guard the C-Code + try + { + OConnectionWrapper * m = ( OConnectionWrapper * ) p; + m->m_r->flush(); + } + catch ( Exception & ) + { + } + } + + void OConnectionWrapper::thisClose( remote_Connection * p) + { + // guard the C-Code + try + { + OConnectionWrapper * m = ( OConnectionWrapper * ) p; + m->m_r->close(); + } + catch( Exception & ) + { + + } + } +} + + + diff --git a/remotebridges/source/bridge/bridge_connection.hxx b/remotebridges/source/bridge/bridge_connection.hxx new file mode 100644 index 000000000000..f105fd8e32ee --- /dev/null +++ b/remotebridges/source/bridge/bridge_connection.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <osl/interlck.h> + +#include <bridges/remote/connection.h> + +#include <com/sun/star/connection/XConnection.hpp> + +namespace remotebridges_bridge +{ + + class OConnectionWrapper : + public remote_Connection + { + public: + OConnectionWrapper( const ::com::sun::star::uno::Reference < + ::com::sun::star::connection::XConnection > & ); + ~OConnectionWrapper(); + + static void SAL_CALL thisAcquire( remote_Connection *); + static void SAL_CALL thisRelease( remote_Connection *); + static sal_Int32 SAL_CALL thisRead( remote_Connection * , sal_Int8 *pDest , sal_Int32 nSize ); + static sal_Int32 SAL_CALL thisWrite( remote_Connection * , + const sal_Int8 *pSource , + sal_Int32 nSize ); + static void SAL_CALL thisFlush( remote_Connection * ); + static void SAL_CALL thisClose( remote_Connection * ); + + ::com::sun::star::uno::Reference < ::com::sun::star::connection::XConnection > m_r; + oslInterlockedCount m_nRef; + }; +} + diff --git a/remotebridges/source/bridge/bridge_provider.cxx b/remotebridges/source/bridge/bridge_provider.cxx new file mode 100644 index 000000000000..1915df35ab31 --- /dev/null +++ b/remotebridges/source/bridge/bridge_provider.cxx @@ -0,0 +1,179 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <stdio.h> + +#include "remote_bridge.hxx" + +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> + +#include <uno/mapping.hxx> +#include <uno/environment.h> + +#include <bridges/remote/remote.h> + +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::bridge; + +namespace remotebridges_bridge +{ + + OInstanceProviderWrapper::OInstanceProviderWrapper( + const Reference <XInstanceProvider > & rProvider, + ORemoteBridge * pBridgeCallback ) : + m_rProvider( rProvider ), + m_nRef( 0 ), + m_pBridgeCallback( pBridgeCallback ) + { + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + acquire = thisAcquire; + release = thisRelease; + getInstance = thisGetInstance; + } + + OInstanceProviderWrapper::~OInstanceProviderWrapper() + { + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); + } + + void OInstanceProviderWrapper::thisAcquire( remote_InstanceProvider *p ) + { + OInstanceProviderWrapper * m = (OInstanceProviderWrapper *) p; + osl_incrementInterlockedCount( &(m->m_nRef ) ); + } + + void OInstanceProviderWrapper::thisRelease( remote_InstanceProvider *p ) + { + OInstanceProviderWrapper * m = ( OInstanceProviderWrapper *) p; + if( ! osl_decrementInterlockedCount( &(m->m_nRef ) ) ) + { + delete m; + } + } + + static void convertToRemoteRuntimeException ( uno_Any **ppException, + const ::rtl::OUString &sMessage, + const Reference< XInterface > &rContext, + Mapping &map ) + { + + uno_type_any_construct( *ppException , + 0 , + getCppuType( (RuntimeException *)0 ).getTypeLibType() , + 0 ); + + typelib_CompoundTypeDescription * pCompType = 0 ; + getCppuType( (Exception*)0 ).getDescription( (typelib_TypeDescription **) &pCompType ); + if( ! ((typelib_TypeDescription *)pCompType)->bComplete ) + { + typelib_typedescription_complete( (typelib_TypeDescription**) &pCompType ); + } + + char *pValue = (char*) (*ppException)->pData; + rtl_uString_assign( (rtl_uString ** ) pValue , sMessage.pData ); + + *((remote_Interface**) pValue+pCompType->pMemberOffsets[1]) = + (remote_Interface*) map.mapInterface( + rContext.get(), getCppuType( &rContext) ); + + typelib_typedescription_release( (typelib_TypeDescription *) pCompType ); + } + + void OInstanceProviderWrapper::thisGetInstance( + remote_InstanceProvider * pProvider , + uno_Environment *pEnvRemote, + remote_Interface **ppRemoteI, + rtl_uString *pInstanceName, + typelib_InterfaceTypeDescription *pType, + uno_Any **ppException + ) + { + OInstanceProviderWrapper * m = (OInstanceProviderWrapper *)pProvider; + + OSL_ASSERT( ppRemoteI ); + if( *ppRemoteI ) + { + (*ppRemoteI)->release( *ppRemoteI ); + *ppRemoteI = 0; + } + + OUString sCppuName( RTL_CONSTASCII_USTRINGPARAM( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) ); + + uno_Environment *pEnvThis = 0; + uno_getEnvironment( &pEnvThis , + sCppuName.pData , + 0 ); + Mapping map( pEnvThis , pEnvRemote ); + pEnvThis->release( pEnvThis ); + + if( OUString( pType->aBase.pTypeName ) == + getCppuType( (Reference<XInterface>*)0).getTypeName() ) + { + try + { + Reference< XInterface > r = m->m_rProvider->getInstance( + OUString( pInstanceName ) ); + + *ppRemoteI = (remote_Interface*) map.mapInterface ( + r.get(), + getCppuType( (Reference< XInterface > *) 0 ) + ); + + if( *ppRemoteI && m->m_pBridgeCallback ) + { + m->m_pBridgeCallback->objectMappedSuccesfully(); + m->m_pBridgeCallback = 0; + } + *ppException = 0; + } + catch( ::com::sun::star::container::NoSuchElementException &e ) + { + // NoSuchElementException not specified, so convert it to a runtime exception + convertToRemoteRuntimeException( + ppException , e.Message.pData , e.Context.get(), map ); + } + catch( ::com::sun::star::uno::RuntimeException &e ) + { + convertToRemoteRuntimeException( + ppException , e.Message.pData , e.Context.get(), map ); + } + + } + else + { + OUStringBuffer msg; + msg.appendAscii( + RTL_CONSTASCII_STRINGPARAM( + "getInstance expected XInterface but got ")); + msg.append(pType->aBase.pTypeName); + convertToRemoteRuntimeException( + ppException, msg.getStr(), Reference< XInterface >(), map); + } + } +} diff --git a/remotebridges/source/bridge/makefile.mk b/remotebridges/source/bridge/makefile.mk new file mode 100644 index 000000000000..1b712bef1913 --- /dev/null +++ b/remotebridges/source/bridge/makefile.mk @@ -0,0 +1,64 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=remotebridges +TARGET = remotebridge.uno +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST = remotebridge + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.IF "$(L10N_framework)"=="" +DLLPRE = +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/remote_bridge.obj \ + $(SLO)$/bridge_connection.obj\ + $(SLO)$/bridge_provider.obj +SHL1TARGET= $(TARGET) +SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map + +SHL1STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(RMCXTLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1RPATH= URELIB + +DEF1NAME= $(SHL1TARGET) +.ENDIF # L10N_framework + +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk diff --git a/remotebridges/source/bridge/remote_bridge.cxx b/remotebridges/source/bridge/remote_bridge.cxx new file mode 100644 index 000000000000..8a849e7e4423 --- /dev/null +++ b/remotebridges/source/bridge/remote_bridge.cxx @@ -0,0 +1,476 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <stdio.h> + +#include "remote_bridge.hxx" +#include "bridge_connection.hxx" +#include <cppuhelper/implementationentry.hxx> + +#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; + + ORemoteBridge::ORemoteBridge() : + OComponentHelper( m_mutex ), + m_pContext( 0 ), + m_pEnvRemote(0 ) + { + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + 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 ); + } + + void ORemoteBridge::objectMappedSuccesfully() + { + MutexGuard guard( m_mutex ); + + if( m_pEnvRemote ) + { + m_pEnvRemote->release( m_pEnvRemote ); + m_pEnvRemote = 0; + } + } + + Any ORemoteBridge::queryInterface( const Type & aType ) throw(RuntimeException) + { + 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 ) + { + // get the appropriate remote environment + uno_Environment *pEnvRemote = 0; + uno_getEnvironment( &pEnvRemote , m_sProtocol.pData , pContext ); + + if( ! pEnvRemote ) + { + pContext->aBase.release( (uno_Context*) pContext ); + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed" ) ), + Reference< XInterface > () ); + } + + Type type = getCppuType( (Reference < XInterface > * ) 0 ); + + remote_Interface *pRemoteI = 0; + uno_Any exception; + uno_Any *pException = &exception; + + pContext->getRemoteInstance( + 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 ); + + 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 ) + { + // got an interface ! + XInterface * pCppI = ( XInterface * ) map.mapInterface( pRemoteI, type ); + rReturn = Reference<XInterface > ( pCppI, SAL_NO_ACQUIRE ); + pRemoteI->release( pRemoteI ); + objectMappedSuccesfully(); + } + } + else + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed." ) ), + Reference< XInterface > () ); + } + + 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 ) + { + sal_Int32 nIndex = 0; + OUString sProtocol = OUString( m_pContext->m_pProtocol ).getToken( 0 , ',' , nIndex ); + 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 * ) + { + ORemoteBridge *m = (ORemoteBridge * ) p; + m->dispose(); + } + + //--------------------------------- + // + //--------------------------------- + Reference< XInterface > SAL_CALL CreateInstance( const Reference< XComponentContext > &) + { + 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; + } + + 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" ); + + 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 } +}; + +extern "C" +{ +sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) +{ + return g_moduleCount.canUnload( &g_moduleCount , pTime ); +} + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries ); +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); +} +} + + + + + diff --git a/remotebridges/source/bridge/remote_bridge.hxx b/remotebridges/source/bridge/remote_bridge.hxx new file mode 100644 index 000000000000..20b5e1a31034 --- /dev/null +++ b/remotebridges/source/bridge/remote_bridge.hxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <osl/mutex.hxx> +#include <osl/diagnose.h> + +#include <uno/mapping.hxx> +#include <uno/environment.h> + +#include <bridges/remote/context.h> +#include <bridges/remote/remote.h> + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/component.hxx> +#include <cppuhelper/typeprovider.hxx> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +#include <com/sun/star/bridge/XBridge.hpp> +#include <com/sun/star/bridge/XInstanceProvider.hpp> + + +namespace remotebridges_bridge +{ + extern rtl_StandardModuleCount g_moduleCount; + + struct MyMutex + { + ::osl::Mutex m_mutex; + }; + + class ORemoteBridge : + public MyMutex, + public remote_DisposingListener, + public ::com::sun::star::lang::XInitialization, + public ::com::sun::star::bridge::XBridge, + public ::cppu::OComponentHelper + { + public: + ORemoteBridge(); + ~ORemoteBridge(); + + // XInterface + public: + ::com::sun::star::uno::Any SAL_CALL + queryInterface( const ::com::sun::star::uno::Type & aType ) throw(::com::sun::star::uno::RuntimeException); + + void SAL_CALL acquire() throw() + { OComponentHelper::acquire(); } + void SAL_CALL release() throw() + { OComponentHelper::release(); } + + public: + virtual void SAL_CALL disposing(); // called by OComponentHelper + + public: + // Methods + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Any >& aArguments ) + throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + public: + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + getInstance( const ::rtl::OUString& sInstanceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getName( ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDescription( ) + throw(::com::sun::star::uno::RuntimeException); + + public: + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL + getTypes( ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getImplementationId( ) throw(::com::sun::star::uno::RuntimeException); + + public: + static void SAL_CALL thisAcquire( remote_DisposingListener * ); + static void SAL_CALL thisRelease( remote_DisposingListener * ); + static void SAL_CALL thisDisposing( remote_DisposingListener * , + rtl_uString * pBridgeName ); + + public: + void objectMappedSuccesfully(); + + public: + remote_Context *m_pContext; + uno_Environment *m_pEnvRemote; + ::rtl::OUString m_sName; + ::rtl::OUString m_sDescription; + ::rtl::OUString m_sProtocol; + }; + + class OInstanceProviderWrapper : + public remote_InstanceProvider + { + public: + OInstanceProviderWrapper( const ::com::sun::star::uno::Reference < + ::com::sun::star::bridge::XInstanceProvider > & rProvider , + ORemoteBridge * pBridgeCallback ); + + ~OInstanceProviderWrapper(); + public: + static void SAL_CALL thisAcquire( remote_InstanceProvider * ); + static void SAL_CALL thisRelease( remote_InstanceProvider * ); + static void SAL_CALL thisGetInstance( remote_InstanceProvider * pProvider , + uno_Environment *pEnvRemote, + remote_Interface **ppRemoteI, + rtl_uString *pInstanceName, + typelib_InterfaceTypeDescription *pType, + uno_Any **ppException ); + + private: + ::com::sun::star::uno::Reference < + ::com::sun::star::bridge::XInstanceProvider > m_rProvider; + oslInterlockedCount m_nRef; + ORemoteBridge *m_pBridgeCallback; + }; + +} + diff --git a/remotebridges/source/bridge/remotebridge.xml b/remotebridges/source/bridge/remotebridge.xml new file mode 100644 index 000000000000..be5e60b59eef --- /dev/null +++ b/remotebridges/source/bridge/remotebridge.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> remotebridge.uno </module-name> + <component-description> + <author> Joerg Budischewski </author> + <name> com.sun.star.comp.remotebridges.Bridge.various </name> + <description> + This component initializes the bridge between two processes + using either iiop or urp (UnoRemoteProtocol) protocol. + </description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="final"/> + <supported-service> com.sun.star.bridge.Bridge </supported-service> + <supported-service> com.sun.star.bridge.IiopBridge </supported-service> + <supported-service> com.sun.star.bridge.UrpBridge </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.bridge.XBridgeFactory </type> + <type> com.sun.star.bridge.XInstanceProvider </type> + <type> com.sun.star.bridge.XBridge </type> + <type> com.sun.star.bridge.BridgeExistsException </type> + <type> com.sun.star.lang.DisposedException </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.lang.XSingleComponentFactory </type> + <type> com.sun.star.uno.XComponentContext </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XAggregation </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> rmcxt </runtime-module-dependency> + <runtime-module-dependency> cppuhelper3 </runtime-module-dependency> + <runtime-module-dependency> cppu3 </runtime-module-dependency> + <runtime-module-dependency> sal3 </runtime-module-dependency> + <runtime-module-dependency> rmcxt3 </runtime-module-dependency> +</module-description> diff --git a/remotebridges/source/dynamicloader/dynamicloader.cxx b/remotebridges/source/dynamicloader/dynamicloader.cxx new file mode 100644 index 000000000000..96a0fc7c2a9c --- /dev/null +++ b/remotebridges/source/dynamicloader/dynamicloader.cxx @@ -0,0 +1,431 @@ + +#include <stdio.h> + +#include <cppuhelper/factory.hxx> + +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> + + +#include <com/sun/star/bridge/XUnoUrlResolver.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + + +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::loader; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::registry; + + +using namespace ::cppu; +using namespace ::rtl; + +namespace dynamic_loader { + + class SingleServiceFactory : public WeakImplHelper2<XServiceInfo, XSingleServiceFactory> { + Reference<XMultiServiceFactory> _xServiceManager; + OUString _serviceName; + OUString _link; + OUString _resolver; + + Reference<XSingleServiceFactory> getRemoteFactory() throw(Exception, RuntimeException); + + public: + + SingleServiceFactory(const Reference<XMultiServiceFactory > & xServiceManager, + const OUString & serviceName, + const OUString & link, + const OUString & resolver) + : _xServiceManager(xServiceManager), + _serviceName(serviceName), + _link(link), + _resolver(resolver) + {} + + // XSingleServiceFactory + Reference<XInterface> SAL_CALL createInstance() throw(Exception, RuntimeException); + Reference<XInterface> SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) + throw(::com::sun::star::uno::Exception, + ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + OUString SAL_CALL getImplementationName() throw(RuntimeException); + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException); + Sequence<OUString> SAL_CALL getSupportedServiceNames(void) throw(RuntimeException); + }; + + + Reference<XSingleServiceFactory> SingleServiceFactory::getRemoteFactory() throw(Exception, RuntimeException) { + Reference<XUnoUrlResolver> xResolver(_xServiceManager->createInstance(_resolver), UNO_QUERY); + if(!xResolver.is()) { + OUString message(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::singleServiceFactory.createInstance - couldn't create resolver: ")); + message += _resolver; + + throw Exception(message, Reference<XInterface>()); + } + + Reference<XInterface> remoteObject = xResolver->resolve(_link); + if(!remoteObject.is()) { + OUString message(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::singleServiceFactory.createInstance - couldn't resolve link: ")); + message += _link; + + throw Exception(message, Reference<XInterface>()); + } + + Reference<XSingleServiceFactory> remoteFactory(remoteObject, UNO_QUERY); + if(!remoteFactory.is()) { + OUString message(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::singleServiceFactory.createInstance - couldn't get XSingleServiceFactory from: ")); + message += _link; + + throw Exception(message, Reference<XInterface>()); + } + + return remoteFactory; + } + + // XSingleServiceFactory + Reference<XInterface> SAL_CALL SingleServiceFactory::createInstance() throw(Exception, RuntimeException) { + OSL_TRACE("dynamic_loader::singleServiceFactory::createInstance"); + + return getRemoteFactory()->createInstance(); + } + + Reference<XInterface> SAL_CALL SingleServiceFactory::createInstanceWithArguments(const Sequence<Any>& Arguments) + throw(Exception, RuntimeException) + { + OSL_TRACE("dynamic_loader::singleServiceFactory::createInstanceWithArguments"); + + return getRemoteFactory()->createInstanceWithArguments(Arguments); + } + + // XServiceInfo + OUString SAL_CALL SingleServiceFactory::getImplementationName() throw(RuntimeException) { + return _link; + } + + sal_Bool SAL_CALL SingleServiceFactory::supportsService(const OUString & ServiceName) throw(RuntimeException) { + return _serviceName.equals(ServiceName); + } + + Sequence<OUString> SAL_CALL SingleServiceFactory::getSupportedServiceNames(void) throw(RuntimeException) { + return Sequence<OUString>(&_serviceName, 1); + } + + + + class DynamicLoader : public WeakImplHelper2<XImplementationLoader, XServiceInfo> { + Reference<XMultiServiceFactory> _xSMgr; + + protected: + DynamicLoader(const Reference<XMultiServiceFactory> & rXSMgr) throw(RuntimeException); + ~DynamicLoader() throw(); + + public: + static const OUString implname; + static const OUString servname; + + static Reference<XInterface> SAL_CALL createInstance(const Reference<XMultiServiceFactory> & rSMgr) throw(Exception); + static Sequence<OUString> SAL_CALL getSupportedServiceNames_Static() throw(); + + static void parseUrl(const OUString & url, OUString * serviceName, OUString * link, OUString * resolver) throw(RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException); + virtual Sequence<OUString> SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // XImplementationLoader + virtual Reference<XInterface> SAL_CALL activate(const OUString & implementationName, + const OUString & implementationLoaderUrl, + const OUString& locationUrl, + const Reference<XRegistryKey>& xKey) throw(CannotActivateFactoryException, RuntimeException); + virtual sal_Bool SAL_CALL writeRegistryInfo(const Reference<XRegistryKey>& xKey, + const OUString& implementationLoaderUrl, + const OUString& locationUrl) throw(CannotRegisterImplementationException, RuntimeException); + }; + + const OUString DynamicLoader::implname = OUString::createFromAscii("com.sun.star.comp.stoc.DynamicLoader"); + const OUString DynamicLoader::servname = OUString::createFromAscii("com.sun.star.loader.Dynamic"); + + Sequence<OUString> SAL_CALL DynamicLoader::getSupportedServiceNames_Static() throw() { + return Sequence<OUString>(&servname, 1); + } + + Reference<XInterface> SAL_CALL DynamicLoader::createInstance(const Reference<XMultiServiceFactory> & rSMgr) throw(Exception) { + Reference<XInterface> xRet; + + try { + XImplementationLoader *pXLoader = (XImplementationLoader *)new DynamicLoader(rSMgr); + + xRet = Reference<XInterface>::query(pXLoader); + } + catch(RuntimeException & runtimeException) { + OString message = OUStringToOString(runtimeException.Message, RTL_TEXTENCODING_ASCII_US); + osl_trace("dynamic loader - could not init cause of %s", message.getStr()); + } + + OSL_TRACE("DynamicLoader - createInstance: %d", xRet.is()); + + + return xRet; + } + + DynamicLoader::DynamicLoader(const Reference<XMultiServiceFactory> & xSMgr) throw(RuntimeException) + : _xSMgr(xSMgr) + { + } + + + DynamicLoader::~DynamicLoader() throw() { + } + + // XServiceInfo + OUString SAL_CALL DynamicLoader::getImplementationName() throw(RuntimeException) { + return implname; + } + + sal_Bool SAL_CALL DynamicLoader::supportsService(const OUString & ServiceName) throw(RuntimeException) { + sal_Bool bSupport = sal_False; + + Sequence<OUString> aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getArray(); + for(sal_Int32 i = 0; i < aSNL.getLength() && !bSupport; ++ i) + bSupport = pArray[i] == ServiceName; + + return bSupport; + } + + Sequence<OUString> SAL_CALL DynamicLoader::getSupportedServiceNames() throw(RuntimeException) { + return getSupportedServiceNames_Static(); + } + + + void DynamicLoader::parseUrl(const OUString & locationUrl, OUString * serviceName, OUString * link, OUString * resolver) throw(RuntimeException) { +#if OSL_DEBUG_LEVEL > 1 + OString tmp = OUStringToOString(locationUrl, RTL_TEXTENCODING_ASCII_US); + OSL_TRACE("DynamicLoader - locationUrl %s", tmp.getStr()); +#endif + + // This is the default resolver + *resolver = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver")); + + const OUString bSlash(OUString(RTL_CONSTASCII_USTRINGPARAM("\\"))); + const OUString tuedle(OUString(RTL_CONSTASCII_USTRINGPARAM("\""))); + const OUString separator(OUString(RTL_CONSTASCII_USTRINGPARAM(","))); + const OUString emptyString(OUString(RTL_CONSTASCII_USTRINGPARAM(""))); + const OUString equalSign(OUString(RTL_CONSTASCII_USTRINGPARAM("="))); + + sal_Int32 index = 0; + sal_Bool left = sal_True; + sal_Bool quote = sal_False; + sal_Bool inString = sal_False; + + const sal_Unicode * raw_url = locationUrl.getStr(); + OUString token; + OUString attribute; + + while(index <= locationUrl.getLength()) { + if(index >= locationUrl.getLength() || (raw_url[index] == separator.getStr()[0] && !quote && !inString)) { // a separator or end? + OUString value; + + if(left) + attribute = token.trim(); + + else + value = token.trim(); + +#if OSL_DEBUG_LEVEL > 1 + OString attribute_tmp = OUStringToOString(attribute, RTL_TEXTENCODING_ASCII_US); + OSL_TRACE("DynamicLoader - attribute %s", attribute_tmp.getStr()); + OString value_tmp = OUStringToOString(value, RTL_TEXTENCODING_ASCII_US); + OSL_TRACE("DynamicLoader - value %s", value_tmp.getStr()); +#endif + + if(attribute.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("servicename")))) + *serviceName = value; + + else if(attribute.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("link")))) + *link = value; + + else if(attribute.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("resolver")))) + *resolver = value; + + else { + OUString message(RTL_CONSTASCII_USTRINGPARAM("help called")); + + if(!attribute.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("help")))) { + message = OUString(RTL_CONSTASCII_USTRINGPARAM("DynamicLoader - unknown attribute: ")); + message += attribute; + } + + fprintf(stdout, "DynamicLoader - help\n"); + fprintf(stdout, "attributes:\n"); + fprintf(stdout, "\tservicename: service name of dynamic component\n"); + fprintf(stdout, "\tlink: link to a single service factory for dynamic component\n"); + fprintf(stdout, "\tresolver: the service which resolves the link\n"); + fprintf(stdout, "\thelp: this help\n"); + + throw RuntimeException(message, Reference<XInterface>()); + } + + left = sal_True; // reset state to be left + token = emptyString; + } + else if(raw_url[index] == bSlash.getStr()[0] && !quote) // a back slash? + quote = sal_True; + + else if(raw_url[index] == equalSign.getStr()[0] && !quote && !inString) { // equalSign (switch from left to right)? + left = sal_False; + + attribute = token.trim(); + token = emptyString; + } + else if(raw_url[index] == tuedle.getStr()[0] && !quote) // begin or end of string? + inString = !inString; + + else { // no special handling + token += OUString(raw_url + index, 1); + quote = sal_False; + } + + ++ index; + } + + // enshure, that attributes are set properly + if(!(*serviceName).getLength()) + throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::DynamicLoader.parseUrl - missing or empty attribute: servicename")), + Reference<XInterface>()); + + if(!(*link).getLength()) + throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::DynamicLoader.parseUrl - missing or empty attribute: link")), + Reference<XInterface>()); + + if(!(*resolver).getLength()) + throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::DynamicLoader.parseUrl - missing or empty attribute: resolver")), + Reference<XInterface>()); + } + + + // XImplementationLoader + sal_Bool SAL_CALL DynamicLoader::writeRegistryInfo(const Reference<XRegistryKey> & xKey, + const OUString & implementationLoaderUrl, + const OUString & locationUrl) + throw(CannotRegisterImplementationException, RuntimeException) + { + OSL_TRACE("DynamicLoader::writeRegistryInfo"); + + OUString serviceName; + OUString link; + OUString resolver; + + try { + parseUrl(locationUrl, &serviceName, &link, &resolver); + } + catch(RuntimeException & runtimeException) { + throw CannotRegisterImplementationException(runtimeException.Message, Reference<XInterface>()); + } + + // create the keys + OUString keyName = OUString::createFromAscii("/"); + keyName += implementationLoaderUrl; + keyName += OUString(RTL_CONSTASCII_USTRINGPARAM("_")); + keyName += serviceName; + keyName += OUString::createFromAscii("/UNO/SERVICES"); + + Reference<XRegistryKey> xNewKey(xKey->createKey(keyName)); + xNewKey->createKey(serviceName); + + sal_Bool bSuccess = sal_True; + + return bSuccess; + } + + Reference<XInterface> SAL_CALL DynamicLoader::activate(const OUString &, + const OUString &, + const OUString & locationUrl, + const Reference<XRegistryKey> &) + throw(CannotActivateFactoryException, RuntimeException) + { + OSL_TRACE("DynamicLoader::activate"); + + OUString serviceName; + OUString link; + OUString resolver; + + parseUrl(locationUrl, &serviceName, &link, &resolver); + + XSingleServiceFactory * xFactory = (XSingleServiceFactory *)new SingleServiceFactory(_xSMgr, + serviceName, + link, + resolver); + + Reference<XInterface> xReturn; + + if(xFactory) + xReturn = Reference<XInterface>::query(xFactory); + + return xReturn; + } +} + + + + +extern "C" { + void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, uno_Environment **) { + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + sal_Bool SAL_CALL component_writeInfo(XMultiServiceFactory *, XRegistryKey * pRegistryKey) { + sal_Bool bRes = sal_False; + + if (pRegistryKey) { + try { + OUString x = OUString::createFromAscii("/"); + x += ::dynamic_loader::DynamicLoader::implname; + x += OUString::createFromAscii("/UNO/SERVICES"); + + + Reference<XRegistryKey> xNewKey(pRegistryKey->createKey(x)); + + const Sequence<OUString> rSNL = ::dynamic_loader::DynamicLoader::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for (sal_Int32 nPos = rSNL.getLength(); nPos--;) + xNewKey->createKey(pArray[nPos]); + + + bRes = sal_True; + } + catch (InvalidRegistryException &) { + OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); + } + } + + return bRes; + } + + void * SAL_CALL component_getFactory(const sal_Char * pImplName, XMultiServiceFactory * pServiceManager, XRegistryKey *) { + void * pRet = 0; + + if (pServiceManager && OUString::createFromAscii(pImplName).equals(::dynamic_loader::DynamicLoader::implname)) { + Reference<XSingleServiceFactory> xFactory(createOneInstanceFactory(pServiceManager, + ::dynamic_loader::DynamicLoader::implname, + ::dynamic_loader::DynamicLoader::createInstance, + ::dynamic_loader::DynamicLoader::getSupportedServiceNames_Static())); + + if (xFactory.is()) { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + else + OSL_TRACE("DynamicLoader - warning - given wrong implName: %s", pImplName); + + return pRet; + } +} diff --git a/remotebridges/source/dynamicloader/dynamicloader.xml b/remotebridges/source/dynamicloader/dynamicloader.xml new file mode 100644 index 000000000000..9735629b8a09 --- /dev/null +++ b/remotebridges/source/dynamicloader/dynamicloader.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> dynamicloader.uno </module-name> + <component-description> + <author> Kay Ramme </author> + <name> com.sun.star.loader.Dynamic </name> + <description> + This service allows the delegation of the resolution + of a SingleServiceFactory for a service to be + delegated to a resolver (e.g. UnoUrlResolver). + </description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="final"/> + <supported-service> com.sun.star.loader.Dynamic </supported-service> + <service-dependency> com.sun.star.bridge.UnoUrlResolver </service-dependency> + <type> com.sun.star.bridge.XUnoUrlResolver </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.XSingleComponentFactory </type> + <type> com.sun.star.uno.XComponentContext </type> + <type> com.sun.star.loader.XImplementationLoader </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper3 </runtime-module-dependency> + <runtime-module-dependency> cppu3 </runtime-module-dependency> + <runtime-module-dependency> sal3 </runtime-module-dependency> +</module-description> diff --git a/remotebridges/source/dynamicloader/makefile.mk b/remotebridges/source/dynamicloader/makefile.mk new file mode 100755 index 000000000000..9135d2fb26f3 --- /dev/null +++ b/remotebridges/source/dynamicloader/makefile.mk @@ -0,0 +1,69 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=remotebridges +TARGET = dynamicloader.uno +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST = dynamicloader + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.IF "$(L10N_framework)"=="" +DLLPRE = + +# ------------------------------------------------------------------ + +# use for types from COMP1TYPELIST +NO_OFFUH=TRUE +CPPUMAKERFLAGS += -C + +SLOFILES= \ + $(SLO)$/dynamicloader.obj + +SHL1TARGET= $(TARGET) +SHL1VERSIONMAP = $(SOLARENV)$/src$/component.map + +SHL1STDLIBS=\ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1IMPLIB= i$(TARGET) +SHL1LIBS=$(SLB)$/$(TARGET).lib + +SHL1DEF=$(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) + +.ENDIF # L10N_framework + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/remotebridges/source/factory/brdgfctr.xml b/remotebridges/source/factory/brdgfctr.xml new file mode 100644 index 000000000000..9e2abf8eef1e --- /dev/null +++ b/remotebridges/source/factory/brdgfctr.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> bridgefac.uno </module-name> + <component-description> + <author> Joerg Budischewski </author> + <name> com.sun.star.comp.remotebridges.BridgeFactory </name> + <description> + This component allows + to establish a connection to another process. + </description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="final"/> + <supported-service> com.sun.star.bridge.BridgeFactory </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.bridge.XBridgeFactory </type> + <type> com.sun.star.bridge.XInstanceProvider </type> + <type> com.sun.star.bridge.XBridge </type> + <type> com.sun.star.bridge.BridgeExistsException </type> + <type> com.sun.star.container.XContentEnumerationAccess </type> + <type> com.sun.star.lang.DisposedException </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.lang.XSingleComponentFactory </type> + <type> com.sun.star.uno.XComponentContext </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XAggregation </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper3 </runtime-module-dependency> + <runtime-module-dependency> cppu3 </runtime-module-dependency> + <runtime-module-dependency> sal3 </runtime-module-dependency> +</module-description> diff --git a/remotebridges/source/factory/bridgefactory.cxx b/remotebridges/source/factory/bridgefactory.cxx new file mode 100644 index 000000000000..71ab9630033c --- /dev/null +++ b/remotebridges/source/factory/bridgefactory.cxx @@ -0,0 +1,499 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <hash_map> + +#include <rtl/alloc.h> + +#include <uno/mapping.hxx> +#include <osl/mutex.hxx> + +#include <bridges/remote/context.h> + +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/component.hxx> +#include <cppuhelper/typeprovider.hxx> +#include "cppuhelper/unourl.hxx" +#include "rtl/malformeduriexception.hxx" + +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <com/sun/star/bridge/XBridgeFactory.hpp> + +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include <com/sun/star/container/XContentEnumerationAccess.hpp> + + +#include "bridgeimpl.hxx" + +using namespace ::rtl; +using namespace ::osl; +using namespace ::cppu; +using namespace ::std; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::connection; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::container; + +#define SERVICE_NAME "com.sun.star.bridge.BridgeFactory" +#define IMPLEMENTATION_NAME "com.sun.star.comp.remotebridges.BridgeFactory" + +namespace remotebridges_factory +{ + rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; + + struct hashOUString + { + size_t operator()(const OUString & s) const + { return s.hashCode(); } + }; + + struct equalOUString + { + sal_Bool operator()(const OUString & s1 , const OUString &s2 ) const + { + return s1 == s2; + } + }; + + typedef ::std::hash_map + < + OUString, + WeakReference< XBridge >, + hashOUString, + equalOUString + > BridgeHashMap; + + + typedef ::std::hash_map + < + OUString, + OUString, + hashOUString, + equalOUString + > ServiceHashMap; + + class OBridgeFactory : + public MyMutex, + public OComponentHelper, + public XBridgeFactory, + public XServiceInfo + { + public: + OBridgeFactory( const Reference < XComponentContext > &rCtx ); + ~OBridgeFactory(); + + public: // XInterface + ::com::sun::star::uno::Any SAL_CALL + queryInterface( const ::com::sun::star::uno::Type & aType ) throw(RuntimeException); + + void SAL_CALL acquire() throw() + { OComponentHelper::acquire(); } + void SAL_CALL release() throw() + { OComponentHelper::release(); } + + public: + virtual ::com::sun::star::uno::Reference< ::com::sun::star::bridge::XBridge > SAL_CALL + createBridge( + const ::rtl::OUString& sName, + const ::rtl::OUString& sProtocol, + const ::com::sun::star::uno::Reference< ::com::sun::star::connection::XConnection >& aConnection, + const ::com::sun::star::uno::Reference< ::com::sun::star::bridge::XInstanceProvider >& anInstanceProvider ) + throw(::com::sun::star::bridge::BridgeExistsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::bridge::XBridge > SAL_CALL + getBridge( const ::rtl::OUString& sName ) + throw(::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::bridge::XBridge > > SAL_CALL + getExistingBridges( ) throw(::com::sun::star::uno::RuntimeException); + + public: //XTypeProvider + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL + getTypes( ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getImplementationId( ) throw(::com::sun::star::uno::RuntimeException); + + public: //XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); + + public: + static OUString getImplementationNameStatic( ) SAL_THROW( () ); + static Sequence< OUString > getSupportedServiceNamesStatic() SAL_THROW( () ); + + private: + void init(); + OUString getServiceNameForProtocol( const OUString &sProtocol ); + + private: + Reference < XMultiComponentFactory > m_rSMgr; + Reference < XComponentContext > m_rCtx; + BridgeHashMap m_mapBridge; + ServiceHashMap m_mapProtocolToService; + sal_Bool m_bInitialized; + ::osl::Mutex m_mutexInit; + }; + + OBridgeFactory::OBridgeFactory( const Reference < XComponentContext > &rCtx ) + : OComponentHelper( m_mutex ) + , m_rSMgr( rCtx->getServiceManager() ) + , m_rCtx( rCtx ) + , m_bInitialized( sal_False ) + { + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + } + + OBridgeFactory::~OBridgeFactory() + { + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); + } + + void OBridgeFactory::init() + { + MutexGuard guard( m_mutexInit ); + if( ! m_bInitialized ) + { + Reference< XContentEnumerationAccess > rContent( m_rSMgr , UNO_QUERY ); + if( rContent.is() ) + { + OUString sMetaService = OUString( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.bridge.Bridge" ) ); + Reference < XEnumeration > rEnum = + rContent->createContentEnumeration( sMetaService ); + if ( rEnum.is() ) + while( rEnum->hasMoreElements() ) + { + Any a = rEnum->nextElement(); + Reference <XServiceInfo> rInfo; + if( a >>= rInfo ) + { + Sequence< OUString > seq = rInfo->getSupportedServiceNames(); + sal_Int32 i; + for( i = 0 ; i < seq.getLength() ; i ++ ) + { + if( seq.getConstArray()[i] != sMetaService ) + { + sal_Int32 nIndex = seq.getConstArray()[i].lastIndexOf( '.' ); + OUString sSuffix = seq.getConstArray()[i].copy(nIndex+1); + if( sSuffix.getLength() > 6 && + 0 == sSuffix.copy( sSuffix.getLength() - 6 ).compareToAscii( "Bridge" ) ) + { + OUString sProtocol = sSuffix.copy(0 , sSuffix.getLength()-6 ).toAsciiLowerCase(); + m_mapProtocolToService[ sProtocol ] = seq.getConstArray()[i]; + } + } + } + } + } + } + m_bInitialized = sal_True; + } + } + + OUString OBridgeFactory::getServiceNameForProtocol( const OUString & sProtocol ) + { + init(); + OUString sService; + OUString sProtocolName; + try + { + sProtocolName = cppu::UnoUrlDescriptor(sProtocol).getName(); + } + catch (rtl::MalformedUriException &) + { + OSL_ENSURE(false, "MalformedUriException"); + } + ServiceHashMap::iterator ii = m_mapProtocolToService.find( sProtocolName ); + if( ii != m_mapProtocolToService.end() ) + { + sService = (*ii).second; + } + else + { + // fallback to the old solution, deprecated, should be removed ! + sService = OUString::createFromAscii( "com.sun.star.bridge.Bridge." ); + sService += sProtocolName; + } + return sService; + } + + Any OBridgeFactory::queryInterface( const Type &aType ) throw(RuntimeException) + { + Any a = ::cppu::queryInterface( + aType , + ( XBridgeFactory * ) this ); + if( a.hasValue() ) + { + return a; + } + + return OComponentHelper::queryInterface( aType ); + + } + + Reference< XBridge > OBridgeFactory::createBridge( + const OUString& sName, + const OUString& sProtocol, + const Reference< XConnection >& aConnection, + const Reference< XInstanceProvider >& anInstanceProvider ) + throw(::com::sun::star::bridge::BridgeExistsException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException) + { + OUString sService = getServiceNameForProtocol( sProtocol ); + + Reference < XInterface > rXInterface = + m_rSMgr->createInstanceWithContext(sService, m_rCtx ); + Reference < XInitialization > rInit(rXInterface, UNO_QUERY ); + Reference < XBridge > rBridge( rInit , UNO_QUERY ); + + if( rInit.is() && rBridge.is() ) + { + Sequence < Any > seqAny( 4 ); + seqAny.getArray()[0] <<= sName; + seqAny.getArray()[1] <<= sProtocol; + seqAny.getArray()[2] <<= aConnection; + seqAny.getArray()[3] <<= anInstanceProvider; + + // let the Exceptions fly .... + rInit->initialize( seqAny ); + } + else + { + throw IllegalArgumentException(); + } + + if( sName.getLength() ) + { + MutexGuard guard( m_mutex ); + // put the bridge into the hashmap + m_mapBridge[ sName ] = rBridge; + } + return rBridge; + } + + Reference< XBridge > OBridgeFactory::getBridge( const ::rtl::OUString& sName ) + throw(::com::sun::star::uno::RuntimeException ) + + { + MutexGuard guard( m_mutex ); + BridgeHashMap::iterator ii = m_mapBridge.find( sName ); + + Reference < XBridge > rBridge; + + if( ii != m_mapBridge.end() ) + { + rBridge = (*ii).second; + if( ! rBridge.is() ) + { + m_mapBridge.erase( ii ); + } + } + + if( ! rBridge.is() ) + { + // try to get it via the C-Context + remote_Context * pRemoteC = remote_getContext( sName.pData ); + + if( pRemoteC ) + { + rBridge = Reference < XBridge > ((XBridge *) new OBridge( pRemoteC ) ); + pRemoteC->aBase.release( (uno_Context * )pRemoteC ); + m_mapBridge[ sName ] = rBridge; + } + } + return rBridge; + } + + Sequence< Reference< XBridge > > OBridgeFactory::getExistingBridges( ) + throw(::com::sun::star::uno::RuntimeException) + { + MutexGuard guard( m_mutex ); + + sal_Int32 nCount; + + rtl_uString **ppName = remote_getContextList( + &nCount, + rtl_allocateMemory ); + + Sequence < Reference < XBridge > > seq( nCount ); + if( nCount ) + { + + for( sal_Int32 i = 0; + i < nCount ; + i ++ ) + { + seq.getArray()[i] = getBridge( OUString( ppName[i]) ); + rtl_uString_release( ppName[i] ); + } + rtl_freeMemory( ppName ); + } + + return seq; + } + + // XTypeProvider + Sequence< Type > SAL_CALL OBridgeFactory::getTypes(void) throw( RuntimeException ) + { + static OTypeCollection *pCollection = 0; + if( ! pCollection ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pCollection ) + { + static OTypeCollection collection( + getCppuType( (Reference< XBridgeFactory > * ) 0 ), + OComponentHelper::getTypes() ); + pCollection = &collection; + } + } + return (*pCollection).getTypes(); + } + + Sequence< sal_Int8 > SAL_CALL OBridgeFactory::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(); + } + + OUString OBridgeFactory::getImplementationNameStatic() + { + static OUString *pName = 0; + if( ! pName ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pName ) + { + static OUString name( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ); + pName = &name; + } + } + return *pName; + } + + Sequence< OUString > OBridgeFactory::getSupportedServiceNamesStatic() + { + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(1); + seqNames.getArray()[0] = OUString::createFromAscii( SERVICE_NAME ); + pNames = &seqNames; + } + } + return *pNames; + } + + OUString OBridgeFactory::getImplementationName( ) throw(RuntimeException) + { + return getImplementationNameStatic(); + } + + sal_Bool SAL_CALL OBridgeFactory::supportsService( const OUString& ServiceName ) throw(RuntimeException) + { + Sequence< OUString > seq = getSupportedServiceNamesStatic(); + sal_Bool bReturn = sal_False; + for( sal_Int32 i = 0 ; i < seq.getLength() ; i ++ ) + { + if( seq.getConstArray()[i] == ServiceName ) + { + bReturn = sal_True; + break; + } + } + return bReturn; + } + + Sequence< OUString > SAL_CALL OBridgeFactory::getSupportedServiceNames( ) throw(RuntimeException) + { + return getSupportedServiceNamesStatic(); + } + + + Reference< XInterface > SAL_CALL CreateInstance(Reference< XComponentContext > const & xContext) + { + return Reference < XInterface > ( *new OBridgeFactory( xContext ) ); + } +} + +using namespace remotebridges_factory; +static ImplementationEntry g_entries[] = +{ + { CreateInstance, OBridgeFactory::getImplementationNameStatic, + OBridgeFactory::getSupportedServiceNamesStatic, createSingleComponentFactory , + &g_moduleCount.modCnt , 0 + }, + { 0, 0, 0, 0, 0, 0 } +}; + +extern "C" +{ +sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) +{ + return g_moduleCount.canUnload( &g_moduleCount , pTime ); +} + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries ); +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); +} +} + + + + diff --git a/remotebridges/source/factory/bridgeimpl.cxx b/remotebridges/source/factory/bridgeimpl.cxx new file mode 100644 index 000000000000..403b18b3fbc0 --- /dev/null +++ b/remotebridges/source/factory/bridgeimpl.cxx @@ -0,0 +1,270 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "bridgeimpl.hxx" + +using namespace ::rtl; +using namespace ::osl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::bridge; + +namespace remotebridges_factory { + + + OBridge::OBridge( remote_Context *pContext ) : + OComponentHelper( m_mutex ), + m_pContext( pContext ) + { + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + + remote_DisposingListener::acquire = thisAcquire; + remote_DisposingListener::release = thisRelease; + remote_DisposingListener::disposing = thisDisposing; + + m_pContext->aBase.acquire( (uno_Context*)m_pContext ); + m_pContext->addDisposingListener( m_pContext, ( remote_DisposingListener * ) this ); + } + + OBridge::~OBridge() + { + if( m_pContext ) + { + m_pContext->aBase.release( (uno_Context * ) m_pContext ); + } + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); + } + + ::com::sun::star::uno::Any OBridge::queryInterface( const ::com::sun::star::uno::Type & aType ) throw(RuntimeException) + { + Any a = ::cppu::queryInterface( + aType , + SAL_STATIC_CAST( XBridge * , this ), + SAL_STATIC_CAST( XTypeProvider * , this ) ); + if( a.hasValue() ) + { + return a; + } + + return OComponentHelper::queryInterface( aType ); + } + + void OBridge::disposing() + { + if( m_pContext ) + { + m_pContext->removeDisposingListener( m_pContext , ( remote_DisposingListener * )this); + + uno_Environment *pEnvRemote = 0; + if( m_pContext->m_pConnection ) + { + sal_Int32 nIndex = 0; + OUString sProtocol = OUString( m_pContext->m_pProtocol ).getToken( 0 , ',' , nIndex ); + uno_getEnvironment( &pEnvRemote , sProtocol.pData , m_pContext ); + OSL_ASSERT( pEnvRemote ); + } + else + { + // within disposing from the context, no further dispose necessary ! + } + + if( pEnvRemote ) + { + pEnvRemote->dispose( pEnvRemote ); + pEnvRemote->release( pEnvRemote ); + pEnvRemote = 0; + } + + m_pContext->aBase.release( (uno_Context*)m_pContext ); + m_pContext = 0; + } + } + + + Reference< XInterface > OBridge::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 ) + { + sal_Int32 nIndex = 0; + OUString sProtocol = OUString( m_pContext->m_pProtocol ).getToken( 0 , ',' , nIndex ); + + // get the appropriate remote environment + uno_Environment *pEnvRemote = 0; + uno_getEnvironment( &pEnvRemote , sProtocol.pData , pContext ); + + if( ! pEnvRemote ) + { + pContext->aBase.release( (uno_Context*) pContext ); + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed" ) ), + Reference< XInterface > () ); + } + + Type type = getCppuType( (Reference < XInterface > * ) 0 ); + + remote_Interface *pRemoteI = 0; + uno_Any exception; + uno_Any *pException = &exception; + + pContext->getRemoteInstance( + 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 ); + + 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 ) + { + // got an interface ! + XInterface * pCppI = ( XInterface * ) map.mapInterface( pRemoteI, type ); + rReturn = Reference<XInterface > ( pCppI, SAL_NO_ACQUIRE ); + pRemoteI->release( pRemoteI ); + } + } + else + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed." ) ), + Reference< XInterface > () ); + } + + return rReturn; + } + + ::rtl::OUString SAL_CALL OBridge::getName( ) + throw(::com::sun::star::uno::RuntimeException) + + { + return OUString( m_pContext->m_pName ); + } + + ::rtl::OUString OBridge::getDescription( ) + throw(::com::sun::star::uno::RuntimeException) + { + return OUString( m_pContext->m_pDescription ); + } + + // XTypeProvider + Sequence< Type > SAL_CALL OBridge::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 ), + OComponentHelper::getTypes() ); + pCollection = &collection; + } + } + + return (*pCollection).getTypes(); + } + + Sequence< sal_Int8 > SAL_CALL OBridge::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(); + } + + //---------------------- + // static methods + //---------------------- + void OBridge::thisAcquire( remote_DisposingListener *p ) + { + OBridge *m = (OBridge * ) p; + m->acquire(); + } + + void OBridge::thisRelease( remote_DisposingListener *p ) + { + OBridge *m = (OBridge * ) p; + m->release(); + } + + void OBridge::thisDisposing( remote_DisposingListener * p, rtl_uString * ) + { + OBridge *m = (OBridge * ) p; + m->dispose(); + } +} diff --git a/remotebridges/source/factory/bridgeimpl.hxx b/remotebridges/source/factory/bridgeimpl.hxx new file mode 100644 index 000000000000..1e483dd57180 --- /dev/null +++ b/remotebridges/source/factory/bridgeimpl.hxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <osl/mutex.hxx> +#include <osl/diagnose.h> + +#include <uno/mapping.hxx> +#include <uno/environment.h> + +#include <bridges/remote/context.h> +#include <bridges/remote/remote.h> + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/component.hxx> +#include <cppuhelper/typeprovider.hxx> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +#include <com/sun/star/bridge/XBridge.hpp> +#include <com/sun/star/bridge/XInstanceProvider.hpp> + +namespace remotebridges_factory { + extern rtl_StandardModuleCount g_moduleCount; + + struct MyMutex + { + ::osl::Mutex m_mutex; + }; + + class OBridge : + public MyMutex, + public remote_DisposingListener, + public ::com::sun::star::bridge::XBridge, + public ::cppu::OComponentHelper + { + public: + OBridge( remote_Context *pContext ); + ~OBridge(); + + // XInterface + public: + ::com::sun::star::uno::Any SAL_CALL + queryInterface( const ::com::sun::star::uno::Type & aType ) throw(com::sun::star::uno::RuntimeException); + + void SAL_CALL acquire() throw() + { OComponentHelper::acquire(); } + void SAL_CALL release() throw() + { OComponentHelper::release(); } + + public: + virtual void SAL_CALL disposing(); // called by OComponentHelper + + public: + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + getInstance( const ::rtl::OUString& sInstanceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getName( ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDescription( ) + throw(::com::sun::star::uno::RuntimeException); + + public: + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL + getTypes( ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getImplementationId( ) throw(::com::sun::star::uno::RuntimeException); + + public: + static void SAL_CALL thisAcquire( remote_DisposingListener * ); + static void SAL_CALL thisRelease( remote_DisposingListener * ); + static void SAL_CALL thisDisposing( remote_DisposingListener * , + rtl_uString * pBridgeName ); + + public: + remote_Context *m_pContext; + ::rtl::OString m_sName; + ::rtl::OString m_sDescription; + }; +} + diff --git a/remotebridges/source/factory/makefile.mk b/remotebridges/source/factory/makefile.mk new file mode 100644 index 000000000000..7cd3875bcfb3 --- /dev/null +++ b/remotebridges/source/factory/makefile.mk @@ -0,0 +1,66 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=remotebridges +TARGET = bridgefac.uno +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST = brdgfctr + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.IF "$(L10N_framework)"=="" +DLLPRE = +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/bridgefactory.obj\ + $(SLO)$/bridgeimpl.obj + +SHL1TARGET= $(TARGET) +SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map + +SHL1STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(RMCXTLIB) + +#SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1RPATH= URELIB + +DEF1NAME= $(SHL1TARGET) +.ENDIF # L10N_framework + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/remotebridges/source/unourl_resolver/makefile.mk b/remotebridges/source/unourl_resolver/makefile.mk new file mode 100644 index 000000000000..a3e4af7f0d91 --- /dev/null +++ b/remotebridges/source/unourl_resolver/makefile.mk @@ -0,0 +1,64 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=remotebridges +TARGET = uuresolver.uno +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST = uuresolver + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.IF "$(L10N_framework)"=="" +DLLPRE = + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/unourl_resolver.obj + +SHL1TARGET= $(TARGET) +SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map + +SHL1STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1RPATH= URELIB + +DEF1NAME= $(SHL1TARGET) +.ENDIF # L10N_framework + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/remotebridges/source/unourl_resolver/unourl_resolver.cxx b/remotebridges/source/unourl_resolver/unourl_resolver.cxx new file mode 100644 index 000000000000..0abf7f80f8a1 --- /dev/null +++ b/remotebridges/source/unourl_resolver/unourl_resolver.cxx @@ -0,0 +1,253 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// #define TRACE(x) OSL_TRACE(x) +#define TRACE(x) + +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implementationentry.hxx> +#include "cppuhelper/unourl.hxx" +#include "rtl/malformeduriexception.hxx" + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/connection/XConnector.hpp> +#include <com/sun/star/bridge/XBridgeFactory.hpp> +#include <com/sun/star/bridge/XUnoUrlResolver.hpp> + +using namespace cppu; +using namespace rtl; +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::connection; +using namespace com::sun::star::bridge; +using namespace com::sun::star::registry; + +#define SERVICENAME "com.sun.star.bridge.UnoUrlResolver" +#define IMPLNAME "com.sun.star.comp.bridge.UnoUrlResolver" + +namespace unourl_resolver +{ + rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; +//-------------------------------------------------------------------------------------------------- +Sequence< OUString > resolver_getSupportedServiceNames() +{ + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(1); + seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME)); + pNames = &seqNames; + } + } + return *pNames; +} + +OUString resolver_getImplementationName() +{ + static OUString *pImplName = 0; + if( ! pImplName ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pImplName ) + { + static OUString implName( + RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ); + pImplName = &implName; + } + } + return *pImplName; +} + +//================================================================================================== +class ResolverImpl : public WeakImplHelper2< XServiceInfo, XUnoUrlResolver > +{ + Reference< XMultiComponentFactory > _xSMgr; + Reference< XComponentContext > _xCtx; + +public: + ResolverImpl( const Reference< XComponentContext > & xSMgr ); + virtual ~ResolverImpl(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XUnoUrlResolver + virtual Reference< XInterface > SAL_CALL resolve( const OUString & rUnoUrl ) + throw (NoConnectException, ConnectionSetupException, RuntimeException); +}; + +//################################################################################################## + +//__________________________________________________________________________________________________ +ResolverImpl::ResolverImpl( const Reference< XComponentContext > & xCtx ) + : _xSMgr( xCtx->getServiceManager() ) + , _xCtx( xCtx ) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +} +//__________________________________________________________________________________________________ +ResolverImpl::~ResolverImpl() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString ResolverImpl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return resolver_getImplementationName(); +} +//__________________________________________________________________________________________________ +sal_Bool ResolverImpl::supportsService( const OUString & rServiceName ) + throw(::com::sun::star::uno::RuntimeException) +{ + const Sequence< OUString > & rSNL = getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + { + if (pArray[nPos] == rServiceName) + return sal_True; + } + return sal_False; +} +//__________________________________________________________________________________________________ +Sequence< OUString > ResolverImpl::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return resolver_getSupportedServiceNames(); +} + +// XUnoUrlResolver +//__________________________________________________________________________________________________ +Reference< XInterface > ResolverImpl::resolve( const OUString & rUnoUrl ) + throw (NoConnectException, ConnectionSetupException, RuntimeException) +{ + OUString aProtocolDescr; + OUString aConnectDescr; + OUString aInstanceName; + try + { + cppu::UnoUrl aUrl(rUnoUrl); + aProtocolDescr = aUrl.getProtocol().getDescriptor(); + aConnectDescr = aUrl.getConnection().getDescriptor(); + aInstanceName = aUrl.getObjectName(); + } + catch (rtl::MalformedUriException & rEx) + { + throw ConnectionSetupException(rEx.getMessage(), 0); + } + + Reference< XConnector > xConnector( + _xSMgr->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector") ), + _xCtx ), + UNO_QUERY ); + + if (! xConnector.is()) + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no connector!" ) ), Reference< XInterface >() ); + + Reference< XConnection > xConnection( xConnector->connect( aConnectDescr ) ); + + // As soon as singletons are ready, switch to singleton ! + Reference< XBridgeFactory > xBridgeFactory( + _xSMgr->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory") ), + _xCtx ), + UNO_QUERY ); + + if (! xBridgeFactory.is()) + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no bridge factory!" ) ), Reference< XInterface >() ); + + // bridge + Reference< XBridge > xBridge( xBridgeFactory->createBridge( + OUString(), aProtocolDescr, + xConnection, Reference< XInstanceProvider >() ) ); + + Reference< XInterface > xRet( xBridge->getInstance( aInstanceName ) ); + + return xRet; +} + +//================================================================================================== +static Reference< XInterface > SAL_CALL ResolverImpl_create( const Reference< XComponentContext > & xCtx ) +{ + return Reference< XInterface >( *new ResolverImpl( xCtx ) ); +} + + +} + +using namespace unourl_resolver; + +static struct ImplementationEntry g_entries[] = +{ + { + ResolverImpl_create, resolver_getImplementationName, + resolver_getSupportedServiceNames, createSingleComponentFactory, + &g_moduleCount.modCnt , 0 + }, + { 0, 0, 0, 0, 0, 0 } +}; + +extern "C" +{ +sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) +{ + return g_moduleCount.canUnload( &g_moduleCount , pTime ); +} + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries ); +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); +} +} diff --git a/remotebridges/source/unourl_resolver/uuresolver.xml b/remotebridges/source/unourl_resolver/uuresolver.xml new file mode 100644 index 000000000000..c959d4c7db2e --- /dev/null +++ b/remotebridges/source/unourl_resolver/uuresolver.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> uuresolver.uno </module-name> + <component-description> + <author> Daniel Boelzle </author> + <name> com.sun.star.comp.bridge.UnoUrlResolver </name> + <description> + This component allows + to retrieve an object reference from another process. + </description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="final"/> + <supported-service> com.sun.star.bridge.UnoUrlResolver </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XSingleComponentFactory </type> + <type> com.sun.star.uno.XComponentContext </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.connection.XConnector </type> + <type> com.sun.star.bridge.XBridgeFactory </type> + <type> com.sun.star.bridge.XUnoUrlResolver </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.uno.XWeak </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper3 </runtime-module-dependency> + <runtime-module-dependency> cppu3 </runtime-module-dependency> + <runtime-module-dependency> sal3 </runtime-module-dependency> +</module-description> |