Like the C API, JDAPI allows you to write completely generic code for processing
multiple Forms objects of different types. All classes representing Forms objects
implement the JdapiObject
interface, and this type can be used
as the base type. Additionally, there is an abstract type, JdapiModule
,
which also implements JdapiObject
and from which the real module
types extend (this is illustrated in the example
in Loading and Saving Modules).
When getting and setting Forms object properties generically you will need
to use the generic accessors, getStringProperty(), setStringProperty()
and so on, since the specific property accessors are not supported by the JdapiObject
interface (the exception is getName()
).
There are several classes in JDAPI which deal with the Forms model metadata, these are:
JdapiMetadata
this class holds all the metadata for Forms
objects . Use this class and the data it returns to dynamically determine
what properties a given forms object hasJdapiMetaObject
this class represents the metadata for a Forms object (for example, a Block). It describes the object in terms of its properties. The
metaproperty types that the object can contain can be categorized as boolean, child object, integer, object, and string. JdapiMetaProperty
this class represents the metadata for
a given property, obtained from a given JdapiMetaObject which is in turn obtained
from a given Forms object. JdapiMetaProperty also has some static utility
methods for inspecting any property (usually by constant value) The class JdapiMetaData
contains a complete description of the
metadata for each Forms object. For each Forms object type there is also a corresponding
JdapiMetaObject
which can be obtained from JdapiMetaData
(or from an instance of the object) by calling getJdapiMetaObject()
,
and describes the set of metaproperties for the corresponding Forms object.
It is possible to obtain iterators of all properties or specific types. The
iterators operate on sets of JdapiMetaProperty
type. For example:
JdapiIterator stringProps = metaObject.getStringMetaProperties();
For each property there is a corresponding JdapiMetaProperty
which
can be obtained and which describes the property. For example it can describe
its data type, whether it can be set, and so on. For example:
... while (stringProps.hasNext()) { JdapiMetaProperty prop = (JdapiMetaProperty)stringProps.next(); if (prop.allowGet()) { // this line returns the equivalent value to the JdapiTypes.<prop>_PTID constant
int propNum = prop.getPropertyID(); System.out.println( "Property No. " + propNum + " has value " + jo.getStringProperty(propNum)); } }
This is where the generic accessors together with the metadata can be very
powerful since code can be written to process a whole module object by object,
reusing the same processing code and without catering for each specific type
of object. The alternative would be to use a large switch
statement
or chained if/else if...
code structure and select on the specific
object type.
The following code sample illustrates how to use generic methods to traverse a form and get and manipulate Forms object properties.
import oracle.forms.jdapi.*; /** * Example to traverse a Form Module object tree in a generic way */
public class TraverseFormExample { public static void main(String[] args) { FormModule fmb = FormModule.open("myform.fmb"); traverse(fmb); }/** * Recursive method for tree-walking a Form via object ownership metadata * * This method will inspect the passed object for any possible * child objects and process them recursively * * @param jo Forms object representing start point of traversal */
public static void traverse(JdapiObject jo) {// first do any processing on the passed object we want to
System.out.println("Found object " + jo.getName());// use the passed object's metadata object
// to obtain its possible child object metaproperties
JdapiMetaObject meta = jo.getJdapiMetaObject(); JdapiIterator childProps = meta.getChildObjectMetaProperties();// iterate round the child object properties
while(childProps.hasNext()) { JdapiMetaProperty mprop = (JdapiMetaProperty)childProps.next(); JdapiIterator childObjects = jo.getChildObjectProperty(); mprop.getPropertyId()// won't enter this loop if the object iterator is empty
if(childObjects!=null) { while (childObjects.hasNext()) {// finally, recurse
traverse((JdapiObject)childObjects.next()); } } } } }
Comments: For each Forms object, get the corresponding metadata
object from it, retrieve a list (iterator) of child object property types and
test each one to see if any of those child objects exist. In the example there
is only minimal "real" processing (the System.println()
statement), whereas in practice you could call any Java/JDAPI methods here.
Note that nowhere in the code is there a reference of specific object types
(Block, Canvas, and so on).
This is a classic generic tree-walking algorithm which can be used with JDAPI to do almost any processing task. Comparing this example with the generic traversal example in the C API white paper will illustrate the ease of use and clarity of using a Java API.