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
~TargetObject()63 virtual ~TargetObject() {
64 --s_obj;
65 OSL_TRACE( "~TargetObject()" );
66 }
TargetObject()67 TargetObject()
68 { ++s_obj; }
69
70 Any SAL_CALL queryInterface( Type const & type )
71 throw (RuntimeException);
72
73 // XServiceInfo
getImplementationName()74 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
75 { return OUString::createFromAscii( "target" ); }
supportsService(const OUString &)76 virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ )
77 throw (RuntimeException)
78 { return sal_False; }
getSupportedServiceNames()79 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
80 throw (RuntimeException)
81 { return Sequence< OUString >(); }
82 // XProxyFactory
createProxy(const Reference<XInterface> & xTarget)83 virtual Reference< XAggregation > SAL_CALL createProxy(
84 const Reference< XInterface > & xTarget ) throw (RuntimeException)
85 { return Reference< XAggregation >( xTarget, UNO_QUERY ); }
86 // XCurrentContext
getValueByName(OUString const & name)87 virtual Any SAL_CALL getValueByName( OUString const & name )
88 throw (RuntimeException)
89 { return makeAny( name ); }
90 };
91
92 //______________________________________________________________________________
queryInterface(Type const & type)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
TestMaster()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
~TestMaster()122 virtual ~TestMaster() {
123 --s_obj;
124 OSL_TRACE( "~TestMaster()" );
125 }
126
queryInterface(const Type & rType)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
getImplementationName()138 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
139 { return OUString::createFromAscii( "master" ); }
supportsService(const OUString &)140 virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ )
141 throw (RuntimeException)
142 { return sal_False; }
getSupportedServiceNames()143 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
144 throw (RuntimeException)
145 { return Sequence< OUString >(); }
146 };
147
148 int TestMaster::s_obj = 0;
149
150
create(Reference<XInterface> const & xTarget,Reference<reflection::XProxyFactory> const & xProxyFac)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
create(Reference<reflection::XProxyFactory> const & xProxyFac)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
test_proxyfac_(Reference<XInterface> const & xMaster,OUString const & test,Reference<reflection::XProxyFactory> const &)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
test_proxyfac(Reference<XInterface> const & xMaster,OUString const & test,Reference<reflection::XProxyFactory> const & xProxyFac)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
SAL_IMPLEMENT_MAIN()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