Extending the Change History service for a custom module
To enable change history for a custom noun, you
must create Java classes that extend the abstract class AbstractChangeHistoryServiceDelegateImpl.
After you create the classes, they must be registered in wc-business-object-mediator.xml for
the customized module.
About this task
After the Java files are created, they must be registered
in wc-business-object-mediator.xml for the customized
module. The change history service uses a foundation class that is
common to all change history. The className
and interfaceName
are
common to all nouns. For your customized setup, you must add <_config:mediator-property>
elements
to specify the name of your noun and the class to use more services.
Procedure
To enable the change history service for a custom module:
- In the Project-Server/ejbModule directory, create a package and name it com.mycompany.commerce.project.changehistory.
- Import ProjectChangeHistoryServiceImpl.java and ProjectCollectionChangeHistoryServiceImpl.java into the package.
- Both Java classes have five methods that you must override
and provide your own implementation. The following methods must be
implemented:
- getObjectCodeForObject() – Returns the value of the noun you want to display in the history tab. This method can be configured to get whatever noun attribute makes the most sense to display. For a recipe object, it makes the most sense to display the name field.
- getStatementToFindObjectCode() – Returns a SQL statement that is used to retrieve noun information from the database.
- getUniqueID() – Retrieves the unique identifier (primary key) of the noun.
- getObjectStoreID() – Retrieves the unique store identifier of the object.
- getResolvedCMCObject() – Gets the logical name of the object that is used in Management Center.
Note: Depending on the complexity of your noun, other methods that are detailed in the documentation for com.ibm.commerce.foundation.server.services.changehistory.utility.AbstractChangeHistoryServiceDelegateImpl might also need customization.The following code is an example of the ProjectChangeHistoryServiceImpl.java file:
package com.mycompany.commerce.project.changehistory; import com.ibm.commerce.foundation.server.services.changehistory.exception.ChangeHistoryApplicationDelegateException; import com.ibm.commerce.foundation.server.services.changehistory.utility.AbstractChangeHistoryServiceDelegateImpl; import com.mycompany.commerce.project.facade.datatypes.ProjectExternalIdentifierType; import com.mycompany.commerce.project.facade.datatypes.ProjectIdentifierType; import com.mycompany.commerce.project.facade.datatypes.ProjectType; import commonj.sdo.DataObject; public class ProjectChangeHistoryServiceImpl extends AbstractChangeHistoryServiceDelegateImpl { private static final String UI_OBJECT_NAME = "Recipe"; /** * This method returns the value of your noun you want to be displayed in the Chnage History pane. * This can be configured to grab a name, number, etc, whatever makes the most sense for your noun. * For example for an recipe object it makes the most sense to display the name field. */ @Override protected String getObjectCodeForObject(Object noun) { if(noun instanceof ProjectType){ ProjectType pt = (ProjectType) noun; ProjectIdentifierType pit = pt.getProjectIdentifier(); ProjectExternalIdentifierType peit = pit.getExternalIdentifier(); if(peit != null){ return peit.getName(); } else { return null; } }else { return null; } } /** * This method returns a string that is the SQL to the unique ID. This is used elsewhere in case * the entire noun has not been retrieved then a SQL can be run to get the data instead. */ @Override protected String getStatementToFindObjectCode() { return "select PRJNAME from XPROJECT where XPROJECT_ID=?"; } /** * This method returns the unique ID of the change history object. Use getChangedDataObject() * to get the noun object then cast it as a DataObject. Use getString() of the dataObject * with the correct path as the parameter, here we want "ProjectIdentifier/UniqueID" */ @Override public Long getUniqueID() { Object noun = getChangedDataObject(); if(noun instanceof DataObject){ DataObject newNoun = (DataObject) noun; return Long.valueOf(newNoun.getString("ProjectIdentifier/UniqueID")); } else{ return null; } } // This method queries the SQL to get the Store ID of the object @Override public Long getObjectStoreID() throws ChangeHistoryApplicationDelegateException { Long storeId = null; final String storeidSQL = "select STOREENT_ID from XPROJECT where XPROJECT_ID = ?"; String storeidString; storeidString = executeQuery(storeidSQL); if (storeidString != null) { storeId = Long.valueOf(storeidString); } return storeId; } // This method is to get the object logical name used in CMC @Override public String getResolvedCMCObject() { return UI_OBJECT_NAME ; } }
The following code is an example of the ProjectCollectionChangeHistoryServiceImpl.java file:
package com.mycompany.commerce.project.changehistory; import com.ibm.commerce.foundation.server.services.changehistory.exception.ChangeHistoryApplicationDelegateException; import com.ibm.commerce.foundation.server.services.changehistory.utility.AbstractChangeHistoryServiceDelegateImpl; import com.mycompany.commerce.project.facade.datatypes.ProjectCollectionExternalIdentifierType; import com.mycompany.commerce.project.facade.datatypes.ProjectCollectionIdentifierType; import com.mycompany.commerce.project.facade.datatypes.ProjectCollectionType; import commonj.sdo.DataObject; public class ProjectCollectionChangeHistoryServiceImpl extends AbstractChangeHistoryServiceDelegateImpl{ private static final String UI_OBJECT_NAME = "RecipeCollection"; /** * This method returns the value of the noun you want to be displayed in the Change History pane. * This can be configured to grab a name, number, etc, whatever makes the most sense for your noun. * For example for a recipe collection object it makes the most sense to display the name field. */ @Override protected String getObjectCodeForObject(Object noun) throws ChangeHistoryApplicationDelegateException { if(noun instanceof ProjectCollectionType){ ProjectCollectionType pt = (ProjectCollectionType) noun; ProjectCollectionIdentifierType pit = pt.getProjectCollectionIdentifier(); ProjectCollectionExternalIdentifierType peit = pit.getExternalIdentifier(); if(peit != null){ return peit.getName(); } else { return null; } }else { return null; } } /** * Returns a string that is the SQL to the unique id. This is used elsewhere in case the * entire noun hasn't been retireved then a sql can be run to get the data instead. */ @Override protected String getStatementToFindObjectCode() { return "select PRJCOLNAME from XPRJCOL where XPRJCOL_ID=?"; } /** * Returns the unique ID of the change history object. Use getChangedDataObject() to get * the noun object then cast it as a DataObject. Use getString() of the dataObject with * the correct path as the parameter, here we want "ProjectCollectionIdentifier/UniqueID" */ @Override public Long getUniqueID() { Object noun = getChangedDataObject(); if(noun instanceof DataObject){ DataObject newNoun = (DataObject) noun; return Long.valueOf(newNoun.getString("ProjectCollectionIdentifier/UniqueID")); } else{ return null; } } // This method queries the SQL to get the Store ID of the object @Override public Long getObjectStoreID() throws ChangeHistoryApplicationDelegateException { Long storeId = null; final String storeidSQL = "select STOREENT_ID from XPRJCOL where XPRJCOL_ID = ?"; String storeidString = executeQuery(storeidSQL); if (storeidString != null) { storeId = Long.valueOf(storeidString); } return storeId; } // This method gets the object logical name used in CMC @Override public String getResolvedCMCObject() { return UI_OBJECT_NAME ; } }
- Next, for each
object
you must add a mediator to register the Java classes you implemented in the previous step.- Open WC_eardir/xml/config/com.mycompany.commerce.project/wc-business-object-mediator.xml.
- Find the Project
object
by locating this line:<_config:object logicalType="com.mycompany.commerce.project.facade.datatypes.ProjectType" physicalType= "com.mycompany.commerce.project.facade.server.entity.datatypes.Xproject">
- Immediately beneath the Project object, add the following mediator
code for the Project object:
- Create a
<_config:mediator>
element with aclassName
of .ibm.commerce.foundation.internal.server.services.changehistory.mediator.EchoBusinessObjectChangeHistoryMediatorImpl and aninterfaceName
of .ibm.commerce.foundation.server.services.dataaccess.bom.mediator.EchoBusinessObjectChangeHistoryMediator. See 1 in the sample file. - Create a set of
<_config:mediator-property>
elements for the change control mediator.nounName
indicates the name of the noun. For this tutorial, the value is Project.classNameForAdditionalService
indicates the implementation class for handing the change history for this noun. For this tutorial, the value is ProjectChangeHistoryServiceImpl. See 2. - Close the section with ending elements
</_config:mediator-properties>
and</_config:mediator>
. See 3.
- Create a
- Find the ProjectCollection
object
by locating this line:<_config:object logicalType="com.mycompany.commerce.project.facade.datatypes.ProjectCollectionType" physicalType= "com.mycompany.commerce.project.facade.server.entity.datatypes.Xprjcol">
- Immediately beneath the ProjectCollection object, add the following
mediator code for the ProjectCollection object:
- Create a
<_config:mediator>
element with aclassName
of .ibm.commerce.foundation.internal.server.services.changehistory.mediator.EchoBusinessObjectChangeHistoryMediatorImpl and aninterfaceName
of .ibm.commerce.foundation.server.services.dataaccess.bom.mediator.EchoBusinessObjectChangeHistoryMediator. See 4. - Create a set of
<_config:mediator-property>
elements for the change control mediator.nounName
indicates the name of the noun. For this tutorial, the value is ProjectCollection.classNameForAdditionalService
indicates the implementation class for handing the change history for this noun. For this tutorial, the value is ProjectChangeHistoryServiceImpl. See 5. - Close the section with ending elements
</_config:mediator-properties>
and</_config:mediator>
. See 6.
- Create a
- Save and close wc-business-object-mediator.xml.
Defined object mediators for the Recipe and RecipeCollection objects 1 <!-- PROJECT CHANGE HISTORY MEDIATOR --> <_config:mediator className="com.ibm.commerce.foundation.server.services.changehistory.mediator. EchoBusinessObjectChangeHistoryDelegateMediatorImpl" interfaceName="com.ibm.commerce.foundation. server.services.dataaccess.bom.mediator.EchoBusinessObjectChangeHistoryMediator">
2 <_config:mediator-properties> <_config:mediator-property name="nounName" value="Project" /> <_config:mediator-property name="classNameForAdditionalService" value="com.mycompany.commerce.project.changehistory.ProjectChangeHistoryServiceImpl" /> </_config:mediator-properties>
3 </_config:mediator-properties> </_config:mediator>
4 <!-- PROJECTCOLLECTION CHANGE HISTORY MEDIATOR --> <_config:mediator className="com.ibm.commerce.foundation.server.services.changehistory.mediator. EchoBusinessObjectChangeHistoryDelegateMediatorImpl" interfaceName="com.ibm.commerce.foundation. server.services.dataaccess.bom.mediator.EchoBusinessObjectChangeHistoryMediator">
5 <_config:mediator-properties> <_config:mediator-property name="nounName" value="ProjectCollection" /> <_config:mediator-property name="classNameForAdditionalService" value="com.mycompany.commerce.project.changehistory.ProjectChangeHistoryServiceImpl" /> </_config:mediator-properties>
6 </_config:mediator-properties> </_config:mediator>