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