This chapter provides a quick reference for common development tasks. The details are described in the Cookbook chapter.
Contents
Creating MOs and Maintenance Transactions
Building the Application Viewer
Contents
Hooking into UI Javascript User Exits
Hooking into Java User Exits (interceptors)
UI pages can have various events extended in order to add to or possibly override base product behavior. To create a Javascript user exit:
· Identify the page to extend.
· Create a JSP extension file (.xjs file) for the given page containing the necessary method for the given action.
· Identify user exits to code.
· Code the desired user exit logic into the JSP extension file.
Interceptors allow additional logic to be executed before or after the invocation of a service. To implement an interceptor:
· Identify the page to extend.
· Identify the interceptor interface to implement.
· Create an interceptor class.
· Code the desired logic into the interceptor class.
· Register the class in CMServiceConfig.xml.
Business entities are the Java representation of persistent data in the system. These objects are transparently initialized and persisted into the database. Many entities are already defined by the base application but may be extended through customization. Likewise, new entities may be created which expose custom tables as business entities.
There are two kinds of hand-coded logic associated with business entities: logic that exposes useful methods to the outside world and logic that is used within the entity itself to perform validation and handle the cascading effects of its changes in state.
Logic exposed to outside callers is what is coded on the business entity's implementation class (the "Impl") class. These "business methods" are then generated onto the entity's "business interface" (e.g. the Person interface). The business interface is the contract that the entity has with other objects.
Quite another thing is how an entity validates and otherwise deals with its changes of state. This is event-driven logic that is not exposed to outside callers and never belongs on the business interface. This type of interface is commonly referred as a "specialization interface" rather than a "business interface" and is coded in change handlers. Unlike a business interface, which receives messages from other objects, a specialization interface is one that provides a mechanism purely for extension of some baseline behavior. In that spirit, the framework design clearly separates the two kinds of code.
Contents
Extending the Business Interface
Extending the Specialization Interface
Creating New Business Entities
Specifying the Business Interface
Specifying the Specialization Interface
· Create a new implementation class.
· Specify appropriate annotations for an extension implementation class.
· Code business methods.
· Generate artifacts.
· Create a JUnit test.
· Generate artifacts.
· Run JUnit tests.
· Deploy to runtime.
· Test in runtime.
· Create a new change handler.
· Specify appropriate annotations for a change handler.
· Code specialization interface.
· Generate artifacts.
· Create a JUnit test.
· Generate artifacts.
· Run JUnit tests.
· Deploy to runtime.
· Test in runtime.
Business entities are the object representation of persistent data in the database. To create a new business entity the tables, fields and other meta-data should have already been defined in corresponding meta-data tables. Likewise, the schema objects must already be in the database. Having completed these steps, the business entity is defined to the Java programming and runtime environment by:
· Create a new implementation class.
· Specify appropriate annotations for an implementation class.
· Code business methods.
· Create a JUnit test.
· Generate artifacts.
· Run JUnit tests.
· Deploy to runtime.
· Test in runtime.
· Create a new change handler.
· Specify appropriate annotations for a change handler.
· Code specialization interface, if any.
· Create a JUnit test.
· Generate artifacts.
· Run JUnit tests.
· Deploy to runtime.
· Test in runtime.
Not all maintenance logic can go in the initial application's Maintenance. For instance, how can you retrieve the description of a foreign key whose table does not exist in that application?
An "extension" methodology exists whereby an existing page can have behavior added to it at predetermined plug-in points.
This is done by having a list of maintenance extensions that can be supplied for any given maintenance. At runtime, this list is kept and when a maintenance is initialized, new instances of its extensions are created. These extensions are called after any original maintenance behavior, and in the order of loaded applications. This means that the extensions should have no dependence on what other extensions have run, excepting the original maintenance having run.
· Create a new maintenance extension class.
· Specify the annotations required for a maintenance extension.
· Code desired logic in appropriate methods (see AbstractMaintenanceExtension).
· Generate artifacts.
· Code JUnit tests.
· Run JUnit tests.
· Deploy to runtime.
· Test in runtime.
Business Components provide a mechanism to provide non-persistent business logic (as opposed to business entities that add to persistent objects). An example business component is as follows:
/**
* Component used to query for {@link Person} instances based on various
* predefined criteria.
*
* @BusinessComponent
* (customizationReplaceable = false)
*/
public class PersonFinders_Impl
extends GenericBusinessComponent
implements PersonFinders
/**
* @param nameType a name type
* @return count of names by name type
*
* @BusinessMethod (customizationCallable = true)
*/
public int findCountByNameType(Lookup nameType) {
Query query = createQuery
("FROM PersonName name where name.nameType = :type");
query.bindLookup("type", nameType);
return (int) query.listSize();
}
To add a new component:
· Create a new implementation class.
· Specify appropriate annotations for a business component implementation class.
· Code business methods.
· Specify appropriate annotations for business methods.
· Create a JUnit test.
· Generate artifacts.
· Run JUnit tests.
· Deploy to runtime.
· Test in runtime.
Algorithms provide a powerful and flexible way of extending applications that use the Oracle Utilities Software Development Kit.
Algorithm spots in the application identify different areas that can be extended or customized by implementers. Each algorithm spot defines a set of inputs (typically via set- methods) and output (typically by get- methods).
During implementation, implementers can either re-use existing algorithm types or create new plug-in algorithm. To add a new plug-in algorithm, an implementer will follow these steps:
· Identify the plug-in spot.
· Create an algorithm component.
· Specify appropriate annotations for algorithm component.
· Code the desired logic into the invoke() method.
· Code methods to implement the algorithm spot interface.
· Create a JUnit test.
· Generate artifacts.
· Run JUnit tests.
· Deploy to runtime.
· Create a java class to perform a special plug-in action. This typically would be a modified version of an existing plug-in class. Refer to the algorithm spot definition for the various parameters that are available. In writing it, look out for possible soft parameters that will add flexibility to the plug-in.
· Add an Algorithm Type to correspond to the new plug-in behavior. This includes naming the java class that was created in the previous step. In addition, the soft parameters that are expected by the algorithm are also defined here.
· Create Algorithm specifying the specific algorithm parameter values where applicable. If the algorithm type is flexible enough, it may end up being reused in multiple algorithms, each having a different set of soft parameter values.
· Add the algorithm to the appropriate control table's algorithms. With this step, the plug-in is available to the application.
· Test in runtime.
The framework application supports one portal, Dashboard, which can contain a configurable set of zones that show diverse information.
To create a custom zone:
· Meta-data to define the zone and its parameters
· A Java handler class
To create a new zone:
· Use the ServiceZoneHandler class
· Create a Page Service containing required data
· Create or reuse XSLT template file
· Define meta-data declaring the zone and its parameters
To create a background process, there are three important classes that need to be created.
· An implementation of com.splwg.base.api.batch.BatchJob. This is the "driver" and should:
· Include a "BatchJob" class annotation
· Extend a generated superclass. In the case where the batch job is named "Foo", the generated superclass will be "Foo_Gen".
· An implementation of com.splwg.base.api.batch.ThreadWorker. This is responsible for processing the work distributed to a processing thread. By convention, this is coded as a static inner class within the BatchJob class implementation described above. If the file becomes excessively large, the worker can be split into its own source file. The worker class extends a generated abstract superclass. In the case of the "Foo" batch job, the worker should be named FooWorker and extend "FooWorker_Gen".
· At least one test class extending com.splwg.base.api.testers.BatchJobTestCase. This class will perform automated tests on the batch process. The runs are performed within the test thread and transaction and all changes are rolled back at the end of the test.
After creating the background process, a corresponding entry should be made in the Batch Control table referencing the created BatchJob’s class.
An example batch Job is com.splwg.base.domain.todo.batch.BatchErrorToDoCreation and the test is BatchErrorToDoCreationTest.
BatchJob classes can be tested with JUnit in two ways:
· Extending the BatchJobTestCase class and implementing abstract methods.
· Calling the submitBatchJob(SubmissionParameters) method in any ContextTestCase. This allows testing a mix of one or more background process and other business logic to be tested.
In both of these approaches, the normal commit and rollback logic of BatchJobs is subverted so that all updates performed by the batch process are rolled back when the test completes, either successfully or unsuccessfully. Therefore, these JUnit tests provide a safe way to test batch processes without making irreversible database updates.
A typical development of a new MO and its corresponding maintenance transaction entails the following steps:
· Create database objects, i.e., tables, indexes, etc.
· Enter database type of meta-data using online application from the Admin Menu. This includes:
· Field
· Table
· Table/Field
· Constraints
· Enter MO meta-data using the online system from the Admin Menu.
· Create the entity, changeHandler, and maintenance impl (implementation) classes using Eclipse.
· Generate artifacts based on the impl classes using the Artifact Generator. The artifact generator must also be executed whenever annotations and/or meta-data are changed.
· Add business rules on either the entity or changehandler using Eclipse.
· Create business components, if necessary, in Eclipse.
· Create test classes and then execute JUnit tests in Eclipse.
· If necessary, update maintenance impl class annotation to include fields with derived values using Eclipse. Regenerate artifacts after changing annotation. This generates the service metainfo.
· Add business logic on maintenance impl classes using Eclipse.
· Create maintenance test classes and then execute JUnit tests in Eclipse.
· Create search impl classes using Eclipse.
· Create search test classes and then execute JUnit tests in Eclipse.
· Create a new Maintenance Object from the Admin Menu -> Maintenance Object. This would automaticaly create the Tab Menus and Tab Pages necessary for a new transaction. This will also create the appropriate navigation key for each program component.
· Create javascript user exits for UI program components (e.g. tab menu, tab page, list grid, etc.).
· Add security access to the new application service.
· Create Menu entry for new application service.
· Launch Tomcat server and test the new application service.
Building General Purpose Maintenances
The steps for developing general-purpose maintenances are similar to those for MO-based maintenances, above, but without the need to rely on entity or MO metadata.
· Create the maintenance impl (implementation) classes using Eclipse.
· Generate artifacts based on the impl classes using the Artifact Generator. The artifact generator must also be executed whenever annotations and/or meta-data are changed.
· Create business components, if necessary, in Eclipse.
· Create test classes and then execute JUnit tests in Eclipse.
· If necessary, update maintenance impl class annotation to include fields with derived values using Eclipse. Regenerate artifacts after changing annotation. This generates the service metainfo.
· Add business logic on maintenance impl classes using Eclipse.
· Create maintenance test classes and then execute JUnit tests in Eclipse.
· Create javascript user exits for UI program components (e.g. tab menu, tab page, list grid, etc.).
· Add security access to the new application service.
· Create Menu entry for new application service.
· Launch Tomcat server and test the new application service.
The Application Viewer is used to display information extracted from products. This information is stored in the form of XML files. These files are built using a combination of batch jobs (run from Batch Job Submission) and utility scripts.
Each process (batch job or utility tool) can be run independently as each of them is responsible for creating separate Application Viewer components.
Javadocs can be created for CM source code. They are designed to be integrated into the product’s Javadocs that are delivered in the Application Viewer.
The product’s Javadocs are only delivered for objects or supporting objects that are intended to be referenced by CM code. For instance, only the domain and api packages are included, and some of the files created by the artifact generator are not delivered since they have no practical relevance to CM code. These files have been deliberately and explicitly omitted when creating the product’s Javadocs.
Note that the process that generates Javadocs on CM source code is not selective, and running Javadocs on CM source code may include more object types than what is delivered with the product’s Javadocs.
There is one location that is used for both the product and CM Javadocs. Because they share the same location, there are two steps involved in creating CM Javadocs.
Contents
Prerequisite: all artifacts need to be generated and the code needs to be compiled without errors.
The first step is to generate Javadocs for CM code. The standard behavior of the Javadoc tool is to create indices that show the packages and classes of the source code that the tool was run on. The resulting indices will only show links to the CM classes and not the product’s. To recreate the indices so that they include both the CM and the product’s Javadocs, follow the next step.
A utility script can recreate the Javadoc indices to include both the CM and the product’s Javadocs. The script will scan the files in the Javadoc directory and recreate the indices based on the files that it finds.