1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_io.hxx" 26 #include <osl/mutex.hxx> 27 28 #include <uno/mapping.hxx> 29 30 #include <cppuhelper/factory.hxx> 31 #include <cppuhelper/implbase2.hxx> 32 #include <cppuhelper/implementationentry.hxx> 33 #include "cppuhelper/unourl.hxx" 34 #include "rtl/malformeduriexception.hxx" 35 36 #include <com/sun/star/connection/XAcceptor.hpp> 37 #include <com/sun/star/lang/XServiceInfo.hpp> 38 39 #include "acceptor.hxx" 40 41 #define IMPLEMENTATION_NAME "com.sun.star.comp.io.Acceptor" 42 #define SERVICE_NAME "com.sun.star.connection.Acceptor" 43 44 using namespace ::osl; 45 using namespace ::rtl; 46 using namespace ::cppu; 47 using namespace ::com::sun::star::uno; 48 using namespace ::com::sun::star::lang; 49 using namespace ::com::sun::star::registry; 50 using namespace ::com::sun::star::connection; 51 52 namespace io_acceptor 53 { 54 rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; 55 56 class OAcceptor : public WeakImplHelper2< XAcceptor, XServiceInfo > 57 { 58 public: 59 OAcceptor(const Reference< XComponentContext > & xCtx); 60 virtual ~OAcceptor(); 61 public: 62 // Methods 63 virtual Reference< XConnection > SAL_CALL accept( const OUString& sConnectionDescription ) 64 throw( AlreadyAcceptingException, 65 ConnectionSetupException, 66 IllegalArgumentException, 67 RuntimeException); 68 virtual void SAL_CALL stopAccepting( ) throw( RuntimeException); 69 70 public: // XServiceInfo 71 virtual OUString SAL_CALL getImplementationName() throw(); 72 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(); 73 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(); 74 75 private: 76 PipeAcceptor *m_pPipe; 77 SocketAcceptor *m_pSocket; 78 Mutex m_mutex; 79 OUString m_sLastDescription; 80 sal_Bool m_bInAccept; 81 82 Reference< XMultiComponentFactory > _xSMgr; 83 Reference< XComponentContext > _xCtx; 84 Reference<XAcceptor> _xAcceptor; 85 }; 86 87 88 OAcceptor::OAcceptor( const Reference< XComponentContext > & xCtx ) 89 : m_pPipe( 0 ) 90 , m_pSocket( 0 ) 91 , m_bInAccept( sal_False ) 92 , _xSMgr( xCtx->getServiceManager() ) 93 , _xCtx( xCtx ) 94 { 95 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 96 } 97 98 OAcceptor::~OAcceptor() 99 { 100 if( m_pPipe ) 101 { 102 delete m_pPipe; 103 } 104 if( m_pSocket ) 105 { 106 delete m_pSocket; 107 } 108 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 109 } 110 111 struct BeingInAccept 112 { 113 BeingInAccept( sal_Bool *pFlag,const OUString & sConnectionDescription ) throw( AlreadyAcceptingException) 114 : m_pFlag( pFlag ) 115 { 116 if( *m_pFlag ) 117 { 118 OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "AlreadyAcceptingException :" ) ); 119 sMessage += sConnectionDescription; 120 throw AlreadyAcceptingException( sMessage , Reference< XInterface > () ); 121 } 122 *m_pFlag = sal_True; 123 } 124 ~BeingInAccept() 125 { 126 *m_pFlag = sal_False; 127 } 128 sal_Bool *m_pFlag; 129 }; 130 131 Reference< XConnection > OAcceptor::accept( const OUString &sConnectionDescription ) 132 throw( AlreadyAcceptingException, 133 ConnectionSetupException, 134 IllegalArgumentException, 135 RuntimeException) 136 { 137 OSL_TRACE( 138 "acceptor %s\n", 139 OUStringToOString( 140 sConnectionDescription, RTL_TEXTENCODING_ASCII_US).getStr()); 141 // if there is a thread alread accepting in this object, throw an exception. 142 struct BeingInAccept guard( &m_bInAccept, sConnectionDescription ); 143 144 Reference< XConnection > r; 145 if( m_sLastDescription.getLength() && 146 m_sLastDescription != sConnectionDescription ) 147 { 148 // instantiate another acceptor for different ports 149 OUString sMessage = OUString( RTL_CONSTASCII_USTRINGPARAM( 150 "acceptor::accept called multiple times with different conncetion strings\n" ) ); 151 throw ConnectionSetupException( sMessage, Reference< XInterface > () ); 152 } 153 154 if( ! m_sLastDescription.getLength() ) 155 { 156 // setup the acceptor 157 try 158 { 159 cppu::UnoUrlDescriptor aDesc(sConnectionDescription); 160 if (aDesc.getName().equalsAsciiL( 161 RTL_CONSTASCII_STRINGPARAM("pipe"))) 162 { 163 rtl::OUString aName( 164 aDesc.getParameter( 165 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 166 "name")))); 167 168 m_pPipe = new PipeAcceptor(aName, sConnectionDescription); 169 170 try 171 { 172 m_pPipe->init(); 173 } 174 catch( ... ) 175 { 176 { 177 MutexGuard g( m_mutex ); 178 delete m_pPipe; 179 m_pPipe = 0; 180 } 181 throw; 182 } 183 } 184 else if (aDesc.getName().equalsAsciiL( 185 RTL_CONSTASCII_STRINGPARAM("socket"))) 186 { 187 rtl::OUString aHost; 188 if (aDesc.hasParameter( 189 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host")))) 190 aHost = aDesc.getParameter( 191 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host"))); 192 else 193 aHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 194 "localhost")); 195 sal_uInt16 nPort = static_cast< sal_uInt16 >( 196 aDesc.getParameter( 197 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("port"))). 198 toInt32()); 199 bool bTcpNoDelay 200 = aDesc.getParameter( 201 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 202 "tcpnodelay"))).toInt32() != 0; 203 204 m_pSocket = new SocketAcceptor( 205 aHost, nPort, bTcpNoDelay, sConnectionDescription); 206 207 try 208 { 209 m_pSocket->init(); 210 } 211 catch( ... ) 212 { 213 { 214 MutexGuard g( m_mutex ); 215 delete m_pSocket; 216 m_pSocket = 0; 217 } 218 throw; 219 } 220 } 221 else 222 { 223 OUString delegatee = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor.")); 224 delegatee += aDesc.getName(); 225 226 OSL_TRACE( 227 "trying to get service %s\n", 228 OUStringToOString( 229 delegatee, RTL_TEXTENCODING_ASCII_US).getStr()); 230 _xAcceptor = Reference<XAcceptor>( 231 _xSMgr->createInstanceWithContext(delegatee, _xCtx), UNO_QUERY); 232 233 if(!_xAcceptor.is()) 234 { 235 OUString message(RTL_CONSTASCII_USTRINGPARAM("Acceptor: unknown delegatee ")); 236 message += delegatee; 237 238 throw ConnectionSetupException(message, Reference<XInterface>()); 239 } 240 } 241 } 242 catch (rtl::MalformedUriException & rEx) 243 { 244 throw IllegalArgumentException( 245 rEx.getMessage(), 246 Reference< XInterface > (), 247 0 ); 248 } 249 m_sLastDescription = sConnectionDescription; 250 } 251 252 if( m_pPipe ) 253 { 254 r = m_pPipe->accept(); 255 } 256 else if( m_pSocket ) 257 { 258 r = m_pSocket->accept(); 259 } 260 else 261 { 262 r = _xAcceptor->accept(sConnectionDescription); 263 } 264 265 return r; 266 } 267 268 void SAL_CALL OAcceptor::stopAccepting( ) throw( RuntimeException) 269 { 270 MutexGuard guard( m_mutex ); 271 272 if( m_pPipe ) 273 { 274 m_pPipe->stopAccepting(); 275 } 276 else if ( m_pSocket ) 277 { 278 m_pSocket->stopAccepting(); 279 } 280 else if( _xAcceptor.is() ) 281 { 282 _xAcceptor->stopAccepting(); 283 } 284 285 } 286 287 OUString acceptor_getImplementationName() 288 { 289 return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ); 290 } 291 292 Reference< XInterface > SAL_CALL acceptor_CreateInstance( const Reference< XComponentContext > & xCtx) 293 { 294 return Reference < XInterface >( ( OWeakObject * ) new OAcceptor(xCtx) ); 295 } 296 297 Sequence< OUString > acceptor_getSupportedServiceNames() 298 { 299 static Sequence < OUString > *pNames = 0; 300 if( ! pNames ) 301 { 302 MutexGuard guard( Mutex::getGlobalMutex() ); 303 if( !pNames ) 304 { 305 static Sequence< OUString > seqNames(1); 306 seqNames.getArray()[0] = OUString::createFromAscii( SERVICE_NAME ); 307 pNames = &seqNames; 308 } 309 } 310 return *pNames; 311 } 312 313 OUString OAcceptor::getImplementationName() throw() 314 { 315 return acceptor_getImplementationName(); 316 } 317 318 sal_Bool OAcceptor::supportsService(const OUString& ServiceName) throw() 319 { 320 Sequence< OUString > aSNL = getSupportedServiceNames(); 321 const OUString * pArray = aSNL.getConstArray(); 322 323 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 324 if( pArray[i] == ServiceName ) 325 return sal_True; 326 327 return sal_False; 328 } 329 330 Sequence< OUString > OAcceptor::getSupportedServiceNames(void) throw() 331 { 332 return acceptor_getSupportedServiceNames(); 333 } 334 335 336 } 337 338 using namespace io_acceptor; 339 340 static struct ImplementationEntry g_entries[] = 341 { 342 { 343 acceptor_CreateInstance, acceptor_getImplementationName , 344 acceptor_getSupportedServiceNames, createSingleComponentFactory , 345 &g_moduleCount.modCnt , 0 346 }, 347 { 0, 0, 0, 0, 0, 0 } 348 }; 349 350 extern "C" 351 { 352 353 sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) 354 { 355 return g_moduleCount.canUnload( &g_moduleCount , pTime ); 356 } 357 358 //================================================================================================== 359 void SAL_CALL component_getImplementationEnvironment( 360 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 361 { 362 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 363 } 364 //================================================================================================== 365 void * SAL_CALL component_getFactory( 366 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) 367 { 368 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); 369 } 370 } 371 372 373 374