Home · Examples 


The Qt Jambi Type System

The type system is used when mapping a C++ based library onto a corresponding Java library using the Qt Jambi generator.

The developer can define the scope of the Java API by writing a type system specification. The specification is a handwritten XML document listing the types that will be available in the generated Java API; types that are not declared in the specification will be ignored along with everything that depends on them. In addition, it is possible to manipulate and modify the types and functions. It is even possible to use the type system specification to inject arbitrary code into the source files, such as an extra member function.

The type system specification is passed as an argument to the generator.

Below is a complete reference guide to the various nodes of the type system. For examples of use, take a look at the type system files used to generate the Qt Jambi API. These files can be found in the generator directory of the Qt Jambi package.

See also: Qt Jambi Generator Example

Alphabetical List

access, argument-map, conversion-rule, custom-constructor, custom-destructor, define-ownership, enum-type, extra-includes, include, inject-code, insert-template, interface-type, load-typesystem (multiple type system), modify-argument, modify-field, modify-function, namespace-type, object-type, primitive-type, reject-enum-value, rejection, remove, remove-argument, remove-default-expression, rename, replace, replace-default-expression, replace-type, suppress-warning, template, typesystem, value-type

Specifying Types



Node
Description
typesystem The typesystem node is the root node containing all the type system information.
<typesystem package="..."
    default-superclass="..." (optional)>
</typesystem>
The package attribute is a string describing the package to be used, e.g.,"com.trolltech.qt.core". The optional default-superclass attribute is the complete class name of the default baseclass of all objects in Java, e.g., "com.trolltech.qt.QtJambiObject".
load-typesystem The load-typesystem node specifies which type systems to load when mapping multiple libraries to Java or basing one library on another, and is a child of the typesystem node.
<typesystem ...>
    <load-typesystem name="..."
        generate="yes | no">
</typesystem>
The name attribute is the filename of the type system to load, the generate attribute specifies whether code should be generated or not. The latter must be specified when basing one library on another, making the generator able to understand inheritance hierarchies, primitive mapping, parameter types in functions etc.

Most libraries will be based on both the QtCore and QtGui modules, in which case code generation for these libraries will be disabled.

rejection The rejection node rejects the given class, or the specified function or field, and is a child of the typesystem node.
<typesystem ...>
    <rejection class="..."
        function-name="..." (optional)
        field-name="..." (optional) />
</typesystem>
The class attribute is the C++ class name of the class to reject. Use the optional function-name or field-name attributes to reject a particular function or field. Note that the field-name and function-name cannot be specified at the same time. To remove all occurrences of a given field or function, set the class attribute to *.
primitive-type The primitive-type node describes how a primitive type is mapped from C++ to Java and the Java Native Interface (JNI), and is a child of the typesystem node. Note that most primitives are already specified in the QtCore type system.
<typesystem ...>
    <primitive-type name="..."
        java-name="..." (optional)
        jni-name="..." (optional)
        preferred-conversion="yes | no" (optional)>
</typesystem>
The name attribute is the name of the primitive in C++, the java-name attribute is the name of the primitive in Java, and the jni-name attribute is the name of the primitive in JNI. If the latter two attributes are not specified, their default value will be the same as the name attribute.

If the optional preferred-conversion attribute is set to "no", it indicates that this version of the primitive is not the preferred C++ equivalent of the Java type. For example, both "qint64" and "long long" become "long" in Java but we should prefer the "qint64" version. For this reason we mark "long long" with preferred-conversion="no".

namespace-type The namespace-type node maps the given C++ namespace to Java ( note that the namespace becomes an interface in Java), and is a child of the typesystem node. Note that within namespaces, the generator only supports enums (i.e., no functions or classes).
<typesystem ...>
    <namespace-type name="..."
        package="..." (optional)
        expense-cost="..." (opt)
        expense-limit="..." (opt)/>
</typesystem>
The name attribute is the name of the namespace, e.g., "Qt". The package attribute can be used to override the package of the type system. The expense-cost attribute specifies the memory cost of using an instance of the given type, allowing the garbage collector to optimize the memory management. The cost is specified using Java code. The expense-limit attribute specifies how much an instance's memory consumption must be before the garbage collector is activated (the memory consumption is calculated using the value of the expense-cost attribute).
enum-type The enum-type node maps the given enum from C++ to Java, and is a child of the typesystem node. Use the reject-enum-value to reject values.
<typesystem ...>
    <enum-type name="..."
        flags="yes | no" (optional)
        lower-bound="..." (optional)
        upper-bound="..." (optional)
        force-integer="yes | no" (optional)
        extensible="yes | no" (optional)/>
</typesystem>
The name attribute is the fully qualified C++ name of the enum (e.g.,"Qt::FillRule"). If the optional flags attribute is set to yes (the default is no), the generator will expect an existing QFlags<T> for the given enum type. The lower-bound and upper-bound attributes are used to specify runtime boundschecking for the enum value. The value must be a compilable java statement, such as "QGradient.Spread.PadSpread". If the force-integer attribute is set to yes (the default is no), the generated Java code will use integers instead of Java enums. And finally, the extensible attribute specifies whether the given enum can be extended with user values (the default is no).
value-type The value-type node indicates that the given C++ type is mapped onto Java as a value type, and is a child of the typesystem node.
<typesystem ...>
    <value-type  name="..."
        package ="..." (optional)
        default-superclass ="..." (optional)
        polymorphic-base="yes | no" (opt)
        polymorphic-id-expression="..." (opt)
        expense-cost="..." (opt)
        expense-limit="..." (opt)/>
</typesystem>
The name attribute is the fully qualified C++ class name, such as "QMatrix" or "QPainterPath::Element". The package attribute can be used to override the package of the type system. If there is no C++ base class, the default-superclass attribute can be used to specify a superclass for the given type, in the generated Java API.

The polymorphic-base and polymorphic-id-expression attributes have the same meaning as the object-type node, and the expense-cost and expense-limit attributes have the same meaning as for the namespace-type node.

object-type The object-type node indicates that the given C++ type is mapped onto Java as an object type, and is a child of the typesystem node.
<typesystem ...>
    <object-type name="..."
        package ="..." (optional)
        default-superclass ="..." (optional)
        polymorphic-base="yes | no" (opt)
        polymorphic-id-expression="..." (opt)
        expense-cost="..." (opt)
        expense-limit="..." (opt)/>
</typesystem>
The name attribute is the fully qualified C++ class name. The package attribute can be used to override the package of the type system. If there is no C++ base class, the default-superclass attribute can be used to specify a superclass for the given type, in the generated Java API. The polymorphic-base attribute is used to specify the base class for polymorphic types that do not inherit QObject (like QEvent), i.e. types that do not support introspection. By specifying the base class, introspection is enabled, provided that the subclasses sets the polymorphic-id-expression attribute. For example:
<object-type name="QEvent" polymorphic-base="yes" />
<object-type name="QTimerEvent"
             polymorphic-id-expression="%1->type() == QEvent::Timer)" />
The polymorphic-id-expression attribute specifies code that determines which subclass, in a polymorphic hierarchy, an object belongs to. Instances of %1 in the code will be replaced by the name of the object in question.

The expense-cost and expense-limit attributes have the same meaning as for the namespace-type node.

interface-type The interface-type node indicates that the given class is replaced by an interface pattern when mapping from C++ to Java. It is used to resolve multiple base classes which is not supported by Java. Using the interface-type node implicitly makes the given type an object type.
<typesystem ...>
    <interface-type name="..."
        package ="..." (optional)
        default-superclass ="..." (optional)
        polymorphic-base="yes | no" (opt)
        polymorphic-id-expression="..." (opt)
        expense-cost="..." (opt)
        expense-limit="..." (opt)/>
</typesystem>
The name attribute is the fully qualified C++ class name. The package attribute can be used to override the package of the type system. If there is no C++ base class, the default-superclass attribute can be used to specify a superclass in the generated Java API, for the given class.

The polymorphic-base and polymorphic-id-expression attributes have the same meaning as the object-value node, and the expense-cost and expense-limit attributes have the same meaning as for the namespace-type node.

suppress-warning The generator will generate several warnings which may be irrelevant to the user. The suppress-warning node suppresses the specified warning, and is a child of the typesystem node.
<typesystem...>
    <suppress-warning text="..." />
</typesystem>
The text attribute is the warning text to suppress, and may contain the * wildcard (use "" to escape regular expression matching if the warning contain a regular "*").
template The template node registers a template that can be used to avoid duplicate code when extending the generated code, and is a child of the typesystem node.
<typesystem>
    <template name="my_template">
        // the code
    </template>
</typesystem>
Use the insert-template node to insert the template code (identified by the template's name attribute) into the generated code base.

Value Type Requirements



Node
Description
custom-constructor In Java, value types are required to have a copy constructor. If a C++ class without a copy constructor is mapped onto Java as a value type, it is possible to provide a custom constructor using the custom-constructor node which is a child of the value-type node.
<value-type ...>
    <custom-constructor
         name="..." (optional)
         param-name="..." (optional)>
            // code for custom constructor
    </custom-constructor>
</value-type>
The custom constructor's signature becomes:
 T *name(T *param-name);
If not specified the name of the constructor becomes <lowercase type name>_create() and the parameter name becomes copy.
custom-destructor When a custom constructor is provided using the custom-constructor node, it is most likely required to clean up the allocated memory. For that reason, it is also possible to provide a custom destructor using the custom-destructor node which is a child of the value-type node.
<value-type ...>
    <custom-destructor
         name="..." (optional)
         param-name="..." (optional)>
            // code for custom destructor
    </custom-destructor>
</value-type>
The custom destructor must have the following signature:
 T *name(T *param-name);
If not specified the name of the destructor becomes <lowercase type name>_delete() and the parameter name becomes copy.
insert-template Documented in the Using Code Templates section

Manipulating Object and Value Types



Node
Description
inject-code The inject-code node inserts the given code into the generated code for the given type or function, and is a child of the object-type, value-type and modify-function nodes.
 <value-type ...>
     <inject-code class="java | native | shell | shell-declaration"
         position="beginning | end">
         // the code
     </inject-code>
 </value-type>
The class attribute specifies which module of the generated code that will be affected by the code injection. The class attribute accepts the following values:
  • java: The generated java code
  • native: The generated JNI-based methods
  • shell: The generated shell class
  • shell-declaration: The code will be injected into the generated header file containing the shell class definition.
If the position attribute is set to beginning (the default), the code is inserted at the beginning of the function. If it is set to end, the code is inserted at the end of the function.
modify-field The modify-field node allows you to alter the access privileges for a given C++ field when mapping it onto Java, and is a child of an object-type or a value-type node.
 <object-type ...>
     <modify-field name="..."
         write="true | false" (optional)
         read="true | false" (optional)/>
 </object-type>
The name attribute is the name of the field, the optional write and read attributes specify the field's access privileges in the Java API (both are set to true by default).
modify-function The modify-function node allows you to modify a given C++ function when mapping it onto Java, and is a child of an object-type or a value-type node. Use the modify-argument node to specify which argument the modification affects.
 <object-type ...>
     <modify-function signature="..."
                      remove="all | java"
                      access="public | private | protected"
                      rename="..." >
 </object-type>
The signature attribute is a normalized C++ signature, excluding return values but including potential const declarations.

The remove, access and rename attributes are optional attributes for added convenience; they serve the same purpose as the tags remove, access and rename.

include Documented in the Manipulating Namespace and Interface Types section
extra-includes Documented in the Manipulating Namespace and Interface Types section
insert-template Documented in the Using Code Templates section
delete-in-main-thread Specifies that the object is tied to the main thread and can only be deleted in the application's main thread. This is true for all non-QObjects that use native windowing system resources, such as fonts, pixmaps, and QGraphicsItems. It is also true classes that memory manage objects of these classes.

Manipulating Namespace and Interface Types



Node
Description
extra-includes The extra-includes node contains declarations of additional include files, and can be a child of the interface-type, namespace-type, value-type and object-type nodes.

The generator automatically tries to read the global header for each type. But sometimes it is required to include extra files in the generated C++ code to make sure that the code compiles. These files must be listed using include nodes witin the extra-include node:

 <value-type ...>
     <extra-includes>
         <include file-name="..." location="global | local | java"/>
     </extra-includes>
 </value-type>
The file-name attribute is the file to include, such as "QStringList". The location attribute is where the file is located: global means that the file is located in $INCLUDEPATH and will be included using #include <...>, local means that the file is in a local directory and will be included using #include "...". If the location is set to java then the file-name attribute is expected to contain the fully qualified name for a java class and the specified class will be imported in the generated java code.
include The include node specifies the name and location of a file that must be included, and is a child of the interface-type, namespace-type, value-type, object-type or extra-includes nodes

The generator automatically tries to read the global header for each type. Use the include node to override this behavior, providing an alternative file. The include node can also be used to specify extra include files.

 <value-type ...>
     <include file-name="..."
         location="global | local | java"/>
 </value-type>
The file-name attribute is the file to include, such as "QStringList". The location attribute is where the file is located: global means that the file is located in $INCLUDEPATH and will be included using #include <...>, local means that the file is in a local directory and will be included using #include "...". If the location attribute is set to java in this particular case, it will be ignored.

Manipulating Enum Types



Node
Description
reject-enum-value The reject-enum-value node rejects the enum value specified by the name attribute, and is a child of the enum-type node.
 <enum-type ...>
     <reject-enum-value name="..."/>
 </enum-type>
This node is used when a C++ enum implementation has several identical numeric values, some of which are typically obsolete.

Modifying Functions



Node
Description
modify-argument The modify-argument node specifies which of the given function's arguments the modification affects, and is a child of the modify-function node. Use the remove-argument, replace-default-expression, remove-default-expression, replace-type, reference-count and define-ownership nodes to specify the details of the modification.
 <modify-function ...>
     <modify-argument index="return | this | 1 ..."
          invalidate-after-use="yes | no" (optional) >
         modifications
     </modify-argument>
 </modify-function>
Set the index attribute to "1" for the first argument, "2" for the second one and so on. Alternatively, set it to "return" or "this" if you want to modify the function's return value or the object the function is called upon, respectively.

The invalidate-after-use attribute is optional and defaults to "no". Setting it to "yes" is only applicable for modifications to virtual functions and will cause the Java object passed as the argument to be invalidated after the virtual function call is complete, if the object is owned by C++ and not by Java. This is used as a measure against crashes caused by users retaining references to objects that are later deleted in the underlying C++ code.

remove The remove node removes the given method from the generated Java code, and is a child of the modify-function node.
 <modify-function ...>
     <remove class="all | java" />
 </modify-function>
If the class attribute is set to "java", the function is only removed for the generated java code; the default value is "all".
access The access node changes the access privileges of the given function in the generated Java code, and is a child of the modify-function node.
 <modify-function ...>
     <access modifier="public | protected | private"/>
 </modify-function>
rename The rename node changes the name of the given function in the generated Java code, and is a child of the modify-function node.
 <modify-function...>
     <rename to="..." />
 </modify-function>
The to attribute is the new name of the function.
inject-code Documented in the Manipulating Types section
argument-map The argument-map node maps a C++ argument name to the argument name used in the generated Java code, and is a child of the inject-code node when the latter is a child of a modify-function node.
 <modify-function...>
     <inject-code ...>
         <argument-map index="numeric value"
             meta-name="string value">
     </inject-code>
 </modify-function>
The index attribute is an index, starting at 1, indicating the argument position to which this argument mapping applies. The meta-name attribute is the name used within the code injection to adress the argument at the given position.

Modifying Arguments



Node
Description
remove-argument The remove-argument node removes the given argument from the function's signature, and is a child of the modify-argument node.
 <modify-argument ...>
     <remove-argument />
 </modify-argument>
Typically, when removing an argument, some conversion rules must be specified, e.g., when converting from Java to C++. This can be done using the conversion-rule node.
remove-default-expression The remove-default-expression node disables the use of the default expression for the given argument, and is a child of the modify-argument node.
 <modify-argument...>
     <remove-default-expression />
 </modify-argument>
replace-default-expression The replace-default-expression node replaces the specified argument with the expression specified by the with attribute, and is a child of the modify-argument node.
 <modify-argument...>
     <replace-default-expression with="..." />
 </modify-argument>
replace-type The replace-type node replaces the type of the given argument to the one specified by the modified-type attribute, and is a child of the modify-argument node.
 <modify-argument...>
     <replace-type modified-type="..." />
 </modify-argument>
If the new type is a class, the modified-type attribute must be set to the fully qualified name (including name of the package as well as the class name).

Typically, when changing the type of an argument, some conversion rules must be specified. This can be done using the conversion-rule node.

reference-count The reference-count tag indicates that the function holds a reference to the argument object without assuming ownership of it.
 <modify-argument ...>
     <reference-count action="add | add-all | remove | set | ignore"
                      variable-name="..."
                      declare-variable="..."
                      conditional="..."
                      access="public | private | protected | friendly" />
 </modify-argument>
The action attribute specifies the action to be taken. add, add-all and remove are collection actions. They will add a single object to a list of references, add all objects in a collection to a list of references or remove a single object from a list of references. set will assign the argument to the variable containing the reference (the argument must be a collection if the variable is also used for any of the collection specific actions.) ignore will not inject any code, but will cause the method in question to be removed from the log of possible reference counting API.

The variable-name attribute specifies the name used for the variable that holds the reference(s).

The declare-variable attribute can be used to specify the fully qualified name of the class that owns the reference. This attribute is optional, and should only be specified if the variable should not be declared in the current class. The specified must be in the superclass hierarchy of the current class.

The conditional attribute is optional, and specifies a conditional expression which must be true in order for the action of the reference-count tag to be taken.

The access attribute gives the visibility of the variable. Only applicable if declare-variable is not specified. The default value of access is private.

define-ownership The define-ownership tag indicates that the function changes the ownership rules of the arguemnt object. The class attribute specifies the class of function in which to inject the ownership altering code. The owner attribute specifies the new ownership of the object. It accepts the following values:
  • java: Java will assume full ownership of the object. The native resources will be deleted when the Java object is finalized.
  • c++: The native code assumes full ownership of the object. The Java object will not be garbage collected.
  • default: The object will get default ownership, depending on how it was created.
 <modify-argument ...>
      <define-ownership class="java | shell"
                        owner="java | c++ | default" />
 </modify-argument>
conversion-rule The conversion-rule node allows you to write customized code to convert the given argument between Java and C++, and is a child of the modify-argument node.
 <modify-argument ...>
      <conversion-rule class="shell | native">
         // the code
      </conversion-rule>
 </modify-argument>
This node is typically used in combination with the replace-type and remove-argument nodes. The given code is used instead of the generator's conversion code in the following situations (defined by the modify-argument node's index attribute and the class attribute as well the function implementation and where the function is called from):
Argument Index Function Class Function Implementation Caller Location
1 | 2 ... shell Java (overriding C++) C++
1 | 2 ... native C++ Java
return shell C++ Java
return native Java (overriding C++) C++
Writing %N in the code (where N is a number), will insert the name of the nth argument. Alternatively, %in and %out which will be replaced with the name of the conversion's input and output variable, respectively. Note the output variable must be declared explicitly, for example:
 <conversion-rule class="native">
     bool %out = (bool) %in;
 </conversion-rule>
insert-template Documented in the Using Code Templates section
replace-value The replace-value attribute lets you replace the return statement of a function with a fixed string. This attribute can only be used for the argument at index 0, which is always the function's return value.

Here is an example of how to use modify-argument:

 <modify-argument index="0" replace-value="this"/>

Using Code Templates



Node
Description
insert-template The insert-template node includes the code template identified by the name attribute, and can be a child of the inject-code, conversion-rule, template, custom-constructor and custom-destructor nodes. For example;
 <inject-code class="java" position="beginning">
     <insert-template name="my_template" />
 </inject-code>
Use the replace node to modify the template code.
replace The replace node allows you to modify template code before inserting it into the generated code, and can be a child of the insert-template node.
 <insert-template name="my_template">
     <replace from="..." to="..." />
 </insert-template>
Using this node the code specified by the from attribute is altered into the code specified by the to attribute.


Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) Trademarks
Qt Jambi 4.5.2_01