| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_stoc.hxx" |
| |
| #include "sal/main.h" |
| #include "osl/diagnose.h" |
| #include "rtl/alloc.h" |
| #include "uno/environment.hxx" |
| #include "cppuhelper/servicefactory.hxx" |
| #include "cppuhelper/implbase1.hxx" |
| #include "cppuhelper/implbase3.hxx" |
| #include "com/sun/star/uno/XCurrentContext.hpp" |
| #include "com/sun/star/lang/DisposedException.hpp" |
| #include "com/sun/star/lang/XComponent.hpp" |
| #include "com/sun/star/lang/XServiceInfo.hpp" |
| #include "com/sun/star/registry/XSimpleRegistry.hpp" |
| #include "com/sun/star/registry/XImplementationRegistration.hpp" |
| #include "com/sun/star/beans/XPropertySet.hpp" |
| #include "com/sun/star/reflection/XProxyFactory.hpp" |
| |
| #include <stdio.h> |
| |
| |
| using namespace ::rtl; |
| using namespace ::osl; |
| using namespace ::cppu; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| |
| |
| typedef WeakImplHelper3< lang::XServiceInfo, |
| XCurrentContext, |
| reflection::XProxyFactory > t_impl; |
| |
| //============================================================================== |
| class TargetObject : public t_impl |
| { |
| public: |
| static int s_obj; |
| |
| virtual ~TargetObject() { |
| --s_obj; |
| OSL_TRACE( "~TargetObject()" ); |
| } |
| TargetObject() |
| { ++s_obj; } |
| |
| Any SAL_CALL queryInterface( Type const & type ) |
| throw (RuntimeException); |
| |
| // XServiceInfo |
| virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) |
| { return OUString::createFromAscii( "target" ); } |
| virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ ) |
| throw (RuntimeException) |
| { return sal_False; } |
| virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() |
| throw (RuntimeException) |
| { return Sequence< OUString >(); } |
| // XProxyFactory |
| virtual Reference< XAggregation > SAL_CALL createProxy( |
| const Reference< XInterface > & xTarget ) throw (RuntimeException) |
| { return Reference< XAggregation >( xTarget, UNO_QUERY ); } |
| // XCurrentContext |
| virtual Any SAL_CALL getValueByName( OUString const & name ) |
| throw (RuntimeException) |
| { return makeAny( name ); } |
| }; |
| |
| //______________________________________________________________________________ |
| Any TargetObject::queryInterface( Type const & type ) |
| throw (RuntimeException) |
| { |
| Any ret( t_impl::queryInterface( type ) ); |
| if (ret.hasValue()) |
| return ret; |
| throw lang::DisposedException( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("my test exception") ), |
| static_cast< OWeakObject * >(this) ); |
| } |
| |
| int TargetObject::s_obj = 0; |
| |
| |
| //============================================================================== |
| class TestMaster : public WeakImplHelper1< lang::XServiceInfo > |
| { |
| Reference< XAggregation > m_xProxyTarget; |
| Reference<lang::XServiceInfo> m_xOtherProxyTargetBeforeSetDelegator; |
| |
| inline TestMaster() { ++s_obj; } |
| public: |
| static int s_obj; |
| static Reference< XInterface > create( |
| Reference< reflection::XProxyFactory > const & xProxyFac ); |
| static Reference< XInterface > create( |
| Reference< XInterface > const & xTarget, |
| Reference< reflection::XProxyFactory > const & xProxyFac ); |
| |
| virtual ~TestMaster() { |
| --s_obj; |
| OSL_TRACE( "~TestMaster()" ); |
| } |
| |
| virtual Any SAL_CALL queryInterface( const Type & rType ) |
| throw (RuntimeException) |
| { |
| Any aRet( |
| WeakImplHelper1< lang::XServiceInfo >::queryInterface( rType ) ); |
| if (aRet.hasValue()) |
| return aRet; |
| return m_xProxyTarget->queryAggregation( rType ); |
| } |
| |
| // XServiceInfo |
| virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) |
| { return OUString::createFromAscii( "master" ); } |
| virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ ) |
| throw (RuntimeException) |
| { return sal_False; } |
| virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() |
| throw (RuntimeException) |
| { return Sequence< OUString >(); } |
| }; |
| |
| int TestMaster::s_obj = 0; |
| |
| |
| Reference< XInterface > TestMaster::create( |
| Reference< XInterface > const & xTarget, |
| Reference< reflection::XProxyFactory > const & xProxyFac ) |
| { |
| TestMaster * that = new TestMaster; |
| Reference< XInterface > xRet( static_cast< OWeakObject * >( that ) ); |
| { |
| Reference< XAggregation > xAgg( xProxyFac->createProxy( xTarget ) ); |
| // ownership take over |
| that->m_xProxyTarget.set( xAgg, UNO_QUERY_THROW ); |
| that->m_xOtherProxyTargetBeforeSetDelegator.set( |
| that->m_xProxyTarget, UNO_QUERY ); |
| } |
| that->m_xProxyTarget->setDelegator( xRet ); |
| return xRet; |
| } |
| |
| Reference< XInterface > TestMaster::create( |
| Reference< reflection::XProxyFactory > const & xProxyFac ) |
| { |
| return create( |
| static_cast< OWeakObject * >( new TargetObject ), xProxyFac ); |
| } |
| |
| |
| static void test_proxyfac_( |
| Reference< XInterface > const & xMaster, OUString const & test, |
| Reference< reflection::XProxyFactory > const & /*xProxyFac*/ ) |
| { |
| (void)test; |
| Reference< lang::XServiceInfo > xMaster_XServiceInfo( |
| xMaster, UNO_QUERY_THROW ); |
| OSL_ASSERT( xMaster_XServiceInfo->getImplementationName().equals( test ) ); |
| |
| Reference< reflection::XProxyFactory > xTarget( xMaster, UNO_QUERY_THROW ); |
| Reference< XCurrentContext > xTarget_XCurrentContext( |
| xTarget, UNO_QUERY_THROW ); |
| Reference< XCurrentContext > xMaster_XCurrentContext( |
| xMaster, UNO_QUERY_THROW ); |
| |
| OSL_ASSERT( |
| xTarget_XCurrentContext->getValueByName( test ) == makeAny( test ) ); |
| OSL_ASSERT( |
| xMaster_XCurrentContext->getValueByName( test ) == makeAny( test ) ); |
| |
| Reference< XAggregation > xFakeAgg( xTarget->createProxy( xTarget ) ); |
| if (xFakeAgg.is()) |
| { |
| OSL_ASSERT( xTarget == xFakeAgg ); |
| OSL_ASSERT( xMaster == xFakeAgg ); |
| } |
| |
| Reference< lang::XServiceInfo > xTarget_XServiceInfo( |
| xTarget, UNO_QUERY_THROW ); |
| OSL_ASSERT( xTarget_XServiceInfo->getImplementationName().equals( test ) ); |
| Reference< lang::XServiceInfo > xTarget_XServiceInfo2( |
| xTarget, UNO_QUERY_THROW ); |
| OSL_ASSERT( xTarget_XServiceInfo2.get() == xTarget_XServiceInfo.get() ); |
| |
| OSL_ASSERT( xTarget == xTarget_XCurrentContext ); |
| OSL_ASSERT( xTarget_XCurrentContext == xMaster ); |
| OSL_ASSERT( |
| xTarget_XCurrentContext.get() == xMaster_XCurrentContext.get() ); |
| OSL_ASSERT( xTarget_XCurrentContext == xMaster ); |
| OSL_ASSERT( xTarget == xMaster ); |
| OSL_ASSERT( xTarget_XServiceInfo.get() == xMaster_XServiceInfo.get() ); |
| OSL_ASSERT( xTarget_XServiceInfo == xMaster ); |
| OSL_ASSERT( xMaster_XServiceInfo == xMaster ); |
| |
| try |
| { |
| Reference< registry::XRegistryKey >( |
| xMaster, UNO_QUERY_THROW ); |
| } |
| catch (lang::DisposedException & exc) |
| { |
| if (! exc.Message.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM("my test exception") )) |
| throw; |
| } |
| } |
| |
| static void test_proxyfac( |
| Reference< XInterface > const & xMaster, OUString const & test, |
| Reference< reflection::XProxyFactory > const & xProxyFac ) |
| { |
| test_proxyfac_( xMaster, test, xProxyFac ); |
| // proxy the proxy... |
| Reference< XInterface > xNew( TestMaster::create( xMaster, xProxyFac ) ); |
| test_proxyfac_( |
| xNew, OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), xProxyFac ); |
| } |
| |
| SAL_IMPLEMENT_MAIN() |
| { |
| bool success = true; |
| |
| Environment cpp_env; |
| OUString cpp( RTL_CONSTASCII_USTRINGPARAM( |
| CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); |
| uno_getEnvironment( |
| reinterpret_cast< uno_Environment ** >( &cpp_env ), |
| cpp.pData, 0 ); |
| OSL_ENSURE( cpp_env.is(), "### cannot get C++ uno env!" ); |
| |
| { |
| Reference< lang::XMultiServiceFactory > xMgr( |
| createRegistryServiceFactory( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("stoctest.rdb") ) ) ); |
| |
| try |
| { |
| Reference< registry::XImplementationRegistration > xImplReg( |
| xMgr->createInstance( |
| OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.ImplementationRegistration") |
| ) ), |
| UNO_QUERY ); |
| OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); |
| |
| OUString aLibName( |
| RTL_CONSTASCII_USTRINGPARAM("proxyfac.uno" SAL_DLLEXTENSION) ); |
| xImplReg->registerImplementation( |
| OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.loader.SharedLibrary") ), |
| aLibName, Reference< registry::XSimpleRegistry >() ); |
| |
| Reference< reflection::XProxyFactory > xProxyFac( |
| xMgr->createInstance( |
| OUString::createFromAscii( |
| "com.sun.star.reflection.ProxyFactory") ), |
| UNO_QUERY_THROW ); |
| |
| Reference< XAggregation > x( |
| xProxyFac->createProxy( |
| static_cast< OWeakObject * >( new TargetObject ) ) ); |
| // no call |
| |
| { |
| Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); |
| test_proxyfac( |
| xMaster, |
| OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), |
| xProxyFac ); |
| } |
| { |
| Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); |
| // no call |
| } |
| |
| { |
| Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); |
| Reference< reflection::XProxyFactory > xSlave_lives_alone( |
| xMaster, UNO_QUERY_THROW ); |
| xMaster.clear(); |
| test_proxyfac( |
| xSlave_lives_alone, |
| OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), |
| xProxyFac ); |
| uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); |
| } |
| { |
| Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); |
| Reference< reflection::XProxyFactory > xSlave_lives_alone( |
| xMaster, UNO_QUERY_THROW ); |
| // no call |
| } |
| |
| test_proxyfac( |
| xProxyFac->createProxy( |
| static_cast< OWeakObject * >( new TargetObject ) ), |
| OUString( RTL_CONSTASCII_USTRINGPARAM("target") ), |
| xProxyFac ); |
| uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); |
| } |
| catch (Exception & rExc) |
| { |
| (void)rExc; |
| OSL_ENSURE( |
| ! __FILE__, |
| OUStringToOString( |
| rExc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() ); |
| success = false; |
| } |
| |
| |
| Reference< lang::XComponent > xComp; |
| Reference< beans::XPropertySet >( |
| xMgr, UNO_QUERY_THROW )->getPropertyValue( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) |
| >>= xComp; |
| xComp->dispose(); |
| } |
| |
| if (TestMaster::s_obj != 0) |
| fprintf( stderr, "TestMaster objects: %d\n", TestMaster::s_obj ); |
| if (TargetObject::s_obj != 0) |
| fprintf( stderr, "TargetObject objects: %d\n", TargetObject::s_obj ); |
| |
| uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); |
| void ** ppInterfaces; |
| sal_Int32 len; |
| uno_ExtEnvironment * env = cpp_env.get()->pExtEnv; |
| (*env->getRegisteredInterfaces)( |
| env, &ppInterfaces, &len, rtl_allocateMemory ); |
| if (len != 0) |
| fprintf( stderr, "%d registered C++ interfaces left!\n", len ); |
| |
| success &= (TestMaster::s_obj == 0 && |
| TargetObject::s_obj == 0 && |
| len == 0); |
| if (success) |
| { |
| printf( "testproxyfac succeeded.\n" ); |
| return 0; |
| } |
| else |
| { |
| fprintf( stderr, "testproxyfac failed!\n" ); |
| return 1; |
| } |
| } |
| |