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 //-------------------------------------------------------------------------------------------------- 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 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 119 ResolverImpl::~ResolverImpl() 120 { 121 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 122 } 123 124 // XServiceInfo 125 //__________________________________________________________________________________________________ 126 OUString ResolverImpl::getImplementationName() 127 { 128 return resolver_getImplementationName(); 129 } 130 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 143 Sequence< OUString > ResolverImpl::getSupportedServiceNames() 144 { 145 return resolver_getSupportedServiceNames(); 146 } 147 148 // XUnoUrlResolver 149 //__________________________________________________________________________________________________ 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 //================================================================================================== 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 { 221 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) 222 { 223 return g_moduleCount.canUnload( &g_moduleCount , pTime ); 224 } 225 226 //================================================================================================== 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 //================================================================================================== 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