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_bridges.hxx"
26
27 #include "com/sun/star/bridge/UnoUrlResolver.hpp"
28 #include "com/sun/star/bridge/XUnoUrlResolver.hpp"
29 #include "com/sun/star/lang/XMain.hpp"
30 #include "com/sun/star/lang/XServiceInfo.hpp"
31 #include "com/sun/star/lang/XSingleComponentFactory.hpp"
32 #include "com/sun/star/registry/InvalidRegistryException.hpp"
33 #include "com/sun/star/registry/XRegistryKey.hpp"
34 #include "com/sun/star/uno/Any.hxx"
35 #include "com/sun/star/uno/Exception.hpp"
36 #include "com/sun/star/uno/Reference.hxx"
37 #include "com/sun/star/uno/RuntimeException.hpp"
38 #include "com/sun/star/uno/Sequence.hxx"
39 #include "com/sun/star/uno/Type.hxx"
40 #include "com/sun/star/uno/XComponentContext.hpp"
41 #include "com/sun/star/uno/XInterface.hpp"
42 #include "cppuhelper/factory.hxx"
43 #include "cppuhelper/implbase3.hxx"
44 #include "cppuhelper/weak.hxx"
45 #include "osl/conditn.hxx"
46 #include "osl/interlck.h"
47 #include "rtl/string.h"
48 #include "rtl/ustring.hxx"
49 #include "sal/types.h"
50 #include "test/javauno/acquire/XBase.hpp"
51 #include "test/javauno/acquire/XDerived.hpp"
52 #include "test/javauno/acquire/XTest.hpp"
53 #include "uno/environment.h"
54 #include "uno/lbnames.h"
55
56 #include <iostream>
57 #include <cstdlib>
58
59 namespace css = com::sun::star;
60
61 namespace {
62
63 class WaitCondition {
64 public:
WaitCondition()65 WaitCondition() {}
66
67 ~WaitCondition();
68
get()69 osl::Condition & get() { return m_condition; }
70
71 private:
72 WaitCondition(WaitCondition &); // not implemented
73 void operator =(WaitCondition); // not implemented
74
75 osl::Condition m_condition;
76 };
77
78 }
79
~WaitCondition()80 WaitCondition::~WaitCondition() {
81 std::cout << "waiting for condition\n";
82 if (m_condition.wait() != osl::Condition::result_ok) {
83 throw "osl::Condition::wait failed";
84 }
85 }
86
87 namespace {
88
89 class Interface: public css::uno::XInterface {
90 public:
Interface(osl::Condition & condition)91 explicit Interface(osl::Condition & condition):
92 m_condition(condition), m_refCount(0) {}
93
94 virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type)
95 throw (css::uno::RuntimeException);
96
acquire()97 virtual void SAL_CALL acquire() throw ()
98 { osl_incrementInterlockedCount(&m_refCount); }
99
100 virtual void SAL_CALL release() throw ();
101
102 protected:
~Interface()103 virtual ~Interface() { m_condition.set(); }
104
105 private:
106 Interface(Interface &); // not implemented
107 void operator =(Interface); // not implemented
108
109 osl::Condition & m_condition;
110 oslInterlockedCount m_refCount;
111 };
112
113 }
114
queryInterface(css::uno::Type const & type)115 css::uno::Any Interface::queryInterface(css::uno::Type const & type)
116 throw (css::uno::RuntimeException)
117 {
118 return type.getTypeName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
119 "com.sun.star.uno.XInterface"))
120 ? css::uno::makeAny(css::uno::Reference< css::uno::XInterface >(this))
121 : css::uno::Any();
122 }
123
release()124 void Interface::release() throw () {
125 if (osl_decrementInterlockedCount(&m_refCount) == 0) {
126 delete this;
127 }
128 }
129
130 namespace {
131
132 class Base: public Interface, public test::javauno::acquire::XBase {
133 public:
Base(osl::Condition & condition)134 explicit Base(osl::Condition & condition): Interface(condition) {}
135
136 virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type)
137 throw (css::uno::RuntimeException);
138
acquire()139 virtual void SAL_CALL acquire() throw () { Interface::acquire(); }
140
release()141 virtual void SAL_CALL release() throw () { Interface::release(); }
142
143 protected:
~Base()144 virtual ~Base() {}
145 };
146
147 }
148
queryInterface(css::uno::Type const & type)149 css::uno::Any Base::queryInterface(css::uno::Type const & type)
150 throw (css::uno::RuntimeException)
151 {
152 return type.getTypeName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
153 "test.javauno.acquire.XBase"))
154 ? css::uno::makeAny(
155 css::uno::Reference< test::javauno::acquire::XBase >(this))
156 : Interface::queryInterface(type);
157 }
158
159 namespace {
160
161 class Derived: public Base, public test::javauno::acquire::XDerived {
162 public:
Derived(osl::Condition & condition)163 explicit Derived(osl::Condition & condition): Base(condition) {}
164
165 virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type)
166 throw (css::uno::RuntimeException);
167
acquire()168 virtual void SAL_CALL acquire() throw () { Base::acquire(); }
169
release()170 virtual void SAL_CALL release() throw () { Base::release(); }
171
172 private:
~Derived()173 virtual ~Derived() {}
174 };
175
176 }
177
queryInterface(css::uno::Type const & type)178 css::uno::Any Derived::queryInterface(css::uno::Type const & type)
179 throw (css::uno::RuntimeException)
180 {
181 return (type.getTypeName().equalsAsciiL(
182 RTL_CONSTASCII_STRINGPARAM("test.javauno.acquire.XDerived")))
183 ? css::uno::makeAny(
184 css::uno::Reference< test::javauno::acquire::XDerived >(this))
185 : Interface::queryInterface(type);
186 }
187
188 namespace {
189
190 class Service: public cppu::WeakImplHelper3<
191 css::lang::XServiceInfo, css::lang::XMain, test::javauno::acquire::XTest >
192 {
193 public:
getImplementationName()194 virtual rtl::OUString SAL_CALL getImplementationName()
195 throw (css::uno::RuntimeException)
196 { return getImplementationName_static(); }
197
198 virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
199 throw (css::uno::RuntimeException);
200
201 virtual css::uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames()202 getSupportedServiceNames() throw (css::uno::RuntimeException)
203 { return getSupportedServiceNames_static(); }
204
205 virtual sal_Int32 SAL_CALL
206 run(css::uno::Sequence< rtl::OUString > const & arguments)
207 throw (css::uno::RuntimeException);
208
setInterfaceToInterface(css::uno::Reference<css::uno::XInterface> const & obj)209 virtual void SAL_CALL setInterfaceToInterface(
210 css::uno::Reference< css::uno::XInterface > const & obj)
211 throw (css::uno::RuntimeException)
212 { m_interface = obj; }
213
setBaseToInterface(css::uno::Reference<test::javauno::acquire::XBase> const & obj)214 virtual void SAL_CALL setBaseToInterface(
215 css::uno::Reference< test::javauno::acquire::XBase > const & obj)
216 throw (css::uno::RuntimeException)
217 { m_interface = obj; }
218
setDerivedToInterface(css::uno::Reference<test::javauno::acquire::XDerived> const & obj)219 virtual void SAL_CALL setDerivedToInterface(
220 css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
221 throw (css::uno::RuntimeException)
222 { m_interface = obj; }
223
224 virtual css::uno::Reference< css::uno::XInterface >
getInterfaceFromInterface()225 SAL_CALL getInterfaceFromInterface() throw (css::uno::RuntimeException)
226 { return m_interface; }
227
clearInterface()228 virtual void SAL_CALL clearInterface() throw (css::uno::RuntimeException)
229 { m_interface.clear(); }
230
setBaseToBase(css::uno::Reference<test::javauno::acquire::XBase> const & obj)231 virtual void SAL_CALL setBaseToBase(
232 css::uno::Reference< test::javauno::acquire::XBase > const & obj)
233 throw (css::uno::RuntimeException)
234 { m_base = obj; }
235
setDerivedToBase(css::uno::Reference<test::javauno::acquire::XDerived> const & obj)236 virtual void SAL_CALL setDerivedToBase(
237 css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
238 throw (css::uno::RuntimeException)
239 { m_base = obj.get(); }
240
241 virtual css::uno::Reference< css::uno::XInterface >
getInterfaceFromBase()242 SAL_CALL getInterfaceFromBase() throw (css::uno::RuntimeException)
243 { return m_base; }
244
245 virtual css::uno::Reference< test::javauno::acquire::XBase >
getBaseFromBase()246 SAL_CALL getBaseFromBase() throw (css::uno::RuntimeException)
247 { return m_base; }
248
clearBase()249 virtual void SAL_CALL clearBase() throw (css::uno::RuntimeException)
250 { m_base.clear(); }
251
setDerivedToDerived(css::uno::Reference<test::javauno::acquire::XDerived> const & obj)252 virtual void SAL_CALL setDerivedToDerived(
253 css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
254 throw (css::uno::RuntimeException)
255 { m_derived = obj; }
256
257 virtual css::uno::Reference< css::uno::XInterface >
getInterfaceFromDerived()258 SAL_CALL getInterfaceFromDerived() throw (css::uno::RuntimeException)
259 { return m_derived; }
260
261 virtual css::uno::Reference< test::javauno::acquire::XBase >
getBaseFromDerived()262 SAL_CALL getBaseFromDerived() throw (css::uno::RuntimeException)
263 { return m_derived.get(); }
264
265 virtual css::uno::Reference< test::javauno::acquire::XDerived >
getDerivedFromDerived()266 SAL_CALL getDerivedFromDerived() throw (css::uno::RuntimeException)
267 { return m_derived; }
268
clearDerived()269 virtual void SAL_CALL clearDerived() throw (css::uno::RuntimeException)
270 { m_derived.clear(); }
271
272 virtual css::uno::Reference< css::uno::XInterface >
roundTripInterfaceToInterface(css::uno::Reference<css::uno::XInterface> const & obj)273 SAL_CALL roundTripInterfaceToInterface(
274 css::uno::Reference< css::uno::XInterface > const & obj)
275 throw (css::uno::RuntimeException)
276 { return obj; }
277
278 virtual css::uno::Reference< css::uno::XInterface >
roundTripBaseToInterface(css::uno::Reference<test::javauno::acquire::XBase> const & obj)279 SAL_CALL roundTripBaseToInterface(
280 css::uno::Reference< test::javauno::acquire::XBase > const & obj)
281 throw (css::uno::RuntimeException)
282 { return obj; }
283
284 virtual css::uno::Reference< css::uno::XInterface >
roundTripDerivedToInterface(css::uno::Reference<test::javauno::acquire::XDerived> const & obj)285 SAL_CALL roundTripDerivedToInterface(
286 css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
287 throw (css::uno::RuntimeException)
288 { return obj; }
289
290 virtual css::uno::Reference< test::javauno::acquire::XBase >
roundTripBaseToBase(css::uno::Reference<test::javauno::acquire::XBase> const & obj)291 SAL_CALL roundTripBaseToBase(
292 css::uno::Reference< test::javauno::acquire::XBase > const & obj)
293 throw (css::uno::RuntimeException)
294 { return obj; }
295
296 virtual css::uno::Reference< test::javauno::acquire::XBase >
roundTripDerivedToBase(css::uno::Reference<test::javauno::acquire::XDerived> const & obj)297 SAL_CALL roundTripDerivedToBase(
298 css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
299 throw (css::uno::RuntimeException)
300 { return obj.get(); }
301
302 virtual css::uno::Reference< test::javauno::acquire::XDerived >
roundTripDerivedToDerived(css::uno::Reference<test::javauno::acquire::XDerived> const & obj)303 SAL_CALL roundTripDerivedToDerived(
304 css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
305 throw (css::uno::RuntimeException)
306 { return obj; }
307
308 static rtl::OUString getImplementationName_static();
309
310 static css::uno::Sequence< rtl::OUString >
311 getSupportedServiceNames_static();
312
313 static css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
314 css::uno::Reference< css::uno::XComponentContext > const & context)
315 throw (css::uno::Exception);
316
317 private:
Service(css::uno::Reference<css::uno::XComponentContext> const & context)318 explicit Service(
319 css::uno::Reference< css::uno::XComponentContext > const & context):
320 m_context(context) {}
321
322 css::uno::Reference< css::uno::XComponentContext > m_context;
323 css::uno::Reference< css::uno::XInterface > m_interface;
324 css::uno::Reference< test::javauno::acquire::XBase > m_base;
325 css::uno::Reference< test::javauno::acquire::XDerived > m_derived;
326 };
327
328 }
329
supportsService(rtl::OUString const & serviceName)330 sal_Bool Service::supportsService(rtl::OUString const & serviceName)
331 throw (css::uno::RuntimeException)
332 {
333 css::uno::Sequence< rtl::OUString > names(
334 getSupportedServiceNames_static());
335 for (sal_Int32 i = 0; i< names.getLength(); ++i) {
336 if (names[i] == serviceName) {
337 return true;
338 }
339 }
340 return false;
341 }
342
343 namespace {
344
assertNotNull(css::uno::Reference<T> const & ref)345 template< typename T > void assertNotNull(css::uno::Reference< T > const & ref)
346 {
347 if (!ref.is()) {
348 std::cerr << "assertNotNull failed\n";
349 std::abort();
350 }
351 }
352
353 }
354
run(css::uno::Sequence<rtl::OUString> const & arguments)355 sal_Int32 Service::run(css::uno::Sequence< rtl::OUString > const & arguments)
356 throw (css::uno::RuntimeException)
357 {
358 // - arguments[0] must be the UNO URL to connect to:
359 css::uno::Reference< XTest > test(
360 css::bridge::UnoUrlResolver::create(m_context)->resolve(arguments[0]),
361 css::uno::UNO_QUERY_THROW);
362
363 {
364 WaitCondition c;
365 test->setInterfaceToInterface(new Interface(c.get()));
366 assertNotNull(test->getInterfaceFromInterface());
367 test->clearInterface();
368 }
369 {
370 WaitCondition c;
371 test->setInterfaceToInterface(
372 static_cast< Interface * >(new Base(c.get())));
373 assertNotNull(test->getInterfaceFromInterface());
374 test->clearInterface();
375 }
376 {
377 WaitCondition c;
378 test->setInterfaceToInterface(
379 static_cast< Interface * >(new Derived(c.get())));
380 assertNotNull(test->getInterfaceFromInterface());
381 test->clearInterface();
382 }
383
384 {
385 WaitCondition c;
386 test->setBaseToInterface(new Base(c.get()));
387 assertNotNull(test->getInterfaceFromInterface());
388 test->clearInterface();
389 }
390 {
391 WaitCondition c;
392 test->setBaseToInterface(static_cast< Base * >(new Derived(c.get())));
393 assertNotNull(test->getInterfaceFromInterface());
394 test->clearInterface();
395 }
396
397 {
398 WaitCondition c;
399 test->setDerivedToInterface(new Derived(c.get()));
400 assertNotNull(test->getInterfaceFromInterface());
401 test->clearInterface();
402 }
403
404 {
405 WaitCondition c;
406 test->setBaseToBase(new Base(c.get()));
407 assertNotNull(test->getInterfaceFromBase());
408 assertNotNull(test->getBaseFromBase());
409 test->clearBase();
410 }
411 {
412 WaitCondition c;
413 test->setBaseToBase(static_cast< Base * >(new Derived(c.get())));
414 assertNotNull(test->getInterfaceFromBase());
415 assertNotNull(test->getBaseFromBase());
416 test->clearBase();
417 }
418
419 {
420 WaitCondition c;
421 test->setDerivedToBase(new Derived(c.get()));
422 assertNotNull(test->getInterfaceFromBase());
423 assertNotNull(test->getBaseFromBase());
424 test->clearBase();
425 }
426
427 {
428 WaitCondition c;
429 test->setDerivedToDerived(new Derived(c.get()));
430 assertNotNull(test->getInterfaceFromDerived());
431 assertNotNull(test->getBaseFromDerived());
432 assertNotNull(test->getDerivedFromDerived());
433 test->clearDerived();
434 }
435
436 {
437 WaitCondition c;
438 assertNotNull(
439 test->roundTripInterfaceToInterface(new Interface(c.get())));
440 }
441 {
442 WaitCondition c;
443 assertNotNull(test->roundTripInterfaceToInterface(
444 static_cast< Interface * >(new Base(c.get()))));
445 }
446 {
447 WaitCondition c;
448 assertNotNull(test->roundTripInterfaceToInterface(
449 static_cast< Interface * >(new Derived(c.get()))));
450 }
451
452 {
453 WaitCondition c;
454 assertNotNull(test->roundTripBaseToInterface(new Base(c.get())));
455 }
456 {
457 WaitCondition c;
458 assertNotNull(test->roundTripBaseToInterface(
459 static_cast< Base * >(new Derived(c.get()))));
460 }
461
462 {
463 WaitCondition c;
464 assertNotNull(test->roundTripDerivedToInterface(new Derived(c.get())));
465 }
466
467 {
468 WaitCondition c;
469 assertNotNull(test->roundTripBaseToBase(new Base(c.get())));
470 }
471 {
472 WaitCondition c;
473 assertNotNull(test->roundTripBaseToBase(
474 static_cast< Base * >(new Derived(c.get()))));
475 }
476
477 {
478 WaitCondition c;
479 assertNotNull(test->roundTripDerivedToBase(new Derived(c.get())));
480 }
481
482 {
483 WaitCondition c;
484 assertNotNull(test->roundTripDerivedToDerived(new Derived(c.get())));
485 }
486
487 std::cout << "Client and server both cleanly terminate now: Success\n";
488 return 0;
489 }
490
getImplementationName_static()491 rtl::OUString Service::getImplementationName_static() {
492 return rtl::OUString::createFromAscii(
493 "com.sun.star.test.bridges.testacquire.impl");
494 }
495
getSupportedServiceNames_static()496 css::uno::Sequence< rtl::OUString > Service::getSupportedServiceNames_static() {
497 css::uno::Sequence< rtl::OUString > names(1);
498 names[0] = rtl::OUString::createFromAscii(
499 "com.sun.star.test.bridges.testacquire");
500 return names;
501 }
502
createInstance(css::uno::Reference<css::uno::XComponentContext> const & context)503 css::uno::Reference< css::uno::XInterface > Service::createInstance(
504 css::uno::Reference< css::uno::XComponentContext > const & context)
505 throw (css::uno::Exception)
506 {
507 return static_cast< cppu::OWeakObject * >(new Service(context));
508 }
509
component_getImplementationEnvironment(char const ** envTypeName,uno_Environment **)510 extern "C" void SAL_CALL component_getImplementationEnvironment(
511 char const ** envTypeName, uno_Environment **)
512 {
513 if (envTypeName != 0) {
514 *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
515 }
516 }
517
component_getFactory(char const * implName,void * serviceManager,void *)518 extern "C" void * SAL_CALL component_getFactory(char const * implName,
519 void * serviceManager, void *) {
520 void * p = 0;
521 if (serviceManager != 0) {
522 css::uno::Reference< css::lang::XSingleComponentFactory > f;
523 if (Service::getImplementationName_static().equalsAscii(implName)) {
524 f = cppu::createSingleComponentFactory(
525 &Service::createInstance,
526 Service::getImplementationName_static(),
527 Service::getSupportedServiceNames_static());
528 }
529 if (f.is()) {
530 f->acquire();
531 p = f.get();
532 }
533 }
534 return p;
535 }
536
537 namespace {
538
writeInfo(void * registryKey,rtl::OUString const & implementationName,css::uno::Sequence<rtl::OUString> const & serviceNames)539 bool writeInfo(void * registryKey, rtl::OUString const & implementationName,
540 css::uno::Sequence< rtl::OUString > const & serviceNames) {
541 rtl::OUString keyName(rtl::OUString::createFromAscii("/"));
542 keyName += implementationName;
543 keyName += rtl::OUString::createFromAscii("/UNO/SERVICES");
544 css::uno::Reference< css::registry::XRegistryKey > key;
545 try {
546 key = static_cast< css::registry::XRegistryKey * >(registryKey)->
547 createKey(keyName);
548 } catch (css::registry::InvalidRegistryException &) {}
549 if (!key.is()) {
550 return false;
551 }
552 bool success = true;
553 for (sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
554 try {
555 key->createKey(serviceNames[i]);
556 } catch (css::registry::InvalidRegistryException &) {
557 success = false;
558 break;
559 }
560 }
561 return success;
562 }
563
564 }
565
component_writeInfo(void *,void * registryKey)566 extern "C" sal_Bool SAL_CALL component_writeInfo(void *, void * registryKey) {
567 return registryKey
568 && writeInfo(registryKey, Service::getImplementationName_static(),
569 Service::getSupportedServiceNames_static());
570 }
571