2005/5/10

     
 

Mechanism of Metainfo

artefaktur

| Introduction | How to use | ClassLoader | Serialization | Reflection | Attributes | Mechanism |



How the Metainfo is build in to ACDK


!

The shown examples may be outdated, because meta info structures are changed.

Content of this chapter:

   The Metacompiler
   ACDK classes with Metainfo
     The ACDK classes Metainfo
     The generated information



 The Metacompiler


In the acdk_core package a metacompiler 'acdkmc' is provided.
With this commandline util the meta information of given ACDK classes will be generated.

 ACDK classes with Metainfo


ACDK classes with Metainfo are declared the following way:


// this is myapp/src/com/artefaktur/myapp/MyClass.h
#ifndef com_artefaktur_myapp_MyClass_h
#define com_artefaktur_myapp_MyClass_h
namespace com {
namespace artefaktur {
namespace myapp {

ACDK_DECL_CLASS(MyClass);

class MyClass
: extends acdk::lang::Object
, implements acdk::lang::Comparable
{
  // !!! this tag declares this class has Metainfo
  ACDK_WITH_METAINFO(MyClass)
public:
  RString label;
  MyClass(RString l, int i)
  : label(l)
  {
  }
  void print(acdk::io::RPrintWriter out) throw (acdk::io::RIOException, RThrowable)
  {
    out->println(label);
  }
  // implemented for Comparable
  foreign int compareTo(RObject o) 
  {
    return label->compareTo(RMyClass(o)->label);
  }
};
} // namespace myapp 
} // namespace artefaktur 
} // namespace com 
#endif //com_artefaktur_myapp_MyClass_h

Using the Metacompiler acdkmc In the acdk_core package the metacompiler acdkmc is included. after compiled it can be found in $ACDKHOME/bin/acdkmc[_d|_r].exe for windows plattforms or $ACDKHOME/bin/acdkmc for unix plattforms.

You can pass a single Header to acdkmc to generate Metainfo for the classes defined in this header:
$ ~/myapp> acdkmc src/com/artekatur/myapp/MyClass.h
This will generate a file src/com/artekatur/myapp/MyClass_clazzInfo.cpp.

Alternativally you can also pass a directory name to acdkcm
$ ~/myapp> acdkmc src/com/artekatur/myapp
This will generate a file src/com/artekatur/myapp/myapp_clazzInfo.cpp with all metainformation of the .h files in this directory.

 The ACDK classes Metainfo


The metainfo compiler generates following meta info for the class MyClass:
  • There is a Class named "MyClass" in the namespace "com::artefaktur::myapp".
  • This class:
    • is derived from "acdk::lang::Object"
    • implements the interface "acdk::lang::Comparable"
    • has a public nonstatic member "label" with the type RString
    • has a public nonstatic member "label" with the type RString
    • has a public Constructor with the arguments:
      • IN-parameter of the type "RString" with the name "l"
      • IN-parameter of the type "int" with the name "i"
      • and no throw declarations
    • as a public nonstatic, nonvirtual method named "print" with the arguments:
      • IN-parameter of the type "acdk::io::RPrintWriter" with the name "out".
    • and throw declarations:
      • of the type "acdk::io::RIOException" and
      • of the type "RThrowable"
    • has no information about the method compareTo, because it is tagged as foreign.


 The generated information


The generated type information is cross-linked database of types.
This database is build from C-structures which fullfills following needs:
  • lean in compiled object size
  • less overhead at loading
  • lean in memory overhead
  • fast in access and type browsing
  • minimize identifying types by string, so a type - for example specifies an argument - will not be identified by name, but as pointer to the type definition.


Here the generated code of the ACDK Metainfo compiler.
The best to read this from bottom to top.

!

Implementation details may differ in future versions of ACDK.


// header ommited
namespace com { 
namespace artefaktur { 
namespace myapp { 

// the field named "label"
::acdk::lang::dmi::ClazzFieldInfo MyClass_fields_label = 
{
  ::acdk::lang::reflect::Modifier::PUBLIC | ::acdk::lang::reflect::Modifier::IsClazzFieldInfo,
  "label", // label
  RString::clazzInfo(), // the type 
  (void*)0 // address of field in case of static member
};

// the fields of the class 
::acdk::lang::dmi::ClazzFieldInfo* _MyClass_fields[] = 
{
  &MyClass_fields_label, // has only 1 fiedl
  0 // 0-terminator
};


::acdk::lang::dmi::ClazzSuperInfo _MyClass_super_acdk__lang__Object =
{
  ::acdk::lang::reflect::Modifier::PUBLIC,
  acdk::lang::Object::clazzInfo()
};

::acdk::lang::dmi::ClazzSuperInfo _MyClass_super_acdk__lang__Comparable =
{
  ::acdk::lang::reflect::Modifier::PUBLIC | ::acdk::lang::reflect::Modifier::INTERFACE ,
  acdk::lang::Comparable::clazzInfo()
};

::acdk::lang::dmi::ClazzSuperInfo* _MyClass_interfaces[] =
{
  &_MyClass_super_acdk__lang__Object,
  &_MyClass_super_acdk__lang__Comparable,
  0
};

::acdk::lang::dmi::ClazzMethodArgInfo* MyClass_methods_GetClass__L_acdk_lang_RClass__args[] = 
{
  0
};

::acdk::lang::dmi::ClazzInfo* MyClass_methods_GetClass__L_acdk_lang_RClass__exceptions[] =
{
  0
};

::acdk::lang::dmi::ClazzMethodInfo MyClass_method_GetClass__L_acdk_lang_RClass_ = 
{
  ::acdk::lang::reflect::Modifier::PUBLIC 
  | ::acdk::lang::reflect::Modifier::STATIC 
  | ::acdk::lang::reflect::Modifier::ClazzIsKnownType 
  | ::acdk::lang::reflect::Modifier::IsClazzMethodInfo,// class flags, like static, Constructor
  "GetClass", // name of method
  ::acdk::lang::RClass::clazzInfo(), // return type
  MyClass_methods_GetClass__L_acdk_lang_RClass__args, // return the arguments
  MyClass_methods_GetClass__L_acdk_lang_RClass__exceptions, // the declared exceptions
  0 // address of method currently not supported
};

::acdk::lang::dmi::ClazzMethodArgInfo MyClass_methods_MyClass_LRString_I_LRMyClass__arg_l = 
{
  ::acdk::lang::reflect::Modifier::DUMMY, 
  RString::clazzInfo() ,
  "l"
};

::acdk::lang::dmi::ClazzMethodArgInfo MyClass_methods_MyClass_LRString_I_LRMyClass__arg_i = 
{
  ::acdk::lang::reflect::Modifier::DUMMY, 
  ::acdk::lang::dmi::ClazzInfo::getIntClazz() ,
  "i"
};

::acdk::lang::dmi::ClazzMethodArgInfo* MyClass_methods_MyClass_LRString_I_LRMyClass__args[] = 
{
  &MyClass_methods_MyClass_LRString_I_LRMyClass__arg_l,
  &MyClass_methods_MyClass_LRString_I_LRMyClass__arg_i,
  0
};

::acdk::lang::dmi::ClazzInfo* MyClass_methods_MyClass_LRString_I_LRMyClass__exceptions[] =
{
  0
};

::acdk::lang::dmi::ClazzMethodInfo MyClass_method_MyClass_LRString_I_LRMyClass_ = 
{
  ::acdk::lang::reflect::Modifier::PUBLIC 
  | ::acdk::lang::reflect::Modifier::ClazzIsKnownType 
  | ::acdk::lang::reflect::Modifier::IsConstructor 
  | ::acdk::lang::reflect::Modifier::IsClazzMethodInfo,// class flags, like static, Constructor
  "MyClass", // name of method
  MyClass::clazzInfo(), // return type
  MyClass_methods_MyClass_LRString_I_LRMyClass__args, // return the arguments
  MyClass_methods_MyClass_LRString_I_LRMyClass__exceptions, // the declared exceptions
  0 // address of method currently not supported
};

::acdk::lang::dmi::ClazzMethodArgInfo* MyClass_methods_getClass__L_acdk_lang_RClass__args[] = 
{
  0
};

::acdk::lang::dmi::ClazzInfo* MyClass_methods_getClass__L_acdk_lang_RClass__exceptions[] =
{
  0
};

::acdk::lang::dmi::ClazzMethodInfo MyClass_method_getClass__L_acdk_lang_RClass_ = 
{
  ::acdk::lang::reflect::Modifier::PUBLIC 
  | ::acdk::lang::reflect::Modifier::VIRTUAL 
  | ::acdk::lang::reflect::Modifier::ClazzIsKnownType 
  | ::acdk::lang::reflect::Modifier::IsClazzMethodInfo,// class flags, like static, Constructor
  "getClass", // name of method
  ::acdk::lang::RClass::clazzInfo(), // return type
  MyClass_methods_getClass__L_acdk_lang_RClass__args, // return the arguments
  MyClass_methods_getClass__L_acdk_lang_RClass__exceptions, // the declared exceptions
  0 // address of method currently not supported
};

::acdk::lang::dmi::ClazzMethodArgInfo MyClass_methods_print_Lacdk_io_RPrintWriter__V_arg_out = 
{
  0, 
  acdk::io::RPrintWriter::clazzInfo() ,
  "out"
};

::acdk::lang::dmi::ClazzMethodArgInfo* MyClass_methods_print_Lacdk_io_RPrintWriter__V_args[] = 
{
  &MyClass_methods_print_Lacdk_io_RPrintWriter__V_arg_out,
  0
};

::acdk::lang::dmi::ClazzInfo* MyClass_methods_print_Lacdk_io_RPrintWriter__V_exceptions[] =
{
  acdk::io::RIOException::clazzInfo(), 
  RThrowable::clazzInfo(), 
  0
};

::acdk::lang::dmi::ClazzMethodInfo MyClass_method_print_Lacdk_io_RPrintWriter__V = 
{
  ::acdk::lang::reflect::Modifier::PUBLIC 
  | ::acdk::lang::reflect::Modifier::ClazzIsKnownType 
  | ::acdk::lang::reflect::Modifier::IsClazzMethodInfo,// class flags, like static, Constructor
  "print", // name of method
  ::acdk::lang::dmi::ClazzInfo::getVoidClazz(), // return type
  MyClass_methods_print_Lacdk_io_RPrintWriter__V_args, // return the arguments
  MyClass_methods_print_Lacdk_io_RPrintWriter__V_exceptions, // the declared exceptions
  0 // address of method currently not supported
};

::acdk::lang::dmi::ClazzMethodInfo* _MyClass_methods[] = 
{
  &MyClass_method_GetClass__L_acdk_lang_RClass_,
  &MyClass_method_MyClass_LRString_I_LRMyClass_,
  &MyClass_method_getClass__L_acdk_lang_RClass_,
  &MyClass_method_print_Lacdk_io_RPrintWriter__V,
  0
};

::acdk::lang::dmi::ClazzInfo MyClass::_clazzInfo =
{
  0, // clazz-flags
  "MyClass", // name of class
  "com/artefaktur/myapp", // the namespace
  _MyClass_interfaces, // pointer to Array of ClazzInfo references
  2, // count of Super / Interfaces
  _MyClass_fields, // pointer to Array of fields
  1, // count of Fields
  _MyClass_methods, // pointer to Array of fields
  4, // count of Methods
  0, // create-function for cloning/serializing
  &MyClass::create_array, // create-function for cloning/serializing arrays
  &MyClass::create_array_array, // create-function for cloning/serializing arrays
  0, // Class* thisClass; chaching instance. Filled at runtime
  JLONG_CONSTANT(-354086121025790910), // jlong serialVersionUID; for serialization
  &MyClass::StandardDispatch, // DMI static_dispatch 
 1, // count off all collectable members in this class
  0, // user defined info f.i. clazzinfo for arrays
  0, // next ClazzInfo in chain
};

static ::acdk::lang::dmi::RegisterClazzInfo _register_MyClass(MyClass::clazzInfo());

// DMI part ommited