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
;
55 using ::rtl::OUString
;
57 using ::rtl::OUStringToOString
;
58 using ::rtl::OStringToOUString
;
61 typedef WeakImplHelper4
< XIntroTest
, XPropertySet
, XNameAccess
, XIndexAccess
> ImplIntroTestHelper
;
62 typedef WeakImplHelper1
< XPropertySetInfo
> ImplPropertySetInfoHelper
;
65 #define DEFAULT_INDEX_ACCESS_COUNT 10
66 #define DEFAULT_NAME_ACCESS_COUNT 5
68 //**************************************************************
69 //*** Hilfs-Funktion, um vom Type eine XIdlClass zu bekommen ***
70 //**************************************************************
71 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XMultiServiceFactory
> & xMgr
)
73 static Reference
< XIdlReflection
> xRefl
;
75 // void als Default-Klasse eintragen
76 Reference
<XIdlClass
> xRetClass
;
77 typelib_TypeDescription
* pTD
= 0;
78 rType
.getDescription( &pTD
);
81 OUString
sOWName( pTD
->pTypeName
);
84 xRefl
= Reference
< XIdlReflection
>( xMgr
->createInstance(
85 OUString("com.sun.star.reflection.CoreReflection") ), UNO_QUERY
);
86 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
88 xRetClass
= xRefl
->forName( sOWName
);
94 //****************************************************
95 //*** Hilfs-Funktion, um Any als UString auszugeben ***
96 //****************************************************
97 // ACHTUNG: Kann mal an eine zentrale Stelle uebernommen werden
98 // Wird zunaechst nur fuer einfache Datentypen ausgefuehrt
100 OUString
AnyToString( const Any
& aValue
, sal_Bool bIncludeType
, const Reference
< XMultiServiceFactory
> & xMgr
)
102 Type aValType
= aValue
.getValueType();
103 TypeClass eType
= aValType
.getTypeClass();
109 case TypeClass_TYPE
: aRetStr
= OUString("TYPE TYPE"); break;
110 case TypeClass_INTERFACE
: aRetStr
= OUString("TYPE INTERFACE"); break;
111 case TypeClass_SERVICE
: aRetStr
= OUString("TYPE SERVICE"); break;
112 case TypeClass_STRUCT
: aRetStr
= OUString("TYPE STRUCT"); break;
113 case TypeClass_TYPEDEF
: aRetStr
= OUString("TYPE TYPEDEF"); break;
114 case TypeClass_UNION
: aRetStr
= OUString("TYPE UNION"); break;
115 case TypeClass_ENUM
: aRetStr
= OUString("TYPE ENUM"); break;
116 case TypeClass_EXCEPTION
: aRetStr
= OUString("TYPE EXCEPTION"); break;
117 case TypeClass_ARRAY
: aRetStr
= OUString("TYPE ARRAY"); break;
118 case TypeClass_SEQUENCE
: aRetStr
= OUString("TYPE SEQUENCE"); break;
119 case TypeClass_VOID
: aRetStr
= OUString("TYPE void"); break;
120 case TypeClass_ANY
: aRetStr
= OUString("TYPE any"); break;
121 case TypeClass_UNKNOWN
: aRetStr
= OUString("TYPE unknown"); break;
122 case TypeClass_BOOLEAN
:
124 sal_Bool b
= *(sal_Bool
*)aValue
.getValue();
125 aRetStr
= OUString::valueOf( b
);
130 sal_Unicode c
= *(sal_Unicode
*)aValue
.getValue();
131 aRetStr
= OUString::valueOf( c
);
134 case TypeClass_STRING
:
139 case TypeClass_FLOAT
:
143 snprintf( pBuffer
, sizeof( pBuffer
), "%f", f
);
144 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
147 case TypeClass_DOUBLE
:
151 snprintf( pBuffer
, sizeof( pBuffer
), "%f", d
);
152 aRetStr
= OUString( pBuffer
, strlen( pBuffer
), RTL_TEXTENCODING_ASCII_US
);
159 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
162 case TypeClass_SHORT
:
166 aRetStr
= OUString::valueOf( (sal_Int32
) n
);
173 aRetStr
= OUString::valueOf( n
);
181 Reference
< XIdlClass
> xIdlClass
= TypeToIdlClass( aValType
, xMgr
);
182 aRetStr
= aRetStr
+ OUString( OUString(" (Typ: ") ) + xIdlClass
->getName() + OUString(""));
187 //*****************************************
188 //*** XPropertySetInfo fuer Test-Klasse ***
189 //*****************************************
191 class ImplPropertySetInfo
: public ImplPropertySetInfoHelper
193 friend class ImplIntroTest
;
195 Reference
< XMultiServiceFactory
> mxMgr
;
198 ImplPropertySetInfo( const Reference
< XMultiServiceFactory
> & xMgr
)
201 // Methods of XPropertySetInfo
202 virtual Sequence
< Property
> SAL_CALL
getProperties( )
203 throw(RuntimeException
);
204 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
)
205 throw(UnknownPropertyException
, RuntimeException
);
206 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
)
207 throw(RuntimeException
);
211 Sequence
< Property
> ImplPropertySetInfo::getProperties(void)
212 throw( RuntimeException
)
214 static Sequence
<Property
> * pSeq
= NULL
;
218 // die Informationen für die Properties "Width", "Height" und "Name" anlegen
219 pSeq
= new Sequence
<Property
>( 3 );
220 Property
* pAry
= pSeq
->getArray();
222 pAry
[0].Name
= OUString("Factor");
224 pAry
[0].Type
= getCppuType( (double*) NULL
);
225 pAry
[0].Attributes
= BOUND
| TRANSIENT
;
227 pAry
[1].Name
= OUString("MyCount");
229 pAry
[1].Type
= getCppuType( (sal_Int32
*) NULL
);
230 pAry
[1].Attributes
= BOUND
| TRANSIENT
;
232 pAry
[2].Name
= OUString("Info");
234 pAry
[2].Type
= getCppuType( (OUString
*) NULL
);
235 pAry
[2].Attributes
= TRANSIENT
;
237 // Die Information über alle drei Properties liefern.
241 Property
ImplPropertySetInfo::getPropertyByName(const OUString
& Name
)
242 throw( UnknownPropertyException
, RuntimeException
)
244 Sequence
<Property
> aSeq
= getProperties();
245 const Property
* pAry
= aSeq
.getConstArray();
247 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
249 if( pAry
[i
].Name
== Name
)
252 // Property unbekannt, also leere liefern
256 sal_Bool
ImplPropertySetInfo::hasPropertyByName(const OUString
& Name
)
257 throw( RuntimeException
)
259 Sequence
<Property
> aSeq
= getProperties();
260 const Property
* pAry
= aSeq
.getConstArray();
262 for( sal_Int32 i
= aSeq
.getLength(); i
--; )
264 if( pAry
[i
].Name
== Name
)
267 // Property unbekannt, also leere liefern
271 //*****************************************************************
272 class ImplIntroTest
: public ImplIntroTestHelper
274 Reference
< XMultiServiceFactory
> mxMgr
;
276 friend class ImplPropertySetInfo
;
278 // Properties fuer das PropertySet
281 Reference
< XPropertySetInfo
> m_xMyInfo
;
283 OUString m_ObjectName
;
285 sal_Int16 m_nMarkusAge
;
286 sal_Int16 m_nMarkusChildrenCount
;
293 TypeClass eTypeClass
;
294 Sequence
< OUString
> aStringSeq
;
295 Sequence
< Sequence
< Sequence
< sal_Int16
> > > aMultSeq
;
296 Reference
< XIntroTest
> m_xIntroTest
;
298 // Daten fuer NameAccess
299 Reference
< XIntroTest
>* pNameAccessTab
;
301 // Daten fuer IndexAccess
302 Reference
< XIntroTest
>* pIndexAccessTab
;
303 sal_Int16 iIndexAccessCount
;
306 Property m_aFirstStruct
;
307 PropertyValue m_aSecondStruct
;
309 // Listener merken (zunaechst einfach, nur einen pro Property)
310 Reference
< XPropertyChangeListener
> aPropChangeListener
;
311 OUString aPropChangeListenerStr
;
312 Reference
< XVetoableChangeListener
> aVetoPropChangeListener
;
313 OUString aVetoPropChangeListenerStr
;
318 ImplIntroTest( const Reference
< XMultiServiceFactory
> & xMgr
)
324 // Trotz virtual inline, um Schreibarbeit zu sparen (nur fuer Testzwecke)
326 virtual Reference
< XPropertySetInfo
> SAL_CALL
getPropertySetInfo( )
327 throw(RuntimeException
);
328 virtual void SAL_CALL
setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
329 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
);
330 virtual Any SAL_CALL
getPropertyValue( const OUString
& PropertyName
)
331 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
);
332 virtual void SAL_CALL
addPropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*xListener*/ )
333 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
335 virtual void SAL_CALL
removePropertyChangeListener( const OUString
& /*aPropertyName*/, const Reference
< XPropertyChangeListener
>& /*aListener*/ )
336 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
338 virtual void SAL_CALL
addVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
339 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
341 virtual void SAL_CALL
removeVetoableChangeListener( const OUString
& /*PropertyName*/, const Reference
< XVetoableChangeListener
>& /*aListener*/ )
342 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
345 // XIntroTest-Methoden
347 virtual OUString SAL_CALL
getObjectName() throw(RuntimeException
)
348 { return m_ObjectName
; }
349 virtual void SAL_CALL
setObjectName( const OUString
& _objectname
) throw(RuntimeException
)
350 { m_ObjectName
= _objectname
; }
351 virtual OUString SAL_CALL
getFirstName()
352 throw(RuntimeException
);
353 virtual OUString SAL_CALL
getLastName() throw(RuntimeException
)
354 { return OUString( OUString("Meyer") ); }
355 virtual sal_Int16 SAL_CALL
getAge() throw(RuntimeException
)
356 { return m_nMarkusAge
; }
357 virtual sal_Int16 SAL_CALL
getChildrenCount() throw(RuntimeException
)
358 { return m_nMarkusChildrenCount
; }
359 virtual void SAL_CALL
setChildrenCount( sal_Int16 _childrencount
) throw(RuntimeException
)
360 { m_nMarkusChildrenCount
= _childrencount
; }
361 virtual Property SAL_CALL
getFirstStruct() throw(RuntimeException
)
362 { return m_aFirstStruct
; }
363 virtual void SAL_CALL
setFirstStruct( const Property
& _firststruct
) throw(RuntimeException
)
364 { m_aFirstStruct
= _firststruct
; }
365 virtual PropertyValue SAL_CALL
getSecondStruct() throw(RuntimeException
)
366 { return m_aSecondStruct
; }
367 virtual void SAL_CALL
setSecondStruct( const PropertyValue
& _secondstruct
) throw(RuntimeException
)
368 { m_aSecondStruct
= _secondstruct
; }
371 virtual void SAL_CALL
writeln( const OUString
& Text
)
372 throw(RuntimeException
);
373 virtual sal_Int32 SAL_CALL
getDroenk( ) throw(RuntimeException
)
374 { return m_lDroenk
; }
375 virtual Reference
< ::ModuleA::XIntroTest
> SAL_CALL
getIntroTest( ) throw(RuntimeException
);
376 virtual sal_Int32 SAL_CALL
getUps( sal_Int32 l
) throw(RuntimeException
)
378 virtual void SAL_CALL
setDroenk( sal_Int32 l
) throw(RuntimeException
)
380 virtual sal_Int16 SAL_CALL
getBla( ) throw(RuntimeException
)
382 virtual void SAL_CALL
setBla( sal_Int32 n
) throw(RuntimeException
)
383 { m_nBla
= (sal_Int16
)n
; }
384 virtual sal_Int16 SAL_CALL
getBlub( ) throw(RuntimeException
)
386 virtual void SAL_CALL
setBlub( sal_Int16 n
) throw(RuntimeException
)
388 virtual sal_Int16 SAL_CALL
getGulp( ) throw(RuntimeException
)
390 virtual sal_Int16 SAL_CALL
setGulp( sal_Int16 n
) throw(RuntimeException
)
391 { m_nGulp
= n
; return 1; }
392 virtual TypeClass SAL_CALL
getTypeClass( sal_Int16
/*n*/ ) throw(RuntimeException
)
393 { return eTypeClass
; }
394 virtual void SAL_CALL
setTypeClass( TypeClass t
, double /*d1*/, double /*d2*/ ) throw(RuntimeException
)
396 virtual Sequence
< OUString
> SAL_CALL
getStrings( ) throw(RuntimeException
)
397 { return aStringSeq
; }
398 virtual void SAL_CALL
setStrings( const Sequence
< OUString
>& Strings
) throw(RuntimeException
)
399 { aStringSeq
= Strings
; }
400 virtual void SAL_CALL
setStringsPerMethod( const Sequence
< OUString
>& Strings
, sal_Int16
/*n*/ ) throw(RuntimeException
)
401 { aStringSeq
= Strings
; }
402 virtual Sequence
< Sequence
< Sequence
< sal_Int16
> > > SAL_CALL
getMultiSequence( ) throw(RuntimeException
)
404 virtual void SAL_CALL
setMultiSequence( const Sequence
< Sequence
< Sequence
< sal_Int16
> > >& Seq
) throw(RuntimeException
)
406 virtual void SAL_CALL
addPropertiesChangeListener( const Sequence
< OUString
>& PropertyNames
, const Reference
< XPropertiesChangeListener
>& Listener
)
407 throw(RuntimeException
);
408 virtual void SAL_CALL
removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& Listener
)
409 throw(RuntimeException
);
412 // Methods of XElementAccess
413 virtual Type SAL_CALL
getElementType( )
414 throw(RuntimeException
);
415 virtual sal_Bool SAL_CALL
hasElements( )
416 throw(RuntimeException
);
418 // XNameAccess-Methoden
420 virtual Any SAL_CALL
getByName( const OUString
& aName
)
421 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
);
422 virtual Sequence
< OUString
> SAL_CALL
getElementNames( )
423 throw(RuntimeException
);
424 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
)
425 throw(RuntimeException
);
427 // XIndexAccess-Methoden
429 virtual sal_Int32 SAL_CALL
getCount( )
430 throw(RuntimeException
);
431 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
)
432 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
);
435 void ImplIntroTest::Init( void )
437 // Eindeutigen Namen verpassen
438 static sal_Int32 nObjCount
= 0;
439 OUString
aName( "IntroTest-Obj Nr. " );
440 aName
+= OUString::valueOf( nObjCount
);
441 setObjectName( aName
);
443 // Properties initialisieren
444 aAnyArray
[0] <<= 3.14;
445 aAnyArray
[1] <<= (sal_Int32
)42;
446 aAnyArray
[2] <<= OUString( OUString("Hallo") );
448 // Einmal fuer den internen Gebrauch die PropertySetInfo abholen
449 m_xMyInfo
= getPropertySetInfo();
450 m_xMyInfo
->acquire(); // sonst raucht es am Programm-Ende ab
453 m_nMarkusChildrenCount
= 2;
460 eTypeClass
= TypeClass_INTERFACE
;
462 // String-Sequence intitialisieren
463 aStringSeq
.realloc( 3 );
464 OUString
* pStr
= aStringSeq
.getArray();
465 pStr
[ 0 ] = OUString( OUString("String 0") );
466 pStr
[ 1 ] = OUString( OUString("String 1") );
467 pStr
[ 2 ] = OUString( OUString("String 2") );
469 // structs initialisieren
470 m_aFirstStruct
.Name
= OUString("FirstStruct-Name");
471 m_aFirstStruct
.Handle
= 77777;
473 m_aFirstStruct
.Attributes
= -222;
475 //XInterfaceRef Source;
477 Value
<<= 2.718281828459;
478 m_aSecondStruct
.Value
= Value
;
479 //XIdlClassRef ListenerType;
480 m_aSecondStruct
.State
= PropertyState_DIRECT_VALUE
;
483 iIndexAccessCount
= DEFAULT_INDEX_ACCESS_COUNT
;
484 pIndexAccessTab
= NULL
;
485 pNameAccessTab
= NULL
;
488 Reference
< XPropertySetInfo
> ImplIntroTest::getPropertySetInfo()
489 throw(RuntimeException
)
491 static ImplPropertySetInfo
aInfo( mxMgr
);
492 // Alle Objekt haben die gleichen Properties, deshalb kann
493 // die Info für alle gleich sein
497 void ImplIntroTest::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
498 throw(UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
500 if( aPropChangeListener
.is() && aPropertyName
== aPropChangeListenerStr
)
502 PropertyChangeEvent aEvt
;
503 aEvt
.Source
= (OWeakObject
*)this;
504 aEvt
.PropertyName
= aPropertyName
;
505 aEvt
.PropertyHandle
= 0L;
506 aPropChangeListener
->propertyChange( aEvt
);
508 if( aVetoPropChangeListener
.is() && aPropertyName
== aVetoPropChangeListenerStr
)
510 PropertyChangeEvent aEvt
;
511 aEvt
.Source
= (OWeakObject
*)this;
512 aEvt
.PropertyName
= aVetoPropChangeListenerStr
;
513 aEvt
.PropertyHandle
= 0L;
514 aVetoPropChangeListener
->vetoableChange( aEvt
);
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
== aPropertyName
)
523 aAnyArray
[i
] = aValue
;
527 Any
ImplIntroTest::getPropertyValue( const OUString
& PropertyName
)
528 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
530 Sequence
<Property
> aPropSeq
= m_xMyInfo
->getProperties();
531 sal_Int32 nLen
= aPropSeq
.getLength();
532 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
534 Property aProp
= aPropSeq
.getArray()[ i
];
535 if( aProp
.Name
== PropertyName
)
541 OUString
ImplIntroTest::getFirstName(void)
542 throw(RuntimeException
)
544 return OUString( OUString("Markus") );
547 void ImplIntroTest::writeln( const OUString
& Text
)
548 throw(RuntimeException
)
550 OString
aStr( Text
.getStr(), Text
.getLength(), RTL_TEXTENCODING_ASCII_US
);
552 printf( "%s", aStr
.getStr() );
555 Reference
< XIntroTest
> ImplIntroTest::getIntroTest()
556 throw(RuntimeException
)
558 if( !m_xIntroTest
.is() )
559 m_xIntroTest
= new ImplIntroTest( mxMgr
);
563 // Methoden von XElementAccess
564 Type
ImplIntroTest::getElementType( )
565 throw(RuntimeException
)
570 //return Reference< XIdlClass >();
571 //return Void_getReflection()->getIdlClass();
574 sal_Bool
ImplIntroTest::hasElements( )
575 throw(RuntimeException
)
580 // XNameAccess-Methoden
581 sal_Int32
getIndexForName( const OUString
& ItemName
)
583 OUString aLeftStr
= ItemName
.copy( 0, 4 );
584 if( aLeftStr
== OUString("Item") )
587 OUString aNumStr
= ItemName
.copy( 4 );
588 //sal_Int32 iIndex = (INT32)UStringToString( aNumStr, CHARSET_SYSTEM );
589 //if( iIndex < DEFAULT_NAME_ACCESS_COUNT )
596 Any
ImplIntroTest::getByName( const OUString
& aName
)
597 throw(NoSuchElementException
, WrappedTargetException
, RuntimeException
)
601 if( !pNameAccessTab
)
602 ((ImplIntroTest
*)this)->pNameAccessTab
= new Reference
< XIntroTest
>[ DEFAULT_NAME_ACCESS_COUNT
];
604 sal_Int32 iIndex
= getIndexForName( aName
);
607 if( !pNameAccessTab
[iIndex
].is() )
609 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
610 OUString
aName2( "IntroTest by Name-Access, Index = " );
611 aName2
+= OUString::valueOf( iIndex
);
612 p
->setObjectName( aName2
);
613 pNameAccessTab
[iIndex
] = p
;
616 Reference
< XIntroTest
> xRet
= pNameAccessTab
[iIndex
];
617 aRetAny
= makeAny( xRet
);
622 Sequence
< OUString
> ImplIntroTest::getElementNames( )
623 throw(RuntimeException
)
625 Sequence
<OUString
> aStrSeq( DEFAULT_NAME_ACCESS_COUNT
);
626 OUString
* pStr
= aStrSeq
.getArray();
627 for( sal_Int32 i
= 0 ; i
< DEFAULT_NAME_ACCESS_COUNT
; i
++ )
629 OUString
aName( "Item" );
630 aName
+= OUString::valueOf( i
);
636 sal_Bool
ImplIntroTest::hasByName( const OUString
& aName
)
637 throw(RuntimeException
)
639 return ( getIndexForName( aName
) != -1 );
642 // XIndexAccess-Methoden
643 sal_Int32
ImplIntroTest::getCount( )
644 throw(RuntimeException
)
646 return iIndexAccessCount
;
649 Any
ImplIntroTest::getByIndex( sal_Int32 Index
)
650 throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
654 if( !pIndexAccessTab
)
655 ((ImplIntroTest
*)this)->pIndexAccessTab
= new Reference
< XIntroTest
>[ iIndexAccessCount
];
657 if( Index
< iIndexAccessCount
)
659 if( !pNameAccessTab
[Index
].is() )
661 ImplIntroTest
* p
= new ImplIntroTest( mxMgr
);
662 OUString
aName( "IntroTest by Index-Access, Index = " );
663 aName
+= OUString::valueOf( Index
);
664 p
->setObjectName( aName
);
665 pIndexAccessTab
[Index
] = p
;
667 Reference
< XIntroTest
> xRet
= pIndexAccessTab
[Index
];
668 aRetAny
= makeAny( xRet
);
673 void ImplIntroTest::addPropertiesChangeListener( const Sequence
< OUString
>& /*PropertyNames*/,
674 const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
675 throw(RuntimeException
)
679 void ImplIntroTest::removePropertiesChangeListener
680 ( const Reference
< XPropertiesChangeListener
>& /*Listener*/ )
681 throw(RuntimeException
)
693 // Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen
694 #define MethodConcept_NORMAL_IMPL 0x80000000
697 // Test-Objekt liefern
698 Any
getIntrospectionTestObject( const Reference
< XMultiServiceFactory
> & xMgr
)
701 Reference
< XIntroTest
> xTestObj
= new ImplIntroTest( xMgr
);
702 aObjAny
.setValue( &xTestObj
, ::getCppuType( (const Reference
< XIntroTest
> *)0 ) );
706 static sal_Bool
test_introsp( Reference
< XMultiServiceFactory
> xMgr
,
707 Reference
< XIdlReflection
> /*xRefl*/, Reference
< XIntrospection
> xIntrospection
)
709 DefItem pPropertyDefs
[] =
711 { "Factor", PropertyConcept::PROPERTYSET
},
712 { "MyCount", PropertyConcept::PROPERTYSET
},
713 { "Info", PropertyConcept::PROPERTYSET
},
714 { "ObjectName", PropertyConcept::ATTRIBUTES
},
715 { "FirstName", PropertyConcept::ATTRIBUTES
},
716 { "LastName", PropertyConcept::ATTRIBUTES
},
717 { "Age", PropertyConcept::ATTRIBUTES
},
718 { "ChildrenCount", PropertyConcept::ATTRIBUTES
},
719 { "FirstStruct", PropertyConcept::ATTRIBUTES
},
720 { "SecondStruct", PropertyConcept::ATTRIBUTES
},
721 { "Droenk", PropertyConcept::METHODS
},
722 { "IntroTest", PropertyConcept::METHODS
},
723 { "Bla", PropertyConcept::METHODS
},
724 { "Blub", PropertyConcept::METHODS
},
725 { "Gulp", PropertyConcept::METHODS
},
726 { "Strings", PropertyConcept::METHODS
},
727 { "MultiSequence", PropertyConcept::METHODS
},
728 { "PropertySetInfo", PropertyConcept::METHODS
},
729 { "ElementType", PropertyConcept::METHODS
},
730 { "ElementNames", PropertyConcept::METHODS
},
731 { "Count", PropertyConcept::METHODS
},
732 { "Types", PropertyConcept::METHODS
},
733 { "ImplementationId", PropertyConcept::METHODS
},
737 char const * pDemandedPropVals
[] =
742 "IntroTest-Obj Nr. 0",
764 char const * pDemandedModifiedPropVals
[] =
769 "IntroTest-Obj Nr. 0 (Modified!)",
774 "Wert wurde nicht modifiziert",
775 "Wert wurde nicht modifiziert",
777 "Wert wurde nicht modifiziert",
781 "Wert wurde nicht modifiziert",
782 "Wert wurde nicht modifiziert",
783 "Wert wurde nicht modifiziert",
784 "Wert wurde nicht modifiziert",
785 "Wert wurde nicht modifiziert",
787 "Wert wurde nicht modifiziert"
788 "Wert wurde nicht modifiziert"
791 char const * pDemandedPropTypes
[] =
801 "com.sun.star.beans.Property",
802 "com.sun.star.beans.PropertyValue",
804 "ModuleA.XIntroTest",
810 "com.sun.star.beans.XPropertySetInfo",
818 DefItem pMethodDefs
[] =
820 { "queryInterface", MethodConcept_NORMAL_IMPL
},
821 { "acquire", MethodConcept::DANGEROUS
},
822 { "release", MethodConcept::DANGEROUS
},
823 { "writeln", MethodConcept_NORMAL_IMPL
},
824 { "getDroenk", MethodConcept::PROPERTY
},
825 { "getIntroTest", MethodConcept::PROPERTY
},
826 { "getUps", MethodConcept_NORMAL_IMPL
},
827 { "setDroenk", MethodConcept::PROPERTY
},
828 { "getBla", MethodConcept::PROPERTY
},
829 { "setBla", MethodConcept_NORMAL_IMPL
},
830 { "getBlub", MethodConcept::PROPERTY
},
831 { "setBlub", MethodConcept::PROPERTY
},
832 { "getGulp", MethodConcept::PROPERTY
},
833 { "setGulp", MethodConcept_NORMAL_IMPL
},
834 { "getTypeClass", MethodConcept_NORMAL_IMPL
},
835 { "setTypeClass", MethodConcept_NORMAL_IMPL
},
836 { "getStrings", MethodConcept::PROPERTY
},
837 { "setStrings", MethodConcept::PROPERTY
},
838 { "setStringsPerMethod", MethodConcept_NORMAL_IMPL
},
839 { "getMultiSequence", MethodConcept::PROPERTY
},
840 { "setMultiSequence", MethodConcept::PROPERTY
},
841 { "addPropertiesChangeListener", MethodConcept::LISTENER
},
842 { "removePropertiesChangeListener", MethodConcept::LISTENER
},
843 { "getPropertySetInfo", MethodConcept::PROPERTY
},
844 { "setPropertyValue", MethodConcept_NORMAL_IMPL
},
845 { "getPropertyValue", MethodConcept_NORMAL_IMPL
},
846 { "addPropertyChangeListener", MethodConcept::LISTENER
},
847 { "removePropertyChangeListener", MethodConcept::LISTENER
},
848 { "addVetoableChangeListener", MethodConcept::LISTENER
},
849 { "removeVetoableChangeListener", MethodConcept::LISTENER
},
850 { "getElementType", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
851 { "hasElements", MethodConcept::NAMECONTAINER
| MethodConcept::INDEXCONTAINER
| MethodConcept::ENUMERATION
},
852 { "getByName", MethodConcept::NAMECONTAINER
},
853 { "getElementNames", MethodConcept::PROPERTY
| MethodConcept::NAMECONTAINER
},
854 { "hasByName", MethodConcept::NAMECONTAINER
},
855 { "getCount", MethodConcept::PROPERTY
| MethodConcept::INDEXCONTAINER
},
856 { "getByIndex", MethodConcept::INDEXCONTAINER
},
857 { "getTypes", MethodConcept::PROPERTY
},
858 { "getImplementationId", MethodConcept::PROPERTY
},
859 { "queryAdapter", MethodConcept_NORMAL_IMPL
},
865 //******************************************************
867 // Test-Objekt anlegen
868 Any aObjAny
= getIntrospectionTestObject( xMgr
);
870 // Introspection-Service unspecten
871 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
872 xAccess
= xIntrospection
->inspect( aObjAny
);
873 xAccess
= xIntrospection
->inspect( aObjAny
);
874 OSL_ENSURE( xAccess
.is(), "introspection failed, no XIntrospectionAccess returned" );
878 // Ergebnis der Introspection pruefen
880 // XPropertySet-UIK ermitteln
881 Type aType
= getCppuType( (Reference
< XPropertySet
>*) NULL
);
883 Reference
< XInterface
> xPropSetIface
= xAccess
->queryAdapter( aType
);
884 Reference
< XPropertySet
> xPropSet( xPropSetIface
, UNO_QUERY
);
885 OSL_ENSURE( xPropSet
.is(), "Could not get XPropertySet by queryAdapter()" );
888 Reference
< XExactName
> xExactName( xAccess
, UNO_QUERY
);
889 OSL_ENSURE( xExactName
.is(), "Introspection unterstuetzt kein ExactName" );
891 // Schleife ueber alle Kombinationen von Concepts
892 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 16 ; nConcepts
++ )
894 // Wieviele Properties sollten es sein
895 sal_Int32 nDemandedPropCount
= 0;
897 while( pPropertyDefs
[ iList
].pName
)
899 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
900 nDemandedPropCount
++;
906 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
907 Sequence
<Property
> aRetSeq
= xAccess
->getProperties( nConcepts
);
909 sal_Int32 nLen
= aRetSeq
.getLength();
911 aErrorStr
= "Expected to find ";
912 aErrorStr
+= OString::valueOf( nDemandedPropCount
);
913 aErrorStr
+= " properties but found ";
914 aErrorStr
+= OString::valueOf( nLen
);
915 OSL_ENSURE( nLen
== nDemandedPropCount
, aErrorStr
.getStr() );
917 const Property
* pProps
= aRetSeq
.getConstArray();
921 for( i
= 0 ; i
< nLen
; i
++ )
923 const Property aProp
= pProps
[ i
];
925 // Naechste Passende Methode in der Liste suchen
926 while( pPropertyDefs
[ iList
].pName
)
928 if( pPropertyDefs
[ iList
].nConcept
& nConcepts
)
932 sal_Int32 iDemanded
= iList
;
935 OUString aPropName
= aProp
.Name
;
936 OString
aNameStr( aPropName
.getStr(), aPropName
.getLength(), RTL_TEXTENCODING_ASCII_US
);
938 OString aDemandedName
= pPropertyDefs
[ iDemanded
].pName
;
939 aErrorStr
= "Expected property \"";
940 aErrorStr
+= aDemandedName
;
941 aErrorStr
+= "\", found \"";
942 aErrorStr
+= aNameStr
;
944 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
946 Type aPropType
= aProp
.Type
;
947 OString
aTypeNameStr( OUStringToOString(aPropType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
) );
948 OString aDemandedTypeNameStr
= pDemandedPropTypes
[ iDemanded
];
949 aErrorStr
= "Property \"";
950 aErrorStr
+= aDemandedName
;
951 aErrorStr
+= "\", expected type >";
952 aErrorStr
+= aDemandedTypeNameStr
;
953 aErrorStr
+= "< found type >";
954 aErrorStr
+= aTypeNameStr
;
956 OSL_ENSURE( aTypeNameStr
== aDemandedTypeNameStr
, aErrorStr
.getStr() );
958 // Wert des Property lesen und ausgeben
959 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
961 OString aValStr
= OUStringToOString( AnyToString( aPropVal
, sal_False
, xMgr
), RTL_TEXTENCODING_ASCII_US
);
962 OString aDemandedValStr
= pDemandedPropVals
[ iDemanded
];
963 aErrorStr
= "Property \"";
964 aErrorStr
+= aDemandedName
;
965 aErrorStr
+= "\", expected val >";
966 aErrorStr
+= aDemandedValStr
;
967 aErrorStr
+= "< found val >";
968 aErrorStr
+= aValStr
;
970 OSL_ENSURE( aValStr
== aDemandedValStr
, aErrorStr
.getStr() );
972 // Wert pruefen und typgerecht modifizieren
973 TypeClass eType
= aPropVal
.getValueType().getTypeClass();
975 sal_Bool bModify
= sal_True
;
978 case TypeClass_STRING
:
982 aStr
= aStr
+ OUString(" (Modified!)");
986 case TypeClass_DOUBLE
:
993 case TypeClass_SHORT
:
997 aNewVal
<<= sal_Int16( n
+ 1 );
1000 case TypeClass_LONG
:
1004 aNewVal
<<= sal_Int32( n
+ 1 );
1008 bModify
= sal_False
;
1012 // Modifizieren nur beim letzten Durchlauf
1013 if( nConcepts
== 15 )
1015 // XExactName pruefen, dafuer alles gross machen
1016 // (Introspection ist mit LowerCase implementiert, also anders machen)
1017 OUString aUpperUStr
= aPropName
.toAsciiUpperCase();
1018 OUString aExactName
= xExactName
->getExactName( aUpperUStr
);
1019 if( aExactName
!= aPropName
)
1021 aErrorStr
= "Property \"";
1022 aErrorStr
+= OUStringToOString( aPropName
, RTL_TEXTENCODING_ASCII_US
);
1023 aErrorStr
+= "\", not found as \"";
1024 aErrorStr
+= OUStringToOString(aUpperUStr
, RTL_TEXTENCODING_ASCII_US
);
1025 aErrorStr
+= "\" using XExactName";
1026 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1031 bModify
= sal_False
;
1034 // Neuen Wert setzen, wieder lesen und ausgeben
1037 // UnknownPropertyException bei ReadOnly-Properties abfangen
1040 xPropSet
->setPropertyValue( aPropName
, aNewVal
);
1042 catch(const UnknownPropertyException
&)
1046 aPropVal
= xPropSet
->getPropertyValue( aPropName
);
1048 OUString aStr
= AnyToString( aPropVal
, sal_False
, xMgr
);
1049 OString aModifiedValStr
= OUStringToOString( aStr
, RTL_TEXTENCODING_ASCII_US
);
1050 OString aDemandedModifiedValStr
= pDemandedModifiedPropVals
[ i
];
1051 aErrorStr
= "Property \"";
1052 aErrorStr
+= aDemandedName
;
1053 aErrorStr
+= "\", expected modified val >";
1054 aErrorStr
+= aDemandedModifiedValStr
;
1055 aErrorStr
+= "< found val >";
1056 aErrorStr
+= aModifiedValStr
;
1058 OSL_ENSURE( aModifiedValStr
== aDemandedModifiedValStr
, aErrorStr
.getStr() );
1061 // Checken, ob alle Properties auch einzeln gefunden werden
1062 aErrorStr
= "property \"";
1063 aErrorStr
+= aDemandedName
;
1064 aErrorStr
+= "\" not found with hasProperty()";
1065 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1066 sal_Bool bProperty
= xAccess
->hasProperty( aWDemandedName
, nConcepts
);
1067 OSL_ENSURE( bProperty
, aErrorStr
.getStr() );
1069 aErrorStr
= "property \"";
1070 aErrorStr
+= aDemandedName
;
1071 aErrorStr
+= "\" not equal to same Property in sequence returned by getProperties()";
1074 Property aGetProp
= xAccess
->getProperty( aWDemandedName
, nConcepts
);
1076 catch (const RuntimeException
&)
1078 aErrorStr
= "property \"";
1079 aErrorStr
+= aDemandedName
;
1080 aErrorStr
+= "\", exception was thrown when trying getProperty()";
1081 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1088 // Schleife ueber alle Kombinationen von Concepts
1089 for( sal_Int32 nConcepts
= 0 ; nConcepts
< 128 ; nConcepts
++ )
1091 // Das 2^6-Bit steht fuer "den Rest"
1092 sal_Int32 nRealConcepts
= nConcepts
;
1093 if( nConcepts
& 0x40 )
1094 nRealConcepts
|= (0xFFFFFFFF - 0x3F);
1096 // Wieviele Methoden sollten es sein
1097 sal_Int32 nDemandedMethCount
= 0;
1098 sal_Int32 iList
= 0;
1099 while( pMethodDefs
[ iList
].pName
)
1101 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1102 nDemandedMethCount
++;
1106 // Methoden-Array ausgeben
1107 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( nRealConcepts
);
1108 sal_Int32 nLen
= aMethodSeq
.getLength();
1110 aErrorStr
= "Expected to find ";
1111 aErrorStr
+= OString::valueOf( nDemandedMethCount
);
1112 aErrorStr
+= " methods but found ";
1113 aErrorStr
+= OString::valueOf( nLen
);
1114 OSL_ENSURE( nLen
== nDemandedMethCount
, aErrorStr
.getStr() );
1116 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
1120 for( i
= 0 ; i
< nLen
; i
++ )
1122 // Methode ansprechen
1123 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
1126 OUString aMethName
= rxMethod
->getName();
1127 OString aNameStr
= OUStringToOString(aMethName
, RTL_TEXTENCODING_ASCII_US
);
1129 // Naechste Passende Methode in der Liste suchen
1130 while( pMethodDefs
[ iList
].pName
)
1132 if( pMethodDefs
[ iList
].nConcept
& nRealConcepts
)
1136 OString aDemandedName
= pMethodDefs
[ iList
].pName
;
1139 aErrorStr
= "Expected method \"";
1140 aErrorStr
+= aDemandedName
;
1141 aErrorStr
+= "\", found \"";
1142 aErrorStr
+= aNameStr
;
1144 OSL_ENSURE( aNameStr
== aDemandedName
, aErrorStr
.getStr() );
1146 // Checken, ob alle Methoden auch einzeln gefunden werden
1147 aErrorStr
= "method \"";
1148 aErrorStr
+= aDemandedName
;
1149 aErrorStr
+= "\" not found with hasMethod()";
1150 OUString aWDemandedName
= OStringToOUString(aDemandedName
, RTL_TEXTENCODING_ASCII_US
);
1151 sal_Bool bMethod
= xAccess
->hasMethod( aWDemandedName
, nRealConcepts
);
1152 OSL_ENSURE( bMethod
, aErrorStr
.getStr() );
1154 aErrorStr
= "method \"";
1155 aErrorStr
+= aDemandedName
;
1156 aErrorStr
+= "\" not equal to same method in sequence returned by getMethods()";
1159 Reference
< XIdlMethod
> xGetMethod
= xAccess
->getMethod( aWDemandedName
, nRealConcepts
);
1160 OSL_ENSURE( xGetMethod
== rxMethod
, aErrorStr
.getStr() );
1162 catch (const RuntimeException
&)
1164 aErrorStr
= "method \"";
1165 aErrorStr
+= aDemandedName
;
1166 aErrorStr
+= "\", exception was thrown when trying getMethod()";
1167 OSL_ENSURE( sal_False
, aErrorStr
.getStr() );
1172 // Listener-Klassen ausgeben
1173 Sequence
< Type
> aClassSeq
= xAccess
->getSupportedListeners();
1174 sal_Int32 nLen
= aClassSeq
.getLength();
1176 const Type
* pListeners
= aClassSeq
.getConstArray();
1177 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1179 // Methode ansprechen
1180 const Type
& aListenerType
= pListeners
[i
];
1183 OUString aListenerClassName
= aListenerType
.getTypeName();
1190 SAL_IMPLEMENT_MAIN()
1192 Reference
< XMultiServiceFactory
> xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) );
1194 sal_Bool bSucc
= sal_False
;
1197 Reference
< XImplementationRegistration
> xImplReg(
1198 xMgr
->createInstance( OUString("com.sun.star.registry.ImplementationRegistration") ), UNO_QUERY
);
1199 OSL_ENSURE( xImplReg
.is(), "### no impl reg!" );
1201 // Register services
1202 OUString
libName( "reflection.uno" SAL_DLLEXTENSION
);
1203 fprintf(stderr
, "1\n" );
1204 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1205 libName
, Reference
< XSimpleRegistry
>() );
1206 fprintf(stderr
, "2\n" );
1207 Reference
< XIdlReflection
> xRefl( xMgr
->createInstance( OUString("com.sun.star.reflection.CoreReflection") ), UNO_QUERY
);
1208 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1212 "introspection.uno" SAL_DLLEXTENSION
);
1213 fprintf(stderr
, "3\n" );
1214 xImplReg
->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"),
1215 libName
, Reference
< XSimpleRegistry
>() );
1216 fprintf(stderr
, "4\n" );
1217 Reference
< XIntrospection
> xIntrosp( xMgr
->createInstance( OUString("com.sun.star.beans.Introspection") ), UNO_QUERY
);
1218 OSL_ENSURE( xRefl
.is(), "### no corereflection!" );
1220 fprintf(stderr
, "before test_introsp\n" );
1221 bSucc
= test_introsp( xMgr
, xRefl
, xIntrosp
);
1222 fprintf(stderr
, "after test_introsp\n" );
1224 catch (const Exception
& rExc
)
1226 OSL_FAIL( "### exception occurred!" );
1227 OString
aMsg( OUStringToOString( rExc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
1228 OSL_TRACE( "### exception occurred: " );
1229 OSL_TRACE( "%s", aMsg
.getStr() );
1233 Reference
< XComponent
>( xMgr
, UNO_QUERY
)->dispose();
1235 printf( "testintrosp %s !\n", (bSucc
? "succeeded" : "failed") );
1236 return (bSucc
? 0 : -1);
1239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */