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>
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
;
55 #define DEFAULT_INDEX_ACCESS_COUNT 10
56 #define DEFAULT_NAME_ACCESS_COUNT 5
58 // Auxiliary function, in order to get from one type XIdlClass
59 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XMultiServiceFactory
> & xMgr
)
61 static Reference
< XIdlReflection
> xRefl
;
63 // register void as default class
64 Reference
<XIdlClass
> xRetClass
;
65 typelib_TypeDescription
* pTD
= 0;
66 rType
.getDescription( &pTD
);
69 OUString
sOWName( pTD
->pTypeName
);
72 xRefl
.set( xMgr
->createInstance( "com.sun.star.reflection.CoreReflection" ), UNO_QUERY
);
73 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
75 xRetClass
= xRefl
->forName( sOWName
);
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.
85 OUString
AnyToString( const Any
& aValue
, sal_Bool bIncludeType
, const Reference
< XMultiServiceFactory
> & xMgr
)
87 Type aValType
= aValue
.getValueType();
88 TypeClass eType
= aValType
.getTypeClass();
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
:
107 sal_Bool b
= *(sal_Bool
*)aValue
.getValue();
108 aRetStr
= OUString::valueOf( b
);
113 sal_Unicode c
= *(sal_Unicode
*)aValue
.getValue();
114 aRetStr
= OUString::valueOf( c
);
117 case TypeClass_STRING
:
122 case TypeClass_FLOAT
:
126 snprintf( pBuffer
, sizeof( pBuffer
), "%f", f
);
127 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
130 case TypeClass_DOUBLE
:
134 snprintf( pBuffer
, sizeof( pBuffer
), "%f", d
);
135 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
142 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
145 case TypeClass_SHORT
:
149 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
156 aRetStr
= OUString::valueOf( n
);
164 Reference
< XIdlClass
> xIdlClass
= TypeToIdlClass( aValType
, xMgr
);
165 aRetStr
+= " (Typ: " + xIdlClass
->getName() + ")";
170 // XPropertySetInfo for test class
172 class ImplPropertySetInfo
: public WeakImplHelper
< XPropertySetInfo
>
174 friend class ImplIntroTest
;
176 Reference
< XMultiServiceFactory
> mxMgr
;
179 explicit ImplPropertySetInfo( const Reference
< XMultiServiceFactory
> & xMgr
)
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
);
192 Sequence
< Property
> ImplPropertySetInfo::getProperties()
193 throw( RuntimeException
)
195 static Sequence
<Property
> * pSeq
= NULL
;
199 // Create information for the properties "Width", "Height" and "Name"
200 pSeq
= new Sequence
<Property
>( 3 );
201 Property
* pAry
= pSeq
->getArray();
203 pAry
[0].Name
= "Factor";
205 pAry
[0].Type
= cppu::UnoType
<double>::get();
206 pAry
[0].Attributes
= BOUND
| TRANSIENT
;
208 pAry
[1].Name
= "MyCount";
210 pAry
[1].Type
= cppu::UnoType
<sal_Int32
>::get();
211 pAry
[1].Attributes
= BOUND
| TRANSIENT
;
213 pAry
[2].Name
= "Info";
215 pAry
[2].Type
= cppu::UnoType
<OUString
>::get();
216 pAry
[2].Attributes
= TRANSIENT
;
218 // Return information about all three properties
222 Property
ImplPropertySetInfo::getPropertyByName(const OUString
& Name
)
223 throw( UnknownPropertyException
, RuntimeException
)
225 Sequence
<Property
> aSeq
= getProperties();
226 const Property
* pAry
= aSeq
.getConstArray();
228 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
230 if( pAry
[i
].Name
== Name
)
233 // Property unknown, also return empty ones
237 sal_Bool
ImplPropertySetInfo::hasPropertyByName(const OUString
& Name
)
238 throw( RuntimeException
)
240 Sequence
<Property
> aSeq
= getProperties();
241 const Property
* pAry
= aSeq
.getConstArray();
243 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
245 if( pAry
[i
].Name
== Name
)
248 // Property unknown, also return empty ones
253 class ImplIntroTest
: public WeakImplHelper
< XIntroTest
, XPropertySet
, XNameAccess
, XIndexAccess
>
255 Reference
< XMultiServiceFactory
> mxMgr
;
257 friend class ImplPropertySetInfo
;
259 // Properties for the PropertySet
262 Reference
< XPropertySetInfo
> m_xMyInfo
;
264 OUString m_ObjectName
;
266 sal_Int16 m_nMarkusAge
;
267 sal_Int16 m_nMarkusChildrenCount
;
274 TypeClass eTypeClass
;
275 Sequence
< OUString
> aStringSeq
;
276 Sequence
< Sequence
< Sequence
< sal_Int16
> > > aMultSeq
;
277 Reference
< XIntroTest
> m_xIntroTest
;
279 // Data for NameAccess
280 Reference
< XIntroTest
>* pNameAccessTab
;
282 // Data for IndexAccess
283 Reference
< XIntroTest
>* pIndexAccessTab
;
284 sal_Int16 iIndexAccessCount
;
287 Property m_aFirstStruct
;
288 PropertyValue m_aSecondStruct
;
290 // remember listener (one listener per property)
291 Reference
< XPropertyChangeListener
> aPropChangeListener
;
292 OUString aPropChangeListenerStr
;
293 Reference
< XVetoableChangeListener
> aVetoPropChangeListener
;
294 OUString aVetoPropChangeListenerStr
;
299 explicit ImplIntroTest( const Reference
< XMultiServiceFactory
> & xMgr
)
305 // despite virtual inline, to simplify coding (testing only)
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
);
313 virtual void SAL_CALL
addPropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*xListener*/ )
314 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
316 virtual void SAL_CALL
removePropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*aListener*/ )
317 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
319 virtual void SAL_CALL
addVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
320 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
322 virtual void SAL_CALL
removeVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
323 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
326 // XIntroTest methods
328 virtual OUString SAL_CALL
getObjectName() throw(RuntimeException
)
329 { return m_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
);
334 virtual OUString SAL_CALL
getLastName() throw(RuntimeException
)
335 { return OUString("Meyer"); }
336 virtual sal_Int16 SAL_CALL
getAge() throw(RuntimeException
)
337 { return m_nMarkusAge
; }
338 virtual sal_Int16 SAL_CALL
getChildrenCount() throw(RuntimeException
)
339 { return m_nMarkusChildrenCount
; }
340 virtual void SAL_CALL
setChildrenCount( sal_Int16 _childrencount
) throw(RuntimeException
)
341 { m_nMarkusChildrenCount
= _childrencount
; }
342 virtual Property SAL_CALL
getFirstStruct() throw(RuntimeException
)
343 { return m_aFirstStruct
; }
344 virtual void SAL_CALL
setFirstStruct( const Property
& _firststruct
) throw(RuntimeException
)
345 { m_aFirstStruct
= _firststruct
; }
346 virtual PropertyValue SAL_CALL
getSecondStruct() throw(RuntimeException
)
347 { return m_aSecondStruct
; }
348 virtual void SAL_CALL
setSecondStruct( const PropertyValue
& _secondstruct
) throw(RuntimeException
)
349 { m_aSecondStruct
= _secondstruct
; }
352 virtual void SAL_CALL
writeln( const OUString
& Text
)
353 throw(RuntimeException
);
354 virtual sal_Int32 SAL_CALL
getDroenk( ) throw(RuntimeException
)
355 { return m_lDroenk
; }
356 virtual Reference
< ::ModuleA::XIntroTest
> SAL_CALL
getIntroTest( ) throw(RuntimeException
);
357 virtual sal_Int32 SAL_CALL
getUps( sal_Int32 l
) throw(RuntimeException
)
359 virtual void SAL_CALL
setDroenk( sal_Int32 l
) throw(RuntimeException
)
361 virtual sal_Int16 SAL_CALL
getBla( ) throw(RuntimeException
)
363 virtual void SAL_CALL
setBla( sal_Int32 n
) throw(RuntimeException
)
364 { m_nBla
= (sal_Int16
)n
; }
365 virtual sal_Int16 SAL_CALL
getBlub( ) throw(RuntimeException
)
367 virtual void SAL_CALL
setBlub( sal_Int16 n
) throw(RuntimeException
)
369 virtual sal_Int16 SAL_CALL
getGulp( ) throw(RuntimeException
)
371 virtual sal_Int16 SAL_CALL
setGulp( sal_Int16 n
) throw(RuntimeException
)
372 { m_nGulp
= n
; return 1; }
373 virtual TypeClass SAL_CALL
getTypeClass( sal_Int16
/*n*/ ) throw(RuntimeException
)
374 { return eTypeClass
; }
375 virtual void SAL_CALL
setTypeClass( TypeClass t
, double /*d1*/, double /*d2*/ ) throw(RuntimeException
)
377 virtual Sequence
< OUString
> SAL_CALL
getStrings( ) throw(RuntimeException
)
378 { return aStringSeq
; }
379 virtual void SAL_CALL
setStrings( const Sequence
< OUString
>& Strings
) throw(RuntimeException
)
380 { aStringSeq
= Strings
; }
381 virtual void SAL_CALL
setStringsPerMethod( const Sequence
< OUString
>& Strings
, sal_Int16
/*n*/ ) throw(RuntimeException
)
382 { aStringSeq
= Strings
; }
383 virtual Sequence
< Sequence
< Sequence
< sal_Int16
> > > SAL_CALL
getMultiSequence( ) throw(RuntimeException
)
385 virtual void SAL_CALL
setMultiSequence( const Sequence
< Sequence
< Sequence
< sal_Int16
> > >& Seq
) throw(RuntimeException
)
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
);
393 // Methods of XElementAccess
394 virtual Type SAL_CALL
getElementType( )
395 throw(RuntimeException
);
396 virtual sal_Bool SAL_CALL
hasElements( )
397 throw(RuntimeException
);
399 // XNameAccess 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
);
408 // XIndexAccess 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
);
416 void ImplIntroTest::Init()
419 static sal_Int32 nObjCount
= 0;
420 OUString
aName( "IntroTest-Obj Nr. " );
421 aName
+= OUString::valueOf( nObjCount
);
422 setObjectName( aName
);
424 // initialize properties
425 aAnyArray
[0] <<= 3.14;
426 aAnyArray
[1] <<= (sal_Int32
)42;
427 aAnyArray
[2] <<= OUString( "Hallo" );
429 // fetch PropertySetInfo once for internal use
430 m_xMyInfo
= getPropertySetInfo();
431 m_xMyInfo
->acquire(); // otherwise it could crash at shutdown
434 m_nMarkusChildrenCount
= 2;
441 eTypeClass
= TypeClass_INTERFACE
;
443 // string sequence initialization
444 aStringSeq
.realloc( 3 );
445 aStringSeq
[ 0 ] = "String 0";
446 aStringSeq
[ 1 ] = "String 1";
447 aStringSeq
[ 2 ] = "String 2";
449 // structs initialization
450 m_aFirstStruct
.Name
= "FirstStruct-Name";
451 m_aFirstStruct
.Handle
= 77777;
453 m_aFirstStruct
.Attributes
= -222;
455 //XInterfaceRef Source;
457 Value
<<= 2.718281828459;
458 m_aSecondStruct
.Value
= Value
;
459 //XIdlClassRef ListenerType;
460 m_aSecondStruct
.State
= PropertyState_DIRECT_VALUE
;
463 iIndexAccessCount
= DEFAULT_INDEX_ACCESS_COUNT
;
464 pIndexAccessTab
= NULL
;
465 pNameAccessTab
= NULL
;
468 Reference
< XPropertySetInfo
> ImplIntroTest::getPropertySetInfo()
469 throw(RuntimeException
)
471 static ImplPropertySetInfo
aInfo( mxMgr
);
472 // All objects have the same Properties, so
473 // the Info is the same for all
477 void ImplIntroTest::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
478 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
480 if( aPropChangeListener
.is() && aPropertyName
== aPropChangeListenerStr
)
482 PropertyChangeEvent aEvt
;
483 aEvt
.Source
= (OWeakObject
*)this;
484 aEvt
.PropertyName
= aPropertyName
;
485 aEvt
.PropertyHandle
= 0;
486 aPropChangeListener
->propertyChange( aEvt
);
488 if( aVetoPropChangeListener
.is() && aPropertyName
== aVetoPropChangeListenerStr
)
490 PropertyChangeEvent aEvt
;
491 aEvt
.Source
= (OWeakObject
*)this;
492 aEvt
.PropertyName
= aVetoPropChangeListenerStr
;
493 aEvt
.PropertyHandle
= 0;
494 aVetoPropChangeListener
->vetoableChange( aEvt
);
497 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
498 sal_Int32 nLen
= aPropSeq
.getLength();
499 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
501 Property aProp
= aPropSeq
.getArray()[ i
];
502 if( aProp
.Name
== aPropertyName
)
503 aAnyArray
[i
] = aValue
;
507 Any
ImplIntroTest::getPropertyValue( const OUString
& PropertyName
)
508 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
510 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
511 sal_Int32 nLen
= aPropSeq
.getLength();
512 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
514 Property aProp
= aPropSeq
.getArray()[ i
];
515 if( aProp
.Name
== PropertyName
)
521 OUString
ImplIntroTest::getFirstName()
522 throw(RuntimeException
)
524 return OUString("Markus");
527 void ImplIntroTest::writeln( const OUString
& Text
)
528 throw(RuntimeException
)
530 OString
aStr( Text
.getStr(), Text
.getLength(), RTL_TEXTENCODING_ASCII_US
);
532 printf( "%s", aStr
.getStr() );
535 Reference
< XIntroTest
> ImplIntroTest::getIntroTest()
536 throw(RuntimeException
)
538 if( !m_xIntroTest
.is() )
539 m_xIntroTest
= new ImplIntroTest( mxMgr
);
543 // Methods of XElementAccess
544 Type
ImplIntroTest::getElementType( )
545 throw(RuntimeException
)
552 sal_Bool
ImplIntroTest::hasElements( )
553 throw(RuntimeException
)
558 // XNameAccess methods
559 sal_Int32
getIndexForName( const OUString
& ItemName
)
561 OUString aLeftStr
= ItemName
.copy( 0, 4 );
562 if( aLeftStr
== "Item" )
565 OUString aNumStr
= ItemName
.copy( 4 );
571 Any
ImplIntroTest::getByName( const OUString
& aName
)
572 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
)
576 if( !pNameAccessTab
)
577 pNameAccessTab
= new Reference
< XIntroTest
>[ DEFAULT_NAME_ACCESS_COUNT
];
579 sal_Int32 iIndex
= getIndexForName( aName
);
582 if( !pNameAccessTab
[iIndex
].is() )
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
;
591 Reference
< XIntroTest
> xRet
= pNameAccessTab
[iIndex
];
592 aRetAny
= makeAny( xRet
);
597 Sequence
< OUString
> ImplIntroTest::getElementNames( )
598 throw(RuntimeException
)
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
++ )
604 OUString
aName( "Item" );
605 aName
+= OUString::valueOf( i
);
611 sal_Bool
ImplIntroTest::hasByName( const OUString
& aName
)
612 throw(RuntimeException
)
614 return ( getIndexForName( aName
) != -1 );
617 // XIndexAccess methods
618 sal_Int32
ImplIntroTest::getCount( )
619 throw(RuntimeException
)
621 return iIndexAccessCount
;
624 Any
ImplIntroTest::getByIndex( sal_Int32 Index
)
625 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
629 if( !pIndexAccessTab
)
630 pIndexAccessTab
= new Reference
< XIntroTest
>[ iIndexAccessCount
];
632 if( Index
< iIndexAccessCount
)
634 if( !pNameAccessTab
[Index
].is() )
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
;
642 Reference
< XIntroTest
> xRet
= pIndexAccessTab
[Index
];
643 aRetAny
= makeAny( xRet
);
648 void ImplIntroTest::addPropertiesChangeListener( const Sequence
< OUString
>& /*PropertyNames*/,
649 const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
650 throw(RuntimeException
)
654 void ImplIntroTest::removePropertiesChangeListener
655 ( const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
656 throw(RuntimeException
)
667 // special value for method concept, to mark "normal" functions
668 #define MethodConcept_NORMAL_IMPL 0x80000000
671 // return test object
672 Any
getIntrospectionTestObject( const Reference
< XMultiServiceFactory
> & xMgr
)
675 Reference
< XIntroTest
> xTestObj
= new ImplIntroTest( xMgr
);
676 aObjAny
.setValue( &xTestObj
, cppu::UnoType
<XIntroTest
>::get());
680 static sal_Bool
test_introsp( Reference
< XMultiServiceFactory
> xMgr
,
681 Reference
< XIdlReflection
> /*xRefl*/, Reference
< XIntrospection
> xIntrospection
)
683 DefItem pPropertyDefs
[] =
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
},
711 char const * pDemandedPropVals
[] =
716 "IntroTest-Obj Nr. 0",
738 char const * pDemandedModifiedPropVals
[] =
743 "IntroTest-Obj Nr. 0 (Modified!)",
748 "Value has not been modified",
749 "Value has not been modified",
751 "Value has not been modified",
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",
761 "Value has not been modified",
762 "Value has not been modified",
765 char const * pDemandedPropTypes
[] =
775 "com.sun.star.beans.Property",
776 "com.sun.star.beans.PropertyValue",
778 "ModuleA.XIntroTest",
784 "com.sun.star.beans.XPropertySetInfo",
792 DefItem pMethodDefs
[] =
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
},
840 // create test object
841 Any aObjAny
= getIntrospectionTestObject( xMgr
);
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" );
851 // check result of introspection
853 // determine XPropertySet-UIK
854 Type aType
= cppu::UnoType
<XPropertySet
>::get();
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()" );
861 Reference
< XExactName
> xExactName( xAccess
, UNO_QUERY
);
862 OSL_ENSURE( xExactName
.is(), "Introspection doesn't support ExactName" );
864 // loop over all concept combinations
865 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 16 ; nConcepts
++ )
867 // how many properties should this be
868 sal_Int32 nDemandedPropCount
= 0;
870 while( pPropertyDefs
[ iList
].pName
)
872 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
873 nDemandedPropCount
++;
879 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
880 Sequence
<Property
> aRetSeq
= xAccess
->getProperties( nConcepts
);
882 sal_Int32 nLen
= aRetSeq
.getLength();
884 aErrorStr
= "Expected to find "
885 + OString::valueOf( nDemandedPropCount
)
886 + " properties but found "
887 + OString::valueOf( nLen
);
888 OSL_ENSURE( nLen
== nDemandedPropCount
, aErrorStr
.getStr() );
890 const Property
* pProps
= aRetSeq
.getConstArray();
894 for( i
= 0 ; i
< nLen
; i
++ )
896 const Property aProp
= pProps
[ i
];
898 // search for next suitable method in the list
899 while( pPropertyDefs
[ iList
].pName
)
901 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
905 sal_Int32 iDemanded
= iList
;
908 OUString aPropName
= aProp
.Name
;
909 OString
aNameStr( aPropName
.getStr(), aPropName
.getLength(), RTL_TEXTENCODING_ASCII_US
);
911 OString aDemandedName
= pPropertyDefs
[ iDemanded
].pName
;
912 aErrorStr
= "Expected property \""
917 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
919 Type aPropType
= aProp
.Type
;
920 OString
aTypeNameStr( OUStringToOString(aPropType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
) );
921 OString aDemandedTypeNameStr
= pDemandedPropTypes
[ iDemanded
];
922 aErrorStr
= "Property \""
924 + "\", expected type >"
925 + aDemandedTypeNameStr
929 OSL_ENSURE( aTypeNameStr
== aDemandedTypeNameStr
, aErrorStr
.getStr() );
931 // read and report value of property
932 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
934 OString aValStr
= OUStringToOString( AnyToString( aPropVal
, sal_False
, xMgr
), RTL_TEXTENCODING_ASCII_US
);
935 OString aDemandedValStr
= pDemandedPropVals
[ iDemanded
];
936 aErrorStr
= "Property \""
938 + "\", expected val >"
943 OSL_ENSURE( aValStr
== aDemandedValStr
, aErrorStr
.getStr() );
945 // check value and modify it according to its type
946 TypeClass eType
= aPropVal
.getValueType().getTypeClass();
948 sal_Bool bModify
= sal_True
;
951 case TypeClass_STRING
:
955 aStr
+= " (Modified!)";
959 case TypeClass_DOUBLE
:
966 case TypeClass_SHORT
:
970 aNewVal
<<= sal_Int16( n
+ 1 );
977 aNewVal
<<= sal_Int32( n
+ 1 );
985 // modify only in the last iteration
986 if( nConcepts
== 15 )
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
)
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() );
1004 bModify
= sal_False
;
1007 // set new value, then read and return value
1010 // catch UnknownPropertyException for ReadOnly properties
1013 xPropSet
->setPropertyValue( aPropName
, aNewVal
);
1015 catch(const UnknownPropertyException
&)
1019 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
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 \""
1026 + "\", expected modified val >"
1027 + aDemandedModifiedValStr
1031 OSL_ENSURE( aModifiedValStr
== aDemandedModifiedValStr
, aErrorStr
.getStr() );
1034 // check whether all properties can be found individually
1035 aErrorStr
= "property \""
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() );
1042 aErrorStr
= "property \""
1044 + "\" not equal to same Property in sequence returned by getProperties()";
1047 Property aGetProp
= xAccess
->getProperty( aWDemandedName
, nConcepts
);
1049 catch (const RuntimeException
&)
1051 aErrorStr
= "property \""
1053 + "\", exception was thrown when trying getProperty()";
1054 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1061 // loop over all concept combinations
1062 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 128 ; nConcepts
++ )
1064 // The 2^6th bit stands for "the rest"
1065 sal_Int32 nRealConcepts
= nConcepts
;
1066 if( nConcepts
& 0x40 )
1067 nRealConcepts
|= (0xFFFFFFFF - 0x3F);
1069 // Count the number of methods there should be
1070 sal_Int32 nDemandedMethCount
= 0;
1071 sal_Int32 iList
= 0;
1072 while( pMethodDefs
[ iList
].pName
)
1074 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1075 nDemandedMethCount
++;
1079 // Output the method array.
1080 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( nRealConcepts
);
1081 sal_Int32 nLen
= aMethodSeq
.getLength();
1083 aErrorStr
= "Expected to find "
1084 + OString::valueOf( nDemandedMethCount
)
1085 + " methods but found "
1086 + OString::valueOf( nLen
);
1087 OSL_ENSURE( nLen
== nDemandedMethCount
, aErrorStr
.getStr() );
1089 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
1093 for( i
= 0 ; i
< nLen
; i
++ )
1095 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
1097 OUString aMethName
= rxMethod
->getName();
1098 OString aNameStr
= OUStringToOString(aMethName
, RTL_TEXTENCODING_ASCII_US
);
1100 // locate the next matching method in the list.
1101 while( pMethodDefs
[ iList
].pName
)
1103 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1107 OString aDemandedName
= pMethodDefs
[ iList
].pName
;
1110 aErrorStr
= "Expected method \""
1115 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
1117 // Check that the method is really there with hasMethod.
1118 aErrorStr
= "method \""
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() );
1125 aErrorStr
= "method \""
1127 + "\" not equal to same method in sequence returned by getMethods()";
1130 Reference
< XIdlMethod
> xGetMethod
= xAccess
->getMethod( aWDemandedName
, nRealConcepts
);
1131 OSL_ENSURE( xGetMethod
== rxMethod
, aErrorStr
.getStr() );
1133 catch (const RuntimeException
&)
1135 aErrorStr
= "method \""
1137 + "\", exception was thrown when trying getMethod()";
1138 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1143 // print listener class
1144 Sequence
< Type
> aClassSeq
= xAccess
->getSupportedListeners();
1145 sal_Int32 nLen
= aClassSeq
.getLength();
1147 const Type
* pListeners
= aClassSeq
.getConstArray();
1148 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1150 const Type
& aListenerType
= pListeners
[i
];
1151 OUString aListenerClassName
= aListenerType
.getTypeName();
1158 SAL_IMPLEMENT_MAIN()
1160 Reference
< XMultiServiceFactory
> xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) );
1162 sal_Bool bSucc
= sal_False
;
1165 Reference
< XImplementationRegistration
> xImplReg(
1166 xMgr
->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY
);
1167 OSL_ENSURE( xImplReg
.is(), "### no impl reg!" );
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!" );
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!" );
1187 fprintf(stderr
, "before test_introsp\n" );
1188 bSucc
= test_introsp( xMgr
, xRefl
, xIntrosp
);
1189 fprintf(stderr
, "after test_introsp\n" );
1191 catch (const Exception
& rExc
)
1193 DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc
);
1196 Reference
< XComponent
>( xMgr
, UNO_QUERY
)->dispose();
1198 printf( "testintrosp %s !\n", (bSucc
? "succeeded" : "failed") );
1199 return (bSucc
? 0 : -1);
1202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */