1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <sal/main.h>
22 #include <cppuhelper/implbase.hxx>
23 #include <cppuhelper/servicefactory.hxx>
24 #include <osl/diagnose.h>
25 
26 #include <ModuleA/XIntroTest.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/beans/XIntrospection.hpp>
29 #include <com/sun/star/beans/PropertyAttribute.hpp>
30 #include <com/sun/star/beans/PropertyConcept.hpp>
31 #include <com/sun/star/beans/MethodConcept.hpp>
32 #include <com/sun/star/beans/XExactName.hpp>
33 #include <com/sun/star/container/XElementAccess.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/container/XIndexAccess.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/reflection/XIdlReflection.hpp>
38 #include <com/sun/star/registry/XImplementationRegistration.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 
41 #include <stdio.h>
42 #include <string.h>
43 
44 using namespace cppu;
45 using namespace ModuleA;
46 using namespace css::uno;
47 using namespace css::lang;
48 using namespace css::beans;
49 using namespace css::registry;
50 using namespace css::reflection;
51 using namespace css::container;
52 using namespace css::beans::PropertyAttribute;
53 
54 
55 #define DEFAULT_INDEX_ACCESS_COUNT  10
56 #define DEFAULT_NAME_ACCESS_COUNT   5
57 
58 // Auxiliary function, in order to get from one type XIdlClass
TypeToIdlClass(const Type & rType,const Reference<XMultiServiceFactory> & xMgr)59 Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr )
60 {
61     static Reference< XIdlReflection > xRefl;
62 
63     // register void as default class
64     Reference<XIdlClass> xRetClass;
65     typelib_TypeDescription * pTD = 0;
66     rType.getDescription( &pTD );
67     if( pTD )
68     {
69         OUString sOWName( pTD->pTypeName );
70         if( !xRefl.is() )
71         {
72             xRefl.set( xMgr->createInstance( "com.sun.star.reflection.CoreReflection" ), UNO_QUERY );
73             OSL_ENSURE( xRefl.is(), "### no corereflection!" );
74         }
75         xRetClass = xRefl->forName( sOWName );
76     }
77     return xRetClass;
78 }
79 
80 
81 // Helper function to convert Any to UString
82 // TODO: This code could be moved to a more central place.
83 //       Currently it's used only for simple data types.
84 
AnyToString(const Any & aValue,sal_Bool bIncludeType,const Reference<XMultiServiceFactory> & xMgr)85 OUString AnyToString( const Any& aValue, sal_Bool bIncludeType, const Reference< XMultiServiceFactory > & xMgr )
86 {
87     Type aValType = aValue.getValueType();
88     TypeClass eType = aValType.getTypeClass();
89     char pBuffer[50];
90 
91     OUString aRetStr;
92     switch( eType )
93     {
94         case TypeClass_TYPE:            aRetStr = "TYPE TYPE";           break;
95         case TypeClass_INTERFACE:       aRetStr = "TYPE INTERFACE";      break;
96         case TypeClass_SERVICE:         aRetStr = "TYPE SERVICE";        break;
97         case TypeClass_STRUCT:          aRetStr = "TYPE STRUCT";         break;
98         case TypeClass_TYPEDEF:         aRetStr = "TYPE TYPEDEF";        break;
99         case TypeClass_ENUM:            aRetStr = "TYPE ENUM";           break;
100         case TypeClass_EXCEPTION:       aRetStr = "TYPE EXCEPTION";      break;
101         case TypeClass_SEQUENCE:        aRetStr = "TYPE SEQUENCE";       break;
102         case TypeClass_VOID:            aRetStr = "TYPE void";           break;
103         case TypeClass_ANY:             aRetStr = "TYPE any";            break;
104         case TypeClass_UNKNOWN:         aRetStr = "TYPE unknown";        break;
105         case TypeClass_BOOLEAN:
106         {
107             sal_Bool b = *(sal_Bool*)aValue.getValue();
108             aRetStr = OUString::valueOf( b );
109             break;
110         }
111         case TypeClass_CHAR:
112         {
113             sal_Unicode c = *(sal_Unicode*)aValue.getValue();
114             aRetStr = OUString::valueOf( c );
115             break;
116         }
117         case TypeClass_STRING:
118         {
119             aValue >>= aRetStr;
120             break;
121         }
122         case TypeClass_FLOAT:
123         {
124             float f(0.0);
125             aValue >>= f;
126             snprintf( pBuffer, sizeof( pBuffer ), "%f", f );
127             aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US );
128             break;
129         }
130         case TypeClass_DOUBLE:
131         {
132             double d(0.0);
133             aValue >>= d;
134             snprintf( pBuffer, sizeof( pBuffer ), "%f", d );
135             aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US );
136             break;
137         }
138         case TypeClass_BYTE:
139         {
140             sal_Int8 n(0);
141             aValue >>= n;
142             aRetStr = OUString::valueOf( (sal_Int32) n );
143             break;
144         }
145         case TypeClass_SHORT:
146         {
147             sal_Int16 n(0);
148             aValue >>= n;
149             aRetStr = OUString::valueOf( (sal_Int32) n );
150             break;
151         }
152         case TypeClass_LONG:
153         {
154             sal_Int32 n(0);
155             aValue >>= n;
156             aRetStr = OUString::valueOf( n );
157             break;
158         }
159     default: ;
160     }
161 
162     if( bIncludeType )
163     {
164         Reference< XIdlClass > xIdlClass = TypeToIdlClass( aValType, xMgr );
165         aRetStr += " (Typ: " + xIdlClass->getName() + ")";
166     }
167     return aRetStr;
168 }
169 
170 // XPropertySetInfo for test class
171 
172 class ImplPropertySetInfo : public WeakImplHelper< XPropertySetInfo >
173 {
174      friend class ImplIntroTest;
175 
176       Reference< XMultiServiceFactory > mxMgr;
177 
178 public:
ImplPropertySetInfo(const Reference<XMultiServiceFactory> & xMgr)179     explicit ImplPropertySetInfo( const Reference< XMultiServiceFactory > & xMgr )
180         : mxMgr( xMgr ) {}
181 
182     // Methods of XPropertySetInfo
183     virtual Sequence< Property > SAL_CALL getProperties(  )
184         throw(RuntimeException);
185     virtual Property SAL_CALL getPropertyByName( const OUString& aName )
186         throw(UnknownPropertyException, RuntimeException);
187     virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
188         throw(RuntimeException);
189 };
190 
191 
getProperties()192 Sequence< Property > ImplPropertySetInfo::getProperties()
193     throw( RuntimeException )
194 {
195     static Sequence<Property> * pSeq = NULL;
196 
197     if( !pSeq )
198     {
199         // Create information for the properties "Width", "Height" and "Name"
200         pSeq = new Sequence<Property>( 3 );
201         Property * pAry = pSeq->getArray();
202 
203         pAry[0].Name = "Factor";
204         pAry[0].Handle = -1;
205         pAry[0].Type = cppu::UnoType<double>::get();
206         pAry[0].Attributes = BOUND | TRANSIENT;
207 
208         pAry[1].Name = "MyCount";
209         pAry[1].Handle = -1;
210         pAry[1].Type = cppu::UnoType<sal_Int32>::get();
211         pAry[1].Attributes = BOUND | TRANSIENT;
212 
213         pAry[2].Name = "Info";
214         pAry[2].Handle = -1;
215         pAry[2].Type = cppu::UnoType<OUString>::get();
216         pAry[2].Attributes = TRANSIENT;
217     }
218     // Return information about all three properties
219     return *pSeq;
220 }
221 
getPropertyByName(const OUString & Name)222 Property ImplPropertySetInfo::getPropertyByName(const OUString& Name)
223     throw( UnknownPropertyException, RuntimeException )
224 {
225     Sequence<Property> aSeq = getProperties();
226     const Property * pAry = aSeq.getConstArray();
227 
228     for( sal_Int32 i = aSeq.getLength(); i--; )
229     {
230         if( pAry[i].Name == Name )
231             return pAry[i];
232     }
233     // Property unknown, also return empty ones
234     return Property();
235 }
236 
hasPropertyByName(const OUString & Name)237 sal_Bool ImplPropertySetInfo::hasPropertyByName(const OUString& Name)
238     throw( RuntimeException )
239 {
240     Sequence<Property> aSeq = getProperties();
241     const Property * pAry = aSeq.getConstArray();
242 
243     for( sal_Int32 i = aSeq.getLength(); i--; )
244     {
245         if( pAry[i].Name == Name )
246             return sal_True;
247     }
248     // Property unknown, also return empty ones
249     return sal_False;
250 }
251 
252 
253 class ImplIntroTest : public WeakImplHelper< XIntroTest, XPropertySet, XNameAccess, XIndexAccess >
254 {
255       Reference< XMultiServiceFactory > mxMgr;
256 
257     friend class ImplPropertySetInfo;
258 
259     // Properties for the PropertySet
260     Any aAnyArray[10];
261 
262     Reference< XPropertySetInfo > m_xMyInfo;
263 
264     OUString m_ObjectName;
265 
266     sal_Int16 m_nMarkusAge;
267     sal_Int16 m_nMarkusChildrenCount;
268 
269     long m_lDroenk;
270     sal_Int16 m_nBla;
271     sal_Int16 m_nBlub;
272     sal_Int16 m_nGulp;
273     sal_Int16 m_nLaber;
274     TypeClass eTypeClass;
275     Sequence< OUString > aStringSeq;
276     Sequence< Sequence< Sequence< sal_Int16 > > > aMultSeq;
277     Reference< XIntroTest > m_xIntroTest;
278 
279     // Data for NameAccess
280     Reference< XIntroTest >* pNameAccessTab;
281 
282     // Data for IndexAccess
283     Reference< XIntroTest >* pIndexAccessTab;
284     sal_Int16 iIndexAccessCount;
285 
286     // struct properties
287     Property m_aFirstStruct;
288     PropertyValue m_aSecondStruct;
289 
290     // remember listener (one listener per property)
291     Reference< XPropertyChangeListener > aPropChangeListener;
292     OUString aPropChangeListenerStr;
293     Reference< XVetoableChangeListener > aVetoPropChangeListener;
294     OUString aVetoPropChangeListenerStr;
295 
296     void Init();
297 
298 public:
ImplIntroTest(const Reference<XMultiServiceFactory> & xMgr)299     explicit ImplIntroTest( const Reference< XMultiServiceFactory > & xMgr )
300         : mxMgr( xMgr )
301     {
302         Init();
303     }
304 
305     // despite virtual inline, to simplify coding (testing only)
306     // XPropertySet
307     virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo(  )
308         throw(RuntimeException);
309     virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue )
310         throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
311     virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName )
312         throw(UnknownPropertyException, WrappedTargetException, RuntimeException);
addPropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)313     virtual void SAL_CALL addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ )
314         throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
315             {}
removePropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)316     virtual void SAL_CALL removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ )
317         throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
318             {}
addVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)319     virtual void SAL_CALL addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
320         throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
321             {}
removeVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)322     virtual void SAL_CALL removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
323         throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
324             {}
325 
326     // XIntroTest methods
327     // Attributes
getObjectName()328     virtual OUString SAL_CALL getObjectName() throw(RuntimeException)
329         { return m_ObjectName; }
setObjectName(const OUString & _objectname)330     virtual void SAL_CALL setObjectName( const OUString& _objectname ) throw(RuntimeException)
331         { m_ObjectName = _objectname; }
332     virtual OUString SAL_CALL getFirstName()
333         throw(RuntimeException);
getLastName()334     virtual OUString SAL_CALL getLastName() throw(RuntimeException)
335         { return OUString("Meyer"); }
getAge()336     virtual sal_Int16 SAL_CALL getAge() throw(RuntimeException)
337         { return m_nMarkusAge; }
getChildrenCount()338     virtual sal_Int16 SAL_CALL getChildrenCount() throw(RuntimeException)
339         { return m_nMarkusChildrenCount; }
setChildrenCount(sal_Int16 _childrencount)340     virtual void SAL_CALL setChildrenCount( sal_Int16 _childrencount ) throw(RuntimeException)
341         { m_nMarkusChildrenCount = _childrencount; }
getFirstStruct()342     virtual Property SAL_CALL getFirstStruct() throw(RuntimeException)
343         { return m_aFirstStruct; }
setFirstStruct(const Property & _firststruct)344     virtual void SAL_CALL setFirstStruct( const Property& _firststruct ) throw(RuntimeException)
345         { m_aFirstStruct = _firststruct; }
getSecondStruct()346     virtual PropertyValue SAL_CALL getSecondStruct() throw(RuntimeException)
347         { return m_aSecondStruct; }
setSecondStruct(const PropertyValue & _secondstruct)348     virtual void SAL_CALL setSecondStruct( const PropertyValue& _secondstruct ) throw(RuntimeException)
349         { m_aSecondStruct = _secondstruct; }
350 
351     // Methods
352     virtual void SAL_CALL writeln( const OUString& Text )
353         throw(RuntimeException);
getDroenk()354     virtual sal_Int32 SAL_CALL getDroenk(  ) throw(RuntimeException)
355         { return m_lDroenk; }
356     virtual Reference< ::ModuleA::XIntroTest > SAL_CALL getIntroTest(  ) throw(RuntimeException);
getUps(sal_Int32 l)357     virtual sal_Int32 SAL_CALL getUps( sal_Int32 l ) throw(RuntimeException)
358         { return 2*l; }
setDroenk(sal_Int32 l)359     virtual void SAL_CALL setDroenk( sal_Int32 l ) throw(RuntimeException)
360         { m_lDroenk = l; }
getBla()361     virtual sal_Int16 SAL_CALL getBla(  ) throw(RuntimeException)
362         { return m_nBla; }
setBla(sal_Int32 n)363     virtual void SAL_CALL setBla( sal_Int32 n ) throw(RuntimeException)
364         { m_nBla = (sal_Int16)n; }
getBlub()365     virtual sal_Int16 SAL_CALL getBlub(  ) throw(RuntimeException)
366         { return m_nBlub; }
setBlub(sal_Int16 n)367     virtual void SAL_CALL setBlub( sal_Int16 n ) throw(RuntimeException)
368         { m_nBlub = n; }
getGulp()369     virtual sal_Int16 SAL_CALL getGulp(  ) throw(RuntimeException)
370         { return m_nGulp; }
setGulp(sal_Int16 n)371     virtual sal_Int16 SAL_CALL setGulp( sal_Int16 n ) throw(RuntimeException)
372         { m_nGulp = n; return 1; }
getTypeClass(sal_Int16)373     virtual TypeClass SAL_CALL getTypeClass( sal_Int16 /*n*/ ) throw(RuntimeException)
374         { return eTypeClass; }
setTypeClass(TypeClass t,double,double)375     virtual void SAL_CALL setTypeClass( TypeClass t, double /*d1*/, double /*d2*/ ) throw(RuntimeException)
376         { eTypeClass = t; }
getStrings()377     virtual Sequence< OUString > SAL_CALL getStrings(  ) throw(RuntimeException)
378         { return aStringSeq; }
setStrings(const Sequence<OUString> & Strings)379     virtual void SAL_CALL setStrings( const Sequence< OUString >& Strings ) throw(RuntimeException)
380         { aStringSeq = Strings; }
setStringsPerMethod(const Sequence<OUString> & Strings,sal_Int16)381     virtual void SAL_CALL setStringsPerMethod( const Sequence< OUString >& Strings, sal_Int16 /*n*/ ) throw(RuntimeException)
382         { aStringSeq = Strings; }
getMultiSequence()383     virtual Sequence< Sequence< Sequence< sal_Int16 > > > SAL_CALL getMultiSequence(  ) throw(RuntimeException)
384         { return aMultSeq; }
setMultiSequence(const Sequence<Sequence<Sequence<sal_Int16>>> & Seq)385     virtual void SAL_CALL setMultiSequence( const Sequence< Sequence< Sequence< sal_Int16 > > >& Seq ) throw(RuntimeException)
386         { aMultSeq = Seq; }
387     virtual void SAL_CALL addPropertiesChangeListener( const Sequence< OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener )
388         throw(RuntimeException);
389     virtual void SAL_CALL removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& Listener )
390         throw(RuntimeException);
391 
392 
393     // Methods of XElementAccess
394     virtual Type SAL_CALL getElementType(  )
395         throw(RuntimeException);
396     virtual sal_Bool SAL_CALL hasElements(  )
397         throw(RuntimeException);
398 
399     // XNameAccess methods
400     // Methods
401     virtual Any SAL_CALL getByName( const OUString& aName )
402         throw(NoSuchElementException, WrappedTargetException, RuntimeException);
403     virtual Sequence< OUString > SAL_CALL getElementNames(  )
404         throw(RuntimeException);
405     virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
406         throw(RuntimeException);
407 
408     // XIndexAccess methods
409     // Methods
410     virtual sal_Int32 SAL_CALL getCount(  )
411         throw(RuntimeException);
412     virtual Any SAL_CALL getByIndex( sal_Int32 Index )
413         throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException);
414 };
415 
Init()416 void ImplIntroTest::Init()
417 {
418     // set unique name
419     static sal_Int32 nObjCount = 0;
420     OUString aName( "IntroTest-Obj Nr. " );
421     aName += OUString::valueOf( nObjCount );
422     setObjectName( aName );
423 
424     // initialize properties
425     aAnyArray[0] <<= 3.14;
426     aAnyArray[1] <<= (sal_Int32)42;
427     aAnyArray[2] <<= OUString( "Hallo" );
428 
429     // fetch PropertySetInfo once for internal use
430     m_xMyInfo = getPropertySetInfo();
431     m_xMyInfo->acquire();       // otherwise it could crash at shutdown
432 
433     m_nMarkusAge = 33;
434     m_nMarkusChildrenCount = 2;
435 
436     m_lDroenk = 314;
437     m_nBla = 42;
438     m_nBlub = 111;
439     m_nGulp = 99;
440     m_nLaber = 1;
441     eTypeClass = TypeClass_INTERFACE;
442 
443     // string sequence initialization
444     aStringSeq.realloc( 3 );
445     aStringSeq[ 0 ] = "String 0";
446     aStringSeq[ 1 ] = "String 1";
447     aStringSeq[ 2 ] = "String 2";
448 
449     // structs initialization
450     m_aFirstStruct.Name = "FirstStruct-Name";
451     m_aFirstStruct.Handle = 77777;
452     //XIdlClassRef Type;
453     m_aFirstStruct.Attributes = -222;
454 
455     //XInterfaceRef Source;
456     Any Value;
457     Value <<= 2.718281828459;
458     m_aSecondStruct.Value = Value;
459     //XIdlClassRef ListenerType;
460     m_aSecondStruct.State = PropertyState_DIRECT_VALUE;
461 
462     // IndexAccess
463     iIndexAccessCount = DEFAULT_INDEX_ACCESS_COUNT;
464     pIndexAccessTab = NULL;
465     pNameAccessTab = NULL;
466 }
467 
getPropertySetInfo()468 Reference< XPropertySetInfo > ImplIntroTest::getPropertySetInfo()
469     throw(RuntimeException)
470 {
471     static ImplPropertySetInfo aInfo( mxMgr );
472     // All objects have the same Properties, so
473     // the Info is the same for all
474     return &aInfo;
475 }
476 
setPropertyValue(const OUString & aPropertyName,const Any & aValue)477 void ImplIntroTest::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
478     throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
479 {
480     if( aPropChangeListener.is() && aPropertyName == aPropChangeListenerStr )
481     {
482         PropertyChangeEvent aEvt;
483         aEvt.Source = (OWeakObject*)this;
484         aEvt.PropertyName = aPropertyName;
485         aEvt.PropertyHandle = 0;
486         aPropChangeListener->propertyChange( aEvt );
487     }
488     if( aVetoPropChangeListener.is() && aPropertyName == aVetoPropChangeListenerStr )
489     {
490         PropertyChangeEvent aEvt;
491         aEvt.Source = (OWeakObject*)this;
492         aEvt.PropertyName = aVetoPropChangeListenerStr;
493         aEvt.PropertyHandle = 0;
494         aVetoPropChangeListener->vetoableChange( aEvt );
495     }
496 
497     Sequence<Property> aPropSeq = m_xMyInfo->getProperties();
498     sal_Int32 nLen = aPropSeq.getLength();
499     for( sal_Int32 i = 0 ; i < nLen ; i++ )
500     {
501         Property aProp = aPropSeq.getArray()[ i ];
502         if( aProp.Name == aPropertyName )
503             aAnyArray[i] = aValue;
504     }
505 }
506 
getPropertyValue(const OUString & PropertyName)507 Any ImplIntroTest::getPropertyValue( const OUString& PropertyName )
508     throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
509 {
510     Sequence<Property> aPropSeq = m_xMyInfo->getProperties();
511     sal_Int32 nLen = aPropSeq.getLength();
512     for( sal_Int32 i = 0 ; i < nLen ; i++ )
513     {
514         Property aProp = aPropSeq.getArray()[ i ];
515         if( aProp.Name == PropertyName )
516             return aAnyArray[i];
517     }
518     return Any();
519 }
520 
getFirstName()521 OUString ImplIntroTest::getFirstName()
522     throw(RuntimeException)
523 {
524     return OUString("Markus");
525 }
526 
writeln(const OUString & Text)527 void ImplIntroTest::writeln( const OUString& Text )
528     throw(RuntimeException)
529 {
530     OString aStr( Text.getStr(), Text.getLength(), RTL_TEXTENCODING_ASCII_US );
531 
532     printf( "%s", aStr.getStr() );
533 }
534 
getIntroTest()535 Reference< XIntroTest > ImplIntroTest::getIntroTest()
536     throw(RuntimeException)
537 {
538     if( !m_xIntroTest.is() )
539         m_xIntroTest = new ImplIntroTest( mxMgr );
540     return m_xIntroTest;
541 }
542 
543 // Methods of XElementAccess
getElementType()544 Type ImplIntroTest::getElementType(  )
545     throw(RuntimeException)
546 {
547     // TODO
548     Type aRetType;
549     return aRetType;
550 }
551 
hasElements()552 sal_Bool ImplIntroTest::hasElements(  )
553     throw(RuntimeException)
554 {
555     return sal_True;
556 }
557 
558 // XNameAccess methods
getIndexForName(const OUString & ItemName)559 sal_Int32 getIndexForName( const OUString& ItemName )
560 {
561     OUString aLeftStr = ItemName.copy( 0, 4 );
562     if( aLeftStr == "Item" )
563     {
564         // TODO
565         OUString aNumStr = ItemName.copy( 4 );
566     }
567     return -1;
568 }
569 
570 
getByName(const OUString & aName)571 Any ImplIntroTest::getByName( const OUString& aName )
572     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
573 {
574     Any aRetAny;
575 
576     if( !pNameAccessTab  )
577         pNameAccessTab  = new Reference< XIntroTest >[ DEFAULT_NAME_ACCESS_COUNT ];
578 
579     sal_Int32 iIndex = getIndexForName( aName );
580     if( iIndex != -1 )
581     {
582         if( !pNameAccessTab[iIndex].is() )
583         {
584             ImplIntroTest* p = new ImplIntroTest( mxMgr );
585             OUString aName2( "IntroTest by Name-Access, Index = " );
586             aName2 += OUString::valueOf( iIndex );
587             p->setObjectName( aName2 );
588             pNameAccessTab[iIndex] = p;
589         }
590 
591         Reference< XIntroTest > xRet = pNameAccessTab[iIndex];
592         aRetAny = makeAny( xRet );
593     }
594     return aRetAny;
595 }
596 
getElementNames()597 Sequence< OUString > ImplIntroTest::getElementNames(  )
598     throw(RuntimeException)
599 {
600     Sequence<OUString> aStrSeq( DEFAULT_NAME_ACCESS_COUNT );
601     OUString* pStr = aStrSeq.getArray();
602     for( sal_Int32 i = 0 ; i < DEFAULT_NAME_ACCESS_COUNT ; i++ )
603     {
604         OUString aName( "Item" );
605         aName += OUString::valueOf( i );
606         pStr[i] = aName;
607     }
608     return aStrSeq;
609 }
610 
hasByName(const OUString & aName)611 sal_Bool ImplIntroTest::hasByName( const OUString& aName )
612     throw(RuntimeException)
613 {
614     return ( getIndexForName( aName ) != -1 );
615 }
616 
617 // XIndexAccess methods
getCount()618 sal_Int32 ImplIntroTest::getCount(  )
619     throw(RuntimeException)
620 {
621     return iIndexAccessCount;
622 }
623 
getByIndex(sal_Int32 Index)624 Any ImplIntroTest::getByIndex( sal_Int32 Index )
625     throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
626 {
627     Any aRetAny;
628 
629     if( !pIndexAccessTab )
630         pIndexAccessTab = new Reference< XIntroTest >[ iIndexAccessCount ];
631 
632     if( Index < iIndexAccessCount )
633     {
634         if( !pNameAccessTab[Index].is() )
635         {
636             ImplIntroTest* p = new ImplIntroTest( mxMgr );
637             OUString aName( "IntroTest by Index-Access, Index = " );
638             aName += OUString::valueOf( Index );
639             p->setObjectName( aName );
640             pIndexAccessTab[Index] = p;
641         }
642         Reference< XIntroTest > xRet = pIndexAccessTab[Index];
643         aRetAny = makeAny( xRet );
644     }
645     return aRetAny;
646 }
647 
addPropertiesChangeListener(const Sequence<OUString> &,const Reference<XPropertiesChangeListener> &)648 void ImplIntroTest::addPropertiesChangeListener( const Sequence< OUString >& /*PropertyNames*/,
649                                                  const Reference< XPropertiesChangeListener >& /*Listener*/ )
650         throw(RuntimeException)
651 {
652 }
653 
removePropertiesChangeListener(const Reference<XPropertiesChangeListener> &)654 void ImplIntroTest::removePropertiesChangeListener
655 ( const Reference< XPropertiesChangeListener >& /*Listener*/ )
656         throw(RuntimeException)
657 {
658 }
659 
660 
661 struct DefItem
662 {
663     char const * pName;
664     sal_Int32 nConcept;
665 };
666 
667 // special value for method concept, to mark "normal" functions
668 #define  MethodConcept_NORMAL_IMPL      0x80000000
669 
670 
671 // return test object
getIntrospectionTestObject(const Reference<XMultiServiceFactory> & xMgr)672 Any getIntrospectionTestObject( const Reference< XMultiServiceFactory > & xMgr )
673 {
674     Any aObjAny;
675     Reference< XIntroTest > xTestObj = new ImplIntroTest( xMgr );
676     aObjAny.setValue( &xTestObj, cppu::UnoType<XIntroTest>::get());
677     return aObjAny;
678 }
679 
test_introsp(Reference<XMultiServiceFactory> xMgr,Reference<XIdlReflection>,Reference<XIntrospection> xIntrospection)680 static sal_Bool test_introsp( Reference< XMultiServiceFactory > xMgr,
681                               Reference< XIdlReflection > /*xRefl*/, Reference< XIntrospection > xIntrospection )
682 {
683     DefItem pPropertyDefs[] =
684     {
685         { "Factor", PropertyConcept::PROPERTYSET },
686         { "MyCount", PropertyConcept::PROPERTYSET },
687         { "Info", PropertyConcept::PROPERTYSET },
688         { "ObjectName", PropertyConcept::ATTRIBUTES },
689         { "FirstName", PropertyConcept::ATTRIBUTES },
690         { "LastName", PropertyConcept::ATTRIBUTES },
691         { "Age", PropertyConcept::ATTRIBUTES },
692         { "ChildrenCount", PropertyConcept::ATTRIBUTES },
693         { "FirstStruct", PropertyConcept::ATTRIBUTES },
694         { "SecondStruct", PropertyConcept::ATTRIBUTES },
695         { "Droenk", PropertyConcept::METHODS },
696         { "IntroTest", PropertyConcept::METHODS },
697         { "Bla", PropertyConcept::METHODS },
698         { "Blub", PropertyConcept::METHODS },
699         { "Gulp", PropertyConcept::METHODS },
700         { "Strings", PropertyConcept::METHODS },
701         { "MultiSequence", PropertyConcept::METHODS },
702         { "PropertySetInfo", PropertyConcept::METHODS },
703         { "ElementType", PropertyConcept::METHODS },
704         { "ElementNames", PropertyConcept::METHODS },
705         { "Count", PropertyConcept::METHODS },
706         { "Types", PropertyConcept::METHODS },
707         { "ImplementationId", PropertyConcept::METHODS },
708         { NULL, 0 }
709     };
710 
711     char const * pDemandedPropVals[] =
712     {
713         "3.140000",
714         "42",
715         "Hallo",
716         "IntroTest-Obj Nr. 0",
717         "Markus",
718         "Meyer",
719         "33",
720         "2",
721         "TYPE STRUCT",
722         "TYPE STRUCT",
723         "314",
724         "TYPE INTERFACE",
725         "42",
726         "111",
727         "99",
728         "TYPE SEQUENCE",
729         "TYPE SEQUENCE",
730         "TYPE INTERFACE",
731         "TYPE TYPE",
732         "TYPE SEQUENCE",
733         "10",
734         "TYPE SEQUENCE",
735         "TYPE SEQUENCE",
736     };
737 
738     char const * pDemandedModifiedPropVals[] =
739     {
740         "4.140000",
741         "43",
742         "Hallo (Modified!)",
743         "IntroTest-Obj Nr. 0 (Modified!)",
744         "Markus",
745         "Meyer",
746         "33",
747         "3",
748         "Value has not been modified",
749         "Value has not been modified",
750         "315",
751         "Value has not been modified",
752         "42",
753         "112",
754         "99",
755         "Value has not been modified",
756         "Value has not been modified",
757         "Value has not been modified",
758         "Value has not been modified",
759         "Value has not been modified",
760         "10",
761         "Value has not been modified",
762         "Value has not been modified",
763     };
764 
765     char const * pDemandedPropTypes[] =
766     {
767         "double",
768         "long",
769         "string",
770         "string",
771         "string",
772         "string",
773         "short",
774         "short",
775         "com.sun.star.beans.Property",
776         "com.sun.star.beans.PropertyValue",
777         "long",
778         "ModuleA.XIntroTest",
779         "short",
780         "short",
781         "short",
782         "[]string",
783         "[][][]short",
784         "com.sun.star.beans.XPropertySetInfo",
785         "type",
786         "[]string",
787         "long",
788         "[]type",
789         "[]byte",
790     };
791 
792     DefItem pMethodDefs[] =
793     {
794         { "queryInterface", MethodConcept_NORMAL_IMPL },
795         { "acquire", MethodConcept::DANGEROUS },
796         { "release", MethodConcept::DANGEROUS },
797         { "writeln", MethodConcept_NORMAL_IMPL },
798         { "getDroenk", MethodConcept::PROPERTY },
799         { "getIntroTest", MethodConcept::PROPERTY },
800         { "getUps", MethodConcept_NORMAL_IMPL },
801         { "setDroenk", MethodConcept::PROPERTY },
802         { "getBla", MethodConcept::PROPERTY },
803         { "setBla", MethodConcept_NORMAL_IMPL },
804         { "getBlub", MethodConcept::PROPERTY },
805         { "setBlub", MethodConcept::PROPERTY },
806         { "getGulp", MethodConcept::PROPERTY },
807         { "setGulp", MethodConcept_NORMAL_IMPL },
808         { "getTypeClass", MethodConcept_NORMAL_IMPL },
809         { "setTypeClass", MethodConcept_NORMAL_IMPL },
810         { "getStrings", MethodConcept::PROPERTY },
811         { "setStrings", MethodConcept::PROPERTY },
812         { "setStringsPerMethod", MethodConcept_NORMAL_IMPL },
813         { "getMultiSequence", MethodConcept::PROPERTY },
814         { "setMultiSequence", MethodConcept::PROPERTY },
815         { "addPropertiesChangeListener", MethodConcept::LISTENER },
816         { "removePropertiesChangeListener", MethodConcept::LISTENER },
817         { "getPropertySetInfo", MethodConcept::PROPERTY },
818         { "setPropertyValue", MethodConcept_NORMAL_IMPL },
819         { "getPropertyValue", MethodConcept_NORMAL_IMPL },
820         { "addPropertyChangeListener", MethodConcept::LISTENER },
821         { "removePropertyChangeListener", MethodConcept::LISTENER },
822         { "addVetoableChangeListener", MethodConcept::LISTENER },
823         { "removeVetoableChangeListener", MethodConcept::LISTENER },
824         { "getElementType", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER| MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION  },
825         { "hasElements", MethodConcept::NAMECONTAINER | MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION },
826         { "getByName", MethodConcept::NAMECONTAINER },
827         { "getElementNames", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER },
828         { "hasByName", MethodConcept::NAMECONTAINER },
829         { "getCount", MethodConcept::PROPERTY | MethodConcept::INDEXCONTAINER },
830         { "getByIndex", MethodConcept::INDEXCONTAINER },
831         { "getTypes", MethodConcept::PROPERTY },
832         { "getImplementationId", MethodConcept::PROPERTY },
833         { "queryAdapter", MethodConcept_NORMAL_IMPL },
834         { NULL, 0 }
835     };
836 
837     OString aErrorStr;
838 
839 
840     // create test object
841     Any aObjAny = getIntrospectionTestObject( xMgr );
842 
843     // inspect introspection service
844     xIntrospection->inspect( aObjAny );
845     xIntrospection->inspect( aObjAny );
846     Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
847     OSL_ENSURE( xAccess.is(), "introspection failed, no XIntrospectionAccess returned" );
848     if( !xAccess.is() )
849         return sal_False;
850 
851     // check result of introspection
852 
853     // determine XPropertySet-UIK
854     Type aType = cppu::UnoType<XPropertySet>::get();
855 
856     Reference< XInterface > xPropSetIface = xAccess->queryAdapter( aType );
857     Reference< XPropertySet > xPropSet( xPropSetIface, UNO_QUERY );
858     OSL_ENSURE( xPropSet.is(), "Could not get XPropertySet by queryAdapter()" );
859 
860     // XExactName
861     Reference< XExactName > xExactName( xAccess, UNO_QUERY );
862     OSL_ENSURE( xExactName.is(), "Introspection doesn't support ExactName" );
863 
864     // loop over all concept combinations
865     for( sal_Int32 nConcepts = 0 ; nConcepts < 16 ; nConcepts++ )
866     {
867         // how many properties should this be
868         sal_Int32 nDemandedPropCount = 0;
869         sal_Int32 iList = 0;
870         while( pPropertyDefs[ iList ].pName )
871         {
872             if( pPropertyDefs[ iList ].nConcept & nConcepts )
873                 nDemandedPropCount++;
874             iList++;
875         }
876 
877         if( xPropSet.is() )
878         {
879             Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
880             Sequence<Property> aRetSeq = xAccess->getProperties( nConcepts );
881 
882             sal_Int32 nLen = aRetSeq.getLength();
883 
884             aErrorStr = "Expected to find "
885                       + OString::valueOf( nDemandedPropCount )
886                       + " properties but found "
887                       + OString::valueOf( nLen );
888             OSL_ENSURE( nLen == nDemandedPropCount, aErrorStr.getStr() );
889 
890             const Property* pProps = aRetSeq.getConstArray();
891             Any aPropVal;
892             sal_Int32 i;
893             iList = 0;
894             for( i = 0 ; i < nLen ; i++ )
895             {
896                 const Property aProp = pProps[ i ];
897 
898                 // search for next suitable method in the list
899                 while( pPropertyDefs[ iList ].pName )
900                 {
901                     if( pPropertyDefs[ iList ].nConcept & nConcepts )
902                         break;
903                     iList++;
904                 }
905                 sal_Int32 iDemanded = iList;
906                 iList++;
907 
908                 OUString aPropName = aProp.Name;
909                 OString aNameStr( aPropName.getStr(), aPropName.getLength(), RTL_TEXTENCODING_ASCII_US );
910 
911                 OString aDemandedName = pPropertyDefs[ iDemanded ].pName;
912                 aErrorStr = "Expected property \""
913                           + aDemandedName
914                           + "\", found \""
915                           + aNameStr
916                           + "\"";
917                 OSL_ENSURE( aNameStr == aDemandedName, aErrorStr.getStr() );
918 
919                 Type aPropType = aProp.Type;
920                 OString aTypeNameStr( OUStringToOString(aPropType.getTypeName(), RTL_TEXTENCODING_ASCII_US) );
921                 OString aDemandedTypeNameStr = pDemandedPropTypes[ iDemanded ];
922                 aErrorStr = "Property \""
923                           + aDemandedName
924                           + "\", expected type >"
925                           + aDemandedTypeNameStr
926                           + "< found type >"
927                           + aTypeNameStr
928                           + "<";
929                 OSL_ENSURE( aTypeNameStr == aDemandedTypeNameStr, aErrorStr.getStr() );
930 
931                 // read and report value of property
932                 aPropVal = xPropSet->getPropertyValue( aPropName );
933 
934                 OString aValStr = OUStringToOString( AnyToString( aPropVal, sal_False, xMgr ), RTL_TEXTENCODING_ASCII_US );
935                 OString aDemandedValStr = pDemandedPropVals[ iDemanded ];
936                 aErrorStr = "Property \""
937                           + aDemandedName
938                           + "\", expected val >"
939                           + aDemandedValStr
940                           + "< found val >"
941                           + aValStr
942                           + "<";
943                 OSL_ENSURE( aValStr == aDemandedValStr, aErrorStr.getStr() );
944 
945                 // check value and modify it according to its type
946                 TypeClass eType = aPropVal.getValueType().getTypeClass();
947                 Any aNewVal;
948                 sal_Bool bModify = sal_True;
949                 switch( eType )
950                 {
951                     case TypeClass_STRING:
952                     {
953                         OUString aStr;
954                         aPropVal >>= aStr;
955                         aStr += " (Modified!)";
956                         aNewVal <<= aStr;
957                         break;
958                     }
959                     case TypeClass_DOUBLE:
960                     {
961                         double d(0.0);
962                         aPropVal >>= d;
963                         aNewVal <<= d + 1.0;
964                         break;
965                     }
966                     case TypeClass_SHORT:
967                     {
968                         sal_Int16 n(0);
969                         aPropVal >>= n;
970                         aNewVal <<= sal_Int16( n + 1 );
971                         break;
972                     }
973                     case TypeClass_LONG:
974                     {
975                         sal_Int32 n(0);
976                         aPropVal >>= n;
977                         aNewVal <<= sal_Int32( n + 1 );
978                         break;
979                     }
980                     default:
981                         bModify = sal_False;
982                         break;
983                 }
984 
985                 // modify only in the last iteration
986                 if( nConcepts == 15 )
987                 {
988                     // check XExactName, switch everything to upper case
989                     // (introspection uses lower case)
990                     OUString aUpperUStr = aPropName.toAsciiUpperCase();
991                     OUString aExactName = xExactName->getExactName( aUpperUStr );
992                     if( aExactName != aPropName )
993                     {
994                         aErrorStr = "Property \""
995                                   + OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US )
996                                   + "\", not found as \""
997                                   + OUStringToOString(aUpperUStr, RTL_TEXTENCODING_ASCII_US )
998                                   + "\" using XExactName";
999                         OSL_ENSURE( sal_False, aErrorStr.getStr() );
1000                     }
1001                 }
1002                 else
1003                 {
1004                     bModify = sal_False;
1005                 }
1006 
1007                 // set new value, then read and return value
1008                 if( bModify )
1009                 {
1010                     // catch UnknownPropertyException for ReadOnly properties
1011                     try
1012                     {
1013                         xPropSet->setPropertyValue( aPropName, aNewVal );
1014                     }
1015                     catch(const UnknownPropertyException &)
1016                     {
1017                     }
1018 
1019                     aPropVal = xPropSet->getPropertyValue( aPropName );
1020 
1021                     OUString aStr = AnyToString( aPropVal, sal_False, xMgr );
1022                     OString aModifiedValStr = OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US );
1023                     OString aDemandedModifiedValStr = pDemandedModifiedPropVals[ i ];
1024                     aErrorStr = "Property \""
1025                               + aDemandedName
1026                               + "\", expected modified val >"
1027                               + aDemandedModifiedValStr
1028                               + "< found val >"
1029                               + aModifiedValStr
1030                               + "<";
1031                     OSL_ENSURE( aModifiedValStr == aDemandedModifiedValStr, aErrorStr.getStr() );
1032                 }
1033 
1034                 // check whether all properties can be found individually
1035                 aErrorStr = "property \""
1036                           + aDemandedName
1037                           + "\" not found with hasProperty()";
1038                 OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US );
1039                 sal_Bool bProperty = xAccess->hasProperty( aWDemandedName, nConcepts );
1040                 OSL_ENSURE( bProperty, aErrorStr.getStr() );
1041 
1042                 aErrorStr = "property \""
1043                           + aDemandedName
1044                           + "\" not equal to same Property in sequence returned by getProperties()";
1045                 try
1046                 {
1047                     Property aGetProp = xAccess->getProperty( aWDemandedName, nConcepts );
1048                 }
1049                 catch (const RuntimeException &)
1050                 {
1051                     aErrorStr = "property \""
1052                               + aDemandedName
1053                               + "\", exception was thrown when trying getProperty()";
1054                     OSL_ENSURE( sal_False, aErrorStr.getStr() );
1055                 }
1056 
1057             }
1058         }
1059     }
1060 
1061     // loop over all concept combinations
1062     for( sal_Int32 nConcepts = 0 ; nConcepts < 128 ; nConcepts++ )
1063     {
1064         // The 2^6th bit stands for "the rest"
1065         sal_Int32 nRealConcepts = nConcepts;
1066         if( nConcepts & 0x40 )
1067             nRealConcepts |= (0xFFFFFFFF - 0x3F);
1068 
1069         // Count the number of methods there should be
1070         sal_Int32 nDemandedMethCount = 0;
1071         sal_Int32 iList = 0;
1072         while( pMethodDefs[ iList ].pName )
1073         {
1074             if( pMethodDefs[ iList ].nConcept & nRealConcepts )
1075                 nDemandedMethCount++;
1076             iList++;
1077         }
1078 
1079         // Output the method array.
1080         Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( nRealConcepts );
1081         sal_Int32 nLen = aMethodSeq.getLength();
1082 
1083         aErrorStr = "Expected to find "
1084                   + OString::valueOf( nDemandedMethCount )
1085                   + " methods but found "
1086                   + OString::valueOf( nLen );
1087         OSL_ENSURE( nLen == nDemandedMethCount, aErrorStr.getStr() );
1088 
1089         const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
1090         sal_Int32 i;
1091         iList = 0;
1092 
1093         for( i = 0 ; i < nLen ; i++ )
1094         {
1095             const Reference< XIdlMethod >& rxMethod = pMethods[i];
1096 
1097             OUString aMethName = rxMethod->getName();
1098             OString aNameStr = OUStringToOString(aMethName, RTL_TEXTENCODING_ASCII_US );
1099 
1100             // locate the next matching method in the list.
1101             while( pMethodDefs[ iList ].pName )
1102             {
1103                 if( pMethodDefs[ iList ].nConcept & nRealConcepts )
1104                     break;
1105                 iList++;
1106             }
1107             OString aDemandedName = pMethodDefs[ iList ].pName;
1108             iList++;
1109 
1110             aErrorStr = "Expected method \""
1111                       + aDemandedName
1112                       + "\", found \""
1113                       + aNameStr
1114                       + "\"";
1115             OSL_ENSURE( aNameStr == aDemandedName, aErrorStr.getStr() );
1116 
1117             // Check that the method is really there with hasMethod.
1118             aErrorStr = "method \""
1119                       + aDemandedName
1120                       + "\" not found with hasMethod()";
1121             OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US );
1122             sal_Bool bMethod = xAccess->hasMethod( aWDemandedName, nRealConcepts );
1123             OSL_ENSURE( bMethod, aErrorStr.getStr() );
1124 
1125             aErrorStr = "method \""
1126                       + aDemandedName
1127                       + "\" not equal to same method in sequence returned by getMethods()";
1128             try
1129             {
1130                 Reference< XIdlMethod > xGetMethod = xAccess->getMethod( aWDemandedName, nRealConcepts );
1131                 OSL_ENSURE( xGetMethod == rxMethod , aErrorStr.getStr() );
1132             }
1133             catch (const RuntimeException &)
1134             {
1135                 aErrorStr = "method \""
1136                           + aDemandedName
1137                           + "\", exception was thrown when trying getMethod()";
1138                 OSL_ENSURE( sal_False, aErrorStr.getStr() );
1139             }
1140         }
1141     }
1142 
1143     // print listener class
1144     Sequence< Type > aClassSeq = xAccess->getSupportedListeners();
1145     sal_Int32 nLen = aClassSeq.getLength();
1146 
1147     const Type* pListeners = aClassSeq.getConstArray();
1148     for( sal_Int32 i = 0 ; i < nLen ; i++ )
1149     {
1150         const Type& aListenerType = pListeners[i];
1151         OUString aListenerClassName = aListenerType.getTypeName();
1152     }
1153 
1154     return sal_True;
1155 }
1156 
1157 
SAL_IMPLEMENT_MAIN()1158 SAL_IMPLEMENT_MAIN()
1159 {
1160     Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) );
1161 
1162     sal_Bool bSucc = sal_False;
1163     try
1164     {
1165         Reference< XImplementationRegistration > xImplReg(
1166             xMgr->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY );
1167         OSL_ENSURE( xImplReg.is(), "### no impl reg!" );
1168 
1169         // Register services
1170         OUString libName( "reflection.uno" SAL_DLLEXTENSION );
1171         fprintf(stderr, "1\n" );
1172         xImplReg->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1173                                          libName, Reference< XSimpleRegistry >() );
1174         fprintf(stderr, "2\n" );
1175         Reference< XIdlReflection > xRefl( xMgr->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY );
1176         OSL_ENSURE( xRefl.is(), "### no corereflection!" );
1177 
1178         // Introspection
1179         libName = OUString( "introspection.uno" SAL_DLLEXTENSION);
1180         fprintf(stderr, "3\n" );
1181         xImplReg->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1182                                          libName, Reference< XSimpleRegistry >() );
1183         fprintf(stderr, "4\n" );
1184         Reference< XIntrospection > xIntrosp( xMgr->createInstance("com.sun.star.beans.Introspection"), UNO_QUERY );
1185         OSL_ENSURE( xRefl.is(), "### no corereflection!" );
1186 
1187         fprintf(stderr, "before test_introsp\n" );
1188         bSucc = test_introsp( xMgr, xRefl, xIntrosp );
1189         fprintf(stderr, "after test_introsp\n" );
1190     }
1191     catch (const Exception & rExc)
1192     {
1193         DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc );
1194     }
1195 
1196     Reference< XComponent >( xMgr, UNO_QUERY )->dispose();
1197 
1198     printf( "testintrosp %s !\n", (bSucc ? "succeeded" : "failed") );
1199     return (bSucc ? 0 : -1);
1200 }
1201 
1202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1203