| View previous topic :: View next topic |
| Author |
Message |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
Posted: Wed Dec 22, 2004 6:42 am Post subject: Reflection Helper in C++ |
|
|
I give in this post nothing very new. Almost all what is in this post is already presented in
Some Introspection techniques (various languages) http://www.oooforum.org/forum/viewtopic.php?t=7068
and also in Calling XRay from C++ [url] http://www.oooforum.org/forum/viewtopic.php?t=13751[/url]
What is new is the programming style. I stop here with my C-like style and give my first C++ class style.
From now on, I will entitle my post "helper" when it's a class. This is frequently encountered in SDK Java examples.
My first helper is an help on Reflection information. The better tools doing that are Bernard Marcelly's XRay (in OOoBasic and in Delphi)
Here is the ReflectionHelper.hpp file :
| Code: |
// Serge Moutou
#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/XIntrospection.hpp>
#include <com/sun/star/beans/XIntrospectionAccess.hpp>
#include <com/sun/star/lang/XTypeProvider.hpp>
#include <com/sun/star/beans/MethodConcept.hpp>
#include <com/sun/star/reflection/XIdlMethod.hpp>
#include <com/sun/star/uno/Type.hxx>
#include <com/sun/star/beans/Property.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/reflection/ParamMode.hpp>
using rtl::OUString;
using namespace com::sun::star::reflection;
using namespace com::sun::star::beans;
using namespace com::sun::star::lang;
using namespace com::sun::star::uno;
class ReflectionHelper {
public:
ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM);
Sequence < OUString > getMethods(),
getTypes(),
getServices(),
getPropertiesWithoutValues(),
getPropertiesWithValues();
private:
Any toInspect;
Reference< XMultiServiceFactory > xServiceManager;
Reference< XIntrospection >xIntrospection;
Reference< XIntrospectionAccess > xIntrospec;
Reference< XTypeProvider > xTypeProvider;
OUString getValueName(Any object);
OUString getParamMode(ParamMode paramMode);
// methods
Sequence< Reference< XIdlMethod > > mMethods;
// Interfaces
Sequence< Type > types;
// Services
Reference< XServiceInfo > xServiceInfo;
// Sequence< OUString > services;
// Properties
Sequence< Property > Properties;
};
|
What is new in the code below is : the type returned by methods is printed out
| Code: |
// C++
// Serge Moutou
// 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()));
// comments because cannot use such constructed name as shapes's name
// for (sal_Int32 i=0; i<SeqByte.getLength()-1; 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()));
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;
}
|
The first include is to changed and adapt it your situation. _________________ Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide
Last edited by SergeM on Fri Dec 02, 2005 11:01 am; edited 1 time in total |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
|