xref: /trunk/main/bridges/test/java_uno/acquire/testacquire.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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