xref: /aoo42x/main/stoc/test/testproxyfac.cxx (revision cdf0e10c)
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