1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <cppuhelper/implbase.hxx>
23 #include <cppuhelper/servicefactory.hxx>
24 #include <osl/diagnose.h>
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>
46 using namespace ModuleA
;
47 using namespace css::uno
;
48 using namespace css::lang
;
49 using namespace css::beans
;
50 using namespace css::registry
;
51 using namespace css::reflection
;
52 using namespace css::container
;
53 using namespace css::beans::PropertyAttribute
;
56 #define DEFAULT_INDEX_ACCESS_COUNT 10
57 #define DEFAULT_NAME_ACCESS_COUNT 5
59 // Auxiliary function, in order to get from one type XIdlClass
60 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XMultiServiceFactory
> & xMgr
)
62 static Reference
< XIdlReflection
> xRefl
;
64 // register void as default class
65 Reference
<XIdlClass
> xRetClass
;
66 typelib_TypeDescription
* pTD
= 0;
67 rType
.getDescription( &pTD
);
70 OUString
sOWName( pTD
->pTypeName
);
73 xRefl
.set( xMgr
->createInstance( "com.sun.star.reflection.CoreReflection" ), UNO_QUERY
);
74 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
76 xRetClass
= xRefl
->forName( sOWName
);
82 // Helper function to convert Any to UString
83 // TODO: This code could be moved to a more central place.
84 // Currently it's used only for simple data types.
86 OUString
AnyToString( const Any
& aValue
, sal_Bool bIncludeType
, const Reference
< XMultiServiceFactory
> & xMgr
)
88 Type aValType
= aValue
.getValueType();
89 TypeClass eType
= aValType
.getTypeClass();
95 case TypeClass_TYPE
: aRetStr
= "TYPE TYPE"; break;
96 case TypeClass_INTERFACE
: aRetStr
= "TYPE INTERFACE"; break;
97 case TypeClass_SERVICE
: aRetStr
= "TYPE SERVICE"; break;
98 case TypeClass_STRUCT
: aRetStr
= "TYPE STRUCT"; break;
99 case TypeClass_TYPEDEF
: aRetStr
= "TYPE TYPEDEF"; break;
100 case TypeClass_ENUM
: aRetStr
= "TYPE ENUM"; break;
101 case TypeClass_EXCEPTION
: aRetStr
= "TYPE EXCEPTION"; break;
102 case TypeClass_SEQUENCE
: aRetStr
= "TYPE SEQUENCE"; break;
103 case TypeClass_VOID
: aRetStr
= "TYPE void"; break;
104 case TypeClass_ANY
: aRetStr
= "TYPE any"; break;
105 case TypeClass_UNKNOWN
: aRetStr
= "TYPE unknown"; break;
106 case TypeClass_BOOLEAN
:
108 sal_Bool b
= *(sal_Bool
*)aValue
.getValue();
109 aRetStr
= OUString::valueOf( b
);
114 sal_Unicode c
= *(sal_Unicode
*)aValue
.getValue();
115 aRetStr
= OUString::valueOf( c
);
118 case TypeClass_STRING
:
123 case TypeClass_FLOAT
:
127 snprintf( pBuffer
, sizeof( pBuffer
), "%f", f
);
128 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
131 case TypeClass_DOUBLE
:
135 snprintf( pBuffer
, sizeof( pBuffer
), "%f", d
);
136 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
143 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
146 case TypeClass_SHORT
:
150 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
157 aRetStr
= OUString::valueOf( n
);
165 Reference
< XIdlClass
> xIdlClass
= TypeToIdlClass( aValType
, xMgr
);
166 aRetStr
+= " (Typ: " + xIdlClass
->getName() + ")";
171 // XPropertySetInfo for test class
173 class ImplPropertySetInfo
: public WeakImplHelper
< XPropertySetInfo
>
175 friend class ImplIntroTest
;
177 Reference
< XMultiServiceFactory
> mxMgr
;
180 explicit ImplPropertySetInfo( const Reference
< XMultiServiceFactory
> & xMgr
)
183 // Methods of XPropertySetInfo
184 virtual Sequence
< Property
> SAL_CALL
getProperties( )
185 throw(RuntimeException
);
186 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
)
187 throw(UnknownPropertyException
, RuntimeException
);
188 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
)
189 throw(RuntimeException
);
193 Sequence
< Property
> ImplPropertySetInfo::getProperties()
194 throw( RuntimeException
)
196 static Sequence
<Property
> * pSeq
= NULL
;
200 // Create information for the properties "Width", "Height" and "Name"
201 pSeq
= new Sequence
<Property
>( 3 );
202 Property
* pAry
= pSeq
->getArray();
204 pAry
[0].Name
= "Factor";
206 pAry
[0].Type
= cppu::UnoType
<double>::get();
207 pAry
[0].Attributes
= BOUND
| TRANSIENT
;
209 pAry
[1].Name
= "MyCount";
211 pAry
[1].Type
= cppu::UnoType
<sal_Int32
>::get();
212 pAry
[1].Attributes
= BOUND
| TRANSIENT
;
214 pAry
[2].Name
= "Info";
216 pAry
[2].Type
= cppu::UnoType
<OUString
>::get();
217 pAry
[2].Attributes
= TRANSIENT
;
219 // Return information about all three properties
223 Property
ImplPropertySetInfo::getPropertyByName(const OUString
& Name
)
224 throw( UnknownPropertyException
, RuntimeException
)
226 Sequence
<Property
> aSeq
= getProperties();
227 const Property
* pAry
= aSeq
.getConstArray();
229 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
231 if( pAry
[i
].Name
== Name
)
234 // Property unknown, also return empty ones
238 sal_Bool
ImplPropertySetInfo::hasPropertyByName(const OUString
& Name
)
239 throw( RuntimeException
)
241 Sequence
<Property
> aSeq
= getProperties();
242 const Property
* pAry
= aSeq
.getConstArray();
244 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
246 if( pAry
[i
].Name
== Name
)
249 // Property unknown, also return empty ones
254 class ImplIntroTest
: public WeakImplHelper
< XIntroTest
, XPropertySet
, XNameAccess
, XIndexAccess
>
256 Reference
< XMultiServiceFactory
> mxMgr
;
258 friend class ImplPropertySetInfo
;
260 // Properties for the PropertySet
263 Reference
< XPropertySetInfo
> m_xMyInfo
;
265 OUString m_ObjectName
;
267 sal_Int16 m_nMarkusAge
;
268 sal_Int16 m_nMarkusChildrenCount
;
275 TypeClass eTypeClass
;
276 Sequence
< OUString
> aStringSeq
;
277 Sequence
< Sequence
< Sequence
< sal_Int16
> > > aMultSeq
;
278 Reference
< XIntroTest
> m_xIntroTest
;
280 // Data for NameAccess
281 Reference
< XIntroTest
>* pNameAccessTab
;
283 // Data for IndexAccess
284 Reference
< XIntroTest
>* pIndexAccessTab
;
285 sal_Int16 iIndexAccessCount
;
288 Property m_aFirstStruct
;
289 PropertyValue m_aSecondStruct
;
291 // remember listener (one listener per property)
292 Reference
< XPropertyChangeListener
> aPropChangeListener
;
293 OUString aPropChangeListenerStr
;
294 Reference
< XVetoableChangeListener
> aVetoPropChangeListener
;
295 OUString aVetoPropChangeListenerStr
;
300 explicit ImplIntroTest( const Reference
< XMultiServiceFactory
> & xMgr
)
306 // despite virtual inline, to simplify coding (testing only)
308 virtual Reference
< XPropertySetInfo
> SAL_CALL
getPropertySetInfo( )
309 throw(RuntimeException
);
310 virtual void SAL_CALL
setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
311 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
);
312 virtual Any SAL_CALL
getPropertyValue( const OUString
& PropertyName
)
313 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
);
314 virtual void SAL_CALL
addPropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*xListener*/ )
315 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
317 virtual void SAL_CALL
removePropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*aListener*/ )
318 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
320 virtual void SAL_CALL
addVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
321 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
323 virtual void SAL_CALL
removeVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
324 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
327 // XIntroTest methods
329 virtual OUString SAL_CALL
getObjectName() throw(RuntimeException
)
330 { return m_ObjectName
; }
331 virtual void SAL_CALL
setObjectName( const OUString
& _objectname
) throw(RuntimeException
)
332 { m_ObjectName
= _objectname
; }
333 virtual OUString SAL_CALL
getFirstName()
334 throw(RuntimeException
);
335 virtual OUString SAL_CALL
getLastName() throw(RuntimeException
)
336 { return OUString("Meyer"); }
337 virtual sal_Int16 SAL_CALL
getAge() throw(RuntimeException
)
338 { return m_nMarkusAge
; }
339 virtual sal_Int16 SAL_CALL
getChildrenCount() throw(RuntimeException
)
340 { return m_nMarkusChildrenCount
; }
341 virtual void SAL_CALL
setChildrenCount( sal_Int16 _childrencount
) throw(RuntimeException
)
342 { m_nMarkusChildrenCount
= _childrencount
; }
343 virtual Property SAL_CALL
getFirstStruct() throw(RuntimeException
)
344 { return m_aFirstStruct
; }
345 virtual void SAL_CALL
setFirstStruct( const Property
& _firststruct
) throw(RuntimeException
)
346 { m_aFirstStruct
= _firststruct
; }
347 virtual PropertyValue SAL_CALL
getSecondStruct() throw(RuntimeException
)
348 { return m_aSecondStruct
; }
349 virtual void SAL_CALL
setSecondStruct( const PropertyValue
& _secondstruct
) throw(RuntimeException
)
350 { m_aSecondStruct
= _secondstruct
; }
353 virtual void SAL_CALL
writeln( const OUString
& Text
)
354 throw(RuntimeException
);
355 virtual sal_Int32 SAL_CALL
getDroenk( ) throw(RuntimeException
)
356 { return m_lDroenk
; }
357 virtual Reference
< ::ModuleA::XIntroTest
> SAL_CALL
getIntroTest( ) throw(RuntimeException
);
358 virtual sal_Int32 SAL_CALL
getUps( sal_Int32 l
) throw(RuntimeException
)
360 virtual void SAL_CALL
setDroenk( sal_Int32 l
) throw(RuntimeException
)
362 virtual sal_Int16 SAL_CALL
getBla( ) throw(RuntimeException
)
364 virtual void SAL_CALL
setBla( sal_Int32 n
) throw(RuntimeException
)
365 { m_nBla
= (sal_Int16
)n
; }
366 virtual sal_Int16 SAL_CALL
getBlub( ) throw(RuntimeException
)
368 virtual void SAL_CALL
setBlub( sal_Int16 n
) throw(RuntimeException
)
370 virtual sal_Int16 SAL_CALL
getGulp( ) throw(RuntimeException
)
372 virtual sal_Int16 SAL_CALL
setGulp( sal_Int16 n
) throw(RuntimeException
)
373 { m_nGulp
= n
; return 1; }
374 virtual TypeClass SAL_CALL
getTypeClass( sal_Int16
/*n*/ ) throw(RuntimeException
)
375 { return eTypeClass
; }
376 virtual void SAL_CALL
setTypeClass( TypeClass t
, double /*d1*/, double /*d2*/ ) throw(RuntimeException
)
378 virtual Sequence
< OUString
> SAL_CALL
getStrings( ) throw(RuntimeException
)
379 { return aStringSeq
; }
380 virtual void SAL_CALL
setStrings( const Sequence
< OUString
>& Strings
) throw(RuntimeException
)
381 { aStringSeq
= Strings
; }
382 virtual void SAL_CALL
setStringsPerMethod( const Sequence
< OUString
>& Strings
, sal_Int16
/*n*/ ) throw(RuntimeException
)
383 { aStringSeq
= Strings
; }
384 virtual Sequence
< Sequence
< Sequence
< sal_Int16
> > > SAL_CALL
getMultiSequence( ) throw(RuntimeException
)
386 virtual void SAL_CALL
setMultiSequence( const Sequence
< Sequence
< Sequence
< sal_Int16
> > >& Seq
) throw(RuntimeException
)
388 virtual void SAL_CALL
addPropertiesChangeListener( const Sequence
< OUString
>& PropertyNames
, const Reference
< XPropertiesChangeListener
>& Listener
)
389 throw(RuntimeException
);
390 virtual void SAL_CALL
removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& Listener
)
391 throw(RuntimeException
);
394 // Methods of XElementAccess
395 virtual Type SAL_CALL
getElementType( )
396 throw(RuntimeException
);
397 virtual sal_Bool SAL_CALL
hasElements( )
398 throw(RuntimeException
);
400 // XNameAccess methods
402 virtual Any SAL_CALL
getByName( const OUString
& aName
)
403 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
);
404 virtual Sequence
< OUString
> SAL_CALL
getElementNames( )
405 throw(RuntimeException
);
406 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
)
407 throw(RuntimeException
);
409 // XIndexAccess methods
411 virtual sal_Int32 SAL_CALL
getCount( )
412 throw(RuntimeException
);
413 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
)
414 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
);
417 void ImplIntroTest::Init()
420 static sal_Int32 nObjCount
= 0;
421 OUString
aName( "IntroTest-Obj Nr. " );
422 aName
+= OUString::valueOf( nObjCount
);
423 setObjectName( aName
);
425 // initialize properties
426 aAnyArray
[0] <<= 3.14;
427 aAnyArray
[1] <<= (sal_Int32
)42;
428 aAnyArray
[2] <<= OUString( "Hallo" );
430 // fetch PropertySetInfo once for internal use
431 m_xMyInfo
= getPropertySetInfo();
432 m_xMyInfo
->acquire(); // otherwise it could crash at shutdown
435 m_nMarkusChildrenCount
= 2;
442 eTypeClass
= TypeClass_INTERFACE
;
444 // string sequence initialization
445 aStringSeq
.realloc( 3 );
446 aStringSeq
[ 0 ] = "String 0";
447 aStringSeq
[ 1 ] = "String 1";
448 aStringSeq
[ 2 ] = "String 2";
450 // structs initialization
451 m_aFirstStruct
.Name
= "FirstStruct-Name";
452 m_aFirstStruct
.Handle
= 77777;
454 m_aFirstStruct
.Attributes
= -222;
456 //XInterfaceRef Source;
459 m_aSecondStruct
.Value
= Value
;
460 //XIdlClassRef ListenerType;
461 m_aSecondStruct
.State
= PropertyState_DIRECT_VALUE
;
464 iIndexAccessCount
= DEFAULT_INDEX_ACCESS_COUNT
;
465 pIndexAccessTab
= NULL
;
466 pNameAccessTab
= NULL
;
469 Reference
< XPropertySetInfo
> ImplIntroTest::getPropertySetInfo()
470 throw(RuntimeException
)
472 static ImplPropertySetInfo
aInfo( mxMgr
);
473 // All objects have the same Properties, so
474 // the Info is the same for all
478 void ImplIntroTest::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
479 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
481 if( aPropChangeListener
.is() && aPropertyName
== aPropChangeListenerStr
)
483 PropertyChangeEvent aEvt
;
484 aEvt
.Source
= (OWeakObject
*)this;
485 aEvt
.PropertyName
= aPropertyName
;
486 aEvt
.PropertyHandle
= 0;
487 aPropChangeListener
->propertyChange( aEvt
);
489 if( aVetoPropChangeListener
.is() && aPropertyName
== aVetoPropChangeListenerStr
)
491 PropertyChangeEvent aEvt
;
492 aEvt
.Source
= (OWeakObject
*)this;
493 aEvt
.PropertyName
= aVetoPropChangeListenerStr
;
494 aEvt
.PropertyHandle
= 0;
495 aVetoPropChangeListener
->vetoableChange( aEvt
);
498 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
499 sal_Int32 nLen
= aPropSeq
.getLength();
500 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
502 Property aProp
= aPropSeq
.getArray()[ i
];
503 if( aProp
.Name
== aPropertyName
)
504 aAnyArray
[i
] = aValue
;
508 Any
ImplIntroTest::getPropertyValue( const OUString
& PropertyName
)
509 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
511 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
512 sal_Int32 nLen
= aPropSeq
.getLength();
513 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
515 Property aProp
= aPropSeq
.getArray()[ i
];
516 if( aProp
.Name
== PropertyName
)
522 OUString
ImplIntroTest::getFirstName()
523 throw(RuntimeException
)
525 return OUString("Markus");
528 void ImplIntroTest::writeln( const OUString
& Text
)
529 throw(RuntimeException
)
531 OString
aStr( Text
.getStr(), Text
.getLength(), RTL_TEXTENCODING_ASCII_US
);
533 printf( "%s", aStr
.getStr() );
536 Reference
< XIntroTest
> ImplIntroTest::getIntroTest()
537 throw(RuntimeException
)
539 if( !m_xIntroTest
.is() )
540 m_xIntroTest
= new ImplIntroTest( mxMgr
);
544 // Methods of XElementAccess
545 Type
ImplIntroTest::getElementType( )
546 throw(RuntimeException
)
553 sal_Bool
ImplIntroTest::hasElements( )
554 throw(RuntimeException
)
559 // XNameAccess methods
560 sal_Int32
getIndexForName( const OUString
& ItemName
)
562 OUString aLeftStr
= ItemName
.copy( 0, 4 );
563 if( aLeftStr
== "Item" )
566 OUString aNumStr
= ItemName
.copy( 4 );
572 Any
ImplIntroTest::getByName( const OUString
& aName
)
573 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
)
577 if( !pNameAccessTab
)
578 pNameAccessTab
= new Reference
< XIntroTest
>[ DEFAULT_NAME_ACCESS_COUNT
];
580 sal_Int32 iIndex
= getIndexForName( aName
);
583 if( !pNameAccessTab
[iIndex
].is() )
585 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
586 OUString
aName2( "IntroTest by Name-Access, Index = " );
587 aName2
+= OUString::valueOf( iIndex
);
588 p
->setObjectName( aName2
);
589 pNameAccessTab
[iIndex
] = p
;
592 Reference
< XIntroTest
> xRet
= pNameAccessTab
[iIndex
];
593 aRetAny
= makeAny( xRet
);
598 Sequence
< OUString
> ImplIntroTest::getElementNames( )
599 throw(RuntimeException
)
601 Sequence
<OUString
> aStrSeq( DEFAULT_NAME_ACCESS_COUNT
);
602 OUString
* pStr
= aStrSeq
.getArray();
603 for( sal_Int32 i
= 0 ; i
< DEFAULT_NAME_ACCESS_COUNT
; i
++ )
605 OUString
aName( "Item" );
606 aName
+= OUString::valueOf( i
);
612 sal_Bool
ImplIntroTest::hasByName( const OUString
& aName
)
613 throw(RuntimeException
)
615 return ( getIndexForName( aName
) != -1 );
618 // XIndexAccess methods
619 sal_Int32
ImplIntroTest::getCount( )
620 throw(RuntimeException
)
622 return iIndexAccessCount
;
625 Any
ImplIntroTest::getByIndex( sal_Int32 Index
)
626 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
630 if( !pIndexAccessTab
)
631 pIndexAccessTab
= new Reference
< XIntroTest
>[ iIndexAccessCount
];
633 if( Index
< iIndexAccessCount
)
635 if( !pNameAccessTab
[Index
].is() )
637 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
638 OUString
aName( "IntroTest by Index-Access, Index = " );
639 aName
+= OUString::valueOf( Index
);
640 p
->setObjectName( aName
);
641 pIndexAccessTab
[Index
] = p
;
643 Reference
< XIntroTest
> xRet
= pIndexAccessTab
[Index
];
644 aRetAny
= makeAny( xRet
);
649 void ImplIntroTest::addPropertiesChangeListener( const Sequence
< OUString
>& /*PropertyNames*/,
650 const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
651 throw(RuntimeException
)
655 void ImplIntroTest::removePropertiesChangeListener
656 ( const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
657 throw(RuntimeException
)
668 // special value for method concept, to mark "normal" functions
669 #define MethodConcept_NORMAL_IMPL 0x80000000
672 // return test object
673 Any
getIntrospectionTestObject( const Reference
< XMultiServiceFactory
> & xMgr
)
676 Reference
< XIntroTest
> xTestObj
= new ImplIntroTest( xMgr
);
677 aObjAny
.setValue( &xTestObj
, cppu::UnoType
<XIntroTest
>::get());
681 static sal_Bool
test_introsp( Reference
< XMultiServiceFactory
> xMgr
,
682 Reference
< XIdlReflection
> /*xRefl*/, Reference
< XIntrospection
> xIntrospection
)
684 DefItem pPropertyDefs
[] =
686 { "Factor", PropertyConcept::PROPERTYSET
},
687 { "MyCount", PropertyConcept::PROPERTYSET
},
688 { "Info", PropertyConcept::PROPERTYSET
},
689 { "ObjectName", PropertyConcept::ATTRIBUTES
},
690 { "FirstName", PropertyConcept::ATTRIBUTES
},
691 { "LastName", PropertyConcept::ATTRIBUTES
},
692 { "Age", PropertyConcept::ATTRIBUTES
},
693 { "ChildrenCount", PropertyConcept::ATTRIBUTES
},
694 { "FirstStruct", PropertyConcept::ATTRIBUTES
},
695 { "SecondStruct", PropertyConcept::ATTRIBUTES
},
696 { "Droenk", PropertyConcept::METHODS
},
697 { "IntroTest", PropertyConcept::METHODS
},
698 { "Bla", PropertyConcept::METHODS
},
699 { "Blub", PropertyConcept::METHODS
},
700 { "Gulp", PropertyConcept::METHODS
},
701 { "Strings", PropertyConcept::METHODS
},
702 { "MultiSequence", PropertyConcept::METHODS
},
703 { "PropertySetInfo", PropertyConcept::METHODS
},
704 { "ElementType", PropertyConcept::METHODS
},
705 { "ElementNames", PropertyConcept::METHODS
},
706 { "Count", PropertyConcept::METHODS
},
707 { "Types", PropertyConcept::METHODS
},
708 { "ImplementationId", PropertyConcept::METHODS
},
712 char const * pDemandedPropVals
[] =
717 "IntroTest-Obj Nr. 0",
739 char const * pDemandedModifiedPropVals
[] =
744 "IntroTest-Obj Nr. 0 (Modified!)",
749 "Value has not been modified",
750 "Value has not been modified",
752 "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 "Value has not been modified",
762 "Value has not been modified",
763 "Value has not been modified",
766 char const * pDemandedPropTypes
[] =
776 "com.sun.star.beans.Property",
777 "com.sun.star.beans.PropertyValue",
779 "ModuleA.XIntroTest",
785 "com.sun.star.beans.XPropertySetInfo",
793 DefItem pMethodDefs
[] =
795 { "queryInterface", MethodConcept_NORMAL_IMPL
},
796 { "acquire", MethodConcept::DANGEROUS
},
797 { "release", MethodConcept::DANGEROUS
},
798 { "writeln", MethodConcept_NORMAL_IMPL
},
799 { "getDroenk", MethodConcept::PROPERTY
},
800 { "getIntroTest", MethodConcept::PROPERTY
},
801 { "getUps", MethodConcept_NORMAL_IMPL
},
802 { "setDroenk", MethodConcept::PROPERTY
},
803 { "getBla", MethodConcept::PROPERTY
},
804 { "setBla", MethodConcept_NORMAL_IMPL
},
805 { "getBlub", MethodConcept::PROPERTY
},
806 { "setBlub", MethodConcept::PROPERTY
},
807 { "getGulp", MethodConcept::PROPERTY
},
808 { "setGulp", MethodConcept_NORMAL_IMPL
},
809 { "getTypeClass", MethodConcept_NORMAL_IMPL
},
810 { "setTypeClass", MethodConcept_NORMAL_IMPL
},
811 { "getStrings", MethodConcept::PROPERTY
},
812 { "setStrings", MethodConcept::PROPERTY
},
813 { "setStringsPerMethod", MethodConcept_NORMAL_IMPL
},
814 { "getMultiSequence", MethodConcept::PROPERTY
},
815 { "setMultiSequence", MethodConcept::PROPERTY
},
816 { "addPropertiesChangeListener", MethodConcept::LISTENER
},
817 { "removePropertiesChangeListener", MethodConcept::LISTENER
},
818 { "getPropertySetInfo", MethodConcept::PROPERTY
},
819 { "setPropertyValue", MethodConcept_NORMAL_IMPL
},
820 { "getPropertyValue", MethodConcept_NORMAL_IMPL
},
821 { "addPropertyChangeListener", MethodConcept::LISTENER
},
822 { "removePropertyChangeListener", MethodConcept::LISTENER
},
823 { "addVetoableChangeListener", MethodConcept::LISTENER
},
824 { "removeVetoableChangeListener", MethodConcept::LISTENER
},
825 { "getElementType", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
826 { "hasElements", MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
827 { "getByName", MethodConcept::NAMECONTAINER
},
828 { "getElementNames", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
},
829 { "hasByName", MethodConcept::NAMECONTAINER
},
830 { "getCount", MethodConcept::PROPERTY
| MethodConcept::INDEXCONTAINER
},
831 { "getByIndex", MethodConcept::INDEXCONTAINER
},
832 { "getTypes", MethodConcept::PROPERTY
},
833 { "getImplementationId", MethodConcept::PROPERTY
},
834 { "queryAdapter", MethodConcept_NORMAL_IMPL
},
841 // create test object
842 Any aObjAny
= getIntrospectionTestObject( xMgr
);
844 // inspect introspection service
845 xIntrospection
->inspect( aObjAny
);
846 xIntrospection
->inspect( aObjAny
);
847 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
848 OSL_ENSURE( xAccess
.is(), "introspection failed, no XIntrospectionAccess returned" );
852 // check result of introspection
854 // determine XPropertySet-UIK
855 Type aType
= cppu::UnoType
<XPropertySet
>::get();
857 Reference
< XInterface
> xPropSetIface
= xAccess
->queryAdapter( aType
);
858 Reference
< XPropertySet
> xPropSet( xPropSetIface
, UNO_QUERY
);
859 OSL_ENSURE( xPropSet
.is(), "Could not get XPropertySet by queryAdapter()" );
862 Reference
< XExactName
> xExactName( xAccess
, UNO_QUERY
);
863 OSL_ENSURE( xExactName
.is(), "Introspection doesn't support ExactName" );
865 // loop over all concept combinations
866 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 16 ; nConcepts
++ )
868 // how many properties should this be
869 sal_Int32 nDemandedPropCount
= 0;
871 while( pPropertyDefs
[ iList
].pName
)
873 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
874 nDemandedPropCount
++;
880 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
881 Sequence
<Property
> aRetSeq
= xAccess
->getProperties( nConcepts
);
883 sal_Int32 nLen
= aRetSeq
.getLength();
885 aErrorStr
= "Expected to find "
886 + OString::valueOf( nDemandedPropCount
)
887 + " properties but found "
888 + OString::valueOf( nLen
);
889 OSL_ENSURE( nLen
== nDemandedPropCount
, aErrorStr
.getStr() );
891 const Property
* pProps
= aRetSeq
.getConstArray();
895 for( i
= 0 ; i
< nLen
; i
++ )
897 const Property aProp
= pProps
[ i
];
899 // search for next suitable method in the list
900 while( pPropertyDefs
[ iList
].pName
)
902 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
906 sal_Int32 iDemanded
= iList
;
909 OUString aPropName
= aProp
.Name
;
910 OString
aNameStr( aPropName
.getStr(), aPropName
.getLength(), RTL_TEXTENCODING_ASCII_US
);
912 OString aDemandedName
= pPropertyDefs
[ iDemanded
].pName
;
913 aErrorStr
= "Expected property \""
918 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
920 Type aPropType
= aProp
.Type
;
921 OString
aTypeNameStr( OUStringToOString(aPropType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
) );
922 OString aDemandedTypeNameStr
= pDemandedPropTypes
[ iDemanded
];
923 aErrorStr
= "Property \""
925 + "\", expected type >"
926 + aDemandedTypeNameStr
930 OSL_ENSURE( aTypeNameStr
== aDemandedTypeNameStr
, aErrorStr
.getStr() );
932 // read and report value of property
933 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
935 OString aValStr
= OUStringToOString( AnyToString( aPropVal
, sal_False
, xMgr
), RTL_TEXTENCODING_ASCII_US
);
936 OString aDemandedValStr
= pDemandedPropVals
[ iDemanded
];
937 aErrorStr
= "Property \""
939 + "\", expected val >"
944 OSL_ENSURE( aValStr
== aDemandedValStr
, aErrorStr
.getStr() );
946 // check value and modify it according to its type
947 TypeClass eType
= aPropVal
.getValueTypeClass();
949 sal_Bool bModify
= sal_True
;
952 case TypeClass_STRING
:
956 aStr
+= " (Modified!)";
960 case TypeClass_DOUBLE
:
967 case TypeClass_SHORT
:
971 aNewVal
<<= sal_Int16( n
+ 1 );
978 aNewVal
<<= sal_Int32( n
+ 1 );
986 // modify only in the last iteration
987 if( nConcepts
== 15 )
989 // check XExactName, switch everything to upper case
990 // (introspection uses lower case)
991 OUString aUpperUStr
= aPropName
.toAsciiUpperCase();
992 OUString aExactName
= xExactName
->getExactName( aUpperUStr
);
993 if( aExactName
!= aPropName
)
995 aErrorStr
= "Property \""
996 + OUStringToOString( aPropName
, RTL_TEXTENCODING_ASCII_US
)
997 + "\", not found as \""
998 + OUStringToOString(aUpperUStr
, RTL_TEXTENCODING_ASCII_US
)
999 + "\" using XExactName";
1000 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1005 bModify
= sal_False
;
1008 // set new value, then read and return value
1011 // catch UnknownPropertyException for ReadOnly properties
1014 xPropSet
->setPropertyValue( aPropName
, aNewVal
);
1016 catch(const UnknownPropertyException
&)
1020 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
1022 OUString aStr
= AnyToString( aPropVal
, sal_False
, xMgr
);
1023 OString aModifiedValStr
= OUStringToOString( aStr
, RTL_TEXTENCODING_ASCII_US
);
1024 OString aDemandedModifiedValStr
= pDemandedModifiedPropVals
[ i
];
1025 aErrorStr
= "Property \""
1027 + "\", expected modified val >"
1028 + aDemandedModifiedValStr
1032 OSL_ENSURE( aModifiedValStr
== aDemandedModifiedValStr
, aErrorStr
.getStr() );
1035 // check whether all properties can be found individually
1036 aErrorStr
= "property \""
1038 + "\" not found with hasProperty()";
1039 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1040 sal_Bool bProperty
= xAccess
->hasProperty( aWDemandedName
, nConcepts
);
1041 OSL_ENSURE( bProperty
, aErrorStr
.getStr() );
1043 aErrorStr
= "property \""
1045 + "\" not equal to same Property in sequence returned by getProperties()";
1048 Property aGetProp
= xAccess
->getProperty( aWDemandedName
, nConcepts
);
1050 catch (const RuntimeException
&)
1052 aErrorStr
= "property \""
1054 + "\", exception was thrown when trying getProperty()";
1055 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1062 // loop over all concept combinations
1063 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 128 ; nConcepts
++ )
1065 // The 2^6th bit stands for "the rest"
1066 sal_Int32 nRealConcepts
= nConcepts
;
1067 if( nConcepts
& 0x40 )
1068 nRealConcepts
|= (0xFFFFFFFF - 0x3F);
1070 // Count the number of methods there should be
1071 sal_Int32 nDemandedMethCount
= 0;
1072 sal_Int32 iList
= 0;
1073 while( pMethodDefs
[ iList
].pName
)
1075 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1076 nDemandedMethCount
++;
1080 // Output the method array.
1081 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( nRealConcepts
);
1082 sal_Int32 nLen
= aMethodSeq
.getLength();
1084 aErrorStr
= "Expected to find "
1085 + OString::valueOf( nDemandedMethCount
)
1086 + " methods but found "
1087 + OString::valueOf( nLen
);
1088 OSL_ENSURE( nLen
== nDemandedMethCount
, aErrorStr
.getStr() );
1090 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
1094 for( i
= 0 ; i
< nLen
; i
++ )
1096 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
1098 OUString aMethName
= rxMethod
->getName();
1099 OString aNameStr
= OUStringToOString(aMethName
, RTL_TEXTENCODING_ASCII_US
);
1101 // locate the next matching method in the list.
1102 while( pMethodDefs
[ iList
].pName
)
1104 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1108 OString aDemandedName
= pMethodDefs
[ iList
].pName
;
1111 aErrorStr
= "Expected method \""
1116 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
1118 // Check that the method is really there with hasMethod.
1119 aErrorStr
= "method \""
1121 + "\" not found with hasMethod()";
1122 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1123 sal_Bool bMethod
= xAccess
->hasMethod( aWDemandedName
, nRealConcepts
);
1124 OSL_ENSURE( bMethod
, aErrorStr
.getStr() );
1126 aErrorStr
= "method \""
1128 + "\" not equal to same method in sequence returned by getMethods()";
1131 Reference
< XIdlMethod
> xGetMethod
= xAccess
->getMethod( aWDemandedName
, nRealConcepts
);
1132 OSL_ENSURE( xGetMethod
== rxMethod
, aErrorStr
.getStr() );
1134 catch (const RuntimeException
&)
1136 aErrorStr
= "method \""
1138 + "\", exception was thrown when trying getMethod()";
1139 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1144 // print listener class
1145 Sequence
< Type
> aClassSeq
= xAccess
->getSupportedListeners();
1146 sal_Int32 nLen
= aClassSeq
.getLength();
1148 const Type
* pListeners
= aClassSeq
.getConstArray();
1149 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1151 const Type
& aListenerType
= pListeners
[i
];
1152 OUString aListenerClassName
= aListenerType
.getTypeName();
1159 SAL_IMPLEMENT_MAIN()
1161 Reference
< XMultiServiceFactory
> xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) );
1163 sal_Bool bSucc
= sal_False
;
1166 Reference
< XImplementationRegistration
> xImplReg(
1167 xMgr
->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY
);
1168 OSL_ENSURE( xImplReg
.is(), "### no impl reg!" );
1170 // Register services
1171 OUString
libName( "reflection.uno" SAL_DLLEXTENSION
);
1172 fprintf(stderr
, "1\n" );
1173 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1174 libName
, Reference
< XSimpleRegistry
>() );
1175 fprintf(stderr
, "2\n" );
1176 Reference
< XIdlReflection
> xRefl( xMgr
->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY
);
1177 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1180 libName
= OUString( "introspection.uno" SAL_DLLEXTENSION
);
1181 fprintf(stderr
, "3\n" );
1182 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1183 libName
, Reference
< XSimpleRegistry
>() );
1184 fprintf(stderr
, "4\n" );
1185 Reference
< XIntrospection
> xIntrosp( xMgr
->createInstance("com.sun.star.beans.Introspection"), UNO_QUERY
);
1186 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1188 fprintf(stderr
, "before test_introsp\n" );
1189 bSucc
= test_introsp( xMgr
, xRefl
, xIntrosp
);
1190 fprintf(stderr
, "after test_introsp\n" );
1192 catch (const Exception
& rExc
)
1194 DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc
);
1197 Reference
< XComponent
>( xMgr
, UNO_QUERY
)->dispose();
1199 printf( "testintrosp %s !\n", (bSucc
? "succeeded" : "failed") );
1200 return (bSucc
? 0 : -1);
1203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */