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/implbase1.hxx>
23 #include <cppuhelper/implbase4.hxx>
24 #include <cppuhelper/servicefactory.hxx>
25 #include <osl/diagnose.h>
27 #include <ModuleA/XIntroTest.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/beans/XIntrospection.hpp>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/beans/PropertyConcept.hpp>
32 #include <com/sun/star/beans/MethodConcept.hpp>
33 #include <com/sun/star/beans/XExactName.hpp>
34 #include <com/sun/star/container/XElementAccess.hpp>
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include <com/sun/star/container/XIndexAccess.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/reflection/XIdlReflection.hpp>
39 #include <com/sun/star/registry/XImplementationRegistration.hpp>
40 #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
;
57 typedef WeakImplHelper4
< XIntroTest
, XPropertySet
, XNameAccess
, XIndexAccess
> ImplIntroTestHelper
;
58 typedef WeakImplHelper1
< XPropertySetInfo
> ImplPropertySetInfoHelper
;
61 #define DEFAULT_INDEX_ACCESS_COUNT 10
62 #define DEFAULT_NAME_ACCESS_COUNT 5
64 // Auxiliary function, in order to get from one type XIdlClass
65 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XMultiServiceFactory
> & xMgr
)
67 static Reference
< XIdlReflection
> xRefl
;
69 // register void as default class
70 Reference
<XIdlClass
> xRetClass
;
71 typelib_TypeDescription
* pTD
= 0;
72 rType
.getDescription( &pTD
);
75 OUString
sOWName( pTD
->pTypeName
);
78 xRefl
= Reference
< XIdlReflection
>( xMgr
->createInstance(
79 OUString("com.sun.star.reflection.CoreReflection") ), UNO_QUERY
);
80 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
82 xRetClass
= xRefl
->forName( sOWName
);
88 // Helper function to convert Any to UString
89 // TODO: This code could be moved to a more central place.
90 // Currently it's used only for simple data types.
92 OUString
AnyToString( const Any
& aValue
, sal_Bool bIncludeType
, const Reference
< XMultiServiceFactory
> & xMgr
)
94 Type aValType
= aValue
.getValueType();
95 TypeClass eType
= aValType
.getTypeClass();
101 case TypeClass_TYPE
: aRetStr
= "TYPE TYPE"; break;
102 case TypeClass_INTERFACE
: aRetStr
= "TYPE INTERFACE"; break;
103 case TypeClass_SERVICE
: aRetStr
= "TYPE SERVICE"; break;
104 case TypeClass_STRUCT
: aRetStr
= "TYPE STRUCT"; break;
105 case TypeClass_TYPEDEF
: aRetStr
= "TYPE TYPEDEF"; break;
106 case TypeClass_ENUM
: aRetStr
= "TYPE ENUM"; break;
107 case TypeClass_EXCEPTION
: aRetStr
= "TYPE EXCEPTION"; break;
108 case TypeClass_SEQUENCE
: aRetStr
= "TYPE SEQUENCE"; break;
109 case TypeClass_VOID
: aRetStr
= "TYPE void"; break;
110 case TypeClass_ANY
: aRetStr
= "TYPE any"; break;
111 case TypeClass_UNKNOWN
: aRetStr
= "TYPE unknown"; break;
112 case TypeClass_BOOLEAN
:
114 sal_Bool b
= *(sal_Bool
*)aValue
.getValue();
115 aRetStr
= OUString::valueOf( b
);
120 sal_Unicode c
= *(sal_Unicode
*)aValue
.getValue();
121 aRetStr
= OUString::valueOf( c
);
124 case TypeClass_STRING
:
129 case TypeClass_FLOAT
:
133 snprintf( pBuffer
, sizeof( pBuffer
), "%f", f
);
134 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
137 case TypeClass_DOUBLE
:
141 snprintf( pBuffer
, sizeof( pBuffer
), "%f", d
);
142 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
149 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
152 case TypeClass_SHORT
:
156 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
163 aRetStr
= OUString::valueOf( n
);
171 Reference
< XIdlClass
> xIdlClass
= TypeToIdlClass( aValType
, xMgr
);
172 aRetStr
+= " (Typ: " + xIdlClass
->getName() + ")";
177 // XPropertySetInfo for test class
179 class ImplPropertySetInfo
: public ImplPropertySetInfoHelper
181 friend class ImplIntroTest
;
183 Reference
< XMultiServiceFactory
> mxMgr
;
186 ImplPropertySetInfo( const Reference
< XMultiServiceFactory
> & xMgr
)
189 // Methods of XPropertySetInfo
190 virtual Sequence
< Property
> SAL_CALL
getProperties( )
191 throw(RuntimeException
);
192 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
)
193 throw(UnknownPropertyException
, RuntimeException
);
194 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
)
195 throw(RuntimeException
);
199 Sequence
< Property
> ImplPropertySetInfo::getProperties()
200 throw( RuntimeException
)
202 static Sequence
<Property
> * pSeq
= NULL
;
206 // Create information for the properties "Width", "Height" and "Name"
207 pSeq
= new Sequence
<Property
>( 3 );
208 Property
* pAry
= pSeq
->getArray();
210 pAry
[0].Name
= "Factor";
212 pAry
[0].Type
= cppu::UnoType
<double>::get();
213 pAry
[0].Attributes
= BOUND
| TRANSIENT
;
215 pAry
[1].Name
= "MyCount";
217 pAry
[1].Type
= cppu::UnoType
<sal_Int32
>::get();
218 pAry
[1].Attributes
= BOUND
| TRANSIENT
;
220 pAry
[2].Name
= "Info";
222 pAry
[2].Type
= cppu::UnoType
<OUString
>::get();
223 pAry
[2].Attributes
= TRANSIENT
;
225 // Return information about all three properties
229 Property
ImplPropertySetInfo::getPropertyByName(const OUString
& Name
)
230 throw( UnknownPropertyException
, RuntimeException
)
232 Sequence
<Property
> aSeq
= getProperties();
233 const Property
* pAry
= aSeq
.getConstArray();
235 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
237 if( pAry
[i
].Name
== Name
)
240 // Property unknown, also return empty ones
244 sal_Bool
ImplPropertySetInfo::hasPropertyByName(const OUString
& Name
)
245 throw( RuntimeException
)
247 Sequence
<Property
> aSeq
= getProperties();
248 const Property
* pAry
= aSeq
.getConstArray();
250 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
252 if( pAry
[i
].Name
== Name
)
255 // Property unknown, also return empty ones
260 class ImplIntroTest
: public ImplIntroTestHelper
262 Reference
< XMultiServiceFactory
> mxMgr
;
264 friend class ImplPropertySetInfo
;
266 // Properties for the PropertySet
269 Reference
< XPropertySetInfo
> m_xMyInfo
;
271 OUString m_ObjectName
;
273 sal_Int16 m_nMarkusAge
;
274 sal_Int16 m_nMarkusChildrenCount
;
281 TypeClass eTypeClass
;
282 Sequence
< OUString
> aStringSeq
;
283 Sequence
< Sequence
< Sequence
< sal_Int16
> > > aMultSeq
;
284 Reference
< XIntroTest
> m_xIntroTest
;
286 // Data for NameAccess
287 Reference
< XIntroTest
>* pNameAccessTab
;
289 // Data for IndexAccess
290 Reference
< XIntroTest
>* pIndexAccessTab
;
291 sal_Int16 iIndexAccessCount
;
294 Property m_aFirstStruct
;
295 PropertyValue m_aSecondStruct
;
297 // remember listener (one listener per property)
298 Reference
< XPropertyChangeListener
> aPropChangeListener
;
299 OUString aPropChangeListenerStr
;
300 Reference
< XVetoableChangeListener
> aVetoPropChangeListener
;
301 OUString aVetoPropChangeListenerStr
;
306 ImplIntroTest( const Reference
< XMultiServiceFactory
> & xMgr
)
312 // despite virtual inline, to simplify coding (testing only)
314 virtual Reference
< XPropertySetInfo
> SAL_CALL
getPropertySetInfo( )
315 throw(RuntimeException
);
316 virtual void SAL_CALL
setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
317 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
);
318 virtual Any SAL_CALL
getPropertyValue( const OUString
& PropertyName
)
319 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
);
320 virtual void SAL_CALL
addPropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*xListener*/ )
321 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
323 virtual void SAL_CALL
removePropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*aListener*/ )
324 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
326 virtual void SAL_CALL
addVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
327 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
329 virtual void SAL_CALL
removeVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
330 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
333 // XIntroTest methods
335 virtual OUString SAL_CALL
getObjectName() throw(RuntimeException
)
336 { return m_ObjectName
; }
337 virtual void SAL_CALL
setObjectName( const OUString
& _objectname
) throw(RuntimeException
)
338 { m_ObjectName
= _objectname
; }
339 virtual OUString SAL_CALL
getFirstName()
340 throw(RuntimeException
);
341 virtual OUString SAL_CALL
getLastName() throw(RuntimeException
)
342 { return OUString( OUString("Meyer") ); }
343 virtual sal_Int16 SAL_CALL
getAge() throw(RuntimeException
)
344 { return m_nMarkusAge
; }
345 virtual sal_Int16 SAL_CALL
getChildrenCount() throw(RuntimeException
)
346 { return m_nMarkusChildrenCount
; }
347 virtual void SAL_CALL
setChildrenCount( sal_Int16 _childrencount
) throw(RuntimeException
)
348 { m_nMarkusChildrenCount
= _childrencount
; }
349 virtual Property SAL_CALL
getFirstStruct() throw(RuntimeException
)
350 { return m_aFirstStruct
; }
351 virtual void SAL_CALL
setFirstStruct( const Property
& _firststruct
) throw(RuntimeException
)
352 { m_aFirstStruct
= _firststruct
; }
353 virtual PropertyValue SAL_CALL
getSecondStruct() throw(RuntimeException
)
354 { return m_aSecondStruct
; }
355 virtual void SAL_CALL
setSecondStruct( const PropertyValue
& _secondstruct
) throw(RuntimeException
)
356 { m_aSecondStruct
= _secondstruct
; }
359 virtual void SAL_CALL
writeln( const OUString
& Text
)
360 throw(RuntimeException
);
361 virtual sal_Int32 SAL_CALL
getDroenk( ) throw(RuntimeException
)
362 { return m_lDroenk
; }
363 virtual Reference
< ::ModuleA::XIntroTest
> SAL_CALL
getIntroTest( ) throw(RuntimeException
);
364 virtual sal_Int32 SAL_CALL
getUps( sal_Int32 l
) throw(RuntimeException
)
366 virtual void SAL_CALL
setDroenk( sal_Int32 l
) throw(RuntimeException
)
368 virtual sal_Int16 SAL_CALL
getBla( ) throw(RuntimeException
)
370 virtual void SAL_CALL
setBla( sal_Int32 n
) throw(RuntimeException
)
371 { m_nBla
= (sal_Int16
)n
; }
372 virtual sal_Int16 SAL_CALL
getBlub( ) throw(RuntimeException
)
374 virtual void SAL_CALL
setBlub( sal_Int16 n
) throw(RuntimeException
)
376 virtual sal_Int16 SAL_CALL
getGulp( ) throw(RuntimeException
)
378 virtual sal_Int16 SAL_CALL
setGulp( sal_Int16 n
) throw(RuntimeException
)
379 { m_nGulp
= n
; return 1; }
380 virtual TypeClass SAL_CALL
getTypeClass( sal_Int16
/*n*/ ) throw(RuntimeException
)
381 { return eTypeClass
; }
382 virtual void SAL_CALL
setTypeClass( TypeClass t
, double /*d1*/, double /*d2*/ ) throw(RuntimeException
)
384 virtual Sequence
< OUString
> SAL_CALL
getStrings( ) throw(RuntimeException
)
385 { return aStringSeq
; }
386 virtual void SAL_CALL
setStrings( const Sequence
< OUString
>& Strings
) throw(RuntimeException
)
387 { aStringSeq
= Strings
; }
388 virtual void SAL_CALL
setStringsPerMethod( const Sequence
< OUString
>& Strings
, sal_Int16
/*n*/ ) throw(RuntimeException
)
389 { aStringSeq
= Strings
; }
390 virtual Sequence
< Sequence
< Sequence
< sal_Int16
> > > SAL_CALL
getMultiSequence( ) throw(RuntimeException
)
392 virtual void SAL_CALL
setMultiSequence( const Sequence
< Sequence
< Sequence
< sal_Int16
> > >& Seq
) throw(RuntimeException
)
394 virtual void SAL_CALL
addPropertiesChangeListener( const Sequence
< OUString
>& PropertyNames
, const Reference
< XPropertiesChangeListener
>& Listener
)
395 throw(RuntimeException
);
396 virtual void SAL_CALL
removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& Listener
)
397 throw(RuntimeException
);
400 // Methods of XElementAccess
401 virtual Type SAL_CALL
getElementType( )
402 throw(RuntimeException
);
403 virtual sal_Bool SAL_CALL
hasElements( )
404 throw(RuntimeException
);
406 // XNameAccess methods
408 virtual Any SAL_CALL
getByName( const OUString
& aName
)
409 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
);
410 virtual Sequence
< OUString
> SAL_CALL
getElementNames( )
411 throw(RuntimeException
);
412 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
)
413 throw(RuntimeException
);
415 // XIndexAccess methods
417 virtual sal_Int32 SAL_CALL
getCount( )
418 throw(RuntimeException
);
419 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
)
420 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
);
423 void ImplIntroTest::Init()
426 static sal_Int32 nObjCount
= 0;
427 OUString
aName( "IntroTest-Obj Nr. " );
428 aName
+= OUString::valueOf( nObjCount
);
429 setObjectName( aName
);
431 // initialize properties
432 aAnyArray
[0] <<= 3.14;
433 aAnyArray
[1] <<= (sal_Int32
)42;
434 aAnyArray
[2] <<= OUString( "Hallo" );
436 // fetch PropertySetInfo once for internal use
437 m_xMyInfo
= getPropertySetInfo();
438 m_xMyInfo
->acquire(); // otherwise it could crash at shutdown
441 m_nMarkusChildrenCount
= 2;
448 eTypeClass
= TypeClass_INTERFACE
;
450 // string sequence initialization
451 aStringSeq
.realloc( 3 );
452 aStringSeq
[ 0 ] = "String 0";
453 aStringSeq
[ 1 ] = "String 1";
454 aStringSeq
[ 2 ] = "String 2";
456 // structs initialization
457 m_aFirstStruct
.Name
= "FirstStruct-Name";
458 m_aFirstStruct
.Handle
= 77777;
460 m_aFirstStruct
.Attributes
= -222;
462 //XInterfaceRef Source;
464 Value
<<= 2.718281828459;
465 m_aSecondStruct
.Value
= Value
;
466 //XIdlClassRef ListenerType;
467 m_aSecondStruct
.State
= PropertyState_DIRECT_VALUE
;
470 iIndexAccessCount
= DEFAULT_INDEX_ACCESS_COUNT
;
471 pIndexAccessTab
= NULL
;
472 pNameAccessTab
= NULL
;
475 Reference
< XPropertySetInfo
> ImplIntroTest::getPropertySetInfo()
476 throw(RuntimeException
)
478 static ImplPropertySetInfo
aInfo( mxMgr
);
479 // All objects have the same Properties, so
480 // the Info is the same for all
484 void ImplIntroTest::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
485 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
487 if( aPropChangeListener
.is() && aPropertyName
== aPropChangeListenerStr
)
489 PropertyChangeEvent aEvt
;
490 aEvt
.Source
= (OWeakObject
*)this;
491 aEvt
.PropertyName
= aPropertyName
;
492 aEvt
.PropertyHandle
= 0L;
493 aPropChangeListener
->propertyChange( aEvt
);
495 if( aVetoPropChangeListener
.is() && aPropertyName
== aVetoPropChangeListenerStr
)
497 PropertyChangeEvent aEvt
;
498 aEvt
.Source
= (OWeakObject
*)this;
499 aEvt
.PropertyName
= aVetoPropChangeListenerStr
;
500 aEvt
.PropertyHandle
= 0L;
501 aVetoPropChangeListener
->vetoableChange( aEvt
);
504 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
505 sal_Int32 nLen
= aPropSeq
.getLength();
506 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
508 Property aProp
= aPropSeq
.getArray()[ i
];
509 if( aProp
.Name
== aPropertyName
)
510 aAnyArray
[i
] = aValue
;
514 Any
ImplIntroTest::getPropertyValue( const OUString
& PropertyName
)
515 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
517 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
518 sal_Int32 nLen
= aPropSeq
.getLength();
519 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
521 Property aProp
= aPropSeq
.getArray()[ i
];
522 if( aProp
.Name
== PropertyName
)
528 OUString
ImplIntroTest::getFirstName()
529 throw(RuntimeException
)
531 return OUString( OUString("Markus") );
534 void ImplIntroTest::writeln( const OUString
& Text
)
535 throw(RuntimeException
)
537 OString
aStr( Text
.getStr(), Text
.getLength(), RTL_TEXTENCODING_ASCII_US
);
539 printf( "%s", aStr
.getStr() );
542 Reference
< XIntroTest
> ImplIntroTest::getIntroTest()
543 throw(RuntimeException
)
545 if( !m_xIntroTest
.is() )
546 m_xIntroTest
= new ImplIntroTest( mxMgr
);
550 // Methods of XElementAccess
551 Type
ImplIntroTest::getElementType( )
552 throw(RuntimeException
)
559 sal_Bool
ImplIntroTest::hasElements( )
560 throw(RuntimeException
)
565 // XNameAccess methods
566 sal_Int32
getIndexForName( const OUString
& ItemName
)
568 OUString aLeftStr
= ItemName
.copy( 0, 4 );
569 if( aLeftStr
== "Item" )
572 OUString aNumStr
= ItemName
.copy( 4 );
578 Any
ImplIntroTest::getByName( const OUString
& aName
)
579 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
)
583 if( !pNameAccessTab
)
584 pNameAccessTab
= new Reference
< XIntroTest
>[ DEFAULT_NAME_ACCESS_COUNT
];
586 sal_Int32 iIndex
= getIndexForName( aName
);
589 if( !pNameAccessTab
[iIndex
].is() )
591 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
592 OUString
aName2( "IntroTest by Name-Access, Index = " );
593 aName2
+= OUString::valueOf( iIndex
);
594 p
->setObjectName( aName2
);
595 pNameAccessTab
[iIndex
] = p
;
598 Reference
< XIntroTest
> xRet
= pNameAccessTab
[iIndex
];
599 aRetAny
= makeAny( xRet
);
604 Sequence
< OUString
> ImplIntroTest::getElementNames( )
605 throw(RuntimeException
)
607 Sequence
<OUString
> aStrSeq( DEFAULT_NAME_ACCESS_COUNT
);
608 OUString
* pStr
= aStrSeq
.getArray();
609 for( sal_Int32 i
= 0 ; i
< DEFAULT_NAME_ACCESS_COUNT
; i
++ )
611 OUString
aName( "Item" );
612 aName
+= OUString::valueOf( i
);
618 sal_Bool
ImplIntroTest::hasByName( const OUString
& aName
)
619 throw(RuntimeException
)
621 return ( getIndexForName( aName
) != -1 );
624 // XIndexAccess methods
625 sal_Int32
ImplIntroTest::getCount( )
626 throw(RuntimeException
)
628 return iIndexAccessCount
;
631 Any
ImplIntroTest::getByIndex( sal_Int32 Index
)
632 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
636 if( !pIndexAccessTab
)
637 pIndexAccessTab
= new Reference
< XIntroTest
>[ iIndexAccessCount
];
639 if( Index
< iIndexAccessCount
)
641 if( !pNameAccessTab
[Index
].is() )
643 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
644 OUString
aName( "IntroTest by Index-Access, Index = " );
645 aName
+= OUString::valueOf( Index
);
646 p
->setObjectName( aName
);
647 pIndexAccessTab
[Index
] = p
;
649 Reference
< XIntroTest
> xRet
= pIndexAccessTab
[Index
];
650 aRetAny
= makeAny( xRet
);
655 void ImplIntroTest::addPropertiesChangeListener( const Sequence
< OUString
>& /*PropertyNames*/,
656 const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
657 throw(RuntimeException
)
661 void ImplIntroTest::removePropertiesChangeListener
662 ( const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
663 throw(RuntimeException
)
675 // special value for method concept, to mark "normal" functions
676 #define MethodConcept_NORMAL_IMPL 0x80000000
679 // return test object
680 Any
getIntrospectionTestObject( const Reference
< XMultiServiceFactory
> & xMgr
)
683 Reference
< XIntroTest
> xTestObj
= new ImplIntroTest( xMgr
);
684 aObjAny
.setValue( &xTestObj
, cppu::UnoType
<XIntroTest
>::get());
688 static sal_Bool
test_introsp( Reference
< XMultiServiceFactory
> xMgr
,
689 Reference
< XIdlReflection
> /*xRefl*/, Reference
< XIntrospection
> xIntrospection
)
691 DefItem pPropertyDefs
[] =
693 { "Factor", PropertyConcept::PROPERTYSET
},
694 { "MyCount", PropertyConcept::PROPERTYSET
},
695 { "Info", PropertyConcept::PROPERTYSET
},
696 { "ObjectName", PropertyConcept::ATTRIBUTES
},
697 { "FirstName", PropertyConcept::ATTRIBUTES
},
698 { "LastName", PropertyConcept::ATTRIBUTES
},
699 { "Age", PropertyConcept::ATTRIBUTES
},
700 { "ChildrenCount", PropertyConcept::ATTRIBUTES
},
701 { "FirstStruct", PropertyConcept::ATTRIBUTES
},
702 { "SecondStruct", PropertyConcept::ATTRIBUTES
},
703 { "Droenk", PropertyConcept::METHODS
},
704 { "IntroTest", PropertyConcept::METHODS
},
705 { "Bla", PropertyConcept::METHODS
},
706 { "Blub", PropertyConcept::METHODS
},
707 { "Gulp", PropertyConcept::METHODS
},
708 { "Strings", PropertyConcept::METHODS
},
709 { "MultiSequence", PropertyConcept::METHODS
},
710 { "PropertySetInfo", PropertyConcept::METHODS
},
711 { "ElementType", PropertyConcept::METHODS
},
712 { "ElementNames", PropertyConcept::METHODS
},
713 { "Count", PropertyConcept::METHODS
},
714 { "Types", PropertyConcept::METHODS
},
715 { "ImplementationId", PropertyConcept::METHODS
},
719 char const * pDemandedPropVals
[] =
724 "IntroTest-Obj Nr. 0",
746 char const * pDemandedModifiedPropVals
[] =
751 "IntroTest-Obj Nr. 0 (Modified!)",
756 "Wert wurde nicht modifiziert",
757 "Wert wurde nicht modifiziert",
759 "Wert wurde nicht modifiziert",
763 "Wert wurde nicht modifiziert",
764 "Wert wurde nicht modifiziert",
765 "Wert wurde nicht modifiziert",
766 "Wert wurde nicht modifiziert",
767 "Wert wurde nicht modifiziert",
769 "Wert wurde nicht modifiziert"
770 "Wert wurde nicht modifiziert"
773 char const * pDemandedPropTypes
[] =
783 "com.sun.star.beans.Property",
784 "com.sun.star.beans.PropertyValue",
786 "ModuleA.XIntroTest",
792 "com.sun.star.beans.XPropertySetInfo",
800 DefItem pMethodDefs
[] =
802 { "queryInterface", MethodConcept_NORMAL_IMPL
},
803 { "acquire", MethodConcept::DANGEROUS
},
804 { "release", MethodConcept::DANGEROUS
},
805 { "writeln", MethodConcept_NORMAL_IMPL
},
806 { "getDroenk", MethodConcept::PROPERTY
},
807 { "getIntroTest", MethodConcept::PROPERTY
},
808 { "getUps", MethodConcept_NORMAL_IMPL
},
809 { "setDroenk", MethodConcept::PROPERTY
},
810 { "getBla", MethodConcept::PROPERTY
},
811 { "setBla", MethodConcept_NORMAL_IMPL
},
812 { "getBlub", MethodConcept::PROPERTY
},
813 { "setBlub", MethodConcept::PROPERTY
},
814 { "getGulp", MethodConcept::PROPERTY
},
815 { "setGulp", MethodConcept_NORMAL_IMPL
},
816 { "getTypeClass", MethodConcept_NORMAL_IMPL
},
817 { "setTypeClass", MethodConcept_NORMAL_IMPL
},
818 { "getStrings", MethodConcept::PROPERTY
},
819 { "setStrings", MethodConcept::PROPERTY
},
820 { "setStringsPerMethod", MethodConcept_NORMAL_IMPL
},
821 { "getMultiSequence", MethodConcept::PROPERTY
},
822 { "setMultiSequence", MethodConcept::PROPERTY
},
823 { "addPropertiesChangeListener", MethodConcept::LISTENER
},
824 { "removePropertiesChangeListener", MethodConcept::LISTENER
},
825 { "getPropertySetInfo", MethodConcept::PROPERTY
},
826 { "setPropertyValue", MethodConcept_NORMAL_IMPL
},
827 { "getPropertyValue", MethodConcept_NORMAL_IMPL
},
828 { "addPropertyChangeListener", MethodConcept::LISTENER
},
829 { "removePropertyChangeListener", MethodConcept::LISTENER
},
830 { "addVetoableChangeListener", MethodConcept::LISTENER
},
831 { "removeVetoableChangeListener", MethodConcept::LISTENER
},
832 { "getElementType", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
833 { "hasElements", MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
834 { "getByName", MethodConcept::NAMECONTAINER
},
835 { "getElementNames", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
},
836 { "hasByName", MethodConcept::NAMECONTAINER
},
837 { "getCount", MethodConcept::PROPERTY
| MethodConcept::INDEXCONTAINER
},
838 { "getByIndex", MethodConcept::INDEXCONTAINER
},
839 { "getTypes", MethodConcept::PROPERTY
},
840 { "getImplementationId", MethodConcept::PROPERTY
},
841 { "queryAdapter", MethodConcept_NORMAL_IMPL
},
849 // create test object
850 Any aObjAny
= getIntrospectionTestObject( xMgr
);
852 // inspect introspection service
853 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
854 xAccess
= xIntrospection
->inspect( aObjAny
);
855 xAccess
= xIntrospection
->inspect( aObjAny
);
856 OSL_ENSURE( xAccess
.is(), "introspection failed, no XIntrospectionAccess returned" );
860 // check result of introspection
862 // determine XPropertySet-UIK
863 Type aType
= cppu::UnoType
<XPropertySet
>::get();
865 Reference
< XInterface
> xPropSetIface
= xAccess
->queryAdapter( aType
);
866 Reference
< XPropertySet
> xPropSet( xPropSetIface
, UNO_QUERY
);
867 OSL_ENSURE( xPropSet
.is(), "Could not get XPropertySet by queryAdapter()" );
870 Reference
< XExactName
> xExactName( xAccess
, UNO_QUERY
);
871 OSL_ENSURE( xExactName
.is(), "Introspection unterstuetzt kein ExactName" );
873 // loop over all concept combinations
874 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 16 ; nConcepts
++ )
876 // how many properties should this be
877 sal_Int32 nDemandedPropCount
= 0;
879 while( pPropertyDefs
[ iList
].pName
)
881 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
882 nDemandedPropCount
++;
888 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
889 Sequence
<Property
> aRetSeq
= xAccess
->getProperties( nConcepts
);
891 sal_Int32 nLen
= aRetSeq
.getLength();
893 aErrorStr
= "Expected to find ";
894 aErrorStr
+= OString::valueOf( nDemandedPropCount
);
895 aErrorStr
+= " properties but found ";
896 aErrorStr
+= OString::valueOf( nLen
);
897 OSL_ENSURE( nLen
== nDemandedPropCount
, aErrorStr
.getStr() );
899 const Property
* pProps
= aRetSeq
.getConstArray();
903 for( i
= 0 ; i
< nLen
; i
++ )
905 const Property aProp
= pProps
[ i
];
907 // search for next suitable method in the list
908 while( pPropertyDefs
[ iList
].pName
)
910 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
914 sal_Int32 iDemanded
= iList
;
917 OUString aPropName
= aProp
.Name
;
918 OString
aNameStr( aPropName
.getStr(), aPropName
.getLength(), RTL_TEXTENCODING_ASCII_US
);
920 OString aDemandedName
= pPropertyDefs
[ iDemanded
].pName
;
921 aErrorStr
= "Expected property \"";
922 aErrorStr
+= aDemandedName
;
923 aErrorStr
+= "\", found \"";
924 aErrorStr
+= aNameStr
;
926 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
928 Type aPropType
= aProp
.Type
;
929 OString
aTypeNameStr( OUStringToOString(aPropType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
) );
930 OString aDemandedTypeNameStr
= pDemandedPropTypes
[ iDemanded
];
931 aErrorStr
= "Property \"";
932 aErrorStr
+= aDemandedName
;
933 aErrorStr
+= "\", expected type >";
934 aErrorStr
+= aDemandedTypeNameStr
;
935 aErrorStr
+= "< found type >";
936 aErrorStr
+= aTypeNameStr
;
938 OSL_ENSURE( aTypeNameStr
== aDemandedTypeNameStr
, aErrorStr
.getStr() );
940 // read and report value of property
941 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
943 OString aValStr
= OUStringToOString( AnyToString( aPropVal
, sal_False
, xMgr
), RTL_TEXTENCODING_ASCII_US
);
944 OString aDemandedValStr
= pDemandedPropVals
[ iDemanded
];
945 aErrorStr
= "Property \"";
946 aErrorStr
+= aDemandedName
;
947 aErrorStr
+= "\", expected val >";
948 aErrorStr
+= aDemandedValStr
;
949 aErrorStr
+= "< found val >";
950 aErrorStr
+= aValStr
;
952 OSL_ENSURE( aValStr
== aDemandedValStr
, aErrorStr
.getStr() );
954 // check value and modify it according to its type
955 TypeClass eType
= aPropVal
.getValueType().getTypeClass();
957 sal_Bool bModify
= sal_True
;
960 case TypeClass_STRING
:
964 aStr
+= " (Modified!)";
968 case TypeClass_DOUBLE
:
975 case TypeClass_SHORT
:
979 aNewVal
<<= sal_Int16( n
+ 1 );
986 aNewVal
<<= sal_Int32( n
+ 1 );
994 // modify only in the last iteration
995 if( nConcepts
== 15 )
997 // check XExactName, switch everything to upper case
998 // (introspection uses lower case)
999 OUString aUpperUStr
= aPropName
.toAsciiUpperCase();
1000 OUString aExactName
= xExactName
->getExactName( aUpperUStr
);
1001 if( aExactName
!= aPropName
)
1003 aErrorStr
= "Property \"";
1004 aErrorStr
+= OUStringToOString( aPropName
, RTL_TEXTENCODING_ASCII_US
);
1005 aErrorStr
+= "\", not found as \"";
1006 aErrorStr
+= OUStringToOString(aUpperUStr
, RTL_TEXTENCODING_ASCII_US
);
1007 aErrorStr
+= "\" using XExactName";
1008 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1013 bModify
= sal_False
;
1016 // set new value, then read and return value
1019 // catch UnknownPropertyException for ReadOnly properties
1022 xPropSet
->setPropertyValue( aPropName
, aNewVal
);
1024 catch(const UnknownPropertyException
&)
1028 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
1030 OUString aStr
= AnyToString( aPropVal
, sal_False
, xMgr
);
1031 OString aModifiedValStr
= OUStringToOString( aStr
, RTL_TEXTENCODING_ASCII_US
);
1032 OString aDemandedModifiedValStr
= pDemandedModifiedPropVals
[ i
];
1033 aErrorStr
= "Property \"";
1034 aErrorStr
+= aDemandedName
;
1035 aErrorStr
+= "\", expected modified val >";
1036 aErrorStr
+= aDemandedModifiedValStr
;
1037 aErrorStr
+= "< found val >";
1038 aErrorStr
+= aModifiedValStr
;
1040 OSL_ENSURE( aModifiedValStr
== aDemandedModifiedValStr
, aErrorStr
.getStr() );
1043 // check whether all properties can be found individually
1044 aErrorStr
= "property \"";
1045 aErrorStr
+= aDemandedName
;
1046 aErrorStr
+= "\" not found with hasProperty()";
1047 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1048 sal_Bool bProperty
= xAccess
->hasProperty( aWDemandedName
, nConcepts
);
1049 OSL_ENSURE( bProperty
, aErrorStr
.getStr() );
1051 aErrorStr
= "property \"";
1052 aErrorStr
+= aDemandedName
;
1053 aErrorStr
+= "\" not equal to same Property in sequence returned by getProperties()";
1056 Property aGetProp
= xAccess
->getProperty( aWDemandedName
, nConcepts
);
1058 catch (const RuntimeException
&)
1060 aErrorStr
= "property \"";
1061 aErrorStr
+= aDemandedName
;
1062 aErrorStr
+= "\", exception was thrown when trying getProperty()";
1063 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1070 // loop over all concept combinations
1071 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 128 ; nConcepts
++ )
1073 // Das 2^6-Bit steht fuer "den Rest"
1074 sal_Int32 nRealConcepts
= nConcepts
;
1075 if( nConcepts
& 0x40 )
1076 nRealConcepts
|= (0xFFFFFFFF - 0x3F);
1078 // Wieviele Methoden sollten es sein
1079 sal_Int32 nDemandedMethCount
= 0;
1080 sal_Int32 iList
= 0;
1081 while( pMethodDefs
[ iList
].pName
)
1083 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1084 nDemandedMethCount
++;
1088 // Methoden-Array ausgeben
1089 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( nRealConcepts
);
1090 sal_Int32 nLen
= aMethodSeq
.getLength();
1092 aErrorStr
= "Expected to find ";
1093 aErrorStr
+= OString::valueOf( nDemandedMethCount
);
1094 aErrorStr
+= " methods but found ";
1095 aErrorStr
+= OString::valueOf( nLen
);
1096 OSL_ENSURE( nLen
== nDemandedMethCount
, aErrorStr
.getStr() );
1098 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
1102 for( i
= 0 ; i
< nLen
; i
++ )
1104 // Methode ansprechen
1105 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
1108 OUString aMethName
= rxMethod
->getName();
1109 OString aNameStr
= OUStringToOString(aMethName
, RTL_TEXTENCODING_ASCII_US
);
1111 // Naechste Passende Methode in der Liste suchen
1112 while( pMethodDefs
[ iList
].pName
)
1114 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1118 OString aDemandedName
= pMethodDefs
[ iList
].pName
;
1121 aErrorStr
= "Expected method \"";
1122 aErrorStr
+= aDemandedName
;
1123 aErrorStr
+= "\", found \"";
1124 aErrorStr
+= aNameStr
;
1126 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
1128 // Checken, ob alle Methoden auch einzeln gefunden werden
1129 aErrorStr
= "method \"";
1130 aErrorStr
+= aDemandedName
;
1131 aErrorStr
+= "\" not found with hasMethod()";
1132 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1133 sal_Bool bMethod
= xAccess
->hasMethod( aWDemandedName
, nRealConcepts
);
1134 OSL_ENSURE( bMethod
, aErrorStr
.getStr() );
1136 aErrorStr
= "method \"";
1137 aErrorStr
+= aDemandedName
;
1138 aErrorStr
+= "\" not equal to same method in sequence returned by getMethods()";
1141 Reference
< XIdlMethod
> xGetMethod
= xAccess
->getMethod( aWDemandedName
, nRealConcepts
);
1142 OSL_ENSURE( xGetMethod
== rxMethod
, aErrorStr
.getStr() );
1144 catch (const RuntimeException
&)
1146 aErrorStr
= "method \"";
1147 aErrorStr
+= aDemandedName
;
1148 aErrorStr
+= "\", exception was thrown when trying getMethod()";
1149 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1154 // print listener class
1155 Sequence
< Type
> aClassSeq
= xAccess
->getSupportedListeners();
1156 sal_Int32 nLen
= aClassSeq
.getLength();
1158 const Type
* pListeners
= aClassSeq
.getConstArray();
1159 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1161 // Methode ansprechen
1162 const Type
& aListenerType
= pListeners
[i
];
1165 OUString aListenerClassName
= aListenerType
.getTypeName();
1172 SAL_IMPLEMENT_MAIN()
1174 Reference
< XMultiServiceFactory
> xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) );
1176 sal_Bool bSucc
= sal_False
;
1179 Reference
< XImplementationRegistration
> xImplReg(
1180 xMgr
->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY
);
1181 OSL_ENSURE( xImplReg
.is(), "### no impl reg!" );
1183 // Register services
1184 OUString
libName( "reflection.uno" SAL_DLLEXTENSION
);
1185 fprintf(stderr
, "1\n" );
1186 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1187 libName
, Reference
< XSimpleRegistry
>() );
1188 fprintf(stderr
, "2\n" );
1189 Reference
< XIdlReflection
> xRefl( xMgr
->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY
);
1190 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1193 libName
= OUString( "introspection.uno" SAL_DLLEXTENSION
);
1194 fprintf(stderr
, "3\n" );
1195 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1196 libName
, Reference
< XSimpleRegistry
>() );
1197 fprintf(stderr
, "4\n" );
1198 Reference
< XIntrospection
> xIntrosp( xMgr
->createInstance("com.sun.star.beans.Introspection"), UNO_QUERY
);
1199 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1201 fprintf(stderr
, "before test_introsp\n" );
1202 bSucc
= test_introsp( xMgr
, xRefl
, xIntrosp
);
1203 fprintf(stderr
, "after test_introsp\n" );
1205 catch (const Exception
& rExc
)
1207 OSL_FAIL( "### exception occurred!" );
1208 OString
aMsg( OUStringToOString( rExc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
1209 OSL_TRACE( "### exception occurred: " );
1210 OSL_TRACE( "%s", aMsg
.getStr() );
1214 Reference
< XComponent
>( xMgr
, UNO_QUERY
)->dispose();
1216 printf( "testintrosp %s !\n", (bSucc
? "succeeded" : "failed") );
1217 return (bSucc
? 0 : -1);
1220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */