XIntrospection Interface

From OpenOffice.org Wiki

Jump to: navigation, search

We prefer to use the Java Inspector method : inspect a real object. You can then find values of the properties for example. (<OpenOffice.org1.1_SDK>/examples/java/Inspector) Again we first give some of used interfaces.

// IDL
module com {  module sun {  module star {  module beans {

interface XIntrospection: com::sun::star::uno::XInterface
{ 
	com::sun::star::beans::XIntrospectionAccess inspect( [in] any aObject );
};
}; }; }; };

where we see we have to focus our attention to XIntrospectionAccess interface :

// IDL
module com {  module sun {  module star {  module beans {
interface XIntrospectionAccess: com::sun::star::uno::XInterface
{ 
	long getSuppliedMethodConcepts(); 
	long getSuppliedPropertyConcepts();
	com::sun::star::beans::Property getProperty( [in] string aName,
			 [in] long nPropertyConcepts ) 
			raises( com::sun::star::container::NoSuchElementException );
	boolean hasProperty( [in] string aName,
			 [in] long nPropertyConcepts ); 
	sequence<com::sun::star::beans::Property> getProperties(  
				[in] long nPropertyConcepts );
	com::sun::star::reflection::XIdlMethod getMethod( [in] string aName, 
			 [in] long nMethodConcepts )
			raises( com::sun::star::lang::NoSuchMethodException ); 
	boolean hasMethod( [in] string aName, 
			 [in] long nMethodConcepts );
	sequence<com::sun::star::reflection::XIdlMethod> getMethods(
			[in] long nMethodConcepts ); 
	sequence<type> getSupportedListeners(); 
	com::sun::star::uno::XInterface queryAdapter( [in] type aInterfaceType ) 
			raises( com::sun::star::beans::IllegalTypeException ); 
};
}; }; }; };

Please go on alone and have a look in the other involved IDL files.

Contents

Obtaining methods information

We present now how to construct the Reflection information with a schematic representation.

Image:XIntrospectionMethodInfo.png

The figure above explains how to get the methods information with returned type, name of method and parameters information. Please note that getParamMode is not provided by SDK but a my own code (inspired by Inspector Java code) We fist give this code :

//Listing 12 getParamMode function
// C++
// Don't forget to add : #include <com/sun/star/reflection/ParamMode.hpp>
// Don't forget to add "com.sun.star.reflection.ParamMode \" in the makefile
OUString getParamMode(ParamMode paramMode) {
// comes from <OpenOffice1.1_SDK>/examples/java/Inspector
  OUString toReturn;
  toReturn = OUString::createFromAscii("");
  if (paramMode == ParamMode_IN) toReturn = OUString::createFromAscii("IN"); else
    if (paramMode == ParamMode_OUT) toReturn = OUString::createFromAscii("OUT"); else
      if (paramMode == ParamMode_INOUT) toReturn = OUString::createFromAscii("INOUT");
  return toReturn;
}

Now the complete implementation is given : starting from Figure 1.7 it's easy to see we need two parameters, a XMultiServiceFactory and an Any :

//Listing 13 getMethods function
//C++
// translated in C++ from <OpenOffice1.1_SDK>/examples/java/Inspector
 
// Don't forget to add : using namespace com::sun::star::beans;
// Don't forget to add : #include <com/sun/star/beans/XIntrospection.hpp>
// Don't forget to add "com.sun.star.beans.XIntrospection \" in the makefile
 
Sequence <OUString> getMethods(Any any,Reference< XMultiServiceFactory > rSVM)
	Reference< XIntrospection >xIntrospection = Reference< XIntrospection >
					( rSVM->createInstance(
                                 OUString( RTL_CONSTASCII_USTRINGPARAM(
                                      "com.sun.star.beans.Introspection" ))), UNO_QUERY );
 
// ********* get all methods for the given object *********************
 
	Reference< XIntrospectionAccess > xIntrospec = xIntrospection->inspect(any);
 
// Don't forget to add : #include <com/sun/star/beans/MethodConcept.hpp>
// Don't forget to add "com.sun.star.beans.MethodConcept \" in the makefile
	Sequence< Reference < XIdlMethod > > mMethods = xIntrospec -> getMethods(MethodConcept::ALL);
	Sequence<OUString> OUStrs(mMethods.getLength());
	for (int i=0;i<mMethods.getLength();i++){
		OUString params;
		params=OUString::createFromAscii("(");
		Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();
		if (ParamInfos.getLength() > 0) {
			for (int j=0;j<ParamInfos.getLength();j++){
				Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;
				if (j == 0)
				// first parameter has no leading comma
				params += OUString::createFromAscii("[") + getParamMode(ParamInfos[j].aMode)+
				OUString::createFromAscii("]") +
				xIdlClass->getName();
				else
				params += OUString::createFromAscii(",[") + getParamMode(ParamInfos[j].aMode)+
				OUString::createFromAscii("]")+
				xIdlClass->getName();
			}
		}
		params += OUString::createFromAscii(")");
		OUStrs[i]= mMethods[i]->getName()+params;
	}
	return OUStrs;
}

Obtaining all the interfaces

Obtaining all the types (or interfaces) is a straight forwarder work as shown in the figure below :

The Listing 14 below shows among others the corresponding C++ code.

Obtaining all the services is more easier :

Again the Listing 14 below shows the corresponding C++ code.

Obtaining all the properties

To make a break, the problem of finding properties values will be discussed later. If you know Java language have a look at SDK : <OpenOffice.org1.1_SDK>/examples/java/Inspector/InstanceInspector.java and see the corresponding Java code.

The problem of properties values is given here with a C++ class below. Look for the corresponding code.

Complete Introspection Class

Before going further have a look to Constructing Helpers section. Here is the implementation code.


//Listing 14 Implementation of the reflection helper
// C++
// with help of <OpenOffice1.1_SDK>/examples/java/Inspector
// and Bernard Marcelly XRay tool
// version 0.1 (22 Dec 2004)
// To do : Exception Handling, to go further with properties values
#include "/home/smoutou/OpenOffice.org1.1_SDK/examples/DevelopersGuide/ProfUNO/CppBinding/ReflectionHelper.hpp"
#include <com/sun/star/reflection/XIdlClass.hpp>
#include <com/sun/star/beans/PropertyConcept.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
//#include <com/sun/star/reflection/ParamMode.hpp> done in ReflectionHelper.hpp
 
// constructor
ReflectionHelper::ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM)
	: toInspect(any), xServiceManager(oSVM){
	xIntrospection = Reference< XIntrospection >( xServiceManager->createInstance(
                                OUString( RTL_CONSTASCII_USTRINGPARAM(
                                "com.sun.star.beans.Introspection" ))), UNO_QUERY );
	xIntrospec = xIntrospection->inspect(toInspect);
	mMethods = xIntrospec -> getMethods(MethodConcept::ALL);
	xTypeProvider = Reference< XTypeProvider> (toInspect,UNO_QUERY);
	types = xTypeProvider->getTypes();
	xServiceInfo = Reference< XServiceInfo>(toInspect,UNO_QUERY);
	Properties = xIntrospec -> getProperties(PropertyConcept::ALL);
}
 
Sequence < OUString > ReflectionHelper::getServices() {
	return xServiceInfo->getSupportedServiceNames();
}
 
Sequence < OUString > ReflectionHelper::getMethods(){
	Sequence< OUString > methods(mMethods.getLength());
	for (int i=0;i<mMethods.getLength();i++){
		OUString params;
		params=OUString::createFromAscii("(");
		Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();
		if (ParamInfos.getLength() > 0) {
			for (int j=0;j<ParamInfos.getLength();j++){
				Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;
				if (j == 0)
				// first parameter has no leading comma
				params += OUString::createFromAscii("[") + getParamMode(ParamInfos[j].aMode)+
				OUString::createFromAscii("]") +
				xIdlClass->getName();
				else
				params += OUString::createFromAscii(",[") + getParamMode(ParamInfos[j].aMode)+
				OUString::createFromAscii("]")+
				xIdlClass->getName();
			}
		}
		params += OUString::createFromAscii(")");
		methods[i] = mMethods[i]->getReturnType()->getName()+OUString::createFromAscii(" ")+
			mMethods[i]->getName()+params;
	}
	return methods;
}
 
Sequence < OUString > ReflectionHelper::getTypes(){
	Sequence< OUString > interfaces(types.getLength());
	for (int i=0;i<types.getLength();i++){
		interfaces[i] = types[i].getTypeName();
	}
	return interfaces;
}
 
// to improve : change all the tests with getCppuType : probably quicker than a string test
OUString ReflectionHelper::getValueName(Any object){
	OUString OUStr;
	OUStr = OUString::createFromAscii("!! No computed value !!");
	if (object.hasValue()) {
		if (object.isExtractableTo(getCppuBooleanType())){
			sal_Bool MyBool;
			object >>= MyBool;
			return OUStr.valueOf((sal_Bool) MyBool);
		} else
		if (object.getValueTypeName() == OUString::createFromAscii("string")) {
			OUString *MyOUStr;
			MyOUStr = (OUString *) object.getValue();
			OUStr = OUString::createFromAscii("\"");
			return OUStr + *MyOUStr + OUString::createFromAscii("\"");
		} else
		if (object.getValueTypeName() == OUString::createFromAscii("long")) {
			sal_Int32 *MyLong;
			MyLong = (sal_Int32*) object.getValue();
			return OUStr.valueOf((sal_Int32) *MyLong);
		} else
		if (object.getValueTypeName() == OUString::createFromAscii("short")) {
			sal_Int16 *MyShort;
			MyShort = (sal_Int16*) object.getValue();
			return OUStr.valueOf((sal_Int32) *MyShort);
		} else
		if (object.getValueTypeName() == OUString::createFromAscii("[]byte")) {
			Sequence< sal_Int8 > SeqByte;
			object >>= SeqByte;
			OUStr = OUString::createFromAscii("Length:");
			OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqByte.getLength()));
			for (sal_Int32 i=0; i<SeqByte.getLength(); i++){
				OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqByte[i]));
				OUStr=OUStr.concat(OUString::createFromAscii(" "));
			}
			return OUStr;
		} else
		if (object.getValueTypeName() == OUString::createFromAscii("[]string")) {
			Sequence< OUString > SeqOUStr;
			object >>= SeqOUStr;
			OUStr = OUString::createFromAscii("Length:");
			OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqOUStr.getLength())+
			OUString::createFromAscii(" : "));
			for (sal_Int32 i=0; i<SeqOUStr.getLength(); i++){
				OUStr=OUStr.concat(OUString::createFromAscii("\"")
				                   +SeqOUStr[i]
						   			+ OUString::createFromAscii("\""));
			}
           return OUStr;
		} else return OUStr;
	} else return OUStr;
}
 
// Get properties with values : only those computed in getValueName
Sequence < OUString > ReflectionHelper::getPropertiesWithValues(){
	Sequence< OUString > propWithVal(Properties.getLength());
	for (int i=0;i<Properties.getLength();i++){
		Type typ =  getCppuType( (const Reference< XPropertySet > *)0);
		Reference< XPropertySet > rPropertySet(xIntrospec->queryAdapter(typ),UNO_QUERY);
		Reference< XPropertySetInfo > rPropertySetInfo=rPropertySet->getPropertySetInfo();
		Any object;		if (rPropertySetInfo->hasPropertyByName(Properties[i].Name)){
			object <<= rPropertySet->getPropertyValue(Properties[i].Name);
			//if (object.hasValue()) printf("Valeur trouvee : \n");
			propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+
				Properties[i].Type.getTypeName() + OUString::createFromAscii(") ")
				+ getValueName(object);
		}
	}
	return propWithVal;
}
 
// Get properties without values but types
Sequence < OUString > ReflectionHelper::getPropertiesWithoutValues(){
	Sequence< OUString > propWithVal(Properties.getLength());
	for (int i=0;i<Properties.getLength();i++){
		Type typ =  getCppuType( (const Reference< XPropertySet > *)0);
		Reference< XPropertySet > xPropertySet(xIntrospec->queryAdapter(typ),UNO_QUERY);
		Reference< XPropertySetInfo > xPropertySetInfo=xPropertySet->getPropertySetInfo();
		if (xPropertySetInfo->hasPropertyByName(Properties[i].Name)){
			propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+
				Properties[i].Type.getTypeName() + OUString::createFromAscii(")");
		}
	}
	return propWithVal;
}
 
// Don't forget to add : #include <com/sun/star/reflection/ParamMode.hpp>
// Don't forget to add "com.sun.star.reflection.ParamMode \" in the makefile
OUString ReflectionHelper::getParamMode(ParamMode paramMode) {
  OUString toReturn;
  toReturn = OUString::createFromAscii("");
  if (paramMode == ParamMode_IN) toReturn = OUString::createFromAscii("IN"); else
    if (paramMode == ParamMode_OUT) toReturn = OUString::createFromAscii("OUT"); else
      if (paramMode == ParamMode_INOUT) toReturn = OUString::createFromAscii("INOUT");
  return toReturn;
}

This is quite a lot of code. Let's give a schematic representation (added with other in this article).

== Shematic Representation of properties

Obtaining properties with values is a difficult task. I hope the Figure below will help you to understand the code. Image:PropertiesIntrospection.png

This code use getValueName for the moment because of the difficulties I encounter to resolve the problem of printing out the values of properties. I think I don't use the better way to solve it : that problem should be better resolved with improving the use of getCppuType or seeing an other way with Any type.

Go back to IDL Files and C++

See also


Personal tools