Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers 10g (10.1.3.1.0) Part Number B25947-01 |
|
|
View PDF |
An application module can expose its data model of view objects to clients without requiring any custom Java code. This allows client code to use the ApplicationModule
, ViewObject
, RowSet
, and Row
interfaces in the oracle.jbo
package to work directly with any view object in the data model. However, just because you can programmatically manipulate view objects any way you want to in client code doesn't mean that doing so is always a best practice.
Whenever the programmatic code that manipulates view objects is a logical aspect of implementing your complete business service functionality, you should encapsulate the details by writing a custom method in your application module's Java class. This includes code that:
Configures view object properties to query the correct data to display
Iterates over view object rows to return an aggregate calculation
Performs any kind of multistep procedural logic with one or more view objects
By centralizing these implementation details in your application module, you gain the following benefits:
You make the intent of your code more clear to clients
You allow multiple client pages to easily call the same code if needed
You simplify regression-testing your complete business service functionality
You keep the option open to improve your implementation without affecting clients
You enable declarative invocation of logical business functionality in your pages.
To add a custom service method to your application module, you must first enable a custom Java class for it. If you have configured your IDE-level Business Components Java generation preferences to automatically generate an application module class, you're set. If you're not sure whether your application module has a custom Java class, as shown in Figure 8-3, check the context menu for the Go to Application Module Class option. This option lets you quickly navigate to your application module's custom class, but if you don't see the option in the menu then that means your application module is currently an XML-only component.
To enable the class, open the Application Module Editor, visit the Java page, select the Generate Java File checkbox for an Application Module Class, then click OK to finish the wizard.
For an application module named devguide.model.SRService
, the default name for its custom Java file will be SRServiceImpl.java
. The file is created in the same ./devguide/model
directory as the component's XML component definition file.
The Java generation options for the application module continue to be reflected on the Java page on subsequent visits to the Application Module Editor. Just as with the XML definition file, JDeveloper keeps the generated code in your custom java classes up to date with any changes you make in the editor. If later you decide you didn't require a custom Java file for any reason, unchecking the relevant option in the Java page causes the custom Java file to be removed.
By default, the application module Java class will look similar to what you see in Example 8-4 when you've first enabled it. Of interest, it contains:
Getter methods for each view object instance in the data model
A main()
method allowing you to debug the application module using the Business Components Browser
Example 8-4 Default Application Module Generated Code
package devguide.model; import devguide.model.common.SRService; import oracle.jbo.server.ApplicationModuleImpl; import oracle.jbo.server.ViewLinkImpl; import oracle.jbo.server.ViewObjectImpl; // --------------------------------------------------------------------- // --- File generated by Oracle ADF Business Components Design Time. // --- Custom code may be added to this class. // --- Warning: Do not modify method signatures of generated methods. // --------------------------------------------------------------------- public class SRServiceImpl extends ApplicationModuleImpl { /** This is the default constructor (do not remove) */ public SRServiceImpl() { } /** Sample main for debugging Business Components code using the tester */ public static void main(String[] args) { launchTester("devguide.model", /* package name */ "SRServiceLocal" /* Configuration Name */); } /** Container's getter for YourViewObjectInstance1 */ public ViewObjectImpl getYourViewObjectInstance1() { return (ViewObjectImpl)findViewObject("YourViewObjectInstance1"); } // ... Additional ViewObjectImpl getters for each view object instance // ... ViewLink getters for view link instances here }
As shown in Figure 8-4, your application module class extends the base ADF ApplicationModuleImpl
class to inherit all the default behavior before adding your custom code.
As you learn more about the overall business service role of the application module in this chapter, you'll find it useful to exercise your application module under the JDeveloper debugger while using the Business Components Browser as the testing interface. To debug an application module using the tester, select the application module in the Application Navigator and then either:
In the Application Navigator, right-click the application module and choose Go to Application Module Class from the context menu.
Select Debug from the right-mouse context menu in the code editor
To add a custom service method to an application module, simply navigate to application module's custom class and type in the Java code for a new method into the application module's Java implementation class. Use the following guidelines to decide on the appropriate visibility for the method. If you will use the method only inside this component's implementation as a helper method, make the method private
. If you want to allow eventual subclasses of your application module to be able to invoke or override the method, make it protected
. If you need clients to be able to invoke it, it must be public
. See the examples of the SRServiceImpl
methods in previous chapters.
Note: TheSRService application module in this chapter is using the strongly typed, custom entity object classes that you saw illustrated in the SRServiceImpl2.java example at the end of Chapter 6, "Creating a Business Domain Layer Using Entity Objects". |
Example 8-5 shows a private retrieveServiceRequestById()
helper method in the SRServiceImpl.java
class for the SRService
application module. It uses the static
getDefinition()
method of the ServiceRequestImpl
entity object class to access its related entity definition, uses the createPrimaryKey()
method on the entity object class to create an appropriate Key object to look up the service request, then used the findByPrimaryKey()
method on the entity definition to find the entity row in the entity cache. It returns an instance of the strongly typed ServiceRequestImpl
class, the custom Java class for the ServiceRequest
entity object.
Example 8-5 Private Helper Method in Custom Application Module Class
// In devguide.model.SRServiceImpl class /* * Helper method to return a ServiceRequest by Id */ private ServiceRequestImpl retrieveServiceRequestById(long requestId) { EntityDefImpl svcReqDef = ServiceRequestImpl.getDefinitionObject(); Key svcReqKey = ServiceRequestImpl.createPrimaryKey(new DBSequence(requestId)); return (ServiceRequestImpl)svcReqDef.findByPrimaryKey(getDBTransaction(), svcReqKey); }
Example 8-6 shows a public createProduct()
method that allows the caller to pass in a name and description of a product to be created. It uses the getDefinition()
method of the ProductImpl
entity object class to access its related entity definition, uses the createInstance2()
method to create a new ProductImpl
entity row whose Name
and Description
attributes it populates with the parameter values passed in before committing the transaction.
Example 8-6 Public Method in Custom Application Module Class
/* * Create a new Product and Return its new id */ public long createProduct(String name, String description) { EntityDefImpl productDef = ProductImpl.getDefinitionObject(); ProductImpl newProduct = (ProductImpl)productDef.createInstance2(getDBTransaction(),null); newProduct.setName(name); newProduct.setDescription(description); try { getDBTransaction().commit(); } catch (JboException ex) { getDBTransaction().rollback(); throw ex; } DBSequence newIdAssigned = newProduct.getProdId(); return newIdAssigned.getSequenceNumber().longValue(); }