Wednesday, March 17, 2010

Concept of Nested AM.

Hi All,
Writing a theoretical article after a long time. What inspired me to write.... hmm... lot of questioning developers :) . Ok, my target with this article is to make an OA Framework developer understand what is nested AM? and how can u find a nested AM instance from master/root AM instance? What we should know about it while developing extensions or new pages.

What is a Nested AM?
An application module may be a root application module or a nested application module. A root application module is not contained in another applicatin module. It provides transaction context for all objects contained in it. It may optionally contain nested application modules. A root application module is created through JNDI calls.

A nested application module is contained in another application module. The containing application module is referred to as the parent application module. If one traverses this containership ancestry, one will eventually find the root application module (which does not have a parent application module). A nested application module uses the transaction context provided by the root application module. Thus, data modifications performed in application modules parented by one root application module will commit or rollback together.

Associated with the root application module is the Transaction object, which provides this transaction context. From any (root or nested) application module, the user can retrieve the transaction object through a call to getOADBTransaction(). In reality, getOADBTransaction() first locates the root application module and then returns the transaction object from it.

The transaction object manages connection to database and entity caches. Thus, changes made through one view object are visible to other view objects as long as these view objects all parented by the one root application module. In contrast, if two view objects are parented by two separate root application modules, then changes made through the view object will not be seen by the second view object until the changes are committed to database through the first root application module and the second VO executes query (to retrieve the most up-to-date data from database).

Creating Application Module
A root application module is created by:

Finding the application module home through JNDI.
Calling create() on the application module home.
Here is a sample code to create a root application module:

java.util.Hashtable env = new java.util.Hashtable();

// Add environment entries into env...

javax.naming.Context ic = new InitialContext(env);

// 'defName' is the JNDI name for the application module
// definition from which the root application module is to
// be created
String defName = ...;

oracle.jbo.ApplicationModuleHome home = ic.lookup(defName);
oracle.jbo.ApplicationModule am = home.create();

One creates a nested application module by calling createApplicationModule on the parent Application module.

How nested AM concept works in OAF :
Now to associate a nested application module with a region,
specify either of the following properties:
1) AM Instance -- The application module instance name as specified in the application module's data
model. For example, PoSummaryAM1.
2) AM Definition -- The fully qualified name of the application module instance. For example,

If you specify the AM Instance property, OA Framework attempts to find and return the AM instance with the given name. It searches the application module associated with the parent web bean.
If you specify the AM Definition property, OA Framework assigns a generated AM instance name to the nested region. This name is comprised of the following values:
a) Region code of the associated nested region (if the region was originally created in AK)
b) Nested region application ID
c) Nested region ID
d) AM definition name.

OA Framework checks to see if the nested AM with the system-generated name has been already created under the application module of the parent web bean. If the instance is not found, OA Framework creates and uses a nested AM with the system-generated name. Otherwise, it reuses the pre-existing AM with the system generated

When specifying both the AM Instance and AM Definition properties
if a matching AM instance is found, OA Framework compares its definition with the AM Definition property value. If there is a mismatch, OA Framework throws an exception.
If a matching AM instance is not found, OA Framework creates and returns a nested application module instance with the given AM instance name and the definition.

Code for finding nested AM instance in root AM :
Hence, whenever you are trying to find an nested AM instance linked to a OA region under pagelayout region, please check the am defination and am instance property of that region, because only then you would be able to have a idea of name of nested AM instance. It can be system generated AM instance or name given by developer for AM instance.So, you need to confirm this from the three cases mentioned in the previous article.For debugging purposes, you can get the list if Application modules in root AM and print there names ,too :

String[] nestedAMNames = parentAM.getApplicationModuleNames();

// If you want to retrieve all currently loaded nested Application Modules
ApplicationModule[] nestedAMs = new ApplicationModule[nestedAMNames.length];

for (int i = 0; i < nestedAMNames.length; i++)
nestedAM[i] = parentAM.findApplicationModule(nestedAMNames[i]);

Otherwise for finding nested AM instance by :
ApplicationModule nestedAM = parentAM.findApplicationModule("MyNestedAM");

This concept is really helpful while doing extensions in OAF, as you may have to find a nested AM in a CO of particular OAF region.You can always find root AM of the page in any controller using pagecontext.getRootApplicationModule().

I hope after reading this article nested AM conecept becomes crystal clear in your mind :), if not raise queries, and I will try to answer you.