1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
;
38 extern "C" void offacc_workerfunc (void * acc
)
40 ((Acceptor
*)acc
)->run();
43 Mutex
Acceptor::m_aMutex
;
45 Acceptor::Acceptor( const Reference
< XMultiServiceFactory
>& 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" )),
59 m_rBridgeFactory
= BridgeFactory::create(m_rContext
);
65 m_rAcceptor
->stopAccepting();
68 osl::MutexGuard
g(m_aMutex
);
71 //prevent locking if the thread is still waiting
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
);
82 com::sun::star::uno::Reference
< com::sun::star::bridge::XBridge
> b(
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" );
99 // wait until we get enabled
100 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "desktop (lo119109)"\
101 "Acceptor::run waiting for office to come up");
103 if (m_bDying
) //see destructor
105 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "desktop (lo119109)"\
106 "Acceptor::run now enabled and continuing");
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
137 void SAL_CALL
Acceptor::initialize( const Sequence
<Any
>& aArguments
)
140 // prevent multiple initialization
141 ClearableMutexGuard
aGuard( m_aMutex
);
142 RTL_LOGFILE_CONTEXT( aLog
, "destop (lo119109) Acceptor::initialize()" );
144 sal_Bool bOk
= sal_False
;
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();
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);
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
))) &&
184 throw IllegalArgumentException(
185 OUString("invalid initialization"), m_rContext
, 1);
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
]));
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
);
224 Reference
< XInterface
> Acceptor::impl_getInstance( const Reference
< XMultiServiceFactory
>& aFactory
)
227 return (XComponent
*) new Acceptor( aFactory
);
228 } catch ( const Exception
& ) {
229 return (XComponent
*) NULL
;
234 AccInstanceProvider::AccInstanceProvider(const Reference
<XMultiServiceFactory
>& aFactory
, const Reference
<XConnection
>& rConnection
)
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" )),
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
;
277 // component management stuff...
278 // ----------------------------------------------------------------------------
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.
304 pReturn
= xFactory
.get();
308 // Return with result of this operation.
314 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */