Externalizable Business Objects
What are externalizable business objects?
An Externalizable Business Object (EBO) is a class that implements an interface that extends the ExternalizableBusinessObject
interface. (Note that there is an interface involved that extends the EBO interface). This interface will define getter methods corresponding to the properties that are exposed.
An EBO is a business object with the following properties:
- All business objects belong to a module. An EBO will be owned by an optional module and accessed by a (optional or core) module that does not own it.
- It has the potential to be stored in a data repository that may be different from the main database, if the implementing institution so desires.
- Any access to the EBO from another module will be read-only.
Creating an Externalizable Business Object
The Contracts and Grants (CG) is an optional module within KFS, and some CG business objects will be accessed/referenced by the Chart of Accounts (COA) module. For example, the CG business object Cfda (for Catalog of Federal Domestic Assistance) is accessed as a reference object of the COA module's Account business object.
Step 1: Create a sub-interface to Externalizable Business Object
The first step is to create an interface that extends ExternalizableBusinessObject
that has getter methods for the fields that should be exposed to other modules. If the getter method returns a BusinessObject
that is not in a core module, then the return type should be an interface that extends ExternalizableBusinessObject
as well.
package org.kuali.kfs.integration.cg; import org.kuali.kfs.kns.bo.ExternalizableBusinessObject; public interface ContractsAndGrantsCfda extends ExternalizableBusinessObject { public String getCfdaNumber(); public String getCfdaProgramTitleName(); public boolean getCfdaStatusCode(); public String getCfdaMaintenanceTypeId(); }
All EBO sub-interfaces should be in a sub-package of an "integration" package corresponding to the module that owns it. For example, since Cfda is a CG business object, it is in the org.kuali.kfs.integration.cg
package.
Step 2: Register the module-specific integration sub-package to the appropriate module service
Now that we've created an EBO interface, we need to let the appropriate module that owns it know that it is responsible for the EBO interface. To do so, we register an additional package under the "packagePrefixes" section of the module configuration.
In our example, the CG module will be responsible for the ContractsAndGrantsCfda
interface because the module will own the package in which the interface resides.
<bean id="cgModuleConfiguration" parent="cgModuleConfiguration-parentBean" /> <bean id="cgModuleConfiguration-parentBean" class="org.kuali.kfs.sys.FinancialSystemModuleConfiguration" abstract="true"> <!-- other properties of the module configuration bean --> <property name="packagePrefixes"> <list> <value>org.kuali.kfs.module.cg</value> <value>org.kuali.kfs.integration.businessobject.cg</value> <!-- this item was added to support EBOs --> </list> </property> </bean>
Step: Specify the implementation class of the ExternalizableBusinessObject
sub-interface
This step only applies if the actual implementation class is a business object that is persisted in OJB.
The base implementation of the module service, ModuleServiceBase
, assumes that the EBO is implemented by a class that is persisted in OJB (i.e. really internal to KFS).
If the actual implementation does not reside within OJB (i.e. the data comes from another data repository), then the developer will need to subclass ModuleServiceBase
and override the appropriate methods related to EBOs.
The next step is to specify the implementation classes for the ExternalizableBusinessObject
sub-interface. This allows the system to determine, given a ExternalizableBusinessObject
, what is the concrete implementation class?
<bean id="cgModuleConfiguration" parent="cgModuleConfiguration-parentBean" /> <bean id="cgModuleConfiguration-parentBean" class="org.kuali.kfs.sys.FinancialSystemModuleConfiguration" abstract="true"> <!-- other properties of the module configuration bean --> <property name="packagePrefixes"> <list> <value>org.kuali.kfs.module.cg</value> <value>org.kuali.kfs.integration.businessobject.cg</value> </list> </property> <property name="externalizableBusinessObjectImplementations"> <map> <entry key="org.kuali.kfs.integration.businessobject.cg.ContractsAndGrantsCfda" value="org.kuali.kfs.module.cg.businessobject.Cfda" /> </map> </property> </bean>
In the "externalizableBusinessObjectImplementations" property, we define a map of EBO sub-interface class to concrete class mappings. The concrete class will implement the sub-interface. For the above example, it indicates that when a ContractsAndGrantsCfda
is encountered, that the Cfda
concrete should be used.
Upon completion of this step, when the data dictionary tries to access metadata about the ContractsAndGrantsCfda
interface, metadata from Cfda
is returned because it has been registered that ContractsAndGrantsCfda
's has been implemented by Cfda
.
Step 4: Implement relationships to EBOs
See Externalizable Business Objects 1-to-1 references and Externalizable Business Objects 1-to-n references