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() throw(::com::sun::star::uno::RuntimeException);
102 	virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
103 	virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
104 
105 	// XUnoUrlResolver
106     virtual Reference< XInterface > SAL_CALL resolve( const OUString & rUnoUrl )
107 		throw (NoConnectException, ConnectionSetupException, RuntimeException);
108 };
109 
110 //##################################################################################################
111 
112 //__________________________________________________________________________________________________
ResolverImpl(const Reference<XComponentContext> & xCtx)113 ResolverImpl::ResolverImpl( const Reference< XComponentContext > & xCtx )
114 	: _xSMgr( xCtx->getServiceManager() )
115 	, _xCtx( xCtx )
116 {
117 	g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
118 }
119 //__________________________________________________________________________________________________
~ResolverImpl()120 ResolverImpl::~ResolverImpl()
121 {
122 	g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
123 }
124 
125 // XServiceInfo
126 //__________________________________________________________________________________________________
getImplementationName()127 OUString ResolverImpl::getImplementationName()
128 	throw(::com::sun::star::uno::RuntimeException)
129 {
130 	return resolver_getImplementationName();
131 }
132 //__________________________________________________________________________________________________
supportsService(const OUString & rServiceName)133 sal_Bool ResolverImpl::supportsService( const OUString & rServiceName )
134 	throw(::com::sun::star::uno::RuntimeException)
135 {
136 	const Sequence< OUString > & rSNL = getSupportedServiceNames();
137 	const OUString * pArray = rSNL.getConstArray();
138 	for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
139 	{
140 		if (pArray[nPos] == rServiceName)
141 			return sal_True;
142 	}
143 	return sal_False;
144 }
145 //__________________________________________________________________________________________________
getSupportedServiceNames()146 Sequence< OUString > ResolverImpl::getSupportedServiceNames()
147 	throw(::com::sun::star::uno::RuntimeException)
148 {
149 	return resolver_getSupportedServiceNames();
150 }
151 
152 // XUnoUrlResolver
153 //__________________________________________________________________________________________________
resolve(const OUString & rUnoUrl)154 Reference< XInterface > ResolverImpl::resolve( const OUString & rUnoUrl )
155 	throw (NoConnectException, ConnectionSetupException, RuntimeException)
156 {
157     OUString aProtocolDescr;
158     OUString aConnectDescr;
159     OUString aInstanceName;
160     try
161     {
162         cppu::UnoUrl aUrl(rUnoUrl);
163         aProtocolDescr = aUrl.getProtocol().getDescriptor();
164         aConnectDescr = aUrl.getConnection().getDescriptor();
165         aInstanceName = aUrl.getObjectName();
166     }
167     catch (rtl::MalformedUriException & rEx)
168     {
169         throw ConnectionSetupException(rEx.getMessage(), 0);
170     }
171 
172 	Reference< XConnector > xConnector(
173 		_xSMgr->createInstanceWithContext(
174 			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector") ),
175 			_xCtx ),
176 		UNO_QUERY );
177 
178 	if (! xConnector.is())
179 		throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no connector!" ) ), Reference< XInterface >() );
180 
181 	Reference< XConnection > xConnection( xConnector->connect( aConnectDescr ) );
182 
183 	// As soon as singletons are ready, switch to singleton !
184 	Reference< XBridgeFactory > xBridgeFactory(
185 		_xSMgr->createInstanceWithContext(
186 			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory") ),
187 			_xCtx ),
188 		UNO_QUERY );
189 
190 	if (! xBridgeFactory.is())
191 		throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no bridge factory!" ) ), Reference< XInterface >() );
192 
193 	// bridge
194 	Reference< XBridge > xBridge( xBridgeFactory->createBridge(
195 		OUString(), aProtocolDescr,
196 		xConnection, Reference< XInstanceProvider >() ) );
197 
198 	Reference< XInterface > xRet( xBridge->getInstance( aInstanceName ) );
199 
200 	return xRet;
201 }
202 
203 //==================================================================================================
ResolverImpl_create(const Reference<XComponentContext> & xCtx)204 static Reference< XInterface > SAL_CALL ResolverImpl_create( const Reference< XComponentContext > & xCtx )
205 {
206 	return Reference< XInterface >( *new ResolverImpl( xCtx ) );
207 }
208 
209 
210 }
211 
212 using namespace unourl_resolver;
213 
214 static struct ImplementationEntry g_entries[] =
215 {
216 	{
217 		ResolverImpl_create, resolver_getImplementationName,
218 		resolver_getSupportedServiceNames, createSingleComponentFactory,
219 		&g_moduleCount.modCnt , 0
220 	},
221 	{ 0, 0, 0, 0, 0, 0 }
222 };
223 
224 extern "C"
225 {
component_canUnload(TimeValue * pTime)226 sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
227 {
228 	return g_moduleCount.canUnload( &g_moduleCount , pTime );
229 }
230 
231 //==================================================================================================
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)232 void SAL_CALL component_getImplementationEnvironment(
233 	const sal_Char ** ppEnvTypeName, uno_Environment ** )
234 {
235 	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
236 }
237 //==================================================================================================
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void * pRegistryKey)238 void * SAL_CALL component_getFactory(
239 	const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
240 {
241 	return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
242 }
243 }
244