diff options
Diffstat (limited to 'stoc/test/testintrosp.cxx')
-rw-r--r-- | stoc/test/testintrosp.cxx | 1202 |
1 files changed, 1202 insertions, 0 deletions
diff --git a/stoc/test/testintrosp.cxx b/stoc/test/testintrosp.cxx new file mode 100644 index 000000000..e33ee178e --- /dev/null +++ b/stoc/test/testintrosp.cxx @@ -0,0 +1,1202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <sal/main.h> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/servicefactory.hxx> +#include <osl/diagnose.h> + +#include <ModuleA/XIntroTest.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyConcept.hpp> +#include <com/sun/star/beans/MethodConcept.hpp> +#include <com/sun/star/beans/XExactName.hpp> +#include <com/sun/star/container/XElementAccess.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#include <stdio.h> +#include <string.h> + +using namespace cppu; +using namespace ModuleA; +using namespace css::uno; +using namespace css::lang; +using namespace css::beans; +using namespace css::registry; +using namespace css::reflection; +using namespace css::container; +using namespace css::beans::PropertyAttribute; + + +#define DEFAULT_INDEX_ACCESS_COUNT 10 +#define DEFAULT_NAME_ACCESS_COUNT 5 + +// Auxiliary function, in order to get from one type XIdlClass +Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr ) +{ + static Reference< XIdlReflection > xRefl; + + // register void as default class + Reference<XIdlClass> xRetClass; + typelib_TypeDescription * pTD = 0; + rType.getDescription( &pTD ); + if( pTD ) + { + OUString sOWName( pTD->pTypeName ); + if( !xRefl.is() ) + { + xRefl.set( xMgr->createInstance( "com.sun.star.reflection.CoreReflection" ), UNO_QUERY ); + OSL_ENSURE( xRefl.is(), "### no corereflection!" ); + } + xRetClass = xRefl->forName( sOWName ); + } + return xRetClass; +} + + +// Helper function to convert Any to UString +// TODO: This code could be moved to a more central place. +// Currently it's used only for simple data types. + +OUString AnyToString( const Any& aValue, sal_Bool bIncludeType, const Reference< XMultiServiceFactory > & xMgr ) +{ + Type aValType = aValue.getValueType(); + TypeClass eType = aValType.getTypeClass(); + char pBuffer[50]; + + OUString aRetStr; + switch( eType ) + { + case TypeClass_TYPE: aRetStr = "TYPE TYPE"; break; + case TypeClass_INTERFACE: aRetStr = "TYPE INTERFACE"; break; + case TypeClass_SERVICE: aRetStr = "TYPE SERVICE"; break; + case TypeClass_STRUCT: aRetStr = "TYPE STRUCT"; break; + case TypeClass_TYPEDEF: aRetStr = "TYPE TYPEDEF"; break; + case TypeClass_ENUM: aRetStr = "TYPE ENUM"; break; + case TypeClass_EXCEPTION: aRetStr = "TYPE EXCEPTION"; break; + case TypeClass_SEQUENCE: aRetStr = "TYPE SEQUENCE"; break; + case TypeClass_VOID: aRetStr = "TYPE void"; break; + case TypeClass_ANY: aRetStr = "TYPE any"; break; + case TypeClass_UNKNOWN: aRetStr = "TYPE unknown"; break; + case TypeClass_BOOLEAN: + { + sal_Bool b = *(sal_Bool*)aValue.getValue(); + aRetStr = OUString::valueOf( b ); + break; + } + case TypeClass_CHAR: + { + sal_Unicode c = *(sal_Unicode*)aValue.getValue(); + aRetStr = OUString::valueOf( c ); + break; + } + case TypeClass_STRING: + { + aValue >>= aRetStr; + break; + } + case TypeClass_FLOAT: + { + float f(0.0); + aValue >>= f; + snprintf( pBuffer, sizeof( pBuffer ), "%f", f ); + aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US ); + break; + } + case TypeClass_DOUBLE: + { + double d(0.0); + aValue >>= d; + snprintf( pBuffer, sizeof( pBuffer ), "%f", d ); + aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US ); + break; + } + case TypeClass_BYTE: + { + sal_Int8 n(0); + aValue >>= n; + aRetStr = OUString::valueOf( (sal_Int32) n ); + break; + } + case TypeClass_SHORT: + { + sal_Int16 n(0); + aValue >>= n; + aRetStr = OUString::valueOf( (sal_Int32) n ); + break; + } + case TypeClass_LONG: + { + sal_Int32 n(0); + aValue >>= n; + aRetStr = OUString::valueOf( n ); + break; + } + default: ; + } + + if( bIncludeType ) + { + Reference< XIdlClass > xIdlClass = TypeToIdlClass( aValType, xMgr ); + aRetStr += " (Typ: " + xIdlClass->getName() + ")"; + } + return aRetStr; +} + +// XPropertySetInfo for test class + +class ImplPropertySetInfo : public WeakImplHelper< XPropertySetInfo > +{ + friend class ImplIntroTest; + + Reference< XMultiServiceFactory > mxMgr; + +public: + explicit ImplPropertySetInfo( const Reference< XMultiServiceFactory > & xMgr ) + : mxMgr( xMgr ) {} + + // Methods of XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties( ) + throw(RuntimeException); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) + throw(UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) + throw(RuntimeException); +}; + + +Sequence< Property > ImplPropertySetInfo::getProperties() + throw( RuntimeException ) +{ + static Sequence<Property> * pSeq = NULL; + + if( !pSeq ) + { + // Create information for the properties "Width", "Height" and "Name" + pSeq = new Sequence<Property>( 3 ); + Property * pAry = pSeq->getArray(); + + pAry[0].Name = "Factor"; + pAry[0].Handle = -1; + pAry[0].Type = cppu::UnoType<double>::get(); + pAry[0].Attributes = BOUND | TRANSIENT; + + pAry[1].Name = "MyCount"; + pAry[1].Handle = -1; + pAry[1].Type = cppu::UnoType<sal_Int32>::get(); + pAry[1].Attributes = BOUND | TRANSIENT; + + pAry[2].Name = "Info"; + pAry[2].Handle = -1; + pAry[2].Type = cppu::UnoType<OUString>::get(); + pAry[2].Attributes = TRANSIENT; + } + // Return information about all three properties + return *pSeq; +} + +Property ImplPropertySetInfo::getPropertyByName(const OUString& Name) + throw( UnknownPropertyException, RuntimeException ) +{ + Sequence<Property> aSeq = getProperties(); + const Property * pAry = aSeq.getConstArray(); + + for( sal_Int32 i = aSeq.getLength(); i--; ) + { + if( pAry[i].Name == Name ) + return pAry[i]; + } + // Property unknown, also return empty ones + return Property(); +} + +sal_Bool ImplPropertySetInfo::hasPropertyByName(const OUString& Name) + throw( RuntimeException ) +{ + Sequence<Property> aSeq = getProperties(); + const Property * pAry = aSeq.getConstArray(); + + for( sal_Int32 i = aSeq.getLength(); i--; ) + { + if( pAry[i].Name == Name ) + return sal_True; + } + // Property unknown, also return empty ones + return sal_False; +} + + +class ImplIntroTest : public WeakImplHelper< XIntroTest, XPropertySet, XNameAccess, XIndexAccess > +{ + Reference< XMultiServiceFactory > mxMgr; + + friend class ImplPropertySetInfo; + + // Properties for the PropertySet + Any aAnyArray[10]; + + Reference< XPropertySetInfo > m_xMyInfo; + + OUString m_ObjectName; + + sal_Int16 m_nMarkusAge; + sal_Int16 m_nMarkusChildrenCount; + + long m_lDroenk; + sal_Int16 m_nBla; + sal_Int16 m_nBlub; + sal_Int16 m_nGulp; + sal_Int16 m_nLaber; + TypeClass eTypeClass; + Sequence< OUString > aStringSeq; + Sequence< Sequence< Sequence< sal_Int16 > > > aMultSeq; + Reference< XIntroTest > m_xIntroTest; + + // Data for NameAccess + Reference< XIntroTest >* pNameAccessTab; + + // Data for IndexAccess + Reference< XIntroTest >* pIndexAccessTab; + sal_Int16 iIndexAccessCount; + + // struct properties + Property m_aFirstStruct; + PropertyValue m_aSecondStruct; + + // remember listener (one listener per property) + Reference< XPropertyChangeListener > aPropChangeListener; + OUString aPropChangeListenerStr; + Reference< XVetoableChangeListener > aVetoPropChangeListener; + OUString aVetoPropChangeListenerStr; + + void Init(); + +public: + explicit ImplIntroTest( const Reference< XMultiServiceFactory > & xMgr ) + : mxMgr( xMgr ) + { + Init(); + } + + // despite virtual inline, to simplify coding (testing only) + // XPropertySet + virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw(RuntimeException); + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException); + virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + + // XIntroTest methods + // Attributes + virtual OUString SAL_CALL getObjectName() throw(RuntimeException) + { return m_ObjectName; } + virtual void SAL_CALL setObjectName( const OUString& _objectname ) throw(RuntimeException) + { m_ObjectName = _objectname; } + virtual OUString SAL_CALL getFirstName() + throw(RuntimeException); + virtual OUString SAL_CALL getLastName() throw(RuntimeException) + { return OUString("Meyer"); } + virtual sal_Int16 SAL_CALL getAge() throw(RuntimeException) + { return m_nMarkusAge; } + virtual sal_Int16 SAL_CALL getChildrenCount() throw(RuntimeException) + { return m_nMarkusChildrenCount; } + virtual void SAL_CALL setChildrenCount( sal_Int16 _childrencount ) throw(RuntimeException) + { m_nMarkusChildrenCount = _childrencount; } + virtual Property SAL_CALL getFirstStruct() throw(RuntimeException) + { return m_aFirstStruct; } + virtual void SAL_CALL setFirstStruct( const Property& _firststruct ) throw(RuntimeException) + { m_aFirstStruct = _firststruct; } + virtual PropertyValue SAL_CALL getSecondStruct() throw(RuntimeException) + { return m_aSecondStruct; } + virtual void SAL_CALL setSecondStruct( const PropertyValue& _secondstruct ) throw(RuntimeException) + { m_aSecondStruct = _secondstruct; } + + // Methods + virtual void SAL_CALL writeln( const OUString& Text ) + throw(RuntimeException); + virtual sal_Int32 SAL_CALL getDroenk( ) throw(RuntimeException) + { return m_lDroenk; } + virtual Reference< ::ModuleA::XIntroTest > SAL_CALL getIntroTest( ) throw(RuntimeException); + virtual sal_Int32 SAL_CALL getUps( sal_Int32 l ) throw(RuntimeException) + { return 2*l; } + virtual void SAL_CALL setDroenk( sal_Int32 l ) throw(RuntimeException) + { m_lDroenk = l; } + virtual sal_Int16 SAL_CALL getBla( ) throw(RuntimeException) + { return m_nBla; } + virtual void SAL_CALL setBla( sal_Int32 n ) throw(RuntimeException) + { m_nBla = (sal_Int16)n; } + virtual sal_Int16 SAL_CALL getBlub( ) throw(RuntimeException) + { return m_nBlub; } + virtual void SAL_CALL setBlub( sal_Int16 n ) throw(RuntimeException) + { m_nBlub = n; } + virtual sal_Int16 SAL_CALL getGulp( ) throw(RuntimeException) + { return m_nGulp; } + virtual sal_Int16 SAL_CALL setGulp( sal_Int16 n ) throw(RuntimeException) + { m_nGulp = n; return 1; } + virtual TypeClass SAL_CALL getTypeClass( sal_Int16 /*n*/ ) throw(RuntimeException) + { return eTypeClass; } + virtual void SAL_CALL setTypeClass( TypeClass t, double /*d1*/, double /*d2*/ ) throw(RuntimeException) + { eTypeClass = t; } + virtual Sequence< OUString > SAL_CALL getStrings( ) throw(RuntimeException) + { return aStringSeq; } + virtual void SAL_CALL setStrings( const Sequence< OUString >& Strings ) throw(RuntimeException) + { aStringSeq = Strings; } + virtual void SAL_CALL setStringsPerMethod( const Sequence< OUString >& Strings, sal_Int16 /*n*/ ) throw(RuntimeException) + { aStringSeq = Strings; } + virtual Sequence< Sequence< Sequence< sal_Int16 > > > SAL_CALL getMultiSequence( ) throw(RuntimeException) + { return aMultSeq; } + virtual void SAL_CALL setMultiSequence( const Sequence< Sequence< Sequence< sal_Int16 > > >& Seq ) throw(RuntimeException) + { aMultSeq = Seq; } + virtual void SAL_CALL addPropertiesChangeListener( const Sequence< OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException); + virtual void SAL_CALL removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException); + + + // Methods of XElementAccess + virtual Type SAL_CALL getElementType( ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) + throw(RuntimeException); + + // XNameAccess methods + // Methods + virtual Any SAL_CALL getByName( const OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getElementNames( ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) + throw(RuntimeException); + + // XIndexAccess methods + // Methods + virtual sal_Int32 SAL_CALL getCount( ) + throw(RuntimeException); + virtual Any SAL_CALL getByIndex( sal_Int32 Index ) + throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException); +}; + +void ImplIntroTest::Init() +{ + // set unique name + static sal_Int32 nObjCount = 0; + OUString aName( "IntroTest-Obj Nr. " ); + aName += OUString::valueOf( nObjCount ); + setObjectName( aName ); + + // initialize properties + aAnyArray[0] <<= 3.14; + aAnyArray[1] <<= (sal_Int32)42; + aAnyArray[2] <<= OUString( "Hallo" ); + + // fetch PropertySetInfo once for internal use + m_xMyInfo = getPropertySetInfo(); + m_xMyInfo->acquire(); // otherwise it could crash at shutdown + + m_nMarkusAge = 33; + m_nMarkusChildrenCount = 2; + + m_lDroenk = 314; + m_nBla = 42; + m_nBlub = 111; + m_nGulp = 99; + m_nLaber = 1; + eTypeClass = TypeClass_INTERFACE; + + // string sequence initialization + aStringSeq.realloc( 3 ); + aStringSeq[ 0 ] = "String 0"; + aStringSeq[ 1 ] = "String 1"; + aStringSeq[ 2 ] = "String 2"; + + // structs initialization + m_aFirstStruct.Name = "FirstStruct-Name"; + m_aFirstStruct.Handle = 77777; + //XIdlClassRef Type; + m_aFirstStruct.Attributes = -222; + + //XInterfaceRef Source; + Any Value; + Value <<= 2.718281828459; + m_aSecondStruct.Value = Value; + //XIdlClassRef ListenerType; + m_aSecondStruct.State = PropertyState_DIRECT_VALUE; + + // IndexAccess + iIndexAccessCount = DEFAULT_INDEX_ACCESS_COUNT; + pIndexAccessTab = NULL; + pNameAccessTab = NULL; +} + +Reference< XPropertySetInfo > ImplIntroTest::getPropertySetInfo() + throw(RuntimeException) +{ + static ImplPropertySetInfo aInfo( mxMgr ); + // All objects have the same Properties, so + // the Info is the same for all + return &aInfo; +} + +void ImplIntroTest::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + if( aPropChangeListener.is() && aPropertyName == aPropChangeListenerStr ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aPropertyName; + aEvt.PropertyHandle = 0; + aPropChangeListener->propertyChange( aEvt ); + } + if( aVetoPropChangeListener.is() && aPropertyName == aVetoPropChangeListenerStr ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aVetoPropChangeListenerStr; + aEvt.PropertyHandle = 0; + aVetoPropChangeListener->vetoableChange( aEvt ); + } + + Sequence<Property> aPropSeq = m_xMyInfo->getProperties(); + sal_Int32 nLen = aPropSeq.getLength(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + Property aProp = aPropSeq.getArray()[ i ]; + if( aProp.Name == aPropertyName ) + aAnyArray[i] = aValue; + } +} + +Any ImplIntroTest::getPropertyValue( const OUString& PropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + Sequence<Property> aPropSeq = m_xMyInfo->getProperties(); + sal_Int32 nLen = aPropSeq.getLength(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + Property aProp = aPropSeq.getArray()[ i ]; + if( aProp.Name == PropertyName ) + return aAnyArray[i]; + } + return Any(); +} + +OUString ImplIntroTest::getFirstName() + throw(RuntimeException) +{ + return OUString("Markus"); +} + +void ImplIntroTest::writeln( const OUString& Text ) + throw(RuntimeException) +{ + OString aStr( Text.getStr(), Text.getLength(), RTL_TEXTENCODING_ASCII_US ); + + printf( "%s", aStr.getStr() ); +} + +Reference< XIntroTest > ImplIntroTest::getIntroTest() + throw(RuntimeException) +{ + if( !m_xIntroTest.is() ) + m_xIntroTest = new ImplIntroTest( mxMgr ); + return m_xIntroTest; +} + +// Methods of XElementAccess +Type ImplIntroTest::getElementType( ) + throw(RuntimeException) +{ + // TODO + Type aRetType; + return aRetType; +} + +sal_Bool ImplIntroTest::hasElements( ) + throw(RuntimeException) +{ + return sal_True; +} + +// XNameAccess methods +sal_Int32 getIndexForName( const OUString& ItemName ) +{ + OUString aLeftStr = ItemName.copy( 0, 4 ); + if( aLeftStr == "Item" ) + { + // TODO + OUString aNumStr = ItemName.copy( 4 ); + } + return -1; +} + + +Any ImplIntroTest::getByName( const OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException) +{ + Any aRetAny; + + if( !pNameAccessTab ) + pNameAccessTab = new Reference< XIntroTest >[ DEFAULT_NAME_ACCESS_COUNT ]; + + sal_Int32 iIndex = getIndexForName( aName ); + if( iIndex != -1 ) + { + if( !pNameAccessTab[iIndex].is() ) + { + ImplIntroTest* p = new ImplIntroTest( mxMgr ); + OUString aName2( "IntroTest by Name-Access, Index = " ); + aName2 += OUString::valueOf( iIndex ); + p->setObjectName( aName2 ); + pNameAccessTab[iIndex] = p; + } + + Reference< XIntroTest > xRet = pNameAccessTab[iIndex]; + aRetAny = makeAny( xRet ); + } + return aRetAny; +} + +Sequence< OUString > ImplIntroTest::getElementNames( ) + throw(RuntimeException) +{ + Sequence<OUString> aStrSeq( DEFAULT_NAME_ACCESS_COUNT ); + OUString* pStr = aStrSeq.getArray(); + for( sal_Int32 i = 0 ; i < DEFAULT_NAME_ACCESS_COUNT ; i++ ) + { + OUString aName( "Item" ); + aName += OUString::valueOf( i ); + pStr[i] = aName; + } + return aStrSeq; +} + +sal_Bool ImplIntroTest::hasByName( const OUString& aName ) + throw(RuntimeException) +{ + return ( getIndexForName( aName ) != -1 ); +} + +// XIndexAccess methods +sal_Int32 ImplIntroTest::getCount( ) + throw(RuntimeException) +{ + return iIndexAccessCount; +} + +Any ImplIntroTest::getByIndex( sal_Int32 Index ) + throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + Any aRetAny; + + if( !pIndexAccessTab ) + pIndexAccessTab = new Reference< XIntroTest >[ iIndexAccessCount ]; + + if( Index < iIndexAccessCount ) + { + if( !pNameAccessTab[Index].is() ) + { + ImplIntroTest* p = new ImplIntroTest( mxMgr ); + OUString aName( "IntroTest by Index-Access, Index = " ); + aName += OUString::valueOf( Index ); + p->setObjectName( aName ); + pIndexAccessTab[Index] = p; + } + Reference< XIntroTest > xRet = pIndexAccessTab[Index]; + aRetAny = makeAny( xRet ); + } + return aRetAny; +} + +void ImplIntroTest::addPropertiesChangeListener( const Sequence< OUString >& /*PropertyNames*/, + const Reference< XPropertiesChangeListener >& /*Listener*/ ) + throw(RuntimeException) +{ +} + +void ImplIntroTest::removePropertiesChangeListener +( const Reference< XPropertiesChangeListener >& /*Listener*/ ) + throw(RuntimeException) +{ +} + + +struct DefItem +{ + char const * pName; + sal_Int32 nConcept; +}; + +// special value for method concept, to mark "normal" functions +#define MethodConcept_NORMAL_IMPL 0x80000000 + + +// return test object +Any getIntrospectionTestObject( const Reference< XMultiServiceFactory > & xMgr ) +{ + Any aObjAny; + Reference< XIntroTest > xTestObj = new ImplIntroTest( xMgr ); + aObjAny.setValue( &xTestObj, cppu::UnoType<XIntroTest>::get()); + return aObjAny; +} + +static sal_Bool test_introsp( Reference< XMultiServiceFactory > xMgr, + Reference< XIdlReflection > /*xRefl*/, Reference< XIntrospection > xIntrospection ) +{ + DefItem pPropertyDefs[] = + { + { "Factor", PropertyConcept::PROPERTYSET }, + { "MyCount", PropertyConcept::PROPERTYSET }, + { "Info", PropertyConcept::PROPERTYSET }, + { "ObjectName", PropertyConcept::ATTRIBUTES }, + { "FirstName", PropertyConcept::ATTRIBUTES }, + { "LastName", PropertyConcept::ATTRIBUTES }, + { "Age", PropertyConcept::ATTRIBUTES }, + { "ChildrenCount", PropertyConcept::ATTRIBUTES }, + { "FirstStruct", PropertyConcept::ATTRIBUTES }, + { "SecondStruct", PropertyConcept::ATTRIBUTES }, + { "Droenk", PropertyConcept::METHODS }, + { "IntroTest", PropertyConcept::METHODS }, + { "Bla", PropertyConcept::METHODS }, + { "Blub", PropertyConcept::METHODS }, + { "Gulp", PropertyConcept::METHODS }, + { "Strings", PropertyConcept::METHODS }, + { "MultiSequence", PropertyConcept::METHODS }, + { "PropertySetInfo", PropertyConcept::METHODS }, + { "ElementType", PropertyConcept::METHODS }, + { "ElementNames", PropertyConcept::METHODS }, + { "Count", PropertyConcept::METHODS }, + { "Types", PropertyConcept::METHODS }, + { "ImplementationId", PropertyConcept::METHODS }, + { NULL, 0 } + }; + + char const * pDemandedPropVals[] = + { + "3.140000", + "42", + "Hallo", + "IntroTest-Obj Nr. 0", + "Markus", + "Meyer", + "33", + "2", + "TYPE STRUCT", + "TYPE STRUCT", + "314", + "TYPE INTERFACE", + "42", + "111", + "99", + "TYPE SEQUENCE", + "TYPE SEQUENCE", + "TYPE INTERFACE", + "TYPE TYPE", + "TYPE SEQUENCE", + "10", + "TYPE SEQUENCE", + "TYPE SEQUENCE", + }; + + char const * pDemandedModifiedPropVals[] = + { + "4.140000", + "43", + "Hallo (Modified!)", + "IntroTest-Obj Nr. 0 (Modified!)", + "Markus", + "Meyer", + "33", + "3", + "Value has not been modified", + "Value has not been modified", + "315", + "Value has not been modified", + "42", + "112", + "99", + "Value has not been modified", + "Value has not been modified", + "Value has not been modified", + "Value has not been modified", + "Value has not been modified", + "10", + "Value has not been modified", + "Value has not been modified", + }; + + char const * pDemandedPropTypes[] = + { + "double", + "long", + "string", + "string", + "string", + "string", + "short", + "short", + "com.sun.star.beans.Property", + "com.sun.star.beans.PropertyValue", + "long", + "ModuleA.XIntroTest", + "short", + "short", + "short", + "[]string", + "[][][]short", + "com.sun.star.beans.XPropertySetInfo", + "type", + "[]string", + "long", + "[]type", + "[]byte", + }; + + DefItem pMethodDefs[] = + { + { "queryInterface", MethodConcept_NORMAL_IMPL }, + { "acquire", MethodConcept::DANGEROUS }, + { "release", MethodConcept::DANGEROUS }, + { "writeln", MethodConcept_NORMAL_IMPL }, + { "getDroenk", MethodConcept::PROPERTY }, + { "getIntroTest", MethodConcept::PROPERTY }, + { "getUps", MethodConcept_NORMAL_IMPL }, + { "setDroenk", MethodConcept::PROPERTY }, + { "getBla", MethodConcept::PROPERTY }, + { "setBla", MethodConcept_NORMAL_IMPL }, + { "getBlub", MethodConcept::PROPERTY }, + { "setBlub", MethodConcept::PROPERTY }, + { "getGulp", MethodConcept::PROPERTY }, + { "setGulp", MethodConcept_NORMAL_IMPL }, + { "getTypeClass", MethodConcept_NORMAL_IMPL }, + { "setTypeClass", MethodConcept_NORMAL_IMPL }, + { "getStrings", MethodConcept::PROPERTY }, + { "setStrings", MethodConcept::PROPERTY }, + { "setStringsPerMethod", MethodConcept_NORMAL_IMPL }, + { "getMultiSequence", MethodConcept::PROPERTY }, + { "setMultiSequence", MethodConcept::PROPERTY }, + { "addPropertiesChangeListener", MethodConcept::LISTENER }, + { "removePropertiesChangeListener", MethodConcept::LISTENER }, + { "getPropertySetInfo", MethodConcept::PROPERTY }, + { "setPropertyValue", MethodConcept_NORMAL_IMPL }, + { "getPropertyValue", MethodConcept_NORMAL_IMPL }, + { "addPropertyChangeListener", MethodConcept::LISTENER }, + { "removePropertyChangeListener", MethodConcept::LISTENER }, + { "addVetoableChangeListener", MethodConcept::LISTENER }, + { "removeVetoableChangeListener", MethodConcept::LISTENER }, + { "getElementType", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER| MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION }, + { "hasElements", MethodConcept::NAMECONTAINER | MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION }, + { "getByName", MethodConcept::NAMECONTAINER }, + { "getElementNames", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER }, + { "hasByName", MethodConcept::NAMECONTAINER }, + { "getCount", MethodConcept::PROPERTY | MethodConcept::INDEXCONTAINER }, + { "getByIndex", MethodConcept::INDEXCONTAINER }, + { "getTypes", MethodConcept::PROPERTY }, + { "getImplementationId", MethodConcept::PROPERTY }, + { "queryAdapter", MethodConcept_NORMAL_IMPL }, + { NULL, 0 } + }; + + OString aErrorStr; + + + // create test object + Any aObjAny = getIntrospectionTestObject( xMgr ); + + // inspect introspection service + xIntrospection->inspect( aObjAny ); + xIntrospection->inspect( aObjAny ); + Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny ); + OSL_ENSURE( xAccess.is(), "introspection failed, no XIntrospectionAccess returned" ); + if( !xAccess.is() ) + return sal_False; + + // check result of introspection + + // determine XPropertySet-UIK + Type aType = cppu::UnoType<XPropertySet>::get(); + + Reference< XInterface > xPropSetIface = xAccess->queryAdapter( aType ); + Reference< XPropertySet > xPropSet( xPropSetIface, UNO_QUERY ); + OSL_ENSURE( xPropSet.is(), "Could not get XPropertySet by queryAdapter()" ); + + // XExactName + Reference< XExactName > xExactName( xAccess, UNO_QUERY ); + OSL_ENSURE( xExactName.is(), "Introspection doesn't support ExactName" ); + + // loop over all concept combinations + for( sal_Int32 nConcepts = 0 ; nConcepts < 16 ; nConcepts++ ) + { + // how many properties should this be + sal_Int32 nDemandedPropCount = 0; + sal_Int32 iList = 0; + while( pPropertyDefs[ iList ].pName ) + { + if( pPropertyDefs[ iList ].nConcept & nConcepts ) + nDemandedPropCount++; + iList++; + } + + if( xPropSet.is() ) + { + Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); + Sequence<Property> aRetSeq = xAccess->getProperties( nConcepts ); + + sal_Int32 nLen = aRetSeq.getLength(); + + aErrorStr = "Expected to find " + + OString::valueOf( nDemandedPropCount ) + + " properties but found " + + OString::valueOf( nLen ); + OSL_ENSURE( nLen == nDemandedPropCount, aErrorStr.getStr() ); + + const Property* pProps = aRetSeq.getConstArray(); + Any aPropVal; + sal_Int32 i; + iList = 0; + for( i = 0 ; i < nLen ; i++ ) + { + const Property aProp = pProps[ i ]; + + // search for next suitable method in the list + while( pPropertyDefs[ iList ].pName ) + { + if( pPropertyDefs[ iList ].nConcept & nConcepts ) + break; + iList++; + } + sal_Int32 iDemanded = iList; + iList++; + + OUString aPropName = aProp.Name; + OString aNameStr( aPropName.getStr(), aPropName.getLength(), RTL_TEXTENCODING_ASCII_US ); + + OString aDemandedName = pPropertyDefs[ iDemanded ].pName; + aErrorStr = "Expected property \"" + + aDemandedName + + "\", found \"" + + aNameStr + + "\""; + OSL_ENSURE( aNameStr == aDemandedName, aErrorStr.getStr() ); + + Type aPropType = aProp.Type; + OString aTypeNameStr( OUStringToOString(aPropType.getTypeName(), RTL_TEXTENCODING_ASCII_US) ); + OString aDemandedTypeNameStr = pDemandedPropTypes[ iDemanded ]; + aErrorStr = "Property \"" + + aDemandedName + + "\", expected type >" + + aDemandedTypeNameStr + + "< found type >" + + aTypeNameStr + + "<"; + OSL_ENSURE( aTypeNameStr == aDemandedTypeNameStr, aErrorStr.getStr() ); + + // read and report value of property + aPropVal = xPropSet->getPropertyValue( aPropName ); + + OString aValStr = OUStringToOString( AnyToString( aPropVal, sal_False, xMgr ), RTL_TEXTENCODING_ASCII_US ); + OString aDemandedValStr = pDemandedPropVals[ iDemanded ]; + aErrorStr = "Property \"" + + aDemandedName + + "\", expected val >" + + aDemandedValStr + + "< found val >" + + aValStr + + "<"; + OSL_ENSURE( aValStr == aDemandedValStr, aErrorStr.getStr() ); + + // check value and modify it according to its type + TypeClass eType = aPropVal.getValueType().getTypeClass(); + Any aNewVal; + sal_Bool bModify = sal_True; + switch( eType ) + { + case TypeClass_STRING: + { + OUString aStr; + aPropVal >>= aStr; + aStr += " (Modified!)"; + aNewVal <<= aStr; + break; + } + case TypeClass_DOUBLE: + { + double d(0.0); + aPropVal >>= d; + aNewVal <<= d + 1.0; + break; + } + case TypeClass_SHORT: + { + sal_Int16 n(0); + aPropVal >>= n; + aNewVal <<= sal_Int16( n + 1 ); + break; + } + case TypeClass_LONG: + { + sal_Int32 n(0); + aPropVal >>= n; + aNewVal <<= sal_Int32( n + 1 ); + break; + } + default: + bModify = sal_False; + break; + } + + // modify only in the last iteration + if( nConcepts == 15 ) + { + // check XExactName, switch everything to upper case + // (introspection uses lower case) + OUString aUpperUStr = aPropName.toAsciiUpperCase(); + OUString aExactName = xExactName->getExactName( aUpperUStr ); + if( aExactName != aPropName ) + { + aErrorStr = "Property \"" + + OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ) + + "\", not found as \"" + + OUStringToOString(aUpperUStr, RTL_TEXTENCODING_ASCII_US ) + + "\" using XExactName"; + OSL_ENSURE( sal_False, aErrorStr.getStr() ); + } + } + else + { + bModify = sal_False; + } + + // set new value, then read and return value + if( bModify ) + { + // catch UnknownPropertyException for ReadOnly properties + try + { + xPropSet->setPropertyValue( aPropName, aNewVal ); + } + catch(const UnknownPropertyException &) + { + } + + aPropVal = xPropSet->getPropertyValue( aPropName ); + + OUString aStr = AnyToString( aPropVal, sal_False, xMgr ); + OString aModifiedValStr = OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US ); + OString aDemandedModifiedValStr = pDemandedModifiedPropVals[ i ]; + aErrorStr = "Property \"" + + aDemandedName + + "\", expected modified val >" + + aDemandedModifiedValStr + + "< found val >" + + aModifiedValStr + + "<"; + OSL_ENSURE( aModifiedValStr == aDemandedModifiedValStr, aErrorStr.getStr() ); + } + + // check whether all properties can be found individually + aErrorStr = "property \"" + + aDemandedName + + "\" not found with hasProperty()"; + OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US ); + sal_Bool bProperty = xAccess->hasProperty( aWDemandedName, nConcepts ); + OSL_ENSURE( bProperty, aErrorStr.getStr() ); + + aErrorStr = "property \"" + + aDemandedName + + "\" not equal to same Property in sequence returned by getProperties()"; + try + { + Property aGetProp = xAccess->getProperty( aWDemandedName, nConcepts ); + } + catch (const RuntimeException &) + { + aErrorStr = "property \"" + + aDemandedName + + "\", exception was thrown when trying getProperty()"; + OSL_ENSURE( sal_False, aErrorStr.getStr() ); + } + + } + } + } + + // loop over all concept combinations + for( sal_Int32 nConcepts = 0 ; nConcepts < 128 ; nConcepts++ ) + { + // The 2^6th bit stands for "the rest" + sal_Int32 nRealConcepts = nConcepts; + if( nConcepts & 0x40 ) + nRealConcepts |= (0xFFFFFFFF - 0x3F); + + // Count the number of methods there should be + sal_Int32 nDemandedMethCount = 0; + sal_Int32 iList = 0; + while( pMethodDefs[ iList ].pName ) + { + if( pMethodDefs[ iList ].nConcept & nRealConcepts ) + nDemandedMethCount++; + iList++; + } + + // Output the method array. + Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( nRealConcepts ); + sal_Int32 nLen = aMethodSeq.getLength(); + + aErrorStr = "Expected to find " + + OString::valueOf( nDemandedMethCount ) + + " methods but found " + + OString::valueOf( nLen ); + OSL_ENSURE( nLen == nDemandedMethCount, aErrorStr.getStr() ); + + const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); + sal_Int32 i; + iList = 0; + + for( i = 0 ; i < nLen ; i++ ) + { + const Reference< XIdlMethod >& rxMethod = pMethods[i]; + + OUString aMethName = rxMethod->getName(); + OString aNameStr = OUStringToOString(aMethName, RTL_TEXTENCODING_ASCII_US ); + + // locate the next matching method in the list. + while( pMethodDefs[ iList ].pName ) + { + if( pMethodDefs[ iList ].nConcept & nRealConcepts ) + break; + iList++; + } + OString aDemandedName = pMethodDefs[ iList ].pName; + iList++; + + aErrorStr = "Expected method \"" + + aDemandedName + + "\", found \"" + + aNameStr + + "\""; + OSL_ENSURE( aNameStr == aDemandedName, aErrorStr.getStr() ); + + // Check that the method is really there with hasMethod. + aErrorStr = "method \"" + + aDemandedName + + "\" not found with hasMethod()"; + OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US ); + sal_Bool bMethod = xAccess->hasMethod( aWDemandedName, nRealConcepts ); + OSL_ENSURE( bMethod, aErrorStr.getStr() ); + + aErrorStr = "method \"" + + aDemandedName + + "\" not equal to same method in sequence returned by getMethods()"; + try + { + Reference< XIdlMethod > xGetMethod = xAccess->getMethod( aWDemandedName, nRealConcepts ); + OSL_ENSURE( xGetMethod == rxMethod , aErrorStr.getStr() ); + } + catch (const RuntimeException &) + { + aErrorStr = "method \"" + + aDemandedName + + "\", exception was thrown when trying getMethod()"; + OSL_ENSURE( sal_False, aErrorStr.getStr() ); + } + } + } + + // print listener class + Sequence< Type > aClassSeq = xAccess->getSupportedListeners(); + sal_Int32 nLen = aClassSeq.getLength(); + + const Type* pListeners = aClassSeq.getConstArray(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + const Type& aListenerType = pListeners[i]; + OUString aListenerClassName = aListenerType.getTypeName(); + } + + return sal_True; +} + + +SAL_IMPLEMENT_MAIN() +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) ); + + sal_Bool bSucc = sal_False; + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY ); + OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); + + // Register services + OUString libName( "reflection.uno" SAL_DLLEXTENSION ); + fprintf(stderr, "1\n" ); + xImplReg->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"), + libName, Reference< XSimpleRegistry >() ); + fprintf(stderr, "2\n" ); + Reference< XIdlReflection > xRefl( xMgr->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY ); + OSL_ENSURE( xRefl.is(), "### no corereflection!" ); + + // Introspection + libName = OUString( "introspection.uno" SAL_DLLEXTENSION); + fprintf(stderr, "3\n" ); + xImplReg->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"), + libName, Reference< XSimpleRegistry >() ); + fprintf(stderr, "4\n" ); + Reference< XIntrospection > xIntrosp( xMgr->createInstance("com.sun.star.beans.Introspection"), UNO_QUERY ); + OSL_ENSURE( xRefl.is(), "### no corereflection!" ); + + fprintf(stderr, "before test_introsp\n" ); + bSucc = test_introsp( xMgr, xRefl, xIntrosp ); + fprintf(stderr, "after test_introsp\n" ); + } + catch (const Exception & rExc) + { + DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + + printf( "testintrosp %s !\n", (bSucc ? "succeeded" : "failed") ); + return (bSucc ? 0 : -1); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |