xref: /trunk/main/io/source/connector/connector.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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