Wednesday, September 9, 2015

Oracle Application Framework Application Module(AM ) Various Methods

·                     Entity Object Create Example
The following example illustrates an application module method that creates and inserts a row into the
SuppliersVO view object. This particular view object is based on the SupplierEOImpl entity object, so BC4J instantiates this behind the scenes when the row is created.
public void createSupplier()
{
  OAViewObject vo = getSuppliersVO();
  Row row = vo.createRow();
  vo.insertRow();

  // As specified in OA Framework Model Coding Standards, 
  // set the new row state to STATUS_INITIALIZED.

·                     View Object Query Examples
This shows an application module method that queries the SuppliersVO view object using search criteria passed from the client.
public void query(String supplierName, String onHoldFlag, String supplierNumber)
{
 SuppliersExpVOImpl vo = getSuppliersExpVO();
  if (vo == null)
  {
    MessageToken[] tokens = { new MessageToken("OBJECT_NAME", "SuppliersExpVO")};
    throw new OAException("ICX", "FWK_TBX_OBJECT_NOT_FOUND", tokens);
  }
  vo.initQuery(supplierName, onHoldFlag, supplierNumber);    
} // end query()

·                     Commit Example
/*
 * Provides a "commit" wrapper so UI controller code doesn't need to get a handle to the transaction itself which is a violation of the client/sever tier separation rules.
 */ 
public void apply()
{
  getTransaction().commit();  
} // end apply()

·                     Modifying Bean Properties
To modify a web bean's properties, you simply need to find the correct bean in the hierarchy using its name the ID you assigned in JDeveloper), and call the appropriate method as shown in the following example.
Warning: When you get a handle to a web bean, always check whether the value is null before calling any of the methods. Even if you expect the bean to be included in the web bean hierarchy, it's possible that a customer may hide it with a personalization.
processRequest(OAPageContext pageContext, OAWebBean webBean)
{
  // Always call this before adding your own code.
  super.processRequest(pageContext, webBean);
  OATableBean table = (OATableBean)webBean.findIndexedChildRecursive("OrdersTable");
  if (table == null)
  {
     MessageToken[] tokens = { new MessageToken("OBJECT_NAME", "OrdersTable")};
     throw new OAException("ICX", "FWK_TBX_OBJECT_NOT_FOUND", tokens);
  }
    
  // Set the purchase-order specific "control bar" select text: 
  // "Select Purchase Order(s) and..."
  String selectPOText = pageContext.getMessage("ICX", "FWK_TBX_T_SELECT_PO", null);
  table.setTableSelectionText(selectPOText);
}

Starting with the controller region's children, the findIndexedChildRecursive(String name)method searches the entire web bean hierarchy looking for the first indexed child with a matching name. If the web bean that you want to modify is a UIX named child (or, if you're not sure whether it is "named" or "indexed"), use the findChildRecursive(String name) method instead. 

·                     processFormRequest( )
Any code that handles user form submit actions belongs in the processFormRequest() method.
The following example is typical of the processFormRequest() code that you will write. It illustrates how to determine that a particular form submit component was selected (in this case, a "Go" button), how to initiate a query in the model code, and how to perform a JSP Forward back to the same page so web bean properties can be changed in the processRequest() method. 
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
   // Always call this before adding your code
   super.processFormRequest(pageContext, webBean);
   
   // Pressing the Go button causes the search to be executed.
   If (pageContext.getParameter("Go") != null)
   {
     String orderNumber = pageContext.getParameter("SearchOrder");
     String created = pageContext.getParameter("Created");
     String showMyOrders = pageContext.getParameter("MyOrders");
     OAApplicationModule am = pageContext.getApplicationModule(webBean);
       
     // All parameters passed using invokeMethod() must be serializable.
     Serializable[] parameters = { orderNumber, created, showMyOrders };
     am.invokeMethod("search", parameters);
     
     // Now forward back to this page so we can implement UI changes as a
     // consequence of the query in processRequest(). NEVER make UI changes in
     // processFormRequest().
     pageContext.setForwardURLToCurrentPage(null, // no parameters to pass
                                            true, // retain the AM                                            
                                                                  OAWebBeanConstants.ADD_BREAD_CRUMB_NO, 
                                            OAWebBeanConstants.IGNORE_MESSAGES
                                                               );   
  }
} // end processFormRequest();

·                     This example shows how to pass request parameters using the setForwardUrl() method, including how to replace a pre-existing parameter value (in this case, with "X" which would be      used as an "ignore" value in the target page).
import com.sun.java.util.collections.HashMap;
import oracle.bali.share.util.IntegerUtils;
processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{   // Always call this before adding your code
   super.processFormRequest(pageContext, webBean);

   String poEvent = pageContext.getParameter("poEvent");
    
   HashMap params = new HashMap(2);

   // Replace the current poEvent request parameter value with "X"
   params.put("poEvent", "X"); 

   // IntegerUtils is a handy utility
   params.put("poStep", IntegerUtils.getInteger(5));

pageContext.setForwardURL("OA.jsp?page=/oracle/apps/dem/employee/webui/EmpDetailsPG", // target page 
                             null, // not necessary with KEEP_MENU_CONTEXT
                             OAWebBeanConstants.KEEP_MENU_CONTEXT, // no change to menu context
                             null, // No need to specify since we're keeping menu context
                             params, // request parameters
                             true, // retain the root application module
                             OAWebBeanConstants.ADD_BREAD_CRUMB_YES, // display breadcrumbs
                             OAException.ERROR); // do not forward w/ errors
}

·                     Usefull Code
processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{ 
  // Check to see if the "Go" button was pressed...
  if (pageContext.getParameter("gButton") != null)
  {
    // Get the search criteria
    String orderNumber = pageContext.getParameter("SearchOrder");
    String created = pageContext.getParameter("Created");
    String showMyOrders = pageContext.getParameter("MyOrders");
    OAApplicationModule am = pageContext.getApplicationModule(webBean);

    // All parameters passed using invokeMethod() must be serializable.    
      Serializable[] parameters = { orderNumber, created, showMyOrders };
    am.invokeMethod("search", parameters);
  }
} 

Tip: Whenever you call invokeMethod() on a server-side BC4J component, any parameters that you pass must be Serializable. The example above illustrates the invokeMethod() signature that expects all the parameters to be Strings. If you need to pass other object types, use the version of invokeMethod() that takes an array of parameter types. For example:
Class[] parameterTypes = { String.class, Hashtable.class, Number.class ...};
am.invokeMethod("search", parameters, parameterTypes);

·                     Delete Example
This example illustrates invoking a delete method on a nested application module associated with a shared region as opposed to the page's root application module.
processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{  if (pageContext.getParameter("DeleteYesButton") != null)
 {
   // User has confirmed that she wants to delete this purchase order.
   // Invoke a method on the AM to set the current row in the VO and 
   // call remove() on this row. 
    
   String poHeaderId = pageContext.getParameter("poHeaderId");
   Serializable[] parameters = { poHeaderId };
   OAApplicationModule am = pageContext.getApplicationModule(webBean);  
   am.invokeMethod("delete", parameters);
  }

·                     Validation Exceptions
Validation exceptions are thrown from entity objects and view objects for both row and attribute level validation failures. oracle.apps.fnd.framework.OAAttrValException - specialization of OAException used for attribute level validation failures oracle.apps.fnd.framework.OARowValException - specialization of OAException used for row (entity) level validation failures

The OA Framework displays error messages to the user as follows: Attribute-level exceptions are visually indicated on the error item(s) and at the top of the page Row-level exceptions are visually indicated on the error row(s) and at the top of the page Page-level exceptions are visually indicated at the top of the page

·                     OAAttrValException
If any attribute-level validation fails in a view object row or an entity object, you can throw an OAAttrValException as shown below.
To instantiate this exception, you must pass the following information: Source object type OAException.TYP_ENTITY_OBJECT or OAException.TYP_VIEW_OBJECT) Full entity definition name or view instance name as appropriate
Primary key of the entity or row Attribute name being validated  Attribute value that failed validation  Error message application short name  Error message name
Entity Object Example
public void setSalary(Number value)
{
   if (value != null)
   {
      // Verify value is > 0
      if (value.compareTo(0) <= 0)
      {
         throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT, // indicates EO source
                                      getEntityDef().getFullName(), // entity name
                                      getPrimaryKey(), // entity primary key
                                      "Salary", // attribute Name
                                      value, // bad attribute value
                                      "AK", // nessage application short name
                                      "FWK_TBX_T_EMP_SALARY_REQUIRED"); // message name
      }
     setAttributeInternal(SALARY, value);
   }
} // end setSalary()

View Row Example
Also see the Mapping section below for additional information about raising these exceptions from a view row.
setDescription(String value) 
{ 
  if("XXX".equals(value)
  {
     throw new OAAttrValException (
                               OAException.TYP_VIEW_OBJECT, // indicates VO row source
                               getViewObject().getFullName(), //View Object full usage name
                               getKey(), // row primary key
                               "Description", //attribute name
                               value, // bad attribute value 
                               "FND", //message application short name
                               "ATTR_EXCEPTION"); // message name
  }
  setAttributeInternal("Description", value); 
} // end setDescription()

·                     OARowValException
If any row-level validation fails in a view object row or an entity object, you can throw an OARowValException as shown below.
To instantiate this exception, you must pass the following information: Full entity definition name or view instance name as appropriate Primary key of the entity or row  Error message application short name  Error message name
Entity Object Example
protected void validateEntity() 
{ 
 super.validateEntity();
 if(attr1!=attr2) 
   throw new OARowValException ( 
        getEntityDef().getFullName(), // entity full definition name 
        getPrimaryKey(),              // entity object primary key 
        "FND",                        // message application short name
        "ATTR_EXCEPTION");            // message name 
}

View Row Example 
Also see the Mapping section below for additional information about raising these exceptions from a view row.
protected void validate() 
{ 
  super.validate(); 
  if(attr1!=attr2) 
    throw new OARowValException ( 
        getViewObject().getFullName(),//View Object full usage name
        getKey(),                     // row primary key 
        "FND",                        // message application short name
        "ATTR_EXCEPTION");            // message name
}

To display the translated text for a static styled text item,
For example, simply call its getText() method as shown (remember to always use any web bean accessor signatures that take OAPageContext as a parameter):
OAMessageStyledTextBean styledTextBean = (OAMessageStyledTextBean)webBean.findIndexedChildRecursive("itemName");
String itemText = styledTextBean.getText(pageContext);

Partial Page Rendering:
Step 5: In the application module that contains your application properties view object, add a method to set the application property values. For example, in the ToolBox Tutorial Sample Library we have a method called
handlePoApprovaChangeEvent() that reads the current value of the PPR event source poplist from the page's underlying entity object, and sets the appropriate property values as shown:
public void handlePoApproveChangeEvent()
{
   // Get the special, single-row application properties and make the first (only) row current.
   OAViewObject vo = (OAViewObject)findViewObject("SampleBrowserPVO1");
   OARow row = (OARow)vo.first();
   
   // Get the value of the view object attribute with the PO Approval status.
   OAViewObject poVO = (OAViewObject)findViewObject("PurchaseOrderHeadersVO1");
   OARow poRow = (OARow)poVO.getCurrentRow();
   String status = (String)poRow.getAttribute("StatusCode");
   
   // Set the application property values based on the PO Approval status value.
   if ("APPROVED".equals(status))
   {
     row.setAttribute("PoApproveRender", Boolean.TRUE); 
     row.setAttribute("PoRejectRender", Boolean.FALSE);
     row.setAttribute("PoApproveReadOnly", Boolean.TRUE); 
     row.setAttribute("PoApproveRequired", "yes");
   }
   else if ("REJECTED".equals(status))
   {
     row.setAttribute("PoApproveRender", Boolean.FALSE); 
     row.setAttribute("PoRejectRender", Boolean.TRUE);
   }
   else 
   {
     row.setAttribute("PoApproveRender", Boolean.TRUE); 
     row.setAttribute("PoRejectRender", Boolean.TRUE);
     row.setAttribute("PoApproveReadOnly", Boolean.TRUE); 
     row.setAttribute("PoApproveRequired", "no");
   }
} // end handlePoApproveChangeEvent()


public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
   super.processFormRequest(pageContext, webBean);
   OAApplicationModule am = 
    (OAApplicationModule)pageContext.getApplicationModule(webBean);
   String event = pageContext.getParameter("event");
   // If the user changes the value of the po approval poplist, call the event handler in the AM to set the appropriate SampleBrowserPVO values. 
   if ("poApproveChange".equals(event)) 
   {
     am.invokeMethod("handlePoApproveChangeEvent");
   }
   else if ("supplierSelect".equals(event))
   {
     am.invokeMethod("handleSupplierSelectionEvent"); 
   }
} // end processFormRequest()

·                     You can also explicitly display a message box of any type using the following code in your controller (this particular example displays a confirmation message after a successful commit).
processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
  // Get the purchase order number from the request.
  String orderNumber = pageContext.getParameter("headerId");
    
  MessageToken[] tokens = { new MessageToken("PO_NUMBER", orderNumber)};
  OAException message = new OAException("ICX", "FWK_TBX_T_PO_UPDATE_CONFIRM", tokens, OAException.CONFIRMATION, null);
  pageContext.putDialogMessage(message);
}

·                     Attribute-Level Validation
As described in Implementing the View in Chapter 3, whenever an HTTP POST request is issued for a page with updateable values, OA Framework writes those values back to the underlying view object, which in turn writes the values to the underlying entity object(s) by calling its setters. 
Since each attribute's validation should be added to its setters (see the ToolBox
PurchaseOrderHeaderEOImpl's setHeaderId() method below as an example), the process of calling the entity object setters executes attribute-level validation.
If you specify any declarative validation (for example, you indicate in the JDeveloper Entity Object Wizard that an attribute cannot be updated after it is saved), this validation is performed in the setAttributeInternal() method that you should call after executing your own validation logic. It is also checked in  validateEntity().
/*
 * Sets the PO Header Id. 
 * Business Rules:
 * Required; cannot be null.
 * Cannot be updated on a committed row.
 */
public void setHeaderId(Number value)
{
  // BC4J validates that this can be updated only on a new line. This
  // adds the additional check of only allowing an update if the value
  // is null to prevent changes while the object is in memory.

  If (getHeaderId() != null)
  {
    throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
                                 getEntityDef().getFullName(), // EO name
                                 getPrimaryKey(), // EO PK
                                 "HeaderId", // Attribute Name
                                 value, // Attribute value
                                 "ICX", // Message product short name
                                 "DEBUG -- need message name"); // Message name
  }
  if (value != null)
  {
    OADBTransaction transaction = (OADBTransaction)getOADBTransaction();
     
    // findByPrimaryKey() is guaranteed to first check the entity cache, then check
    // the database. This is an appropriate use of this method because finding a   
    // match would be the exception rather than the rule so we're not worried 
    // about pulling entities into the middle tier.
  
    Object[] headerKey = {value};
    EntityDefImpl hdrDef = PurchaseOrderHeaderEOImpl.getDefinitionObject();
    PurchaseOrderHeaderEOImpl hdrEO = (PurchaseOrderHeaderEOImpl)hdrDef.findByPrimaryKey(transaction, new Key(headerKey));

    if (hdrEO != null)
    {
      throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
                                   getEntityDef().getFullName(), // EO name
                                   getPrimaryKey(), // EO PK 650
                                   "HeaderId", // Attribute Name
                                   value, // Attribute value
                                   "ICX", // Message product short name
                                   "FWK_TBX_T_PO_ID_UNIQUE"); // Message name
    }
  }

  // Executes declarative validation, and finally sets the new value.
  setAttributeInternal(HEADERID, value);
} // end setHeaderId()


Different "Set" Methods
There are several different ways of setting values within an entity object. In your code, you most often call set<AttributeName>() and setAttributeInternal(). See Entity Object and View Object Attribute Setters for additional information about all the possible options.

·                     Cross-Attribute Validation
Any validation involving two or more attribute values on the entity should be included in the validateEntity() method; do not include any  cross-attribute validation in an individual attribute's setter since attribute values can be set in any (random) order.
You may reference attribute values from referenced entities in your attribute-level validation.

Entity Validation
Whenever OA Framework sets entity object values during an HTTP POST processing cycle, it always validates any view object rows that it touches, which in turn calls validateEntity() on the underlying  entity object(s). Furthermore, entities are validated again prior to posting (up to 10 times in a composition).
Any logic which operates at the row level -- and is not particularly sensitive to being called repeatedly -- should be included in the validateEntity() method. 
The following PurchaseOrderHeaderEOImpl code illustrates typical entity-level validation:
/*
 * Performs entity-level validation including cross-attribute validation that
 * is not appropriately performed in a single attribute setter.
 */
protected void validateEntity()
{
  super.validateEntity();
   
  // If our supplier value has changed, verify that the order is in an "IN_PROCESS"
  // or "REJECTED" state. Changes to the supplier in any other state are disallowed. 
  // Note that these checks for supplier and site are both performed here
  // because they are doing cross-attribute validation.

  String status = getStatusCode();
  if ((("APPROVED")Equals(status)) || ("COMPLETED"Equals(status)))
  {
    // Start by getting the original value and comparing it to the current
    // value. Changes at this point are invalid.
    
    Number oldSupplierId = (Number)getPostedAttribute(SUPPLIERID);
    Number currentSupplierId = getSupplierId();

    if (oldSupplierId.compareTo(currentSupplierId) != 0)
    {
      throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
                                   getEntityDef().getFullName(), // EO name
                                   getPrimaryKey(), // EO PK
                                   "SupplierId", // Attribute Name
                                   currentSupplierId, // Attribute value
                                   "ICX", // Message product short name
                                   "FWK_TBX_T_PO_SUPPLIER_NOUPDATE"); // Message name
    }
     
    // If our supplier site has changed, verify that the order is in an "IN_PROCESS"
    // state. Changes to the supplier site in any other state are disallowed.
    Number oldSiteId = (Number)getPostedAttribute(SUPPLIERSITEID);
    Number currentSiteId = getSupplierSiteId();

    if (oldSiteId.compareTo(currentSiteId) != 0)
    {
      throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
                                  getEntityDef().getFullName(), // EO name
                                  getPrimaryKey(), // EO PK
                                  "SupplierId", // Attribute Name
                                  currentSiteId, // Attribute value
                                  "ICX", // Message product short name
                                  "FWK_TBX_T_PO_SUPSITE_NOUPDATE"); // Message name
    }
  } 

  // Verify that our supplier site is valid for the supplier and make sure it is an active "Purchasing" site.
  SupplierEntityExpert supplierExpert =  SupplierEOImpl.getSupplierEntityExpert(getOADBTransaction());

  if (!(supplierExpert.isSiteValidForPurchasing(getSupplierId(), getSupplierSiteId())))
  {
    throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
                                 getEntityDef().getFullName(), // EO name
                                 getPrimaryKey(), // EO PK
                                 "SupplierSiteId", // Attribute Name
                                 getSupplierSiteId(), // Attribute value
                                 "ICX", // Message product short name
                                 "FWK_TBX_T_PO_SUPSITE_INVALID"); // Message name
  }
} // end validateEntity();

·                     Calling PL/SQL Functions and Procedures
Even when writing Java entity objects, you might need to call PL/SQL functions or procedures. 
Note: Do not use JDBC to perform simple SQL statements. Always leverage view objects for this purpose. If possible, you should define the view object declaratively.
In general, to invoke a stored procedure from within an entity object or an application module, you need to:
1. Create a JDBC CallableStatement with the PL/SQL block containing the stored procedure invocation
2. Bind any variables. 
3. Execute the statement. 
4. Optionally retrieve the values of any OUT parameters. 
5. Close the statement. 
The following application module example shows how to create and use a CallableStatement in an entity object.
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Types; 
OADBTransaction txn = getDBTransaction();
CallableStatement cs = txn.createCallableStatement("begin dbms_application_info.set_module(:1, :2); end;");  

try 
{ 
  cs.setString(1, module); 
  cs.setString(2, action); 
  cs.execute(); 
  cs.close();
} 
catch  (SQLException sqle) 
{ 
  try { cs.close } catch (Exception(e) {}
  throw OAException.wrapperException(sqle);
}

This example illustrates an OUT parameter: 
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Types; 
import oracle.jdbc.driver.OracleCallableStatement;

DBTransaction txn = getDBTransaction();
String sql = "BEGIN :1 := FND_MESSAGE.GET; END;";
CallableStatement cs = txn.createCallableStatement(sql, 1);
String messageBuffer = "";
     
try
{
  ((OracleCallableStatement)cs.registerOutParameter(1, Types.VARCHAR, 0, 2000);
  cs.execute();
  messageBuffer = cs.getString(1);
  cs.close();
}
catch (SQLException sqle)
{
  try { cs.close } catch (Exception(e) {}
  throw OAException.wrapperException(sqle);

}

No comments:

Post a Comment

Best Blogger TipsGet Flower Effect