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 // #define TRACE(x) OSL_TRACE(x)
25 #define TRACE(x)
26
27 #include <osl/diagnose.h>
28 #include <osl/mutex.hxx>
29 #include <cppuhelper/factory.hxx>
30 #include <cppuhelper/implbase2.hxx>
31 #include <cppuhelper/implementationentry.hxx>
32 #include "cppuhelper/unourl.hxx"
33 #include "rtl/malformeduriexception.hxx"
34
35 #include <com/sun/star/lang/XServiceInfo.hpp>
36 #include <com/sun/star/lang/XComponent.hpp>
37 #include <com/sun/star/registry/XRegistryKey.hpp>
38 #include <com/sun/star/connection/XConnector.hpp>
39 #include <com/sun/star/bridge/XBridgeFactory.hpp>
40 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
41
42 using namespace cppu;
43 using namespace rtl;
44 using namespace osl;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::lang;
47 using namespace com::sun::star::connection;
48 using namespace com::sun::star::bridge;
49 using namespace com::sun::star::registry;
50
51 #define SERVICENAME "com.sun.star.bridge.UnoUrlResolver"
52 #define IMPLNAME "com.sun.star.comp.bridge.UnoUrlResolver"
53
54 namespace unourl_resolver
55 {
56 rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
57 //--------------------------------------------------------------------------------------------------
resolver_getSupportedServiceNames()58 Sequence< OUString > resolver_getSupportedServiceNames()
59 {
60 static Sequence < OUString > *pNames = 0;
61 if( ! pNames )
62 {
63 MutexGuard guard( Mutex::getGlobalMutex() );
64 if( !pNames )
65 {
66 static Sequence< OUString > seqNames(1);
67 seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
68 pNames = &seqNames;
69 }
70 }
71 return *pNames;
72 }
73
resolver_getImplementationName()74 OUString resolver_getImplementationName()
75 {
76 static OUString *pImplName = 0;
77 if( ! pImplName )
78 {
79 MutexGuard guard( Mutex::getGlobalMutex() );
80 if( ! pImplName )
81 {
82 static OUString implName(
83 RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
84 pImplName = &implName;
85 }
86 }
87 return *pImplName;
88 }
89
90 //==================================================================================================
91 class ResolverImpl : public WeakImplHelper2< XServiceInfo, XUnoUrlResolver >
92 {
93 Reference< XMultiComponentFactory > _xSMgr;
94 Reference< XComponentContext > _xCtx;
95
96 public:
97 ResolverImpl( const Reference< XComponentContext > & xSMgr );
98 virtual ~ResolverImpl();
99
100 // XServiceInfo
101 virtual OUString SAL_CALL getImplementationName();
102 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName );
103 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames();
104
105 // XUnoUrlResolver
106 virtual Reference< XInterface > SAL_CALL resolve( const OUString & rUnoUrl );
107 };
108
109 //##################################################################################################
110
111 //__________________________________________________________________________________________________
ResolverImpl(const Reference<XComponentContext> & xCtx)112 ResolverImpl::ResolverImpl( const Reference< XComponentContext > & xCtx )
113 : _xSMgr( xCtx->getServiceManager() )
114 , _xCtx( xCtx )
115 {
116 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
117 }
118 //__________________________________________________________________________________________________
~ResolverImpl()119 ResolverImpl::~ResolverImpl()
120 {
121 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
122 }
123
124 // XServiceInfo
125 //__________________________________________________________________________________________________
getImplementationName()126 OUString ResolverImpl::getImplementationName()
127 {
128 return resolver_getImplementationName();
129 }
130 //__________________________________________________________________________________________________
supportsService(const OUString & rServiceName)131 sal_Bool ResolverImpl::supportsService( const OUString & rServiceName )
132 {
133 const Sequence< OUString > & rSNL = getSupportedServiceNames();
134 const OUString * pArray = rSNL.getConstArray();
135 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
136 {
137 if (pArray[nPos] == rServiceName)
138 return sal_True;
139 }
140 return sal_False;
141 }
142 //__________________________________________________________________________________________________
getSupportedServiceNames()143 Sequence< OUString > ResolverImpl::getSupportedServiceNames()
144 {
145 return resolver_getSupportedServiceNames();
146 }
147
148 // XUnoUrlResolver
149 //__________________________________________________________________________________________________
resolve(const OUString & rUnoUrl)150 Reference< XInterface > ResolverImpl::resolve( const OUString & rUnoUrl )
151 {
152 OUString aProtocolDescr;
153 OUString aConnectDescr;
154 OUString aInstanceName;
155 try
156 {
157 cppu::UnoUrl aUrl(rUnoUrl);
158 aProtocolDescr = aUrl.getProtocol().getDescriptor();
159 aConnectDescr = aUrl.getConnection().getDescriptor();
160 aInstanceName = aUrl.getObjectName();
161 }
162 catch (rtl::MalformedUriException & rEx)
163 {
164 throw ConnectionSetupException(rEx.getMessage(), 0);
165 }
166
167 Reference< XConnector > xConnector(
168 _xSMgr->createInstanceWithContext(
169 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector") ),
170 _xCtx ),
171 UNO_QUERY );
172
173 if (! xConnector.is())
174 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no connector!" ) ), Reference< XInterface >() );
175
176 Reference< XConnection > xConnection( xConnector->connect( aConnectDescr ) );
177
178 // As soon as singletons are ready, switch to singleton !
179 Reference< XBridgeFactory > xBridgeFactory(
180 _xSMgr->createInstanceWithContext(
181 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory") ),
182 _xCtx ),
183 UNO_QUERY );
184
185 if (! xBridgeFactory.is())
186 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no bridge factory!" ) ), Reference< XInterface >() );
187
188 // bridge
189 Reference< XBridge > xBridge( xBridgeFactory->createBridge(
190 OUString(), aProtocolDescr,
191 xConnection, Reference< XInstanceProvider >() ) );
192
193 Reference< XInterface > xRet( xBridge->getInstance( aInstanceName ) );
194
195 return xRet;
196 }
197
198 //==================================================================================================
ResolverImpl_create(const Reference<XComponentContext> & xCtx)199 static Reference< XInterface > SAL_CALL ResolverImpl_create( const Reference< XComponentContext > & xCtx )
200 {
201 return Reference< XInterface >( *new ResolverImpl( xCtx ) );
202 }
203
204
205 }
206
207 using namespace unourl_resolver;
208
209 static struct ImplementationEntry g_entries[] =
210 {
211 {
212 ResolverImpl_create, resolver_getImplementationName,
213 resolver_getSupportedServiceNames, createSingleComponentFactory,
214 &g_moduleCount.modCnt , 0
215 },
216 { 0, 0, 0, 0, 0, 0 }
217 };
218
219 extern "C"
220 {
component_canUnload(TimeValue * pTime)221 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
222 {
223 return g_moduleCount.canUnload( &g_moduleCount , pTime );
224 }
225
226 //==================================================================================================
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)227 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
228 const sal_Char ** ppEnvTypeName, uno_Environment ** )
229 {
230 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
231 }
232 //==================================================================================================
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void * pRegistryKey)233 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
234 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
235 {
236 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
237 }
238 }
239