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