1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_stoc.hxx"
30 
31 #include "com/sun/star/beans/XPropertySet.hpp"
32 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
33 #include "com/sun/star/lang/XMain.hpp"
34 #include "com/sun/star/lang/XSingleComponentFactory.hpp"
35 #include "com/sun/star/reflection/XCompoundTypeDescription.hpp"
36 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
37 #include "com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp"
38 #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
39 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
40 #include "com/sun/star/reflection/XPublished.hpp"
41 #include "com/sun/star/reflection/XServiceTypeDescription2.hpp"
42 #include "com/sun/star/reflection/XSingletonTypeDescription2.hpp"
43 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
44 #include "com/sun/star/reflection/XTypeDescription.hpp"
45 #include "com/sun/star/registry/InvalidRegistryException.hpp"
46 #include "com/sun/star/registry/XRegistryKey.hpp"
47 #include "com/sun/star/uno/Any.hxx"
48 #include "com/sun/star/uno/Exception.hpp"
49 #include "com/sun/star/uno/Reference.hxx"
50 #include "com/sun/star/uno/RuntimeException.hpp"
51 #include "com/sun/star/uno/Sequence.hxx"
52 #include "com/sun/star/uno/TypeClass.hpp"
53 #include "com/sun/star/uno/XComponentContext.hpp"
54 #include "com/sun/star/uno/XInterface.hpp"
55 #include "cppuhelper/factory.hxx"
56 #include "cppuhelper/implbase1.hxx"
57 #include "cppuhelper/weak.hxx"
58 #include "rtl/textenc.h"
59 #include "rtl/ustring.h"
60 #include "rtl/ustring.hxx"
61 #include "sal/types.h"
62 #include "uno/environment.h"
63 #include "uno/lbnames.h"
64 
65 #include /*MSVC trouble: <cstdlib>*/ <stdlib.h>
66 #include <iostream>
67 #include <ostream>
68 
69 namespace css = com::sun::star;
70 
71 namespace {
72 
73 class Service: public cppu::WeakImplHelper1< css::lang::XMain > {
74 public:
75     virtual sal_Int32 SAL_CALL
76     run(css::uno::Sequence< rtl::OUString > const & arguments)
77         throw (css::uno::RuntimeException);
78 
79     static rtl::OUString getImplementationName();
80 
81     static css::uno::Sequence< rtl::OUString > getSupportedServiceNames();
82 
83     static css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
84         css::uno::Reference< css::uno::XComponentContext > const & context)
85         throw (css::uno::Exception);
86 
87 private:
88     explicit Service(
89         css::uno::Reference< css::uno::XComponentContext > const & context):
90         m_context(context)
91     {}
92 
93     css::uno::Reference< css::uno::XComponentContext > m_context;
94 };
95 
96 }
97 
98 namespace {
99 
100 std::ostream & operator <<(std::ostream & out, rtl::OUString const & value) {
101     return out << rtl::OUStringToOString(value, RTL_TEXTENCODING_UTF8).getStr();
102 }
103 
104 void assertTrue(bool argument) {
105     if (!argument) {
106         std::cerr
107             << "assertTrue(" << argument << ") failed" << std::endl;
108         /*MSVC trouble: std::*/abort();
109     }
110 }
111 
112 void assertFalse(bool argument) {
113     if (argument) {
114         std::cerr
115             << "assertFalse(" << argument << ") failed" << std::endl;
116         /*MSVC trouble: std::*/abort();
117     }
118 }
119 
120 template< typename T > void assertEqual(T const & value, T const & argument) {
121     if (argument != value) {
122         std::cerr
123             << "assertEqual(" << value << ", " << argument << ") failed"
124             << std::endl;
125         /*MSVC trouble: std::*/abort();
126     }
127 }
128 
129 }
130 
131 sal_Int32 Service::run(css::uno::Sequence< rtl::OUString > const &)
132     throw (css::uno::RuntimeException)
133 {
134     css::uno::Reference< css::lang::XMultiComponentFactory > factory(
135         m_context->getServiceManager());
136     assertTrue(factory.is());
137     css::uno::Sequence< css::uno::Any > args(1);
138     args[0] = css::uno::Reference< css::beans::XPropertySet >(
139         factory, css::uno::UNO_QUERY_THROW)->getPropertyValue(
140             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Registry")));
141     css::uno::Reference< css::container::XHierarchicalNameAccess > provider(
142         factory->createInstanceWithArgumentsAndContext(
143             rtl::OUString(
144                 RTL_CONSTASCII_USTRINGPARAM(
145                     "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider")),
146             args, m_context),
147         css::uno::UNO_QUERY_THROW);
148 
149     // The following assumes that interface members are sorted by increasing
150     // values of XInterfaceMemberTypeDescription.getPosition, the exceptions
151     // of interface attributes and interface methods, the constructors of
152     // services, and the exceptions of service constructors are sorted as given
153     // in the UNOIDL source code:
154 
155     assertEqual< bool >(
156         false,
157         provider->hasByHierarchicalName(
158             rtl::OUString(
159                 RTL_CONSTASCII_USTRINGPARAM("[][]boolean"))));
160     assertEqual< bool >(
161         false,
162         provider->hasByHierarchicalName(
163             rtl::OUString(
164                 RTL_CONSTASCII_USTRINGPARAM(
165                     "test.registrytdprovider.Struct3<boolean,boolean>"))));
166     assertEqual< bool >(
167         false,
168         provider->hasByHierarchicalName(
169             rtl::OUString(
170                 RTL_CONSTASCII_USTRINGPARAM(
171                     "com.sun.star.uno.XComponentContext::getValueByName"))));
172 
173     css::uno::Reference< css::reflection::XCompoundTypeDescription > exception;
174     exception
175         = css::uno::Reference< css::reflection::XCompoundTypeDescription >(
176             provider->getByHierarchicalName(
177                 rtl::OUString(
178                     RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"))),
179             css::uno::UNO_QUERY_THROW);
180     assertEqual(css::uno::TypeClass_EXCEPTION, exception->getTypeClass());
181     assertEqual(
182         rtl::OUString(
183             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception")),
184         exception->getName());
185     assertFalse(exception->getBaseType().is());
186     exception
187         = css::uno::Reference< css::reflection::XCompoundTypeDescription >(
188             provider->getByHierarchicalName(
189                 rtl::OUString(
190                     RTL_CONSTASCII_USTRINGPARAM(
191                         "com.sun.star.uno.RuntimeException"))),
192             css::uno::UNO_QUERY_THROW);
193     assertEqual(css::uno::TypeClass_EXCEPTION, exception->getTypeClass());
194     assertEqual(
195         rtl::OUString(
196             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException")),
197         exception->getName());
198     assertEqual(
199         rtl::OUString(
200             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception")),
201         exception->getBaseType()->getName());
202 
203     css::uno::Reference< css::reflection::XStructTypeDescription > structure;
204 
205     structure = css::uno::Reference< css::reflection::XStructTypeDescription >(
206         provider->getByHierarchicalName(
207             rtl::OUString(
208                 RTL_CONSTASCII_USTRINGPARAM(
209                     "test.registrytdprovider.Struct2"))),
210         css::uno::UNO_QUERY_THROW);
211     assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass());
212     assertEqual(
213         rtl::OUString(
214             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Struct2")),
215         structure->getName());
216     assertFalse(structure->getBaseType().is());
217     assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength());
218     assertEqual(
219         rtl::OUString(
220             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Struct1")),
221         structure->getMemberTypes()[0]->getName());
222     assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength());
223     assertEqual(
224         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("s1")),
225         structure->getMemberNames()[0]);
226     assertEqual< sal_Int32 >(0, structure->getTypeParameters().getLength());
227     assertEqual< sal_Int32 >(0, structure->getTypeArguments().getLength());
228 
229     structure = css::uno::Reference< css::reflection::XStructTypeDescription >(
230         provider->getByHierarchicalName(
231             rtl::OUString(
232                 RTL_CONSTASCII_USTRINGPARAM(
233                     "test.registrytdprovider.Struct3"))),
234         css::uno::UNO_QUERY_THROW);
235     assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass());
236     assertEqual(
237         rtl::OUString(
238             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Struct3")),
239         structure->getName());
240     assertFalse(structure->getBaseType().is());
241     assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength());
242     assertEqual(
243         css::uno::TypeClass_UNKNOWN,
244         structure->getMemberTypes()[0]->getTypeClass());
245     assertEqual(
246         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("U")),
247         structure->getMemberTypes()[0]->getName());
248     assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength());
249     assertEqual(
250         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("s2")),
251         structure->getMemberNames()[0]);
252     assertEqual< sal_Int32 >(2, structure->getTypeParameters().getLength());
253     assertEqual(
254         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("T")),
255         structure->getTypeParameters()[0]);
256     assertEqual(
257         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("U")),
258         structure->getTypeParameters()[1]);
259     assertEqual< sal_Int32 >(0, structure->getTypeArguments().getLength());
260 
261     structure = css::uno::Reference< css::reflection::XStructTypeDescription >(
262         provider->getByHierarchicalName(
263             rtl::OUString(
264                 RTL_CONSTASCII_USTRINGPARAM(
265                     "test.registrytdprovider.Struct4"))),
266         css::uno::UNO_QUERY_THROW);
267     assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass());
268     assertEqual(
269         rtl::OUString(
270             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Struct4")),
271         structure->getName());
272     assertEqual(
273         rtl::OUString(
274             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Struct2")),
275         structure->getBaseType()->getName());
276     assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength());
277     assertEqual(
278         rtl::OUString(
279             RTL_CONSTASCII_USTRINGPARAM(
280                 "test.registrytdprovider.Struct3<"
281                 "test.registrytdprovider.Struct2,"
282                 "test.registrytdprovider.Struct3<boolean,any>>")),
283         structure->getMemberTypes()[0]->getName());
284     assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength());
285     assertEqual(
286         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("s2")),
287         structure->getMemberNames()[0]);
288     assertEqual< sal_Int32 >(0, structure->getTypeParameters().getLength());
289     assertEqual< sal_Int32 >(0, structure->getTypeArguments().getLength());
290 
291     css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >
292         interface;
293 
294     interface
295         = css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >(
296             provider->getByHierarchicalName(
297                 rtl::OUString(
298                     RTL_CONSTASCII_USTRINGPARAM(
299                         "test.registrytdprovider.XTest1"))),
300             css::uno::UNO_QUERY_THROW);
301     assertEqual(css::uno::TypeClass_INTERFACE, interface->getTypeClass());
302     assertEqual(
303         rtl::OUString(
304             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1")),
305         interface->getName());
306     css::uno::Sequence<
307         css::uno::Reference< css::reflection::XTypeDescription > > bases(
308             interface->getBaseTypes());
309     assertEqual< sal_Int32 >(1, bases.getLength());
310     assertEqual(
311         rtl::OUString(
312             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")),
313         bases[0]->getName());
314     css::uno::Sequence<
315         css::uno::Reference< css::reflection::XTypeDescription > >
316             optionalBases(interface->getOptionalBaseTypes());
317     assertEqual< sal_Int32 >(1, optionalBases.getLength());
318     assertEqual(
319         rtl::OUString(
320             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XBase")),
321         optionalBases[0]->getName());
322     css::uno::Sequence<
323         css::uno::Reference<
324             css::reflection::XInterfaceMemberTypeDescription > > members(
325                 interface->getMembers());
326     assertEqual< sal_Int32 >(5, members.getLength());
327 
328     css::uno::Reference< css::reflection::XInterfaceAttributeTypeDescription2 >
329         attribute;
330     css::uno::Sequence<
331         css::uno::Reference< css::reflection::XCompoundTypeDescription > >
332             getExceptions;
333     css::uno::Sequence<
334         css::uno::Reference< css::reflection::XCompoundTypeDescription > >
335             setExceptions;
336     css::uno::Reference< css::reflection::XInterfaceMethodTypeDescription >
337         method;
338 
339     attribute = css::uno::Reference<
340         css::reflection::XInterfaceAttributeTypeDescription2 >(
341             members[0], css::uno::UNO_QUERY_THROW);
342     assertEqual(
343         css::uno::TypeClass_INTERFACE_ATTRIBUTE, attribute->getTypeClass());
344     assertEqual(
345         rtl::OUString(
346             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1::a1")),
347         attribute->getName());
348     assertEqual(
349         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a1")),
350         attribute->getMemberName());
351     assertEqual< sal_Int32 >(3, attribute->getPosition());
352     assertEqual< bool >(false, attribute->isReadOnly());
353     assertEqual(
354         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("short")),
355         attribute->getType()->getName());
356     assertEqual< bool >(true, attribute->isBound());
357     getExceptions = attribute->getGetExceptions();
358     assertEqual< sal_Int32 >(0, getExceptions.getLength());
359     setExceptions = attribute->getSetExceptions();
360     assertEqual< sal_Int32 >(0, setExceptions.getLength());
361 
362     attribute = css::uno::Reference<
363         css::reflection::XInterfaceAttributeTypeDescription2 >(
364             members[1], css::uno::UNO_QUERY_THROW);
365     assertEqual(
366         css::uno::TypeClass_INTERFACE_ATTRIBUTE, attribute->getTypeClass());
367     assertEqual(
368         rtl::OUString(
369             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1::a2")),
370         attribute->getName());
371     assertEqual(
372         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a2")),
373         attribute->getMemberName());
374     assertEqual< sal_Int32 >(4, attribute->getPosition());
375     assertEqual< bool >(false, attribute->isReadOnly());
376     assertEqual(
377         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("long")),
378         attribute->getType()->getName());
379     assertEqual< bool >(false, attribute->isBound());
380     getExceptions = attribute->getGetExceptions();
381     assertEqual< sal_Int32 >(2, getExceptions.getLength());
382     assertEqual(
383         rtl::OUString(
384             RTL_CONSTASCII_USTRINGPARAM(
385                 "com.sun.star.lang.WrappedTargetException")),
386         getExceptions[0]->getName());
387     assertEqual(
388         rtl::OUString(
389             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException")),
390         getExceptions[1]->getName());
391     setExceptions = attribute->getSetExceptions();
392     assertEqual< sal_Int32 >(2, setExceptions.getLength());
393     assertEqual(
394         rtl::OUString(
395             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception")),
396         setExceptions[0]->getName());
397     assertEqual(
398         rtl::OUString(
399             RTL_CONSTASCII_USTRINGPARAM(
400                 "com.sun.star.lang.WrappedTargetException")),
401         setExceptions[1]->getName());
402 
403     attribute = css::uno::Reference<
404         css::reflection::XInterfaceAttributeTypeDescription2 >(
405             members[2], css::uno::UNO_QUERY_THROW);
406     assertEqual(
407         css::uno::TypeClass_INTERFACE_ATTRIBUTE, attribute->getTypeClass());
408     assertEqual(
409         rtl::OUString(
410             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1::a3")),
411         attribute->getName());
412     assertEqual(
413         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a3")),
414         attribute->getMemberName());
415     assertEqual< sal_Int32 >(5, attribute->getPosition());
416     assertEqual< bool >(true, attribute->isReadOnly());
417     assertEqual(
418         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hyper")),
419         attribute->getType()->getName());
420     assertEqual< bool >(true, attribute->isBound());
421     getExceptions = attribute->getGetExceptions();
422     assertEqual< sal_Int32 >(1, getExceptions.getLength());
423     assertEqual(
424         rtl::OUString(
425             RTL_CONSTASCII_USTRINGPARAM(
426                 "com.sun.star.lang.WrappedTargetException")),
427         getExceptions[0]->getName());
428     setExceptions = attribute->getSetExceptions();
429     assertEqual< sal_Int32 >(0, setExceptions.getLength());
430 
431     method = css::uno::Reference<
432         css::reflection::XInterfaceMethodTypeDescription >(
433             members[3], css::uno::UNO_QUERY_THROW);
434     assertEqual(css::uno::TypeClass_INTERFACE_METHOD, method->getTypeClass());
435     assertEqual(
436         rtl::OUString(
437             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1::f1")),
438         method->getName());
439     assertEqual(
440         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("f1")),
441         method->getMemberName());
442     assertEqual< sal_Int32 >(6, method->getPosition());
443     assertEqual< bool >(false, method->isOneway());
444     assertEqual< sal_Int32 >(1, method->getParameters().getLength());
445     assertEqual(
446         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("p")),
447         method->getParameters()[0]->getName());
448     assertEqual(
449         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("any")),
450         method->getParameters()[0]->getType()->getName());
451     assertEqual< bool >(false, method->getParameters()[0]->isIn());
452     assertEqual< bool >(true, method->getParameters()[0]->isOut());
453     assertEqual< sal_Int32 >(0, method->getParameters()[0]->getPosition());
454     assertEqual< sal_Int32 >(1, method->getExceptions().getLength());
455     assertEqual(
456         rtl::OUString(
457             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException")),
458         method->getExceptions()[0]->getName());
459 
460     method = css::uno::Reference<
461         css::reflection::XInterfaceMethodTypeDescription >(
462             members[4], css::uno::UNO_QUERY_THROW);
463     assertEqual(css::uno::TypeClass_INTERFACE_METHOD, method->getTypeClass());
464     assertEqual(
465         rtl::OUString(
466             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1::f2")),
467         method->getName());
468     assertEqual(
469         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("f2")),
470         method->getMemberName());
471     assertEqual< sal_Int32 >(7, method->getPosition());
472     assertEqual< bool >(true, method->isOneway());
473     assertEqual< sal_Int32 >(0, method->getParameters().getLength());
474     assertEqual< sal_Int32 >(0, method->getExceptions().getLength());
475 
476     interface
477         = css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >(
478             provider->getByHierarchicalName(
479                 rtl::OUString(
480                     RTL_CONSTASCII_USTRINGPARAM(
481                         "test.registrytdprovider.XTest2"))),
482             css::uno::UNO_QUERY_THROW);
483     assertEqual(css::uno::TypeClass_INTERFACE, interface->getTypeClass());
484     assertEqual(
485         rtl::OUString(
486             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest2")),
487         interface->getName());
488     assertEqual< sal_Int32 >(1, interface->getBaseTypes().getLength());
489     assertEqual(
490         rtl::OUString(
491             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Typedef2")),
492         interface->getBaseTypes()[0]->getName());
493     assertEqual< sal_Int32 >(0, interface->getOptionalBaseTypes().getLength());
494     assertEqual< sal_Int32 >(0, interface->getMembers().getLength());
495 
496     css::uno::Reference< css::reflection::XServiceTypeDescription2 > service;
497 
498     service = css::uno::Reference< css::reflection::XServiceTypeDescription2 >(
499         provider->getByHierarchicalName(
500             rtl::OUString(
501                 RTL_CONSTASCII_USTRINGPARAM(
502                     "test.registrytdprovider.Service1"))),
503         css::uno::UNO_QUERY_THROW);
504     assertEqual(css::uno::TypeClass_SERVICE, service->getTypeClass());
505     assertEqual(
506         rtl::OUString(
507             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Service1")),
508         service->getName());
509     assertEqual< sal_Int32 >(0, service->getMandatoryServices().getLength());
510     assertEqual< sal_Int32 >(0, service->getOptionalServices().getLength());
511     assertEqual< sal_Int32 >(0, service->getMandatoryInterfaces().getLength());
512     assertEqual< sal_Int32 >(0, service->getOptionalInterfaces().getLength());
513     assertEqual< bool >(true, service->isSingleInterfaceBased());
514     assertEqual(
515         rtl::OUString(
516             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1")),
517         service->getInterface()->getName());
518     assertEqual< sal_Int32 >(2, service->getConstructors().getLength());
519     assertEqual(
520         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("c1")),
521         service->getConstructors()[0]->getName());
522     assertEqual< sal_Int32 >(
523         0, service->getConstructors()[0]->getParameters().getLength());
524     assertEqual< sal_Int32 >(
525         0, service->getConstructors()[0]->getExceptions().getLength());
526     assertEqual(
527         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("c2")),
528         service->getConstructors()[1]->getName());
529     assertEqual< sal_Int32 >(
530         1, service->getConstructors()[1]->getParameters().getLength());
531     assertEqual(
532         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("p")),
533         service->getConstructors()[1]->getParameters()[0]->getName());
534     assertEqual(
535         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("any")),
536         (service->getConstructors()[1]->getParameters()[0]->getType()->
537          getName()));
538     assertEqual< bool >(
539         true, service->getConstructors()[1]->getParameters()[0]->isIn());
540     assertEqual< bool >(
541         false, service->getConstructors()[1]->getParameters()[0]->isOut());
542     assertEqual< sal_Int32 >(
543         0, service->getConstructors()[1]->getParameters()[0]->getPosition());
544     assertEqual< bool >(
545         true,
546         service->getConstructors()[1]->getParameters()[0]->isRestParameter());
547     assertEqual< sal_Int32 >(
548         1, service->getConstructors()[1]->getExceptions().getLength());
549     assertEqual(
550         rtl::OUString(
551             RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException")),
552         service->getConstructors()[1]->getExceptions()[0]->getName());
553 
554     service = css::uno::Reference< css::reflection::XServiceTypeDescription2 >(
555         provider->getByHierarchicalName(
556             rtl::OUString(
557                 RTL_CONSTASCII_USTRINGPARAM(
558                     "test.registrytdprovider.Service2"))),
559         css::uno::UNO_QUERY_THROW);
560     assertEqual(css::uno::TypeClass_SERVICE, service->getTypeClass());
561     assertEqual(
562         rtl::OUString(
563             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Service2")),
564         service->getName());
565     assertEqual< sal_Int32 >(0, service->getMandatoryServices().getLength());
566     assertEqual< sal_Int32 >(0, service->getOptionalServices().getLength());
567     assertEqual< sal_Int32 >(1, service->getMandatoryInterfaces().getLength());
568     assertEqual(
569         rtl::OUString(
570             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1")),
571         service->getMandatoryInterfaces()[0]->getName());
572     assertEqual< sal_Int32 >(1, service->getOptionalInterfaces().getLength());
573     assertEqual(
574         rtl::OUString(
575             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XBase")),
576         service->getOptionalInterfaces()[0]->getName());
577     assertEqual< bool >(false, service->isSingleInterfaceBased());
578     assertFalse(service->getInterface().is());
579     assertEqual< sal_Int32 >(0, service->getConstructors().getLength());
580 
581     service = css::uno::Reference< css::reflection::XServiceTypeDescription2 >(
582         provider->getByHierarchicalName(
583             rtl::OUString(
584                 RTL_CONSTASCII_USTRINGPARAM(
585                     "test.registrytdprovider.Service3"))),
586         css::uno::UNO_QUERY_THROW);
587     assertEqual(css::uno::TypeClass_SERVICE, service->getTypeClass());
588     assertEqual(
589         rtl::OUString(
590             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Service3")),
591         service->getName());
592     assertEqual< sal_Int32 >(0, service->getMandatoryServices().getLength());
593     assertEqual< sal_Int32 >(0, service->getOptionalServices().getLength());
594     assertEqual< sal_Int32 >(0, service->getMandatoryInterfaces().getLength());
595     assertEqual< sal_Int32 >(0, service->getOptionalInterfaces().getLength());
596     assertEqual< bool >(true, service->isSingleInterfaceBased());
597     assertEqual(
598         rtl::OUString(
599             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Typedef2")),
600         service->getInterface()->getName());
601     assertEqual< sal_Int32 >(0, service->getConstructors().getLength());
602 
603     css::uno::Reference< css::reflection::XSingletonTypeDescription2 >
604         singleton;
605 
606     singleton = css::uno::Reference<
607         css::reflection::XSingletonTypeDescription2 >(
608             provider->getByHierarchicalName(
609                 rtl::OUString(
610                     RTL_CONSTASCII_USTRINGPARAM(
611                         "test.registrytdprovider.Singleton1"))),
612             css::uno::UNO_QUERY_THROW);
613     assertEqual(css::uno::TypeClass_SINGLETON, singleton->getTypeClass());
614     assertEqual(
615         rtl::OUString(
616             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Singleton1")),
617         singleton->getName());
618     assertFalse(singleton->getService().is());
619     assertEqual< bool >(true, singleton->isInterfaceBased());
620     assertEqual(
621         rtl::OUString(
622             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.XTest1")),
623         singleton->getInterface()->getName());
624 
625     singleton = css::uno::Reference<
626         css::reflection::XSingletonTypeDescription2 >(
627             provider->getByHierarchicalName(
628                 rtl::OUString(
629                     RTL_CONSTASCII_USTRINGPARAM(
630                         "test.registrytdprovider.Singleton2"))),
631             css::uno::UNO_QUERY_THROW);
632     assertEqual(css::uno::TypeClass_SINGLETON, singleton->getTypeClass());
633     assertEqual(
634         rtl::OUString(
635             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Singleton2")),
636         singleton->getName());
637     assertEqual(
638         rtl::OUString(
639             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Service1")),
640         singleton->getService()->getName());
641     assertEqual< bool >(false, singleton->isInterfaceBased());
642     assertFalse(singleton->getInterface().is());
643 
644     singleton = css::uno::Reference<
645         css::reflection::XSingletonTypeDescription2 >(
646             provider->getByHierarchicalName(
647                 rtl::OUString(
648                     RTL_CONSTASCII_USTRINGPARAM(
649                         "test.registrytdprovider.Singleton3"))),
650             css::uno::UNO_QUERY_THROW);
651     assertEqual(css::uno::TypeClass_SINGLETON, singleton->getTypeClass());
652     assertEqual(
653         rtl::OUString(
654             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Singleton3")),
655         singleton->getName());
656     assertFalse(singleton->getService().is());
657     assertEqual< bool >(true, singleton->isInterfaceBased());
658     assertEqual(
659         rtl::OUString(
660             RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider.Typedef2")),
661         singleton->getInterface()->getName());
662 
663     css::uno::Reference< css::reflection::XPublished > published;
664     published = css::uno::Reference< css::reflection::XPublished >(
665         css::uno::Reference< css::reflection::XTypeDescription >(
666             provider->getByHierarchicalName(
667                 rtl::OUString(
668                     RTL_CONSTASCII_USTRINGPARAM(
669                         "test.registrytdprovider.Enum1"))),
670             css::uno::UNO_QUERY_THROW),
671         css::uno::UNO_QUERY);
672     assertTrue(published.is());
673     assertTrue(published->isPublished());
674     published = css::uno::Reference< css::reflection::XPublished >(
675         css::uno::Reference< css::reflection::XTypeDescription >(
676             provider->getByHierarchicalName(
677                 rtl::OUString(
678                     RTL_CONSTASCII_USTRINGPARAM(
679                         "test.registrytdprovider.Enum2"))),
680             css::uno::UNO_QUERY_THROW),
681         css::uno::UNO_QUERY);
682     assertTrue(published.is());
683     assertFalse(published->isPublished());
684     published = css::uno::Reference< css::reflection::XPublished >(
685         css::uno::Reference< css::reflection::XTypeDescription >(
686             provider->getByHierarchicalName(
687                 rtl::OUString(
688                     RTL_CONSTASCII_USTRINGPARAM(
689                         "test.registrytdprovider.Struct1"))),
690             css::uno::UNO_QUERY_THROW),
691         css::uno::UNO_QUERY);
692     assertTrue(published.is());
693     assertTrue(published->isPublished());
694     published = css::uno::Reference< css::reflection::XPublished >(
695         css::uno::Reference< css::reflection::XTypeDescription >(
696             provider->getByHierarchicalName(
697                 rtl::OUString(
698                     RTL_CONSTASCII_USTRINGPARAM(
699                         "test.registrytdprovider.Struct2"))),
700             css::uno::UNO_QUERY_THROW),
701         css::uno::UNO_QUERY);
702     assertTrue(published.is());
703     assertFalse(published->isPublished());
704     published = css::uno::Reference< css::reflection::XPublished >(
705         css::uno::Reference< css::reflection::XTypeDescription >(
706             provider->getByHierarchicalName(
707                 rtl::OUString(
708                     RTL_CONSTASCII_USTRINGPARAM(
709                         "test.registrytdprovider.Struct3"))),
710             css::uno::UNO_QUERY_THROW),
711         css::uno::UNO_QUERY);
712     assertTrue(published.is());
713     assertTrue(published->isPublished());
714     published = css::uno::Reference< css::reflection::XPublished >(
715         css::uno::Reference< css::reflection::XStructTypeDescription >(
716             provider->getByHierarchicalName(
717                 rtl::OUString(
718                     RTL_CONSTASCII_USTRINGPARAM(
719                         "test.registrytdprovider.Struct3"))),
720             css::uno::UNO_QUERY_THROW)->getMemberTypes()[0],
721         css::uno::UNO_QUERY);
722     assertFalse(published.is());
723     published = css::uno::Reference< css::reflection::XPublished >(
724         css::uno::Reference< css::reflection::XTypeDescription >(
725             provider->getByHierarchicalName(
726                 rtl::OUString(
727                     RTL_CONSTASCII_USTRINGPARAM(
728                         "test.registrytdprovider.Struct3a"))),
729             css::uno::UNO_QUERY_THROW),
730         css::uno::UNO_QUERY);
731     assertTrue(published.is());
732     assertFalse(published->isPublished());
733     published = css::uno::Reference< css::reflection::XPublished >(
734         css::uno::Reference< css::reflection::XTypeDescription >(
735             provider->getByHierarchicalName(
736                 rtl::OUString(
737                     RTL_CONSTASCII_USTRINGPARAM(
738                         "test.registrytdprovider.Exception1"))),
739             css::uno::UNO_QUERY_THROW),
740         css::uno::UNO_QUERY);
741     assertTrue(published.is());
742     assertTrue(published->isPublished());
743     published = css::uno::Reference< css::reflection::XPublished >(
744         css::uno::Reference< css::reflection::XTypeDescription >(
745             provider->getByHierarchicalName(
746                 rtl::OUString(
747                     RTL_CONSTASCII_USTRINGPARAM(
748                         "test.registrytdprovider.Exception2"))),
749             css::uno::UNO_QUERY_THROW),
750         css::uno::UNO_QUERY);
751     assertTrue(published.is());
752     assertFalse(published->isPublished());
753     published = css::uno::Reference< css::reflection::XPublished >(
754         css::uno::Reference< css::reflection::XTypeDescription >(
755             provider->getByHierarchicalName(
756                 rtl::OUString(
757                     RTL_CONSTASCII_USTRINGPARAM(
758                         "test.registrytdprovider.XTest1"))),
759             css::uno::UNO_QUERY_THROW),
760         css::uno::UNO_QUERY);
761     assertTrue(published.is());
762     assertTrue(published->isPublished());
763     published = css::uno::Reference< css::reflection::XPublished >(
764         css::uno::Reference< css::reflection::XTypeDescription >(
765             provider->getByHierarchicalName(
766                 rtl::OUString(
767                     RTL_CONSTASCII_USTRINGPARAM(
768                         "test.registrytdprovider.XTest2"))),
769             css::uno::UNO_QUERY_THROW),
770         css::uno::UNO_QUERY);
771     assertTrue(published.is());
772     assertFalse(published->isPublished());
773     published = css::uno::Reference< css::reflection::XPublished >(
774         css::uno::Reference< css::reflection::XTypeDescription >(
775             provider->getByHierarchicalName(
776                 rtl::OUString(
777                     RTL_CONSTASCII_USTRINGPARAM(
778                         "test.registrytdprovider.Typedef1"))),
779             css::uno::UNO_QUERY_THROW),
780         css::uno::UNO_QUERY);
781     assertTrue(published.is());
782     assertTrue(published->isPublished());
783     published = css::uno::Reference< css::reflection::XPublished >(
784         css::uno::Reference< css::reflection::XTypeDescription >(
785             provider->getByHierarchicalName(
786                 rtl::OUString(
787                     RTL_CONSTASCII_USTRINGPARAM(
788                         "test.registrytdprovider.Typedef2"))),
789             css::uno::UNO_QUERY_THROW),
790         css::uno::UNO_QUERY);
791     assertTrue(published.is());
792     assertFalse(published->isPublished());
793     //TODO: check constants test.registrytdprovider.Const1 (published),
794     // test.registrytdprovider.Const2 (unpublished), and
795     // test.registrytdprovider.Consts1.C (no XPublished), which are not
796     // accessible via provider->getByHierarchicalName (see #i31428)
797     published = css::uno::Reference< css::reflection::XPublished >(
798         css::uno::Reference< css::reflection::XTypeDescription >(
799             provider->getByHierarchicalName(
800                 rtl::OUString(
801                     RTL_CONSTASCII_USTRINGPARAM(
802                         "test.registrytdprovider.Consts1"))),
803             css::uno::UNO_QUERY_THROW),
804         css::uno::UNO_QUERY);
805     assertTrue(published.is());
806     assertTrue(published->isPublished());
807     published = css::uno::Reference< css::reflection::XPublished >(
808         css::uno::Reference< css::reflection::XTypeDescription >(
809             provider->getByHierarchicalName(
810                 rtl::OUString(
811                     RTL_CONSTASCII_USTRINGPARAM(
812                         "test.registrytdprovider.Consts2"))),
813             css::uno::UNO_QUERY_THROW),
814         css::uno::UNO_QUERY);
815     assertTrue(published.is());
816     assertFalse(published->isPublished());
817     published = css::uno::Reference< css::reflection::XPublished >(
818         css::uno::Reference< css::reflection::XTypeDescription >(
819             provider->getByHierarchicalName(
820                 rtl::OUString(
821                     RTL_CONSTASCII_USTRINGPARAM("test.registrytdprovider"))),
822             css::uno::UNO_QUERY_THROW),
823         css::uno::UNO_QUERY);
824     assertFalse(published.is());
825     published = css::uno::Reference< css::reflection::XPublished >(
826         css::uno::Reference< css::reflection::XTypeDescription >(
827             provider->getByHierarchicalName(
828                 rtl::OUString(
829                     RTL_CONSTASCII_USTRINGPARAM(
830                         "test.registrytdprovider.Service1"))),
831             css::uno::UNO_QUERY_THROW),
832         css::uno::UNO_QUERY);
833     assertTrue(published.is());
834     assertTrue(published->isPublished());
835     published = css::uno::Reference< css::reflection::XPublished >(
836         css::uno::Reference< css::reflection::XTypeDescription >(
837             provider->getByHierarchicalName(
838                 rtl::OUString(
839                     RTL_CONSTASCII_USTRINGPARAM(
840                         "test.registrytdprovider.Service2"))),
841             css::uno::UNO_QUERY_THROW),
842         css::uno::UNO_QUERY);
843     assertTrue(published.is());
844     assertFalse(published->isPublished());
845     published = css::uno::Reference< css::reflection::XPublished >(
846         css::uno::Reference< css::reflection::XTypeDescription >(
847             provider->getByHierarchicalName(
848                 rtl::OUString(
849                     RTL_CONSTASCII_USTRINGPARAM(
850                         "test.registrytdprovider.Singleton2"))),
851             css::uno::UNO_QUERY_THROW),
852         css::uno::UNO_QUERY);
853     assertTrue(published.is());
854     assertTrue(published->isPublished());
855     published = css::uno::Reference< css::reflection::XPublished >(
856         css::uno::Reference< css::reflection::XTypeDescription >(
857             provider->getByHierarchicalName(
858                 rtl::OUString(
859                     RTL_CONSTASCII_USTRINGPARAM(
860                         "test.registrytdprovider.Singleton1"))),
861             css::uno::UNO_QUERY_THROW),
862         css::uno::UNO_QUERY);
863     assertTrue(published.is());
864     assertFalse(published->isPublished());
865 
866     return 0;
867 }
868 
869 rtl::OUString Service::getImplementationName() {
870     return rtl::OUString::createFromAscii("test.registrytdprovider.impl");
871 }
872 
873 css::uno::Sequence< rtl::OUString > Service::getSupportedServiceNames() {
874     return css::uno::Sequence< rtl::OUString >();
875 }
876 
877 css::uno::Reference< css::uno::XInterface > Service::createInstance(
878     css::uno::Reference< css::uno::XComponentContext > const & context)
879     throw (css::uno::Exception)
880 {
881     return static_cast< cppu::OWeakObject * >(new Service(context));
882 }
883 
884 extern "C" void SAL_CALL component_getImplementationEnvironment(
885     char const ** envTypeName, uno_Environment **)
886 {
887     if (envTypeName != 0) {
888         *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
889     }
890 }
891 
892 extern "C" void * SAL_CALL component_getFactory(char const * implName,
893                                                 void * serviceManager, void *) {
894     void * p = 0;
895     if (serviceManager != 0) {
896         css::uno::Reference< css::lang::XSingleComponentFactory > f;
897         if (Service::getImplementationName().equalsAscii(implName)) {
898             f = cppu::createSingleComponentFactory(
899                 &Service::createInstance, Service::getImplementationName(),
900                 Service::getSupportedServiceNames());
901         }
902         if (f.is()) {
903             f->acquire();
904             p = f.get();
905         }
906     }
907     return p;
908 }
909 
910 namespace {
911 
912 bool writeInfo(void * registryKey, rtl::OUString const & implementationName,
913                css::uno::Sequence< rtl::OUString > const & serviceNames) {
914     rtl::OUString keyName(rtl::OUString::createFromAscii("/"));
915     keyName += implementationName;
916     keyName += rtl::OUString::createFromAscii("/UNO/SERVICES");
917     css::uno::Reference< css::registry::XRegistryKey > key;
918     try {
919         key = static_cast< css::registry::XRegistryKey * >(registryKey)->
920             createKey(keyName);
921     } catch (css::registry::InvalidRegistryException &) {}
922     if (!key.is()) {
923         return false;
924     }
925     bool success = true;
926     for (sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
927         try {
928             key->createKey(serviceNames[i]);
929         } catch (css::registry::InvalidRegistryException &) {
930             success = false;
931             break;
932         }
933     }
934     return success;
935 }
936 
937 }
938 
939 extern "C" sal_Bool SAL_CALL component_writeInfo(void *, void * registryKey) {
940     return registryKey
941         && writeInfo(registryKey, Service::getImplementationName(),
942                      Service::getSupportedServiceNames());
943 }
944