OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Reflection Helper in C++

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets
View previous topic :: View next topic  
Author Message
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Wed Dec 22, 2004 6:42 am    Post subject: Reflection Helper in C++ Reply with quote

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
View user's profile Send private message Visit poster's website
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Wed Dec 22, 2004 7:07 am    Post subject: Reply with quote

The first use of this helper is given here :
Calling XRay from C++http://www.oooforum.org/forum/viewtopic.php?t=13751
This example only shows we need other helpers to simplify again the code. I will write them later.
_________________
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
Back to top
View user's profile Send private message Visit poster's website
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Fri Dec 24, 2004 5:14 am    Post subject: Reply with quote

An other use of the helper entitled "Three helpers use" again in the thread :

Calling XRay from C++http://www.oooforum.org/forum/viewtopic.php?t=13751
_________________
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
Back to top
View user's profile Send private message Visit poster's website
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Sat Jun 11, 2005 8:37 am    Post subject: Reply with quote

An other example is added in my document : how to print out the results of a reflection in a Dialog like this :

It's an other Reflection helper.
_________________
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
Back to top
View user's profile Send private message Visit poster's website
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Wed Jul 27, 2005 7:30 am    Post subject: Reply with quote

An other simpler way to use an inspector with C++ is to use the Java demo Inspector component. See
Using Inspector from OOoBasic/C++ http://www.oooforum.org/forum/viewtopic.phtml?t=22254
Here is the result :

_________________
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
Back to top
View user's profile Send private message Visit poster's website
SergeM
Super User
Super User


Joined: 09 Sep 2003
Posts: 3211
Location: Troyes France

PostPosted: Wed Jul 26, 2006 10:44 am    Post subject: Reply with quote

See also
http://wiki.services.openoffice.org/wiki/Constructing_Helpers#Reflection_Helper
_________________
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
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group