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 #include "osl/security.hxx" 28 29 #include <uno/mapping.hxx> 30 31 #include <cppuhelper/factory.hxx> 32 #include <cppuhelper/implbase2.hxx> 33 #include <cppuhelper/implementationentry.hxx> 34 #include "cppuhelper/unourl.hxx" 35 #include "rtl/malformeduriexception.hxx" 36 37 #include <com/sun/star/lang/XServiceInfo.hpp> 38 #include <com/sun/star/lang/IllegalArgumentException.hpp> 39 #include <com/sun/star/connection/XConnector.hpp> 40 41 #include "connector.hxx" 42 43 #define IMPLEMENTATION_NAME "com.sun.star.comp.io.Connector" 44 #define SERVICE_NAME "com.sun.star.connection.Connector" 45 46 using namespace ::osl; 47 using namespace ::rtl; 48 using namespace ::cppu; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::lang; 51 using namespace ::com::sun::star::registry; 52 using namespace ::com::sun::star::connection; 53 54 namespace stoc_connector 55 { 56 rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; 57 58 class OConnector : public WeakImplHelper2< XConnector, XServiceInfo > 59 { 60 Reference< XMultiComponentFactory > _xSMgr; 61 Reference< XComponentContext > _xCtx; 62 public: 63 OConnector(const Reference< XComponentContext > &xCtx); 64 ~OConnector(); 65 // Methods 66 virtual Reference< XConnection > SAL_CALL connect( 67 const OUString& sConnectionDescription ) 68 throw( NoConnectException, ConnectionSetupException, 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 76 OConnector::OConnector(const Reference< XComponentContext > &xCtx) 77 : _xSMgr( xCtx->getServiceManager() ) 78 , _xCtx( xCtx ) 79 { 80 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 81 } 82 83 OConnector::~OConnector() 84 { 85 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 86 } 87 88 Reference< XConnection > SAL_CALL OConnector::connect( const OUString& sConnectionDescription ) 89 throw( NoConnectException, ConnectionSetupException, RuntimeException) 90 { 91 OSL_TRACE( 92 "connector %s\n", 93 OUStringToOString( 94 sConnectionDescription, RTL_TEXTENCODING_ASCII_US).getStr()); 95 96 // split string into tokens 97 try 98 { 99 cppu::UnoUrlDescriptor aDesc(sConnectionDescription); 100 101 Reference< XConnection > r; 102 if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( 103 "pipe"))) 104 { 105 rtl::OUString aName( 106 aDesc.getParameter( 107 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name")))); 108 109 PipeConnection *pConn = new PipeConnection( sConnectionDescription ); 110 111 if( pConn->m_pipe.create( aName.pData, osl_Pipe_OPEN, osl::Security() ) ) 112 { 113 r = Reference < XConnection > ( (XConnection * ) pConn ); 114 } 115 else 116 { 117 OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to pipe " ); 118 sMessage += aName; 119 sMessage += OUString::createFromAscii( "(" ); 120 sMessage += OUString::valueOf( (sal_Int32 ) pConn->m_pipe.getError() ); 121 sMessage += OUString::createFromAscii( ")" ); 122 delete pConn; 123 throw NoConnectException( sMessage ,Reference< XInterface > () ); 124 } 125 } 126 else if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( 127 "socket"))) 128 { 129 rtl::OUString aHost; 130 if (aDesc.hasParameter( 131 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host")))) 132 aHost = aDesc.getParameter( 133 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host"))); 134 else 135 aHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 136 "localhost")); 137 sal_uInt16 nPort = static_cast< sal_uInt16 >( 138 aDesc.getParameter( 139 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("port"))). 140 toInt32()); 141 bool bTcpNoDelay 142 = aDesc.getParameter( 143 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 144 "tcpnodelay"))).toInt32() != 0; 145 146 SocketConnection *pConn = new SocketConnection( sConnectionDescription); 147 148 SocketAddr AddrTarget( aHost.pData, nPort ); 149 if(pConn->m_socket.connect(AddrTarget) != osl_Socket_Ok) 150 { 151 OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to socket (" ); 152 OUString sError = pConn->m_socket.getErrorAsString(); 153 sMessage += sError; 154 sMessage += OUString::createFromAscii( ")" ); 155 delete pConn; 156 throw NoConnectException( sMessage, Reference < XInterface > () ); 157 } 158 if( bTcpNoDelay ) 159 { 160 sal_Int32 nTcpNoDelay = sal_True; 161 pConn->m_socket.setOption( osl_Socket_OptionTcpNoDelay , &nTcpNoDelay, 162 sizeof( nTcpNoDelay ) , osl_Socket_LevelTcp ); 163 } 164 pConn->completeConnectionString(); 165 r = Reference< XConnection > ( (XConnection * ) pConn ); 166 } 167 else 168 { 169 OUString delegatee = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector.")); 170 delegatee += aDesc.getName(); 171 172 OSL_TRACE( 173 "connector: trying to get service %s\n", 174 OUStringToOString( 175 delegatee, RTL_TEXTENCODING_ASCII_US).getStr()); 176 Reference<XConnector> xConnector( 177 _xSMgr->createInstanceWithContext(delegatee, _xCtx), UNO_QUERY ); 178 179 if(!xConnector.is()) 180 { 181 OUString message(RTL_CONSTASCII_USTRINGPARAM("Connector: unknown delegatee ")); 182 message += delegatee; 183 184 throw ConnectionSetupException(message, Reference<XInterface>()); 185 } 186 187 sal_Int32 index = sConnectionDescription.indexOf((sal_Unicode) ','); 188 189 r = xConnector->connect(sConnectionDescription.copy(index + 1).trim()); 190 } 191 return r; 192 } 193 catch (rtl::MalformedUriException & rEx) 194 { 195 throw ConnectionSetupException(rEx.getMessage(), 196 Reference< XInterface > ()); 197 } 198 } 199 200 Sequence< OUString > connector_getSupportedServiceNames() 201 { 202 static Sequence < OUString > *pNames = 0; 203 if( ! pNames ) 204 { 205 MutexGuard guard( Mutex::getGlobalMutex() ); 206 if( !pNames ) 207 { 208 static Sequence< OUString > seqNames(1); 209 seqNames.getArray()[0] = OUString::createFromAscii( SERVICE_NAME ); 210 pNames = &seqNames; 211 } 212 } 213 return *pNames; 214 } 215 216 OUString connector_getImplementationName() 217 { 218 return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ); 219 } 220 221 OUString OConnector::getImplementationName() throw() 222 { 223 return connector_getImplementationName(); 224 } 225 226 sal_Bool OConnector::supportsService(const OUString& ServiceName) throw() 227 { 228 Sequence< OUString > aSNL = getSupportedServiceNames(); 229 const OUString * pArray = aSNL.getConstArray(); 230 231 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 232 if( pArray[i] == ServiceName ) 233 return sal_True; 234 235 return sal_False; 236 } 237 238 Sequence< OUString > OConnector::getSupportedServiceNames(void) throw() 239 { 240 return connector_getSupportedServiceNames(); 241 } 242 243 Reference< XInterface > SAL_CALL connector_CreateInstance( const Reference< XComponentContext > & xCtx) 244 { 245 return Reference < XInterface >( ( OWeakObject * ) new OConnector(xCtx) ); 246 } 247 248 249 } 250 using namespace stoc_connector; 251 252 static struct ImplementationEntry g_entries[] = 253 { 254 { 255 connector_CreateInstance, connector_getImplementationName , 256 connector_getSupportedServiceNames, createSingleComponentFactory , 257 &g_moduleCount.modCnt , 0 258 }, 259 { 0, 0, 0, 0, 0, 0 } 260 }; 261 262 extern "C" 263 { 264 265 sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) 266 { 267 return g_moduleCount.canUnload( &g_moduleCount , pTime ); 268 } 269 270 //================================================================================================== 271 void SAL_CALL component_getImplementationEnvironment( 272 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 273 { 274 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 275 } 276 //================================================================================================== 277 void * SAL_CALL component_getFactory( 278 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) 279 { 280 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); 281 } 282 283 } 284 285 286