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 com::sun::star::uno
;
48 using namespace com::sun::star::lang
;
49 using namespace com::sun::star::beans
;
50 using namespace com::sun::star::registry
;
51 using namespace com::sun::star::reflection
;
52 using namespace com::sun::star::container
;
53 using namespace com::sun::star::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 //*******************************************************************
65 //*** Auxiliary function, in order to get from one type XIdlClass ***
66 //*******************************************************************
67 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XMultiServiceFactory
> & xMgr
)
69 static Reference
< XIdlReflection
> xRefl
;
71 // register void as default class
72 Reference
<XIdlClass
> xRetClass
;
73 typelib_TypeDescription
* pTD
= 0;
74 rType
.getDescription( &pTD
);
77 OUString
sOWName( pTD
->pTypeName
);
80 xRefl
= Reference
< XIdlReflection
>( xMgr
->createInstance(
81 OUString("com.sun.star.reflection.CoreReflection") ), UNO_QUERY
);
82 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
84 xRetClass
= xRefl
->forName( sOWName
);
90 //****************************************************
91 //*** Hilfs-Funktion, um Any als UString auszugeben ***
92 //****************************************************
93 // ACHTUNG: Kann mal an eine zentrale Stelle uebernommen werden
94 // Wird zunaechst nur fuer einfache Datentypen ausgefuehrt
96 OUString
AnyToString( const Any
& aValue
, sal_Bool bIncludeType
, const Reference
< XMultiServiceFactory
> & xMgr
)
98 Type aValType
= aValue
.getValueType();
99 TypeClass eType
= aValType
.getTypeClass();
105 case TypeClass_TYPE
: aRetStr
= OUString("TYPE TYPE"); break;
106 case TypeClass_INTERFACE
: aRetStr
= OUString("TYPE INTERFACE"); break;
107 case TypeClass_SERVICE
: aRetStr
= OUString("TYPE SERVICE"); break;
108 case TypeClass_STRUCT
: aRetStr
= OUString("TYPE STRUCT"); break;
109 case TypeClass_TYPEDEF
: aRetStr
= OUString("TYPE TYPEDEF"); break;
110 case TypeClass_UNION
: aRetStr
= OUString("TYPE UNION"); break;
111 case TypeClass_ENUM
: aRetStr
= OUString("TYPE ENUM"); break;
112 case TypeClass_EXCEPTION
: aRetStr
= OUString("TYPE EXCEPTION"); break;
113 case TypeClass_ARRAY
: aRetStr
= OUString("TYPE ARRAY"); break;
114 case TypeClass_SEQUENCE
: aRetStr
= OUString("TYPE SEQUENCE"); break;
115 case TypeClass_VOID
: aRetStr
= OUString("TYPE void"); break;
116 case TypeClass_ANY
: aRetStr
= OUString("TYPE any"); break;
117 case TypeClass_UNKNOWN
: aRetStr
= OUString("TYPE unknown"); break;
118 case TypeClass_BOOLEAN
:
120 sal_Bool b
= *(sal_Bool
*)aValue
.getValue();
121 aRetStr
= OUString::valueOf( b
);
126 sal_Unicode c
= *(sal_Unicode
*)aValue
.getValue();
127 aRetStr
= OUString::valueOf( c
);
130 case TypeClass_STRING
:
135 case TypeClass_FLOAT
:
139 snprintf( pBuffer
, sizeof( pBuffer
), "%f", f
);
140 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
143 case TypeClass_DOUBLE
:
147 snprintf( pBuffer
, sizeof( pBuffer
), "%f", d
);
148 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
155 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
158 case TypeClass_SHORT
:
162 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
169 aRetStr
= OUString::valueOf( n
);
177 Reference
< XIdlClass
> xIdlClass
= TypeToIdlClass( aValType
, xMgr
);
178 aRetStr
+= " (Typ: " + xIdlClass
->getName() + ")";
183 //*****************************************
184 //*** XPropertySetInfo fuer Test-Klasse ***
185 //*****************************************
187 class ImplPropertySetInfo
: public ImplPropertySetInfoHelper
189 friend class ImplIntroTest
;
191 Reference
< XMultiServiceFactory
> mxMgr
;
194 ImplPropertySetInfo( const Reference
< XMultiServiceFactory
> & xMgr
)
197 // Methods of XPropertySetInfo
198 virtual Sequence
< Property
> SAL_CALL
getProperties( )
199 throw(RuntimeException
);
200 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
)
201 throw(UnknownPropertyException
, RuntimeException
);
202 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
)
203 throw(RuntimeException
);
207 Sequence
< Property
> ImplPropertySetInfo::getProperties(void)
208 throw( RuntimeException
)
210 static Sequence
<Property
> * pSeq
= NULL
;
214 // Create information for the properties "Width", "Height" and "Name"
215 pSeq
= new Sequence
<Property
>( 3 );
216 Property
* pAry
= pSeq
->getArray();
218 pAry
[0].Name
= OUString("Factor");
220 pAry
[0].Type
= getCppuType( (double*) NULL
);
221 pAry
[0].Attributes
= BOUND
| TRANSIENT
;
223 pAry
[1].Name
= OUString("MyCount");
225 pAry
[1].Type
= getCppuType( (sal_Int32
*) NULL
);
226 pAry
[1].Attributes
= BOUND
| TRANSIENT
;
228 pAry
[2].Name
= OUString("Info");
230 pAry
[2].Type
= getCppuType( (OUString
*) NULL
);
231 pAry
[2].Attributes
= TRANSIENT
;
233 // Return information about all three properties
237 Property
ImplPropertySetInfo::getPropertyByName(const OUString
& Name
)
238 throw( UnknownPropertyException
, 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
252 sal_Bool
ImplPropertySetInfo::hasPropertyByName(const OUString
& Name
)
253 throw( RuntimeException
)
255 Sequence
<Property
> aSeq
= getProperties();
256 const Property
* pAry
= aSeq
.getConstArray();
258 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
260 if( pAry
[i
].Name
== Name
)
263 // Property unknown, also return empty ones
267 //*****************************************************************
268 class ImplIntroTest
: public ImplIntroTestHelper
270 Reference
< XMultiServiceFactory
> mxMgr
;
272 friend class ImplPropertySetInfo
;
274 // Properties for the PropertySet
277 Reference
< XPropertySetInfo
> m_xMyInfo
;
279 OUString m_ObjectName
;
281 sal_Int16 m_nMarkusAge
;
282 sal_Int16 m_nMarkusChildrenCount
;
289 TypeClass eTypeClass
;
290 Sequence
< OUString
> aStringSeq
;
291 Sequence
< Sequence
< Sequence
< sal_Int16
> > > aMultSeq
;
292 Reference
< XIntroTest
> m_xIntroTest
;
294 // Data for NameAccess
295 Reference
< XIntroTest
>* pNameAccessTab
;
297 // Data for IndexAccess
298 Reference
< XIntroTest
>* pIndexAccessTab
;
299 sal_Int16 iIndexAccessCount
;
302 Property m_aFirstStruct
;
303 PropertyValue m_aSecondStruct
;
305 // Listener merken (zunaechst einfach, nur einen pro Property)
306 Reference
< XPropertyChangeListener
> aPropChangeListener
;
307 OUString aPropChangeListenerStr
;
308 Reference
< XVetoableChangeListener
> aVetoPropChangeListener
;
309 OUString aVetoPropChangeListenerStr
;
314 ImplIntroTest( const Reference
< XMultiServiceFactory
> & xMgr
)
320 // Trotz virtual inline, um Schreibarbeit zu sparen (nur fuer Testzwecke)
322 virtual Reference
< XPropertySetInfo
> SAL_CALL
getPropertySetInfo( )
323 throw(RuntimeException
);
324 virtual void SAL_CALL
setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
325 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
);
326 virtual Any SAL_CALL
getPropertyValue( const OUString
& PropertyName
)
327 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
);
328 virtual void SAL_CALL
addPropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*xListener*/ )
329 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
331 virtual void SAL_CALL
removePropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*aListener*/ )
332 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
334 virtual void SAL_CALL
addVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
335 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
337 virtual void SAL_CALL
removeVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
338 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
341 // XIntroTest methods
343 virtual OUString SAL_CALL
getObjectName() throw(RuntimeException
)
344 { return m_ObjectName
; }
345 virtual void SAL_CALL
setObjectName( const OUString
& _objectname
) throw(RuntimeException
)
346 { m_ObjectName
= _objectname
; }
347 virtual OUString SAL_CALL
getFirstName()
348 throw(RuntimeException
);
349 virtual OUString SAL_CALL
getLastName() throw(RuntimeException
)
350 { return OUString( OUString("Meyer") ); }
351 virtual sal_Int16 SAL_CALL
getAge() throw(RuntimeException
)
352 { return m_nMarkusAge
; }
353 virtual sal_Int16 SAL_CALL
getChildrenCount() throw(RuntimeException
)
354 { return m_nMarkusChildrenCount
; }
355 virtual void SAL_CALL
setChildrenCount( sal_Int16 _childrencount
) throw(RuntimeException
)
356 { m_nMarkusChildrenCount
= _childrencount
; }
357 virtual Property SAL_CALL
getFirstStruct() throw(RuntimeException
)
358 { return m_aFirstStruct
; }
359 virtual void SAL_CALL
setFirstStruct( const Property
& _firststruct
) throw(RuntimeException
)
360 { m_aFirstStruct
= _firststruct
; }
361 virtual PropertyValue SAL_CALL
getSecondStruct() throw(RuntimeException
)
362 { return m_aSecondStruct
; }
363 virtual void SAL_CALL
setSecondStruct( const PropertyValue
& _secondstruct
) throw(RuntimeException
)
364 { m_aSecondStruct
= _secondstruct
; }
367 virtual void SAL_CALL
writeln( const OUString
& Text
)
368 throw(RuntimeException
);
369 virtual sal_Int32 SAL_CALL
getDroenk( ) throw(RuntimeException
)
370 { return m_lDroenk
; }
371 virtual Reference
< ::ModuleA::XIntroTest
> SAL_CALL
getIntroTest( ) throw(RuntimeException
);
372 virtual sal_Int32 SAL_CALL
getUps( sal_Int32 l
) throw(RuntimeException
)
374 virtual void SAL_CALL
setDroenk( sal_Int32 l
) throw(RuntimeException
)
376 virtual sal_Int16 SAL_CALL
getBla( ) throw(RuntimeException
)
378 virtual void SAL_CALL
setBla( sal_Int32 n
) throw(RuntimeException
)
379 { m_nBla
= (sal_Int16
)n
; }
380 virtual sal_Int16 SAL_CALL
getBlub( ) throw(RuntimeException
)
382 virtual void SAL_CALL
setBlub( sal_Int16 n
) throw(RuntimeException
)
384 virtual sal_Int16 SAL_CALL
getGulp( ) throw(RuntimeException
)
386 virtual sal_Int16 SAL_CALL
setGulp( sal_Int16 n
) throw(RuntimeException
)
387 { m_nGulp
= n
; return 1; }
388 virtual TypeClass SAL_CALL
getTypeClass( sal_Int16
/*n*/ ) throw(RuntimeException
)
389 { return eTypeClass
; }
390 virtual void SAL_CALL
setTypeClass( TypeClass t
, double /*d1*/, double /*d2*/ ) throw(RuntimeException
)
392 virtual Sequence
< OUString
> SAL_CALL
getStrings( ) throw(RuntimeException
)
393 { return aStringSeq
; }
394 virtual void SAL_CALL
setStrings( const Sequence
< OUString
>& Strings
) throw(RuntimeException
)
395 { aStringSeq
= Strings
; }
396 virtual void SAL_CALL
setStringsPerMethod( const Sequence
< OUString
>& Strings
, sal_Int16
/*n*/ ) throw(RuntimeException
)
397 { aStringSeq
= Strings
; }
398 virtual Sequence
< Sequence
< Sequence
< sal_Int16
> > > SAL_CALL
getMultiSequence( ) throw(RuntimeException
)
400 virtual void SAL_CALL
setMultiSequence( const Sequence
< Sequence
< Sequence
< sal_Int16
> > >& Seq
) throw(RuntimeException
)
402 virtual void SAL_CALL
addPropertiesChangeListener( const Sequence
< OUString
>& PropertyNames
, const Reference
< XPropertiesChangeListener
>& Listener
)
403 throw(RuntimeException
);
404 virtual void SAL_CALL
removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& Listener
)
405 throw(RuntimeException
);
408 // Methods of XElementAccess
409 virtual Type SAL_CALL
getElementType( )
410 throw(RuntimeException
);
411 virtual sal_Bool SAL_CALL
hasElements( )
412 throw(RuntimeException
);
414 // XNameAccess methods
416 virtual Any SAL_CALL
getByName( const OUString
& aName
)
417 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
);
418 virtual Sequence
< OUString
> SAL_CALL
getElementNames( )
419 throw(RuntimeException
);
420 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
)
421 throw(RuntimeException
);
423 // XIndexAccess methods
425 virtual sal_Int32 SAL_CALL
getCount( )
426 throw(RuntimeException
);
427 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
)
428 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
);
431 void ImplIntroTest::Init( void )
433 // Eindeutigen Namen verpassen
434 static sal_Int32 nObjCount
= 0;
435 OUString
aName( "IntroTest-Obj Nr. " );
436 aName
+= OUString::valueOf( nObjCount
);
437 setObjectName( aName
);
439 // Properties initialization
440 aAnyArray
[0] <<= 3.14;
441 aAnyArray
[1] <<= (sal_Int32
)42;
442 aAnyArray
[2] <<= OUString( OUString("Hallo") );
444 // Einmal fuer den internen Gebrauch die PropertySetInfo abholen
445 m_xMyInfo
= getPropertySetInfo();
446 m_xMyInfo
->acquire(); // sonst raucht es am Programm-Ende ab
449 m_nMarkusChildrenCount
= 2;
456 eTypeClass
= TypeClass_INTERFACE
;
458 // String-Sequence initialization
459 aStringSeq
.realloc( 3 );
460 OUString
* pStr
= aStringSeq
.getArray();
461 pStr
[ 0 ] = OUString( OUString("String 0") );
462 pStr
[ 1 ] = OUString( OUString("String 1") );
463 pStr
[ 2 ] = OUString( OUString("String 2") );
465 // structs initialization
466 m_aFirstStruct
.Name
= OUString("FirstStruct-Name");
467 m_aFirstStruct
.Handle
= 77777;
469 m_aFirstStruct
.Attributes
= -222;
471 //XInterfaceRef Source;
473 Value
<<= 2.718281828459;
474 m_aSecondStruct
.Value
= Value
;
475 //XIdlClassRef ListenerType;
476 m_aSecondStruct
.State
= PropertyState_DIRECT_VALUE
;
479 iIndexAccessCount
= DEFAULT_INDEX_ACCESS_COUNT
;
480 pIndexAccessTab
= NULL
;
481 pNameAccessTab
= NULL
;
484 Reference
< XPropertySetInfo
> ImplIntroTest::getPropertySetInfo()
485 throw(RuntimeException
)
487 static ImplPropertySetInfo
aInfo( mxMgr
);
488 // All objects have the same Properties, so
489 // the Info is the same for all
493 void ImplIntroTest::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
494 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
496 if( aPropChangeListener
.is() && aPropertyName
== aPropChangeListenerStr
)
498 PropertyChangeEvent aEvt
;
499 aEvt
.Source
= (OWeakObject
*)this;
500 aEvt
.PropertyName
= aPropertyName
;
501 aEvt
.PropertyHandle
= 0L;
502 aPropChangeListener
->propertyChange( aEvt
);
504 if( aVetoPropChangeListener
.is() && aPropertyName
== aVetoPropChangeListenerStr
)
506 PropertyChangeEvent aEvt
;
507 aEvt
.Source
= (OWeakObject
*)this;
508 aEvt
.PropertyName
= aVetoPropChangeListenerStr
;
509 aEvt
.PropertyHandle
= 0L;
510 aVetoPropChangeListener
->vetoableChange( aEvt
);
513 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
514 sal_Int32 nLen
= aPropSeq
.getLength();
515 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
517 Property aProp
= aPropSeq
.getArray()[ i
];
518 if( aProp
.Name
== aPropertyName
)
519 aAnyArray
[i
] = aValue
;
523 Any
ImplIntroTest::getPropertyValue( const OUString
& PropertyName
)
524 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
526 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
527 sal_Int32 nLen
= aPropSeq
.getLength();
528 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
530 Property aProp
= aPropSeq
.getArray()[ i
];
531 if( aProp
.Name
== PropertyName
)
537 OUString
ImplIntroTest::getFirstName(void)
538 throw(RuntimeException
)
540 return OUString( OUString("Markus") );
543 void ImplIntroTest::writeln( const OUString
& Text
)
544 throw(RuntimeException
)
546 OString
aStr( Text
.getStr(), Text
.getLength(), RTL_TEXTENCODING_ASCII_US
);
548 printf( "%s", aStr
.getStr() );
551 Reference
< XIntroTest
> ImplIntroTest::getIntroTest()
552 throw(RuntimeException
)
554 if( !m_xIntroTest
.is() )
555 m_xIntroTest
= new ImplIntroTest( mxMgr
);
559 // Methods of XElementAccess
560 Type
ImplIntroTest::getElementType( )
561 throw(RuntimeException
)
568 sal_Bool
ImplIntroTest::hasElements( )
569 throw(RuntimeException
)
574 // XNameAccess methods
575 sal_Int32
getIndexForName( const OUString
& ItemName
)
577 OUString aLeftStr
= ItemName
.copy( 0, 4 );
578 if( aLeftStr
== OUString("Item") )
581 OUString aNumStr
= ItemName
.copy( 4 );
587 Any
ImplIntroTest::getByName( const OUString
& aName
)
588 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
)
592 if( !pNameAccessTab
)
593 ((ImplIntroTest
*)this)->pNameAccessTab
= new Reference
< XIntroTest
>[ DEFAULT_NAME_ACCESS_COUNT
];
595 sal_Int32 iIndex
= getIndexForName( aName
);
598 if( !pNameAccessTab
[iIndex
].is() )
600 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
601 OUString
aName2( "IntroTest by Name-Access, Index = " );
602 aName2
+= OUString::valueOf( iIndex
);
603 p
->setObjectName( aName2
);
604 pNameAccessTab
[iIndex
] = p
;
607 Reference
< XIntroTest
> xRet
= pNameAccessTab
[iIndex
];
608 aRetAny
= makeAny( xRet
);
613 Sequence
< OUString
> ImplIntroTest::getElementNames( )
614 throw(RuntimeException
)
616 Sequence
<OUString
> aStrSeq( DEFAULT_NAME_ACCESS_COUNT
);
617 OUString
* pStr
= aStrSeq
.getArray();
618 for( sal_Int32 i
= 0 ; i
< DEFAULT_NAME_ACCESS_COUNT
; i
++ )
620 OUString
aName( "Item" );
621 aName
+= OUString::valueOf( i
);
627 sal_Bool
ImplIntroTest::hasByName( const OUString
& aName
)
628 throw(RuntimeException
)
630 return ( getIndexForName( aName
) != -1 );
633 // XIndexAccess methods
634 sal_Int32
ImplIntroTest::getCount( )
635 throw(RuntimeException
)
637 return iIndexAccessCount
;
640 Any
ImplIntroTest::getByIndex( sal_Int32 Index
)
641 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
645 if( !pIndexAccessTab
)
646 ((ImplIntroTest
*)this)->pIndexAccessTab
= new Reference
< XIntroTest
>[ iIndexAccessCount
];
648 if( Index
< iIndexAccessCount
)
650 if( !pNameAccessTab
[Index
].is() )
652 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
653 OUString
aName( "IntroTest by Index-Access, Index = " );
654 aName
+= OUString::valueOf( Index
);
655 p
->setObjectName( aName
);
656 pIndexAccessTab
[Index
] = p
;
658 Reference
< XIntroTest
> xRet
= pIndexAccessTab
[Index
];
659 aRetAny
= makeAny( xRet
);
664 void ImplIntroTest::addPropertiesChangeListener( const Sequence
< OUString
>& /*PropertyNames*/,
665 const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
666 throw(RuntimeException
)
670 void ImplIntroTest::removePropertiesChangeListener
671 ( const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
672 throw(RuntimeException
)
684 // Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen
685 #define MethodConcept_NORMAL_IMPL 0x80000000
688 // Test-Objekt liefern
689 Any
getIntrospectionTestObject( const Reference
< XMultiServiceFactory
> & xMgr
)
692 Reference
< XIntroTest
> xTestObj
= new ImplIntroTest( xMgr
);
693 aObjAny
.setValue( &xTestObj
, ::getCppuType( (const Reference
< XIntroTest
> *)0 ) );
697 static sal_Bool
test_introsp( Reference
< XMultiServiceFactory
> xMgr
,
698 Reference
< XIdlReflection
> /*xRefl*/, Reference
< XIntrospection
> xIntrospection
)
700 DefItem pPropertyDefs
[] =
702 { "Factor", PropertyConcept::PROPERTYSET
},
703 { "MyCount", PropertyConcept::PROPERTYSET
},
704 { "Info", PropertyConcept::PROPERTYSET
},
705 { "ObjectName", PropertyConcept::ATTRIBUTES
},
706 { "FirstName", PropertyConcept::ATTRIBUTES
},
707 { "LastName", PropertyConcept::ATTRIBUTES
},
708 { "Age", PropertyConcept::ATTRIBUTES
},
709 { "ChildrenCount", PropertyConcept::ATTRIBUTES
},
710 { "FirstStruct", PropertyConcept::ATTRIBUTES
},
711 { "SecondStruct", PropertyConcept::ATTRIBUTES
},
712 { "Droenk", PropertyConcept::METHODS
},
713 { "IntroTest", PropertyConcept::METHODS
},
714 { "Bla", PropertyConcept::METHODS
},
715 { "Blub", PropertyConcept::METHODS
},
716 { "Gulp", PropertyConcept::METHODS
},
717 { "Strings", PropertyConcept::METHODS
},
718 { "MultiSequence", PropertyConcept::METHODS
},
719 { "PropertySetInfo", PropertyConcept::METHODS
},
720 { "ElementType", PropertyConcept::METHODS
},
721 { "ElementNames", PropertyConcept::METHODS
},
722 { "Count", PropertyConcept::METHODS
},
723 { "Types", PropertyConcept::METHODS
},
724 { "ImplementationId", PropertyConcept::METHODS
},
728 char const * pDemandedPropVals
[] =
733 "IntroTest-Obj Nr. 0",
755 char const * pDemandedModifiedPropVals
[] =
760 "IntroTest-Obj Nr. 0 (Modified!)",
765 "Wert wurde nicht modifiziert",
766 "Wert wurde nicht modifiziert",
768 "Wert wurde nicht modifiziert",
772 "Wert wurde nicht modifiziert",
773 "Wert wurde nicht modifiziert",
774 "Wert wurde nicht modifiziert",
775 "Wert wurde nicht modifiziert",
776 "Wert wurde nicht modifiziert",
778 "Wert wurde nicht modifiziert"
779 "Wert wurde nicht modifiziert"
782 char const * pDemandedPropTypes
[] =
792 "com.sun.star.beans.Property",
793 "com.sun.star.beans.PropertyValue",
795 "ModuleA.XIntroTest",
801 "com.sun.star.beans.XPropertySetInfo",
809 DefItem pMethodDefs
[] =
811 { "queryInterface", MethodConcept_NORMAL_IMPL
},
812 { "acquire", MethodConcept::DANGEROUS
},
813 { "release", MethodConcept::DANGEROUS
},
814 { "writeln", MethodConcept_NORMAL_IMPL
},
815 { "getDroenk", MethodConcept::PROPERTY
},
816 { "getIntroTest", MethodConcept::PROPERTY
},
817 { "getUps", MethodConcept_NORMAL_IMPL
},
818 { "setDroenk", MethodConcept::PROPERTY
},
819 { "getBla", MethodConcept::PROPERTY
},
820 { "setBla", MethodConcept_NORMAL_IMPL
},
821 { "getBlub", MethodConcept::PROPERTY
},
822 { "setBlub", MethodConcept::PROPERTY
},
823 { "getGulp", MethodConcept::PROPERTY
},
824 { "setGulp", MethodConcept_NORMAL_IMPL
},
825 { "getTypeClass", MethodConcept_NORMAL_IMPL
},
826 { "setTypeClass", MethodConcept_NORMAL_IMPL
},
827 { "getStrings", MethodConcept::PROPERTY
},
828 { "setStrings", MethodConcept::PROPERTY
},
829 { "setStringsPerMethod", MethodConcept_NORMAL_IMPL
},
830 { "getMultiSequence", MethodConcept::PROPERTY
},
831 { "setMultiSequence", MethodConcept::PROPERTY
},
832 { "addPropertiesChangeListener", MethodConcept::LISTENER
},
833 { "removePropertiesChangeListener", MethodConcept::LISTENER
},
834 { "getPropertySetInfo", MethodConcept::PROPERTY
},
835 { "setPropertyValue", MethodConcept_NORMAL_IMPL
},
836 { "getPropertyValue", MethodConcept_NORMAL_IMPL
},
837 { "addPropertyChangeListener", MethodConcept::LISTENER
},
838 { "removePropertyChangeListener", MethodConcept::LISTENER
},
839 { "addVetoableChangeListener", MethodConcept::LISTENER
},
840 { "removeVetoableChangeListener", MethodConcept::LISTENER
},
841 { "getElementType", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
842 { "hasElements", MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
843 { "getByName", MethodConcept::NAMECONTAINER
},
844 { "getElementNames", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
},
845 { "hasByName", MethodConcept::NAMECONTAINER
},
846 { "getCount", MethodConcept::PROPERTY
| MethodConcept::INDEXCONTAINER
},
847 { "getByIndex", MethodConcept::INDEXCONTAINER
},
848 { "getTypes", MethodConcept::PROPERTY
},
849 { "getImplementationId", MethodConcept::PROPERTY
},
850 { "queryAdapter", MethodConcept_NORMAL_IMPL
},
856 //******************************************************
858 // create Test object
859 Any aObjAny
= getIntrospectionTestObject( xMgr
);
861 // Introspection-Service unspecten
862 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
863 xAccess
= xIntrospection
->inspect( aObjAny
);
864 xAccess
= xIntrospection
->inspect( aObjAny
);
865 OSL_ENSURE( xAccess
.is(), "introspection failed, no XIntrospectionAccess returned" );
869 // Ergebnis der Introspection pruefen
871 // XPropertySet-UIK ermitteln
872 Type aType
= getCppuType( (Reference
< XPropertySet
>*) NULL
);
874 Reference
< XInterface
> xPropSetIface
= xAccess
->queryAdapter( aType
);
875 Reference
< XPropertySet
> xPropSet( xPropSetIface
, UNO_QUERY
);
876 OSL_ENSURE( xPropSet
.is(), "Could not get XPropertySet by queryAdapter()" );
879 Reference
< XExactName
> xExactName( xAccess
, UNO_QUERY
);
880 OSL_ENSURE( xExactName
.is(), "Introspection unterstuetzt kein ExactName" );
882 // Schleife ueber alle Kombinationen von Concepts
883 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 16 ; nConcepts
++ )
885 // Wieviele Properties sollten es sein
886 sal_Int32 nDemandedPropCount
= 0;
888 while( pPropertyDefs
[ iList
].pName
)
890 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
891 nDemandedPropCount
++;
897 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
898 Sequence
<Property
> aRetSeq
= xAccess
->getProperties( nConcepts
);
900 sal_Int32 nLen
= aRetSeq
.getLength();
902 aErrorStr
= "Expected to find ";
903 aErrorStr
+= OString::valueOf( nDemandedPropCount
);
904 aErrorStr
+= " properties but found ";
905 aErrorStr
+= OString::valueOf( nLen
);
906 OSL_ENSURE( nLen
== nDemandedPropCount
, aErrorStr
.getStr() );
908 const Property
* pProps
= aRetSeq
.getConstArray();
912 for( i
= 0 ; i
< nLen
; i
++ )
914 const Property aProp
= pProps
[ i
];
916 // Naechste Passende Methode in der Liste suchen
917 while( pPropertyDefs
[ iList
].pName
)
919 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
923 sal_Int32 iDemanded
= iList
;
926 OUString aPropName
= aProp
.Name
;
927 OString
aNameStr( aPropName
.getStr(), aPropName
.getLength(), RTL_TEXTENCODING_ASCII_US
);
929 OString aDemandedName
= pPropertyDefs
[ iDemanded
].pName
;
930 aErrorStr
= "Expected property \"";
931 aErrorStr
+= aDemandedName
;
932 aErrorStr
+= "\", found \"";
933 aErrorStr
+= aNameStr
;
935 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
937 Type aPropType
= aProp
.Type
;
938 OString
aTypeNameStr( OUStringToOString(aPropType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
) );
939 OString aDemandedTypeNameStr
= pDemandedPropTypes
[ iDemanded
];
940 aErrorStr
= "Property \"";
941 aErrorStr
+= aDemandedName
;
942 aErrorStr
+= "\", expected type >";
943 aErrorStr
+= aDemandedTypeNameStr
;
944 aErrorStr
+= "< found type >";
945 aErrorStr
+= aTypeNameStr
;
947 OSL_ENSURE( aTypeNameStr
== aDemandedTypeNameStr
, aErrorStr
.getStr() );
949 // Wert des Property lesen und ausgeben
950 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
952 OString aValStr
= OUStringToOString( AnyToString( aPropVal
, sal_False
, xMgr
), RTL_TEXTENCODING_ASCII_US
);
953 OString aDemandedValStr
= pDemandedPropVals
[ iDemanded
];
954 aErrorStr
= "Property \"";
955 aErrorStr
+= aDemandedName
;
956 aErrorStr
+= "\", expected val >";
957 aErrorStr
+= aDemandedValStr
;
958 aErrorStr
+= "< found val >";
959 aErrorStr
+= aValStr
;
961 OSL_ENSURE( aValStr
== aDemandedValStr
, aErrorStr
.getStr() );
963 // Wert pruefen und typgerecht modifizieren
964 TypeClass eType
= aPropVal
.getValueType().getTypeClass();
966 sal_Bool bModify
= sal_True
;
969 case TypeClass_STRING
:
973 aStr
= aStr
+ OUString(" (Modified!)");
977 case TypeClass_DOUBLE
:
984 case TypeClass_SHORT
:
988 aNewVal
<<= sal_Int16( n
+ 1 );
995 aNewVal
<<= sal_Int32( n
+ 1 );
1003 // Modifizieren nur beim letzten Durchlauf
1004 if( nConcepts
== 15 )
1006 // XExactName pruefen, dafuer alles gross machen
1007 // (Introspection ist mit LowerCase implementiert, also anders machen)
1008 OUString aUpperUStr
= aPropName
.toAsciiUpperCase();
1009 OUString aExactName
= xExactName
->getExactName( aUpperUStr
);
1010 if( aExactName
!= aPropName
)
1012 aErrorStr
= "Property \"";
1013 aErrorStr
+= OUStringToOString( aPropName
, RTL_TEXTENCODING_ASCII_US
);
1014 aErrorStr
+= "\", not found as \"";
1015 aErrorStr
+= OUStringToOString(aUpperUStr
, RTL_TEXTENCODING_ASCII_US
);
1016 aErrorStr
+= "\" using XExactName";
1017 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1022 bModify
= sal_False
;
1025 // Neuen Wert setzen, wieder lesen und ausgeben
1028 // UnknownPropertyException bei ReadOnly-Properties abfangen
1031 xPropSet
->setPropertyValue( aPropName
, aNewVal
);
1033 catch(const UnknownPropertyException
&)
1037 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
1039 OUString aStr
= AnyToString( aPropVal
, sal_False
, xMgr
);
1040 OString aModifiedValStr
= OUStringToOString( aStr
, RTL_TEXTENCODING_ASCII_US
);
1041 OString aDemandedModifiedValStr
= pDemandedModifiedPropVals
[ i
];
1042 aErrorStr
= "Property \"";
1043 aErrorStr
+= aDemandedName
;
1044 aErrorStr
+= "\", expected modified val >";
1045 aErrorStr
+= aDemandedModifiedValStr
;
1046 aErrorStr
+= "< found val >";
1047 aErrorStr
+= aModifiedValStr
;
1049 OSL_ENSURE( aModifiedValStr
== aDemandedModifiedValStr
, aErrorStr
.getStr() );
1052 // Checken, ob alle Properties auch einzeln gefunden werden
1053 aErrorStr
= "property \"";
1054 aErrorStr
+= aDemandedName
;
1055 aErrorStr
+= "\" not found with hasProperty()";
1056 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1057 sal_Bool bProperty
= xAccess
->hasProperty( aWDemandedName
, nConcepts
);
1058 OSL_ENSURE( bProperty
, aErrorStr
.getStr() );
1060 aErrorStr
= "property \"";
1061 aErrorStr
+= aDemandedName
;
1062 aErrorStr
+= "\" not equal to same Property in sequence returned by getProperties()";
1065 Property aGetProp
= xAccess
->getProperty( aWDemandedName
, nConcepts
);
1067 catch (const RuntimeException
&)
1069 aErrorStr
= "property \"";
1070 aErrorStr
+= aDemandedName
;
1071 aErrorStr
+= "\", exception was thrown when trying getProperty()";
1072 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1079 // Schleife ueber alle Kombinationen von Concepts
1080 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 128 ; nConcepts
++ )
1082 // Das 2^6-Bit steht fuer "den Rest"
1083 sal_Int32 nRealConcepts
= nConcepts
;
1084 if( nConcepts
& 0x40 )
1085 nRealConcepts
|= (0xFFFFFFFF - 0x3F);
1087 // Wieviele Methoden sollten es sein
1088 sal_Int32 nDemandedMethCount
= 0;
1089 sal_Int32 iList
= 0;
1090 while( pMethodDefs
[ iList
].pName
)
1092 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1093 nDemandedMethCount
++;
1097 // Methoden-Array ausgeben
1098 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( nRealConcepts
);
1099 sal_Int32 nLen
= aMethodSeq
.getLength();
1101 aErrorStr
= "Expected to find ";
1102 aErrorStr
+= OString::valueOf( nDemandedMethCount
);
1103 aErrorStr
+= " methods but found ";
1104 aErrorStr
+= OString::valueOf( nLen
);
1105 OSL_ENSURE( nLen
== nDemandedMethCount
, aErrorStr
.getStr() );
1107 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
1111 for( i
= 0 ; i
< nLen
; i
++ )
1113 // Methode ansprechen
1114 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
1117 OUString aMethName
= rxMethod
->getName();
1118 OString aNameStr
= OUStringToOString(aMethName
, RTL_TEXTENCODING_ASCII_US
);
1120 // Naechste Passende Methode in der Liste suchen
1121 while( pMethodDefs
[ iList
].pName
)
1123 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1127 OString aDemandedName
= pMethodDefs
[ iList
].pName
;
1130 aErrorStr
= "Expected method \"";
1131 aErrorStr
+= aDemandedName
;
1132 aErrorStr
+= "\", found \"";
1133 aErrorStr
+= aNameStr
;
1135 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
1137 // Checken, ob alle Methoden auch einzeln gefunden werden
1138 aErrorStr
= "method \"";
1139 aErrorStr
+= aDemandedName
;
1140 aErrorStr
+= "\" not found with hasMethod()";
1141 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1142 sal_Bool bMethod
= xAccess
->hasMethod( aWDemandedName
, nRealConcepts
);
1143 OSL_ENSURE( bMethod
, aErrorStr
.getStr() );
1145 aErrorStr
= "method \"";
1146 aErrorStr
+= aDemandedName
;
1147 aErrorStr
+= "\" not equal to same method in sequence returned by getMethods()";
1150 Reference
< XIdlMethod
> xGetMethod
= xAccess
->getMethod( aWDemandedName
, nRealConcepts
);
1151 OSL_ENSURE( xGetMethod
== rxMethod
, aErrorStr
.getStr() );
1153 catch (const RuntimeException
&)
1155 aErrorStr
= "method \"";
1156 aErrorStr
+= aDemandedName
;
1157 aErrorStr
+= "\", exception was thrown when trying getMethod()";
1158 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1163 // Listener-Klassen ausgeben
1164 Sequence
< Type
> aClassSeq
= xAccess
->getSupportedListeners();
1165 sal_Int32 nLen
= aClassSeq
.getLength();
1167 const Type
* pListeners
= aClassSeq
.getConstArray();
1168 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1170 // Methode ansprechen
1171 const Type
& aListenerType
= pListeners
[i
];
1174 OUString aListenerClassName
= aListenerType
.getTypeName();
1181 SAL_IMPLEMENT_MAIN()
1183 Reference
< XMultiServiceFactory
> xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) );
1185 sal_Bool bSucc
= sal_False
;
1188 Reference
< XImplementationRegistration
> xImplReg(
1189 xMgr
->createInstance( OUString("com.sun.star.registry.ImplementationRegistration") ), UNO_QUERY
);
1190 OSL_ENSURE( xImplReg
.is(), "### no impl reg!" );
1192 // Register services
1193 OUString
libName( "reflection.uno" SAL_DLLEXTENSION
);
1194 fprintf(stderr
, "1\n" );
1195 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1196 libName
, Reference
< XSimpleRegistry
>() );
1197 fprintf(stderr
, "2\n" );
1198 Reference
< XIdlReflection
> xRefl( xMgr
->createInstance( OUString("com.sun.star.reflection.CoreReflection") ), UNO_QUERY
);
1199 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1203 "introspection.uno" SAL_DLLEXTENSION
);
1204 fprintf(stderr
, "3\n" );
1205 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1206 libName
, Reference
< XSimpleRegistry
>() );
1207 fprintf(stderr
, "4\n" );
1208 Reference
< XIntrospection
> xIntrosp( xMgr
->createInstance( OUString("com.sun.star.beans.Introspection") ), UNO_QUERY
);
1209 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1211 fprintf(stderr
, "before test_introsp\n" );
1212 bSucc
= test_introsp( xMgr
, xRefl
, xIntrosp
);
1213 fprintf(stderr
, "after test_introsp\n" );
1215 catch (const Exception
& rExc
)
1217 OSL_FAIL( "### exception occurred!" );
1218 OString
aMsg( OUStringToOString( rExc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
1219 OSL_TRACE( "### exception occurred: " );
1220 OSL_TRACE( "%s", aMsg
.getStr() );
1224 Reference
< XComponent
>( xMgr
, UNO_QUERY
)->dispose();
1226 printf( "testintrosp %s !\n", (bSucc
? "succeeded" : "failed") );
1227 return (bSucc
? 0 : -1);
1230 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */