xref: /trunk/main/io/source/connector/connector.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_io.hxx"
30 #include <osl/mutex.hxx>
31 #include "osl/security.hxx"
32 
33 #include <uno/mapping.hxx>
34 
35 #include <cppuhelper/factory.hxx>
36 #include <cppuhelper/implbase2.hxx>
37 #include <cppuhelper/implementationentry.hxx>
38 #include "cppuhelper/unourl.hxx"
39 #include "rtl/malformeduriexception.hxx"
40 
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/lang/IllegalArgumentException.hpp>
43 #include <com/sun/star/connection/XConnector.hpp>
44 
45 #include "connector.hxx"
46 
47 #define IMPLEMENTATION_NAME "com.sun.star.comp.io.Connector"
48 #define SERVICE_NAME "com.sun.star.connection.Connector"
49 
50 using namespace ::osl;
51 using namespace ::rtl;
52 using namespace ::cppu;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::registry;
56 using namespace ::com::sun::star::connection;
57 
58 namespace stoc_connector
59 {
60 	rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
61 
62 	class OConnector : public WeakImplHelper2< XConnector, XServiceInfo >
63 	{
64 		Reference< XMultiComponentFactory > _xSMgr;
65 		Reference< XComponentContext > _xCtx;
66 	public:
67 		OConnector(const Reference< XComponentContext > &xCtx);
68 		~OConnector();
69 		// Methods
70 		virtual Reference< XConnection > SAL_CALL connect(
71 			const OUString& sConnectionDescription )
72 			throw( NoConnectException, ConnectionSetupException, RuntimeException);
73 
74 	public: // XServiceInfo
75                 virtual OUString              SAL_CALL getImplementationName() throw();
76                 virtual Sequence< OUString >  SAL_CALL getSupportedServiceNames(void) throw();
77                 virtual sal_Bool              SAL_CALL supportsService(const OUString& ServiceName) throw();
78 	};
79 
80 	OConnector::OConnector(const Reference< XComponentContext > &xCtx)
81 		: _xSMgr( xCtx->getServiceManager() )
82 		, _xCtx( xCtx )
83 	{
84 		g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
85 	}
86 
87 	OConnector::~OConnector()
88 	{
89 		g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
90 	}
91 
92 	Reference< XConnection > SAL_CALL OConnector::connect( const OUString& sConnectionDescription )
93 		throw( NoConnectException, ConnectionSetupException, RuntimeException)
94 	{
95 		OSL_TRACE(
96             "connector %s\n",
97             OUStringToOString(
98                 sConnectionDescription, RTL_TEXTENCODING_ASCII_US).getStr());
99 
100 		// split string into tokens
101         try
102         {
103             cppu::UnoUrlDescriptor aDesc(sConnectionDescription);
104 
105             Reference< XConnection > r;
106             if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
107                                                  "pipe")))
108             {
109                 rtl::OUString aName(
110                     aDesc.getParameter(
111                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name"))));
112 
113                 PipeConnection *pConn = new PipeConnection( sConnectionDescription );
114 
115                 if( pConn->m_pipe.create( aName.pData, osl_Pipe_OPEN, osl::Security() ) )
116                 {
117                     r = Reference < XConnection > ( (XConnection * ) pConn );
118                 }
119                 else
120                 {
121                     OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to pipe " );
122                     sMessage += aName;
123                     sMessage += OUString::createFromAscii( "(" );
124                     sMessage += OUString::valueOf( (sal_Int32 ) pConn->m_pipe.getError() );
125                     sMessage += OUString::createFromAscii( ")" );
126                     delete pConn;
127                     throw NoConnectException( sMessage ,Reference< XInterface > () );
128                 }
129             }
130             else if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
131                                                       "socket")))
132             {
133                 rtl::OUString aHost;
134                 if (aDesc.hasParameter(
135                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host"))))
136                     aHost = aDesc.getParameter(
137                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host")));
138                 else
139                     aHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
140                                               "localhost"));
141                 sal_uInt16 nPort = static_cast< sal_uInt16 >(
142                     aDesc.getParameter(
143                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("port"))).
144                     toInt32());
145                 bool bTcpNoDelay
146                     = aDesc.getParameter(
147                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
148                                           "tcpnodelay"))).toInt32() != 0;
149 
150                 SocketConnection *pConn = new SocketConnection( sConnectionDescription);
151 
152                 SocketAddr AddrTarget( aHost.pData, nPort );
153                 if(pConn->m_socket.connect(AddrTarget) != osl_Socket_Ok)
154                 {
155                     OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to socket (" );
156                     OUString sError = pConn->m_socket.getErrorAsString();
157                     sMessage += sError;
158                     sMessage += OUString::createFromAscii( ")" );
159                     delete pConn;
160                     throw NoConnectException( sMessage, Reference < XInterface > () );
161                 }
162                 if( bTcpNoDelay )
163                 {
164                     sal_Int32 nTcpNoDelay = sal_True;
165                     pConn->m_socket.setOption( osl_Socket_OptionTcpNoDelay , &nTcpNoDelay,
166                                                sizeof( nTcpNoDelay ) , osl_Socket_LevelTcp );
167                 }
168                 pConn->completeConnectionString();
169                 r = Reference< XConnection > ( (XConnection * ) pConn );
170             }
171             else
172             {
173                 OUString delegatee = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector."));
174                 delegatee += aDesc.getName();
175 
176                 OSL_TRACE(
177                     "connector: trying to get service %s\n",
178                     OUStringToOString(
179                         delegatee, RTL_TEXTENCODING_ASCII_US).getStr());
180                 Reference<XConnector> xConnector(
181                     _xSMgr->createInstanceWithContext(delegatee, _xCtx), UNO_QUERY );
182 
183                 if(!xConnector.is())
184                 {
185                     OUString message(RTL_CONSTASCII_USTRINGPARAM("Connector: unknown delegatee "));
186                     message += delegatee;
187 
188                     throw ConnectionSetupException(message, Reference<XInterface>());
189                 }
190 
191                 sal_Int32 index = sConnectionDescription.indexOf((sal_Unicode) ',');
192 
193                 r = xConnector->connect(sConnectionDescription.copy(index + 1).trim());
194             }
195             return r;
196         }
197         catch (rtl::MalformedUriException & rEx)
198         {
199 			throw ConnectionSetupException(rEx.getMessage(),
200                                            Reference< XInterface > ());
201         }
202 	}
203 
204 	Sequence< OUString > connector_getSupportedServiceNames()
205 	{
206 		static Sequence < OUString > *pNames = 0;
207 		if( ! pNames )
208 		{
209 			MutexGuard guard( Mutex::getGlobalMutex() );
210 			if( !pNames )
211 			{
212 				static Sequence< OUString > seqNames(1);
213 				seqNames.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
214 				pNames = &seqNames;
215 			}
216 		}
217 		return *pNames;
218 	}
219 
220 	OUString connector_getImplementationName()
221 	{
222 		return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
223 	}
224 
225         OUString OConnector::getImplementationName() throw()
226 	{
227 		return connector_getImplementationName();
228 	}
229 
230         sal_Bool OConnector::supportsService(const OUString& ServiceName) throw()
231 	{
232 		Sequence< OUString > aSNL = getSupportedServiceNames();
233 		const OUString * pArray = aSNL.getConstArray();
234 
235 		for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
236 			if( pArray[i] == ServiceName )
237 				return sal_True;
238 
239 		return sal_False;
240 	}
241 
242         Sequence< OUString > OConnector::getSupportedServiceNames(void) throw()
243 	{
244 		return connector_getSupportedServiceNames();
245 	}
246 
247 	Reference< XInterface > SAL_CALL connector_CreateInstance( const Reference< XComponentContext > & xCtx)
248 	{
249 		return Reference < XInterface >( ( OWeakObject * ) new OConnector(xCtx) );
250 	}
251 
252 
253 }
254 using namespace stoc_connector;
255 
256 static struct ImplementationEntry g_entries[] =
257 {
258 	{
259 		connector_CreateInstance, connector_getImplementationName ,
260 		connector_getSupportedServiceNames, createSingleComponentFactory ,
261 		&g_moduleCount.modCnt , 0
262 	},
263 	{ 0, 0, 0, 0, 0, 0 }
264 };
265 
266 extern "C"
267 {
268 
269 sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
270 {
271 	return g_moduleCount.canUnload( &g_moduleCount , pTime );
272 }
273 
274 //==================================================================================================
275 void SAL_CALL component_getImplementationEnvironment(
276 	const sal_Char ** ppEnvTypeName, uno_Environment ** )
277 {
278 	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
279 }
280 //==================================================================================================
281 void * SAL_CALL component_getFactory(
282 	const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
283 {
284 	return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
285 }
286 
287 }
288 
289 
290