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