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_stoc.hxx" 30 31 #include "sal/main.h" 32 #include "osl/diagnose.h" 33 #include "rtl/alloc.h" 34 #include "uno/environment.hxx" 35 #include "cppuhelper/servicefactory.hxx" 36 #include "cppuhelper/implbase1.hxx" 37 #include "cppuhelper/implbase3.hxx" 38 #include "com/sun/star/uno/XCurrentContext.hpp" 39 #include "com/sun/star/lang/DisposedException.hpp" 40 #include "com/sun/star/lang/XComponent.hpp" 41 #include "com/sun/star/lang/XServiceInfo.hpp" 42 #include "com/sun/star/registry/XSimpleRegistry.hpp" 43 #include "com/sun/star/registry/XImplementationRegistration.hpp" 44 #include "com/sun/star/beans/XPropertySet.hpp" 45 #include "com/sun/star/reflection/XProxyFactory.hpp" 46 47 #include <stdio.h> 48 49 50 using namespace ::rtl; 51 using namespace ::osl; 52 using namespace ::cppu; 53 using namespace ::com::sun::star; 54 using namespace ::com::sun::star::uno; 55 56 57 typedef WeakImplHelper3< lang::XServiceInfo, 58 XCurrentContext, 59 reflection::XProxyFactory > t_impl; 60 61 //============================================================================== 62 class TargetObject : public t_impl 63 { 64 public: 65 static int s_obj; 66 67 virtual ~TargetObject() { 68 --s_obj; 69 OSL_TRACE( "~TargetObject()" ); 70 } 71 TargetObject() 72 { ++s_obj; } 73 74 Any SAL_CALL queryInterface( Type const & type ) 75 throw (RuntimeException); 76 77 // XServiceInfo 78 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) 79 { return OUString::createFromAscii( "target" ); } 80 virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ ) 81 throw (RuntimeException) 82 { return sal_False; } 83 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() 84 throw (RuntimeException) 85 { return Sequence< OUString >(); } 86 // XProxyFactory 87 virtual Reference< XAggregation > SAL_CALL createProxy( 88 const Reference< XInterface > & xTarget ) throw (RuntimeException) 89 { return Reference< XAggregation >( xTarget, UNO_QUERY ); } 90 // XCurrentContext 91 virtual Any SAL_CALL getValueByName( OUString const & name ) 92 throw (RuntimeException) 93 { return makeAny( name ); } 94 }; 95 96 //______________________________________________________________________________ 97 Any TargetObject::queryInterface( Type const & type ) 98 throw (RuntimeException) 99 { 100 Any ret( t_impl::queryInterface( type ) ); 101 if (ret.hasValue()) 102 return ret; 103 throw lang::DisposedException( 104 OUString( RTL_CONSTASCII_USTRINGPARAM("my test exception") ), 105 static_cast< OWeakObject * >(this) ); 106 } 107 108 int TargetObject::s_obj = 0; 109 110 111 //============================================================================== 112 class TestMaster : public WeakImplHelper1< lang::XServiceInfo > 113 { 114 Reference< XAggregation > m_xProxyTarget; 115 Reference<lang::XServiceInfo> m_xOtherProxyTargetBeforeSetDelegator; 116 117 inline TestMaster() { ++s_obj; } 118 public: 119 static int s_obj; 120 static Reference< XInterface > create( 121 Reference< reflection::XProxyFactory > const & xProxyFac ); 122 static Reference< XInterface > create( 123 Reference< XInterface > const & xTarget, 124 Reference< reflection::XProxyFactory > const & xProxyFac ); 125 126 virtual ~TestMaster() { 127 --s_obj; 128 OSL_TRACE( "~TestMaster()" ); 129 } 130 131 virtual Any SAL_CALL queryInterface( const Type & rType ) 132 throw (RuntimeException) 133 { 134 Any aRet( 135 WeakImplHelper1< lang::XServiceInfo >::queryInterface( rType ) ); 136 if (aRet.hasValue()) 137 return aRet; 138 return m_xProxyTarget->queryAggregation( rType ); 139 } 140 141 // XServiceInfo 142 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) 143 { return OUString::createFromAscii( "master" ); } 144 virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ ) 145 throw (RuntimeException) 146 { return sal_False; } 147 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() 148 throw (RuntimeException) 149 { return Sequence< OUString >(); } 150 }; 151 152 int TestMaster::s_obj = 0; 153 154 155 Reference< XInterface > TestMaster::create( 156 Reference< XInterface > const & xTarget, 157 Reference< reflection::XProxyFactory > const & xProxyFac ) 158 { 159 TestMaster * that = new TestMaster; 160 Reference< XInterface > xRet( static_cast< OWeakObject * >( that ) ); 161 { 162 Reference< XAggregation > xAgg( xProxyFac->createProxy( xTarget ) ); 163 // ownership take over 164 that->m_xProxyTarget.set( xAgg, UNO_QUERY_THROW ); 165 that->m_xOtherProxyTargetBeforeSetDelegator.set( 166 that->m_xProxyTarget, UNO_QUERY ); 167 } 168 that->m_xProxyTarget->setDelegator( xRet ); 169 return xRet; 170 } 171 172 Reference< XInterface > TestMaster::create( 173 Reference< reflection::XProxyFactory > const & xProxyFac ) 174 { 175 return create( 176 static_cast< OWeakObject * >( new TargetObject ), xProxyFac ); 177 } 178 179 180 static void test_proxyfac_( 181 Reference< XInterface > const & xMaster, OUString const & test, 182 Reference< reflection::XProxyFactory > const & /*xProxyFac*/ ) 183 { 184 (void)test; 185 Reference< lang::XServiceInfo > xMaster_XServiceInfo( 186 xMaster, UNO_QUERY_THROW ); 187 OSL_ASSERT( xMaster_XServiceInfo->getImplementationName().equals( test ) ); 188 189 Reference< reflection::XProxyFactory > xTarget( xMaster, UNO_QUERY_THROW ); 190 Reference< XCurrentContext > xTarget_XCurrentContext( 191 xTarget, UNO_QUERY_THROW ); 192 Reference< XCurrentContext > xMaster_XCurrentContext( 193 xMaster, UNO_QUERY_THROW ); 194 195 OSL_ASSERT( 196 xTarget_XCurrentContext->getValueByName( test ) == makeAny( test ) ); 197 OSL_ASSERT( 198 xMaster_XCurrentContext->getValueByName( test ) == makeAny( test ) ); 199 200 Reference< XAggregation > xFakeAgg( xTarget->createProxy( xTarget ) ); 201 if (xFakeAgg.is()) 202 { 203 OSL_ASSERT( xTarget == xFakeAgg ); 204 OSL_ASSERT( xMaster == xFakeAgg ); 205 } 206 207 Reference< lang::XServiceInfo > xTarget_XServiceInfo( 208 xTarget, UNO_QUERY_THROW ); 209 OSL_ASSERT( xTarget_XServiceInfo->getImplementationName().equals( test ) ); 210 Reference< lang::XServiceInfo > xTarget_XServiceInfo2( 211 xTarget, UNO_QUERY_THROW ); 212 OSL_ASSERT( xTarget_XServiceInfo2.get() == xTarget_XServiceInfo.get() ); 213 214 OSL_ASSERT( xTarget == xTarget_XCurrentContext ); 215 OSL_ASSERT( xTarget_XCurrentContext == xMaster ); 216 OSL_ASSERT( 217 xTarget_XCurrentContext.get() == xMaster_XCurrentContext.get() ); 218 OSL_ASSERT( xTarget_XCurrentContext == xMaster ); 219 OSL_ASSERT( xTarget == xMaster ); 220 OSL_ASSERT( xTarget_XServiceInfo.get() == xMaster_XServiceInfo.get() ); 221 OSL_ASSERT( xTarget_XServiceInfo == xMaster ); 222 OSL_ASSERT( xMaster_XServiceInfo == xMaster ); 223 224 try 225 { 226 Reference< registry::XRegistryKey >( 227 xMaster, UNO_QUERY_THROW ); 228 } 229 catch (lang::DisposedException & exc) 230 { 231 if (! exc.Message.equalsAsciiL( 232 RTL_CONSTASCII_STRINGPARAM("my test exception") )) 233 throw; 234 } 235 } 236 237 static void test_proxyfac( 238 Reference< XInterface > const & xMaster, OUString const & test, 239 Reference< reflection::XProxyFactory > const & xProxyFac ) 240 { 241 test_proxyfac_( xMaster, test, xProxyFac ); 242 // proxy the proxy... 243 Reference< XInterface > xNew( TestMaster::create( xMaster, xProxyFac ) ); 244 test_proxyfac_( 245 xNew, OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), xProxyFac ); 246 } 247 248 SAL_IMPLEMENT_MAIN() 249 { 250 bool success = true; 251 252 Environment cpp_env; 253 OUString cpp( RTL_CONSTASCII_USTRINGPARAM( 254 CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); 255 uno_getEnvironment( 256 reinterpret_cast< uno_Environment ** >( &cpp_env ), 257 cpp.pData, 0 ); 258 OSL_ENSURE( cpp_env.is(), "### cannot get C++ uno env!" ); 259 260 { 261 Reference< lang::XMultiServiceFactory > xMgr( 262 createRegistryServiceFactory( 263 OUString( RTL_CONSTASCII_USTRINGPARAM("stoctest.rdb") ) ) ); 264 265 try 266 { 267 Reference< registry::XImplementationRegistration > xImplReg( 268 xMgr->createInstance( 269 OUString( 270 RTL_CONSTASCII_USTRINGPARAM( 271 "com.sun.star.registry.ImplementationRegistration") 272 ) ), 273 UNO_QUERY ); 274 OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); 275 276 OUString aLibName( 277 RTL_CONSTASCII_USTRINGPARAM("proxyfac.uno" SAL_DLLEXTENSION) ); 278 xImplReg->registerImplementation( 279 OUString( 280 RTL_CONSTASCII_USTRINGPARAM( 281 "com.sun.star.loader.SharedLibrary") ), 282 aLibName, Reference< registry::XSimpleRegistry >() ); 283 284 Reference< reflection::XProxyFactory > xProxyFac( 285 xMgr->createInstance( 286 OUString::createFromAscii( 287 "com.sun.star.reflection.ProxyFactory") ), 288 UNO_QUERY_THROW ); 289 290 Reference< XAggregation > x( 291 xProxyFac->createProxy( 292 static_cast< OWeakObject * >( new TargetObject ) ) ); 293 // no call 294 295 { 296 Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); 297 test_proxyfac( 298 xMaster, 299 OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), 300 xProxyFac ); 301 } 302 { 303 Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); 304 // no call 305 } 306 307 { 308 Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); 309 Reference< reflection::XProxyFactory > xSlave_lives_alone( 310 xMaster, UNO_QUERY_THROW ); 311 xMaster.clear(); 312 test_proxyfac( 313 xSlave_lives_alone, 314 OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), 315 xProxyFac ); 316 uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); 317 } 318 { 319 Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); 320 Reference< reflection::XProxyFactory > xSlave_lives_alone( 321 xMaster, UNO_QUERY_THROW ); 322 // no call 323 } 324 325 test_proxyfac( 326 xProxyFac->createProxy( 327 static_cast< OWeakObject * >( new TargetObject ) ), 328 OUString( RTL_CONSTASCII_USTRINGPARAM("target") ), 329 xProxyFac ); 330 uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); 331 } 332 catch (Exception & rExc) 333 { 334 (void)rExc; 335 OSL_ENSURE( 336 ! __FILE__, 337 OUStringToOString( 338 rExc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() ); 339 success = false; 340 } 341 342 343 Reference< lang::XComponent > xComp; 344 Reference< beans::XPropertySet >( 345 xMgr, UNO_QUERY_THROW )->getPropertyValue( 346 OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) 347 >>= xComp; 348 xComp->dispose(); 349 } 350 351 if (TestMaster::s_obj != 0) 352 fprintf( stderr, "TestMaster objects: %d\n", TestMaster::s_obj ); 353 if (TargetObject::s_obj != 0) 354 fprintf( stderr, "TargetObject objects: %d\n", TargetObject::s_obj ); 355 356 uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); 357 void ** ppInterfaces; 358 sal_Int32 len; 359 uno_ExtEnvironment * env = cpp_env.get()->pExtEnv; 360 (*env->getRegisteredInterfaces)( 361 env, &ppInterfaces, &len, rtl_allocateMemory ); 362 if (len != 0) 363 fprintf( stderr, "%d registered C++ interfaces left!\n", len ); 364 365 success &= (TestMaster::s_obj == 0 && 366 TargetObject::s_obj == 0 && 367 len == 0); 368 if (success) 369 { 370 printf( "testproxyfac succeeded.\n" ); 371 return 0; 372 } 373 else 374 { 375 fprintf( stderr, "testproxyfac failed!\n" ); 376 return 1; 377 } 378 } 379 380