bump product version to 4.1.6.2
[LibreOffice.git] / desktop / source / offacc / acceptor.cxx
bloba9b08f476d3a5ee4de8d1aa430f98dc629ec0465
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "acceptor.hxx"
22 #include <com/sun/star/bridge/BridgeFactory.hpp>
23 #include <com/sun/star/uno/XNamingService.hpp>
24 #include <comphelper/processfactory.hxx>
25 #include <cppuhelper/factory.hxx>
26 #include <cppuhelper/supportsservice.hxx>
28 using namespace ::osl;
29 using namespace css::bridge;
30 using namespace css::connection;
31 using namespace css::container;
32 using namespace css::lang;
33 using namespace css::uno;
35 namespace desktop
38 extern "C" void offacc_workerfunc (void * acc)
40 ((Acceptor*)acc)->run();
43 Mutex Acceptor::m_aMutex;
45 Acceptor::Acceptor( const Reference< XMultiServiceFactory >& rFactory )
46 : m_thread(NULL)
47 , m_aAcceptString()
48 , m_aConnectString()
49 , m_aProtocol()
50 , m_bInit(sal_False)
51 , m_bDying(false)
53 m_rSMgr = rFactory;
54 // get component context
55 m_rContext = comphelper::getComponentContext(m_rSMgr);
56 m_rAcceptor = Reference< XAcceptor > (m_rSMgr->createInstance(
57 OUString("com.sun.star.connection.Acceptor" )),
58 UNO_QUERY );
59 m_rBridgeFactory = BridgeFactory::create(m_rContext);
63 Acceptor::~Acceptor()
65 m_rAcceptor->stopAccepting();
66 oslThread t;
68 osl::MutexGuard g(m_aMutex);
69 t = m_thread;
71 //prevent locking if the thread is still waiting
72 m_bDying = true;
73 m_cEnable.set();
74 osl_joinWithThread(t);
76 // Make the final state of m_bridges visible to this thread (since
77 // m_thread is joined, the code that follows is the only one left
78 // accessing m_bridges):
79 osl::MutexGuard g(m_aMutex);
81 for (;;) {
82 com::sun::star::uno::Reference< com::sun::star::bridge::XBridge > b(
83 m_bridges.remove());
84 if (!b.is()) {
85 break;
87 com::sun::star::uno::Reference< com::sun::star::lang::XComponent >(
88 b, com::sun::star::uno::UNO_QUERY_THROW)->dispose();
92 void SAL_CALL Acceptor::run()
94 while ( m_rAcceptor.is() )
96 RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) Acceptor::run" );
97 try
99 // wait until we get enabled
100 RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\
101 "Acceptor::run waiting for office to come up");
102 m_cEnable.wait();
103 if (m_bDying) //see destructor
104 break;
105 RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\
106 "Acceptor::run now enabled and continuing");
108 // accept connection
109 Reference< XConnection > rConnection = m_rAcceptor->accept( m_aConnectString );
110 // if we return without a valid connection we mus assume that the acceptor
111 // is destructed so we break out of the run method terminating the thread
112 if (! rConnection.is()) break;
113 OUString aDescription = rConnection->getDescription();
114 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::run connection %s",
115 OUStringToOString(aDescription, RTL_TEXTENCODING_ASCII_US).getStr());
117 // create instanceprovider for this connection
118 Reference< XInstanceProvider > rInstanceProvider(
119 (XInstanceProvider*)new AccInstanceProvider(m_rSMgr, rConnection));
120 // create the bridge. The remote end will have a reference to this bridge
121 // thus preventing the bridge from being disposed. When the remote end releases
122 // the bridge, it will be destructed.
123 Reference< XBridge > rBridge = m_rBridgeFactory->createBridge(
124 OUString() ,m_aProtocol ,rConnection ,rInstanceProvider );
125 osl::MutexGuard g(m_aMutex);
126 m_bridges.add(rBridge);
127 } catch (const Exception& e) {
128 SAL_WARN("desktop", "caught Exception \"" << e.Message << "\"");
129 // connection failed...
130 // something went wrong during connection setup.
131 // just wait for a new connection to accept
136 // XInitialize
137 void SAL_CALL Acceptor::initialize( const Sequence<Any>& aArguments )
138 throw( Exception )
140 // prevent multiple initialization
141 ClearableMutexGuard aGuard( m_aMutex );
142 RTL_LOGFILE_CONTEXT( aLog, "destop (lo119109) Acceptor::initialize()" );
144 sal_Bool bOk = sal_False;
146 // arg count
147 int nArgs = aArguments.getLength();
149 // not yet initialized and acceptstring
150 if (!m_bInit && nArgs > 0 && (aArguments[0] >>= m_aAcceptString))
152 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::initialize string=%s",
153 OUStringToOString(m_aAcceptString, RTL_TEXTENCODING_ASCII_US).getStr());
155 // get connect string and protocol from accept string
156 // "<connectString>;<protocol>"
157 sal_Int32 nIndex1 = m_aAcceptString.indexOf( (sal_Unicode) ';' );
158 if (nIndex1 < 0) throw IllegalArgumentException(
159 OUString("Invalid accept-string format"), m_rContext, 1);
160 m_aConnectString = m_aAcceptString.copy( 0 , nIndex1 ).trim();
161 nIndex1++;
162 sal_Int32 nIndex2 = m_aAcceptString.indexOf( (sal_Unicode) ';' , nIndex1 );
163 if (nIndex2 < 0) nIndex2 = m_aAcceptString.getLength();
164 m_aProtocol = m_aAcceptString.copy( nIndex1, nIndex2 - nIndex1 );
166 // start accepting in new thread...
167 m_thread = osl_createThread(offacc_workerfunc, this);
168 m_bInit = sal_True;
169 bOk = sal_True;
172 // do we want to enable accepting?
173 sal_Bool bEnable = sal_False;
174 if (((nArgs == 1 && (aArguments[0] >>= bEnable)) ||
175 (nArgs == 2 && (aArguments[1] >>= bEnable))) &&
176 bEnable )
178 m_cEnable.set();
179 bOk = sal_True;
182 if (!bOk)
184 throw IllegalArgumentException(
185 OUString("invalid initialization"), m_rContext, 1);
189 // XServiceInfo
190 const sal_Char *Acceptor::serviceName = "com.sun.star.office.Acceptor";
191 const sal_Char *Acceptor::implementationName = "com.sun.star.office.comp.Acceptor";
192 const sal_Char *Acceptor::supportedServiceNames[] = {"com.sun.star.office.Acceptor", NULL};
193 OUString Acceptor::impl_getImplementationName()
195 return OUString::createFromAscii( implementationName );
197 OUString SAL_CALL Acceptor::getImplementationName()
198 throw (RuntimeException)
200 return Acceptor::impl_getImplementationName();
202 Sequence<OUString> Acceptor::impl_getSupportedServiceNames()
204 Sequence<OUString> aSequence;
205 for (int i=0; supportedServiceNames[i]!=NULL; i++) {
206 aSequence.realloc(i+1);
207 aSequence[i]=(OUString::createFromAscii(supportedServiceNames[i]));
209 return aSequence;
211 Sequence<OUString> SAL_CALL Acceptor::getSupportedServiceNames()
212 throw (RuntimeException)
214 return Acceptor::impl_getSupportedServiceNames();
217 sal_Bool Acceptor::supportsService(OUString const & ServiceName)
218 throw (css::uno::RuntimeException)
220 return cppu::supportsService(this, ServiceName);
223 // Factory
224 Reference< XInterface > Acceptor::impl_getInstance( const Reference< XMultiServiceFactory >& aFactory )
226 try {
227 return (XComponent*) new Acceptor( aFactory );
228 } catch ( const Exception& ) {
229 return (XComponent*) NULL;
233 // InstanceProvider
234 AccInstanceProvider::AccInstanceProvider(const Reference<XMultiServiceFactory>& aFactory, const Reference<XConnection>& rConnection)
236 m_rSMgr = aFactory;
237 m_rConnection = rConnection;
240 AccInstanceProvider::~AccInstanceProvider()
244 Reference<XInterface> SAL_CALL AccInstanceProvider::getInstance (const OUString& aName )
245 throw ( NoSuchElementException )
248 Reference<XInterface> rInstance;
250 if ( aName.compareToAscii( "StarOffice.ServiceManager" ) == 0)
252 rInstance = Reference< XInterface >( m_rSMgr );
254 else if(aName.compareToAscii( "StarOffice.ComponentContext" ) == 0 )
256 rInstance = comphelper::getComponentContext( m_rSMgr );
258 else if ( aName.compareToAscii("StarOffice.NamingService" ) == 0 )
260 Reference< XNamingService > rNamingService(
261 m_rSMgr->createInstance( OUString("com.sun.star.uno.NamingService" )),
262 UNO_QUERY );
263 if ( rNamingService.is() )
265 rNamingService->registerObject(
266 OUString("StarOffice.ServiceManager" ), m_rSMgr );
267 rNamingService->registerObject(
268 OUString("StarOffice.ComponentContext" ), comphelper::getComponentContext( m_rSMgr ));
269 rInstance = rNamingService;
272 return rInstance;
277 // component management stuff...
278 // ----------------------------------------------------------------------------
279 extern "C"
281 using namespace desktop;
283 SAL_DLLPUBLIC_EXPORT void * SAL_CALL offacc_component_getFactory(const sal_Char *pImplementationName, void *pServiceManager, void *)
285 void* pReturn = NULL ;
286 if ( pImplementationName && pServiceManager )
288 // Define variables which are used in following macros.
289 Reference< XSingleServiceFactory > xFactory;
290 Reference< XMultiServiceFactory > xServiceManager(
291 reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
293 if (Acceptor::impl_getImplementationName().equalsAscii( pImplementationName ) )
295 xFactory = Reference< XSingleServiceFactory >( cppu::createSingleFactory(
296 xServiceManager, Acceptor::impl_getImplementationName(),
297 Acceptor::impl_getInstance, Acceptor::impl_getSupportedServiceNames()) );
300 // Factory is valid - service was found.
301 if ( xFactory.is() )
303 xFactory->acquire();
304 pReturn = xFactory.get();
308 // Return with result of this operation.
309 return pReturn ;
312 } // extern "C"
314 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */