Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <osl/mutex.hxx>
21 :
22 : #include <uno/mapping.hxx>
23 :
24 : #include <cppuhelper/factory.hxx>
25 : #include <cppuhelper/implbase2.hxx>
26 : #include <cppuhelper/implementationentry.hxx>
27 : #include <cppuhelper/supportsservice.hxx>
28 : #include "cppuhelper/unourl.hxx"
29 : #include "rtl/malformeduriexception.hxx"
30 :
31 : #include <com/sun/star/connection/XAcceptor.hpp>
32 : #include <com/sun/star/lang/XServiceInfo.hpp>
33 :
34 : #include "services.hxx"
35 : #include "acceptor.hxx"
36 :
37 : #define IMPLEMENTATION_NAME "com.sun.star.comp.io.Acceptor"
38 : #define SERVICE_NAME "com.sun.star.connection.Acceptor"
39 :
40 : using namespace ::osl;
41 : using namespace ::cppu;
42 : using namespace ::com::sun::star::uno;
43 : using namespace ::com::sun::star::lang;
44 : using namespace ::com::sun::star::registry;
45 : using namespace ::com::sun::star::connection;
46 :
47 : namespace io_acceptor
48 : {
49 : class OAcceptor : public WeakImplHelper2< XAcceptor, XServiceInfo >
50 : {
51 : public:
52 : OAcceptor(const Reference< XComponentContext > & xCtx);
53 : virtual ~OAcceptor();
54 : public:
55 : // Methods
56 : virtual Reference< XConnection > SAL_CALL accept( const OUString& sConnectionDescription )
57 : throw( AlreadyAcceptingException,
58 : ConnectionSetupException,
59 : IllegalArgumentException,
60 : RuntimeException, std::exception) SAL_OVERRIDE;
61 : virtual void SAL_CALL stopAccepting( ) throw( RuntimeException, std::exception) SAL_OVERRIDE;
62 :
63 : public: // XServiceInfo
64 : virtual OUString SAL_CALL getImplementationName() throw(std::exception) SAL_OVERRIDE;
65 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(std::exception) SAL_OVERRIDE;
66 : virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(std::exception) SAL_OVERRIDE;
67 :
68 : private:
69 : PipeAcceptor *m_pPipe;
70 : SocketAcceptor *m_pSocket;
71 : Mutex m_mutex;
72 : OUString m_sLastDescription;
73 : bool m_bInAccept;
74 :
75 : Reference< XMultiComponentFactory > _xSMgr;
76 : Reference< XComponentContext > _xCtx;
77 : Reference<XAcceptor> _xAcceptor;
78 : };
79 :
80 :
81 117 : OAcceptor::OAcceptor( const Reference< XComponentContext > & xCtx )
82 : : m_pPipe( 0 )
83 : , m_pSocket( 0 )
84 : , m_bInAccept( false )
85 117 : , _xSMgr( xCtx->getServiceManager() )
86 234 : , _xCtx( xCtx )
87 117 : {}
88 :
89 351 : OAcceptor::~OAcceptor()
90 : {
91 117 : if( m_pPipe )
92 : {
93 64 : delete m_pPipe;
94 : }
95 117 : if( m_pSocket )
96 : {
97 0 : delete m_pSocket;
98 : }
99 234 : }
100 :
101 : struct BeingInAccept
102 : {
103 127 : BeingInAccept( bool *pFlag,const OUString & sConnectionDescription ) throw( AlreadyAcceptingException)
104 127 : : m_pFlag( pFlag )
105 : {
106 127 : if( *m_pFlag )
107 : {
108 0 : OUString sMessage( "AlreadyAcceptingException :" );
109 0 : sMessage += sConnectionDescription;
110 0 : throw AlreadyAcceptingException( sMessage );
111 : }
112 127 : *m_pFlag = true;
113 127 : }
114 127 : ~BeingInAccept()
115 : {
116 127 : *m_pFlag = false;
117 127 : }
118 : bool *m_pFlag;
119 : };
120 :
121 127 : Reference< XConnection > OAcceptor::accept( const OUString &sConnectionDescription )
122 : throw( AlreadyAcceptingException,
123 : ConnectionSetupException,
124 : IllegalArgumentException,
125 : RuntimeException, std::exception)
126 : {
127 : OSL_TRACE(
128 : "acceptor %s\n",
129 : OUStringToOString(
130 : sConnectionDescription, RTL_TEXTENCODING_ASCII_US).getStr());
131 : // if there is a thread alread accepting in this object, throw an exception.
132 127 : struct BeingInAccept guard( &m_bInAccept, sConnectionDescription );
133 :
134 127 : Reference< XConnection > r;
135 190 : if( !m_sLastDescription.isEmpty() &&
136 63 : m_sLastDescription != sConnectionDescription )
137 : {
138 : // instantiate another acceptor for different ports
139 0 : OUString sMessage = "acceptor::accept called multiple times with different conncetion strings\n";
140 0 : throw ConnectionSetupException( sMessage );
141 : }
142 :
143 127 : if( m_sLastDescription.isEmpty() )
144 : {
145 : // setup the acceptor
146 : try
147 : {
148 64 : cppu::UnoUrlDescriptor aDesc(sConnectionDescription);
149 64 : if ( aDesc.getName() == "pipe" )
150 : {
151 : OUString aName(
152 : aDesc.getParameter(
153 64 : OUString("name")));
154 :
155 64 : m_pPipe = new PipeAcceptor(aName, sConnectionDescription);
156 :
157 : try
158 : {
159 64 : m_pPipe->init();
160 : }
161 0 : catch( ... )
162 : {
163 : {
164 0 : MutexGuard g( m_mutex );
165 0 : delete m_pPipe;
166 0 : m_pPipe = 0;
167 : }
168 0 : throw;
169 64 : }
170 : }
171 0 : else if ( aDesc.getName() == "socket" )
172 : {
173 0 : OUString aHost;
174 0 : if (aDesc.hasParameter(
175 0 : OUString("host")))
176 0 : aHost = aDesc.getParameter(
177 0 : OUString("host"));
178 : else
179 0 : aHost = "localhost";
180 : sal_uInt16 nPort = static_cast< sal_uInt16 >(
181 : aDesc.getParameter(
182 : OUString("port")).
183 0 : toInt32());
184 : bool bTcpNoDelay
185 : = aDesc.getParameter(
186 0 : OUString("tcpnodelay")).toInt32() != 0;
187 :
188 : m_pSocket = new SocketAcceptor(
189 0 : aHost, nPort, bTcpNoDelay, sConnectionDescription);
190 :
191 : try
192 : {
193 0 : m_pSocket->init();
194 : }
195 0 : catch( ... )
196 : {
197 : {
198 0 : MutexGuard g( m_mutex );
199 0 : delete m_pSocket;
200 0 : m_pSocket = 0;
201 : }
202 0 : throw;
203 0 : }
204 : }
205 : else
206 : {
207 0 : OUString delegatee = "com.sun.star.connection.Acceptor." + aDesc.getName();
208 :
209 : OSL_TRACE(
210 : "trying to get service %s\n",
211 : OUStringToOString(
212 : delegatee, RTL_TEXTENCODING_ASCII_US).getStr());
213 0 : _xAcceptor = Reference<XAcceptor>(
214 0 : _xSMgr->createInstanceWithContext(delegatee, _xCtx), UNO_QUERY);
215 :
216 0 : if(!_xAcceptor.is())
217 : {
218 0 : OUString message("Acceptor: unknown delegatee ");
219 0 : message += delegatee;
220 :
221 0 : throw ConnectionSetupException(message);
222 0 : }
223 64 : }
224 : }
225 0 : catch (const rtl::MalformedUriException & rEx)
226 : {
227 : throw IllegalArgumentException(
228 0 : rEx.getMessage(),
229 : Reference< XInterface > (),
230 0 : 0 );
231 : }
232 64 : m_sLastDescription = sConnectionDescription;
233 : }
234 :
235 127 : if( m_pPipe )
236 : {
237 127 : r = m_pPipe->accept();
238 : }
239 0 : else if( m_pSocket )
240 : {
241 0 : r = m_pSocket->accept();
242 : }
243 : else
244 : {
245 0 : r = _xAcceptor->accept(sConnectionDescription);
246 : }
247 :
248 127 : return r;
249 : }
250 :
251 115 : void SAL_CALL OAcceptor::stopAccepting( ) throw( RuntimeException, std::exception)
252 : {
253 115 : MutexGuard guard( m_mutex );
254 :
255 115 : if( m_pPipe )
256 : {
257 63 : m_pPipe->stopAccepting();
258 : }
259 52 : else if ( m_pSocket )
260 : {
261 0 : m_pSocket->stopAccepting();
262 : }
263 52 : else if( _xAcceptor.is() )
264 : {
265 0 : _xAcceptor->stopAccepting();
266 115 : }
267 :
268 115 : }
269 :
270 174 : OUString acceptor_getImplementationName()
271 : {
272 174 : return OUString( IMPLEMENTATION_NAME );
273 : }
274 :
275 117 : Reference< XInterface > SAL_CALL acceptor_CreateInstance( const Reference< XComponentContext > & xCtx)
276 : {
277 117 : return Reference < XInterface >( static_cast<OWeakObject *>(new OAcceptor(xCtx)) );
278 : }
279 :
280 118 : Sequence< OUString > acceptor_getSupportedServiceNames()
281 : {
282 118 : Sequence< OUString > seqNames(1);
283 118 : seqNames.getArray()[0] = SERVICE_NAME;
284 118 : return seqNames;
285 : }
286 :
287 1 : OUString OAcceptor::getImplementationName() throw(std::exception)
288 : {
289 1 : return acceptor_getImplementationName();
290 : }
291 :
292 0 : sal_Bool OAcceptor::supportsService(const OUString& ServiceName) throw(std::exception)
293 : {
294 0 : return cppu::supportsService(this, ServiceName);
295 : }
296 :
297 1 : Sequence< OUString > OAcceptor::getSupportedServiceNames() throw(std::exception)
298 : {
299 1 : return acceptor_getSupportedServiceNames();
300 : }
301 :
302 :
303 : }
304 :
305 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|