1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_desktop.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "acceptor.hxx" 32*cdf0e10cSrcweir #include <unotools/bootstrap.hxx> 33*cdf0e10cSrcweir #include <vos/process.hxx> 34*cdf0e10cSrcweir #include <tools/urlobj.hxx> 35*cdf0e10cSrcweir #include <tools/stream.hxx> 36*cdf0e10cSrcweir #include <vcl/svapp.hxx> 37*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 38*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_UNO_XNAMEINGSERVICE_HPP_ 39*cdf0e10cSrcweir #include <com/sun/star/uno/XNamingService.hpp> 40*cdf0e10cSrcweir #endif 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <cppuhelper/factory.hxx> 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir namespace desktop 45*cdf0e10cSrcweir { 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir extern "C" void workerfunc (void * acc) 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir ((Acceptor*)acc)->run(); 50*cdf0e10cSrcweir } 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir static Reference<XInterface> getComponentContext( const Reference<XMultiServiceFactory>& rFactory) 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir Reference<XInterface> rContext; 55*cdf0e10cSrcweir Reference< XPropertySet > rPropSet( rFactory, UNO_QUERY ); 56*cdf0e10cSrcweir Any a = rPropSet->getPropertyValue( 57*cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ); 58*cdf0e10cSrcweir a >>= rContext; 59*cdf0e10cSrcweir return rContext; 60*cdf0e10cSrcweir } 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir Mutex Acceptor::m_aMutex; 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir Acceptor::Acceptor( const Reference< XMultiServiceFactory >& rFactory ) 65*cdf0e10cSrcweir : m_thread(NULL) 66*cdf0e10cSrcweir , m_aAcceptString() 67*cdf0e10cSrcweir , m_aConnectString() 68*cdf0e10cSrcweir , m_aProtocol() 69*cdf0e10cSrcweir , m_bInit(sal_False) 70*cdf0e10cSrcweir , m_bDying(false) 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir m_rSMgr = rFactory; 73*cdf0e10cSrcweir m_rAcceptor = Reference< XAcceptor > (m_rSMgr->createInstance( 74*cdf0e10cSrcweir rtl::OUString::createFromAscii( "com.sun.star.connection.Acceptor" )), 75*cdf0e10cSrcweir UNO_QUERY ); 76*cdf0e10cSrcweir m_rBridgeFactory = Reference < XBridgeFactory > (m_rSMgr->createInstance( 77*cdf0e10cSrcweir rtl::OUString::createFromAscii( "com.sun.star.bridge.BridgeFactory" )), 78*cdf0e10cSrcweir UNO_QUERY ); 79*cdf0e10cSrcweir // get component context 80*cdf0e10cSrcweir m_rContext = getComponentContext(m_rSMgr); 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir Acceptor::~Acceptor() 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir m_rAcceptor->stopAccepting(); 87*cdf0e10cSrcweir oslThread t; 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir osl::MutexGuard g(m_aMutex); 90*cdf0e10cSrcweir t = m_thread; 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir //prevent locking if the thread is still waiting 93*cdf0e10cSrcweir m_bDying = true; 94*cdf0e10cSrcweir m_cEnable.set(); 95*cdf0e10cSrcweir osl_joinWithThread(t); 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir // Make the final state of m_bridges visible to this thread (since 98*cdf0e10cSrcweir // m_thread is joined, the code that follows is the only one left 99*cdf0e10cSrcweir // accessing m_bridges): 100*cdf0e10cSrcweir osl::MutexGuard g(m_aMutex); 101*cdf0e10cSrcweir } 102*cdf0e10cSrcweir for (;;) { 103*cdf0e10cSrcweir com::sun::star::uno::Reference< com::sun::star::bridge::XBridge > b( 104*cdf0e10cSrcweir m_bridges.remove()); 105*cdf0e10cSrcweir if (!b.is()) { 106*cdf0e10cSrcweir break; 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir com::sun::star::uno::Reference< com::sun::star::lang::XComponent >( 109*cdf0e10cSrcweir b, com::sun::star::uno::UNO_QUERY_THROW)->dispose(); 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir void SAL_CALL Acceptor::run() 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir while ( m_rAcceptor.is() && m_rBridgeFactory.is() ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) Acceptor::run" ); 118*cdf0e10cSrcweir try 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir // wait until we get enabled 121*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\ 122*cdf0e10cSrcweir "Acceptor::run waiting for office to come up"); 123*cdf0e10cSrcweir m_cEnable.wait(); 124*cdf0e10cSrcweir if (m_bDying) //see destructor 125*cdf0e10cSrcweir break; 126*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\ 127*cdf0e10cSrcweir "Acceptor::run now enabled and continuing"); 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir // accept connection 130*cdf0e10cSrcweir Reference< XConnection > rConnection = m_rAcceptor->accept( m_aConnectString ); 131*cdf0e10cSrcweir // if we return without a valid connection we mus assume that the acceptor 132*cdf0e10cSrcweir // is destructed so we break out of the run method terminating the thread 133*cdf0e10cSrcweir if (! rConnection.is()) break; 134*cdf0e10cSrcweir OUString aDescription = rConnection->getDescription(); 135*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::run connection %s", 136*cdf0e10cSrcweir OUStringToOString(aDescription, RTL_TEXTENCODING_ASCII_US).getStr()); 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir // create instanceprovider for this connection 139*cdf0e10cSrcweir Reference< XInstanceProvider > rInstanceProvider( 140*cdf0e10cSrcweir (XInstanceProvider*)new AccInstanceProvider(m_rSMgr, rConnection)); 141*cdf0e10cSrcweir // create the bridge. The remote end will have a reference to this bridge 142*cdf0e10cSrcweir // thus preventing the bridge from being disposed. When the remote end releases 143*cdf0e10cSrcweir // the bridge, it will be destructed. 144*cdf0e10cSrcweir Reference< XBridge > rBridge = m_rBridgeFactory->createBridge( 145*cdf0e10cSrcweir rtl::OUString() ,m_aProtocol ,rConnection ,rInstanceProvider ); 146*cdf0e10cSrcweir osl::MutexGuard g(m_aMutex); 147*cdf0e10cSrcweir m_bridges.add(rBridge); 148*cdf0e10cSrcweir } catch (Exception&) { 149*cdf0e10cSrcweir // connection failed... 150*cdf0e10cSrcweir // something went wrong during connection setup. 151*cdf0e10cSrcweir // just wait for a new connection to accept 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir // XInitialize 157*cdf0e10cSrcweir void SAL_CALL Acceptor::initialize( const Sequence<Any>& aArguments ) 158*cdf0e10cSrcweir throw( Exception ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir // prevent multiple initialization 161*cdf0e10cSrcweir ClearableMutexGuard aGuard( m_aMutex ); 162*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "destop (lo119109) Acceptor::initialize()" ); 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir sal_Bool bOk = sal_False; 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir // arg count 167*cdf0e10cSrcweir int nArgs = aArguments.getLength(); 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir // not yet initialized and acceptstring 170*cdf0e10cSrcweir if (!m_bInit && nArgs > 0 && (aArguments[0] >>= m_aAcceptString)) 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::initialize string=%s", 173*cdf0e10cSrcweir OUStringToOString(m_aAcceptString, RTL_TEXTENCODING_ASCII_US).getStr()); 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir // get connect string and protocol from accept string 176*cdf0e10cSrcweir // "<connectString>;<protocol>" 177*cdf0e10cSrcweir sal_Int32 nIndex1 = m_aAcceptString.indexOf( (sal_Unicode) ';' ); 178*cdf0e10cSrcweir if (nIndex1 < 0) throw IllegalArgumentException( 179*cdf0e10cSrcweir OUString::createFromAscii("Invalid accept-string format"), m_rContext, 1); 180*cdf0e10cSrcweir m_aConnectString = m_aAcceptString.copy( 0 , nIndex1 ).trim(); 181*cdf0e10cSrcweir nIndex1++; 182*cdf0e10cSrcweir sal_Int32 nIndex2 = m_aAcceptString.indexOf( (sal_Unicode) ';' , nIndex1 ); 183*cdf0e10cSrcweir if (nIndex2 < 0) nIndex2 = m_aAcceptString.getLength(); 184*cdf0e10cSrcweir m_aProtocol = m_aAcceptString.copy( nIndex1, nIndex2 - nIndex1 ); 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir // start accepting in new thread... 187*cdf0e10cSrcweir m_thread = osl_createThread(workerfunc, this); 188*cdf0e10cSrcweir m_bInit = sal_True; 189*cdf0e10cSrcweir bOk = sal_True; 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir // do we want to enable accepting? 193*cdf0e10cSrcweir sal_Bool bEnable = sal_False; 194*cdf0e10cSrcweir if (((nArgs == 1 && (aArguments[0] >>= bEnable)) || 195*cdf0e10cSrcweir (nArgs == 2 && (aArguments[1] >>= bEnable))) && 196*cdf0e10cSrcweir bEnable ) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir m_cEnable.set(); 199*cdf0e10cSrcweir bOk = sal_True; 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir if (!bOk) 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir throw IllegalArgumentException( 205*cdf0e10cSrcweir OUString::createFromAscii("invalid initialization"), m_rContext, 1); 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir // XServiceInfo 210*cdf0e10cSrcweir const sal_Char *Acceptor::serviceName = "com.sun.star.office.Acceptor"; 211*cdf0e10cSrcweir const sal_Char *Acceptor::implementationName = "com.sun.star.office.comp.Acceptor"; 212*cdf0e10cSrcweir const sal_Char *Acceptor::supportedServiceNames[] = {"com.sun.star.office.Acceptor", NULL}; 213*cdf0e10cSrcweir OUString Acceptor::impl_getImplementationName() 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir return OUString::createFromAscii( implementationName ); 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir OUString SAL_CALL Acceptor::getImplementationName() 218*cdf0e10cSrcweir throw (RuntimeException) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir return Acceptor::impl_getImplementationName(); 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir Sequence<OUString> Acceptor::impl_getSupportedServiceNames() 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir Sequence<OUString> aSequence; 225*cdf0e10cSrcweir for (int i=0; supportedServiceNames[i]!=NULL; i++) { 226*cdf0e10cSrcweir aSequence.realloc(i+1); 227*cdf0e10cSrcweir aSequence[i]=(OUString::createFromAscii(supportedServiceNames[i])); 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir return aSequence; 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir Sequence<OUString> SAL_CALL Acceptor::getSupportedServiceNames() 232*cdf0e10cSrcweir throw (RuntimeException) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir return Acceptor::impl_getSupportedServiceNames(); 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir sal_Bool SAL_CALL Acceptor::supportsService( const OUString&) 237*cdf0e10cSrcweir throw (RuntimeException) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir return sal_False; 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir // Factory 243*cdf0e10cSrcweir Reference< XInterface > Acceptor::impl_getInstance( const Reference< XMultiServiceFactory >& aFactory ) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir try { 246*cdf0e10cSrcweir return (XComponent*) new Acceptor( aFactory ); 247*cdf0e10cSrcweir } catch ( Exception& ) { 248*cdf0e10cSrcweir return (XComponent*) NULL; 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir // InstanceProvider 253*cdf0e10cSrcweir AccInstanceProvider::AccInstanceProvider(const Reference<XMultiServiceFactory>& aFactory, const Reference<XConnection>& rConnection) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir m_rSMgr = aFactory; 256*cdf0e10cSrcweir m_rConnection = rConnection; 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir AccInstanceProvider::~AccInstanceProvider() 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir Reference<XInterface> SAL_CALL AccInstanceProvider::getInstance (const OUString& aName ) 264*cdf0e10cSrcweir throw ( NoSuchElementException ) 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir Reference<XInterface> rInstance; 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir if ( aName.compareToAscii( "StarOffice.ServiceManager" ) == 0) 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir rInstance = Reference< XInterface >( m_rSMgr ); 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir else if(aName.compareToAscii( "StarOffice.ComponentContext" ) == 0 ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir rInstance = getComponentContext( m_rSMgr ); 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir else if ( aName.compareToAscii("StarOffice.NamingService" ) == 0 ) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir Reference< XNamingService > rNamingService( 280*cdf0e10cSrcweir m_rSMgr->createInstance( OUString::createFromAscii( "com.sun.star.uno.NamingService" )), 281*cdf0e10cSrcweir UNO_QUERY ); 282*cdf0e10cSrcweir if ( rNamingService.is() ) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir rNamingService->registerObject( 285*cdf0e10cSrcweir OUString::createFromAscii( "StarOffice.ServiceManager" ), m_rSMgr ); 286*cdf0e10cSrcweir rNamingService->registerObject( 287*cdf0e10cSrcweir OUString::createFromAscii( "StarOffice.ComponentContext" ), getComponentContext( m_rSMgr )); 288*cdf0e10cSrcweir rInstance = rNamingService; 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir /* 292*cdf0e10cSrcweir else if ( aName.compareToAscii("com.sun.star.ucb.RemoteContentProviderAcceptor" )) 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir Reference< XMultiServiceFactory > rSMgr = ::comphelper::getProcessServiceFactory(); 295*cdf0e10cSrcweir if ( rSMgr.is() ) { 296*cdf0e10cSrcweir try { 297*cdf0e10cSrcweir rInstance = rSMgr->createInstance( sObjectName ); 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir catch (Exception const &) {} 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir */ 303*cdf0e10cSrcweir return rInstance; 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir // component management stuff... 309*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 310*cdf0e10cSrcweir extern "C" 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir using namespace desktop; 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir void SAL_CALL 315*cdf0e10cSrcweir component_getImplementationEnvironment(const sal_Char **ppEnvironmentTypeName, uno_Environment **) 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ; 318*cdf0e10cSrcweir } 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir void * SAL_CALL 321*cdf0e10cSrcweir component_getFactory(const sal_Char *pImplementationName, void *pServiceManager, void *) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir void* pReturn = NULL ; 324*cdf0e10cSrcweir if ( pImplementationName && pServiceManager ) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir // Define variables which are used in following macros. 327*cdf0e10cSrcweir Reference< XSingleServiceFactory > xFactory; 328*cdf0e10cSrcweir Reference< XMultiServiceFactory > xServiceManager( 329*cdf0e10cSrcweir reinterpret_cast< XMultiServiceFactory* >(pServiceManager)); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir if (Acceptor::impl_getImplementationName().compareToAscii( pImplementationName ) == COMPARE_EQUAL ) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir xFactory = Reference< XSingleServiceFactory >( cppu::createSingleFactory( 334*cdf0e10cSrcweir xServiceManager, Acceptor::impl_getImplementationName(), 335*cdf0e10cSrcweir Acceptor::impl_getInstance, Acceptor::impl_getSupportedServiceNames()) ); 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir // Factory is valid - service was found. 339*cdf0e10cSrcweir if ( xFactory.is() ) 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir xFactory->acquire(); 342*cdf0e10cSrcweir pReturn = xFactory.get(); 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir 346*cdf0e10cSrcweir // Return with result of this operation. 347*cdf0e10cSrcweir return pReturn ; 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir } // extern "C" 351