A script-enabled browser is required for this page to function properly.

Understanding JDAPI Architecture

JDAPI is designed to be familiar to users of the C API (without laying aside the conventions of Java) and uses the Java Native Interface (JNI) to call the Forms stack. There is a single Java package (oracle.forms.jdapi) which is usually distributed as a jar file. The package contains a number of interfaces and abstract types, utility classes and classes representing all Forms objects. There is no Forms Context object - this behavior is encapsulated by the Jdapi class.

Design-time Forms objects are basically sets of properties of Boolean, integer, string and object types. All JDAPI Forms object classes implement the JdapiObject interface, which is also the fundamental type of all objects. This interface includes generic property accessors by type, i.e. JdapiObject.getStringProperty(), JdapiObject.setStringProperty(), JdapiObject.getIntegerProperty(), JdapiObject.setIntegerProperty() etc.

Object properties represent the "child object" lists of a given Forms object, for example, the Items, Triggers and Relations owned by a Block, and the respective accessor methods return iterators for the requested child list. JDAPI includes an iterator interface, JdapiIterator, which extends java.util.Iterator, and all methods returning iterator objects return this type, regardless of the implementing subclass. Since the methods of java.util.Iterator return java.lang.Object, so do those of JdapiIterator and it is necessary to cast to the appropriate return type or supertype. For example:

 
  // Get the block list from the form module
    JdapiIterator blocks = myForm.getObjectProperty(JdapiTypes.BLOCK_PTID);
    Block myBlock = (Block)blocks.next();
    System.out.println(myBlock.getStringProperty(JdapiTypes.NAME_PTID));
    
    // Now get the item list from the first block
    JdapiIterator items = Block.getObjectProperty(JdapiTypes.ITEM_PTID);
    Item myItem = (Item)items.next();
    System.out.println(myBlock.getStringProperty(JdapiTypes.NAME_PTID)); 

The class JdapiTypes contains a full set of Property Type ID constants (*_PTID) representing specific Forms object properties, and a similar set of (Forms) Object Type ID constants (*_OTID) which represent the Forms Object types themselves. (Note that these values are NOT declared final - this is deliberate and prevents the compiler from optimizing the constant values into user code directly, thus preserving binary compatibility between releases without recompilation).

In addition to the generic accessor methods, each class has specific and more Java-like accessors for its pertinent set of properties. For example, the following code fragment is equivalent to the previous one:

  
    // Get the block list from the form module
    JdapiIterator blocks = myForm.getBlocks();
    Block myBlock = (Block)blocks.next();
    System.out.println(myBlock.getName());
    
    // Now get the item list from the first block
    JdapiIterator items = Block.getItems();
    Item myItem = (Item)items.next();
    System.out.println(myBlock.getName()); 
	

The method getBlocks() will be a member of only the FormModule class, since only Form Modules can own Blocks, and likewise only the Block class will have a getItems() method. On the other hand, several Forms object classes will implement a getTriggers() method, and almost all will implement getName().

The JdapiObject interface is initially implemented by an abstract class, BaseFormsObject, which all Forms object classes extend. As the main implementation class, BaseFormsObject itself has only package-level visibility. This is intentional, so that its implementation can be changed without modifying the public API.

The Java classes representing the Forms objects constitute only a thin convenience layer over the native C API objects and functions i.e. a facade pattern. There is very little Forms functionality implemented in the Java code, which calls directly to the C API via JNI to perform all Forms behavior Because of this there is a significant memory management issue, but fortunately this is mostly handled automatically by the high-level code interacting with Jdapi's object cache.

The Object Cache

This is a performance and efficiency feature which the end user need not be concerned with, but is described here only for information.

Two problems present themselves when using Java objects which are facades for native Forms objects:

The object cache exists to solve these problems. The cache retains a mapping of every accessed Forms object against a reference to the Java object which represents it. Whenever a Forms object is created or accessed (via JNI), the address of the Forms object is used as a key to retrieve the corresponding Java object. If there is none, as in the case of creation or the first instance of access, then the Java object is constructed automatically. Furthermore, each Java object retains a memory pointer to the Forms object it represents, and if the underlying Forms object is destroyed this pointer automatically gets set to null, indicating an invalid object.

The cache ensures that the creation of Java objects is minimized, compared to the case otherwise where during repeated iteration, each access of a Forms object would require instantiation (and subsequent garbage collection) of a new Java object to represent it, resulting in many objects being created and destroyed. Since memory allocation and object creation is one of the slowest aspects of the Java runtime this in itself greatly improves the speed and efficiency of Jdapi programs.

JDAPI Class Hierarchy

Figure 1 illustrates the JDAPI class diagram.

Figure 1. JDAPI Class Diagram (produced using Oracle JDeveloper Class Modeler).

Figure 1 illustrates the JDAPI class diagram