Adding a new validation for the server side

In this step, you will add a new validation on the server side.

About this task

In the previous step, the OpenLaszlo client was validated. Client-side validation presents the user with a warning message upon validation failure. It does not prevent the user from subsequently saving the changes. Therefore, you must add validation in the server side to stop, save or update an action. In this step, you will add a new validation on the server side. The server side validation is implemented in Business Object Mediator. The file wc-business-object-mediator.xml configures the read and change mediators for business objects and business object parts. The line className="com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ChangeActivityMediator" can be found in Drive:\WCToolkitEE70\xml\config\com.ibm.commerce.marketing\wc-business-object-mediator.xml. The ChangeActivityMediator class is replaced with the new mediator. The following steps refer to implementing and registering a new mediator class, and creating a messagekey class and a properties file to define the error message.

Procedure

  1. Create a new messagekey class.
    1. Navigate to WebSphereCommerceServerExtensionsLogic > src. Right-click src and select New > Package. In the Name field, type com.mycompany.marketing.logging and click Finish.
    2. Create a new class file.
      1. Right-click com.mycompany.marketing.logging.
      2. Click New > Class.
      3. In the Name field, type MyMarketingMessageKeys and click Finish.
    3. Copy the following information into MyMarketingMessageKeys class:
      public class MyMarketingMessageKeys {
      	public final static String _APP_Marketingext_END_DATE_AFTER_START_DATE_Over10Days = "_APP_Marketingext_END_DATE_AFTER_START_DATE_Over10Days";
      	} 
    4. Click Save.
  2. Create a properties file.
    1. Navigate to WebSphereCommerceServerExtensionsLogic > src. Right-click src and select New > Package. In the Name field, type com.mycompany.marketing.logging.properties and click Finish.
    2. Right-click com.mycompany.marketing.logging.properties and select New > Other > General > File. In the Name field, type WcMarketingMessages.properties and click Finish.
    3. Right-click com.mycompany.marketing.logging.properties and select New > Other > General > File. In the Name field, type WcMarketingMessages_en_US.properties and click Finish.
    4. Copy the following information into both the WcMarketingMessages_en_US.properties and WcMarketingMessages.properties files:
      _APP_Marketingext_END_DATE_AFTER_START_DATE_Over10Days=Server error: The end date must be at least 10 days after the start date.
    5. Click Save.
  3. Create a new mediator class.
    1. In the Enterprise Explorer view, navigate to WebSphereCommerceServerExtensionsLogic > src.
    2. Right-click src and select New > Class. In the Name field, type MyChangeActivityMediator and in the Superclass field, type com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ChangeActivityMediator. In the Package field, type com.mycompany.marketing and click Finish.
    3. Copy the following information into the MyChangeActivityMediator class:
      package com.mycompany.marketing;
      import java.util.Date;
      import java.util.List;
      import java.util.logging.Logger;
      import com.ibm.commerce.foundation.common.exception.ApplicationError;
      import com.ibm.commerce.foundation.common.util.logging.LoggingHelper;
      import com.ibm.commerce.foundation.common.util.sdo.SDODataTypeHelper;
      import com.ibm.commerce.foundation.server.services.dataaccess.exception.DataMediatorException;
      import com.ibm.commerce.marketing.facade.datatypes.ActivityType;
      import com.ibm.commerce.marketing.facade.server.entity.datatypes.Dmactivity;
      import com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ChangeActivityMediator;
      import com.ibm.commerce.marketing.logging.MarketingApplicationMessageKeys;
      import com.mycompany.marketing.logging.MyMarketingMessageKeys;
      
      /**
      * This class extends ChangeActivityMediator and rewrites validateCreate and validateChange methods for validation of 
      * startdate and enddate of activities. Ensure that the end date is at least 10 days after the start date.
      */
      
      public class MyChangeActivityMediator extends ChangeActivityMediator {
      	
      	private static final String CLASSNAME = MyChangeActivityMediator.class
      			.getName();
      
      	private static final Logger LOGGER = LoggingHelper
      			.getLogger(MyChangeActivityMediator.class);
              /** 
                * This method is for verifying that the end date is at least 10 days after the start date. 
                *This method firstly call supper.validateCreate(),then do validation for startdate and enddate.  
                * If validation fails, a validation error message will be returned.
                * @return validationErrors
                */
      
             public List validateCreate(Object aNoun) throws DataMediatorException {
      		final String METHODNAME = "validateCreate";
      		if (LoggingHelper.isEntryExitTraceEnabled(LOGGER)) {
      			LOGGER.entering(CLASSNAME, METHODNAME, new Object[] { aNoun });
      		}
      		ActivityType activity = (ActivityType) aNoun;
      		try {
      			List validationErrors = super.validateCreate(aNoun);
      			// check that the end date is after the start date
      			Date startDate = null;
      			Date endDate = null;
      
      			startDate = SDODataTypeHelper.getXMLDateTime(activity
      					.getStartDate());
      			endDate = SDODataTypeHelper.getXMLDateTime(activity.getEndDate());
      			if (startDate != null && endDate != null) {
      				LOGGER.log(java.util.logging.Level.INFO,
      						"** this is validateCreate for startdate enddate **");
      				long days = (endDate.getTime() - startDate.getTime()) / 1000 / 3600 / 24;
      				LOGGER.log(java.util.logging.Level.INFO, String.valueOf(days));
      				if (days < 10) {
      					ApplicationError validateError = new ApplicationError(
      							ApplicationError.TYPE_GENERIC_ERROR,
      							MyMarketingMessageKeys._APP_Marketingext_END_DATE_AFTER_START_DATE_Over10Days,
      							null, LOGGER.getResourceBundleName());
      					validationErrors.add(validateError);
      				}
      			}
      			if (LoggingHelper.isEntryExitTraceEnabled(LOGGER)) {
      				LOGGER.exiting(CLASSNAME, METHODNAME, validationErrors);
      			}
      			return validationErrors;
      		} catch (DataMediatorException dme) {
      			throw dme;
      		}
      	}
      
         /** 
           * This method is for verifying the difference of more than 10 day between startdate and enddate. 
           *This method firstly calls supper.validateChange(),then does the validation for startdate and enddate.  
           * If the validation fail, validation error message will return.
           * @return validationErrors
           */
      
      	public List validateChange(Object aNoun) throws DataMediatorException {
      		final String METHODNAME = "validateChange";
      		try {
      			List validationErrors = super.validateChange(aNoun);
      			Dmactivity existingActivity = (Dmactivity) findPhysicalEntity(aNoun);
      			ActivityType activity = (ActivityType) aNoun;
      			Date startDate = null;
      			Date endDate = null;
      			String enddatestring = "enddate";
      			if (activity.getStartDate() != null) {
      				startDate = SDODataTypeHelper.getXMLDateTime(activity
      						.getStartDate());
      				if (startDate == null) {
      					ApplicationError validateError = new ApplicationError(
      							ApplicationError.TYPE_GENERIC_ERROR,
      							MarketingApplicationMessageKeys._APP_CAMPAIGN_INVALID_START_DATE,
      							null, LOGGER.getResourceBundleName());
      					validationErrors.add(validateError);
      				}
      			} else {
      				startDate = existingActivity.getStartdate();
      			}
      			if (activity.getEndDate() != null) {
      				endDate = SDODataTypeHelper.getXMLDateTime(activity
      						.getEndDate());
      				if (endDate == null) {
      					ApplicationError validateError = new ApplicationError(
      							ApplicationError.TYPE_GENERIC_ERROR,
      							MarketingApplicationMessageKeys._APP_CAMPAIGN_INVALID_END_DATE,
      							null, LOGGER.getResourceBundleName());
      					validationErrors.add(validateError);
      				}
      			} else {
      				endDate = existingActivity.getEnddate();
      			}
      			// check that the end date is after the start date
      			if (startDate != null && endDate != null) {
      				LOGGER.log(java.util.logging.Level.INFO,
      						"** this is validateChange for startdate enddate **");
      				long days = (endDate.getTime() - startDate.getTime()) / 1000 / 3600 / 24;
      				LOGGER.log(java.util.logging.Level.INFO, String.valueOf(days));
      				if (days < 10) {
      					ApplicationError validateError = new ApplicationError(
      							ApplicationError.TYPE_GENERIC_ERROR,
      							MyMarketingMessageKeys._APP_Marketingext_END_DATE_AFTER_START_DATE_Over10Days,
      							null, LOGGER.getResourceBundleName());
      					validationErrors.add(validateError);
      				}
      			}
      			if (LoggingHelper.isEntryExitTraceEnabled(LOGGER)) {
      				LOGGER.exiting(CLASSNAME, METHODNAME, validationErrors);
      			}
      			return validationErrors;
      		} catch (DataMediatorException dme) {
      			throw dme;
      		}
      	}}
        
    4. Click Save.
  4. Register the new mediator class.

    To use the MyChangeActivityMediator class, register the class in wc-business-object-mediator.xml. Create a directory com.ibm.commerce.marketing-ext extension folder to store the extended wc-business-object-mediator.xml file.

    1. Link the WCDE_installdir/xml/config folder to your workspace to simplify the customization of configuration files.
      1. In the Enterprise Explorer view, right-click Wc/xml/config and select New > Folder. Select Advanced and select the Link to folder in file system check box.
      2. Type config as the folder name.
      3. Click Browse and navigate to WCDE_installdir/xml/config.
      4. Click Finish.
    2. Create a marketing extensions configuration folder to hold custom configuration files. This naming convention is used at runtime to search for and load service module configurations.
      1. Right-click one of the following folders:
        • WebSphere Commerce Version 7.0.0.0Wc/xml/config
        • Feature Pack 1Wc/config
        • Feature Pack 2Feature Pack 3Wc/xml/config
        .
      2. Select New > Folder.
      3. Name the folder: com.ibm.commerce.marketing-ext.
      4. Click Finish.
    3. Create a new wc-business-object-mediator.xml file.
      1. Right-click com.ibm.commerce.marketing-ext.
      2. Select New > File.
      3. Name the file: wc-business-object-mediator.xml.
      4. Click Finish.
      5. Copy the following information into the wc-business-object-mediator.xml file:
        Note: The following code is copied to the file wc-business-object-mediator.xml from com.ibm.commerce.marketing to com.ibm.commerce.marketing-ext. You also need to replace com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ChangeActivityMediator with com.mycompany.marketing.MyChangeActivityMediator.
        <_config:BusinessObjectMediatorConfiguration
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/foundation/config ../xsd/wc-business-object-mediator.xsd"
        xmlns:_config="http://www.ibm.com/xmlns/prod/commerce/foundation/config" >
         <_config:object logicalType="com.ibm.commerce.marketing.facade.datatypes.ActivityType" 
                   physicalType="com.ibm.commerce.marketing.facade.server.entity.datatypes.Dmactivity">
              <_config:mediator
                  interfaceName="com.ibm.commerce.foundation.server.services.dataaccess.bom.mediator.ReadBusinessObjectMediator"
                  className="com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ReadActivityMediator">
                     <_config:part-mediator
        				         interfaceName="com.ibm.commerce.foundation.server.services.dataaccess.bom.mediator.ReadBusinessObjectPartMediator">
        					       <_config:part-mediator-implementation className="com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ReadCampaignElementMediator" />
                    </_config:part-mediator>
           		</_config:mediator>
              <_config:mediator
        				  interfaceName="com.ibm.commerce.foundation.server.services.dataaccess.bom.mediator.ChangeBusinessObjectMediator"
        				  className="com.mycompany.marketing.MyChangeActivityMediator"
        				  updateAccessProfile="IBM_Admin_Details">
             		     <_config:part-mediator
        				         interfaceName="com.ibm.commerce.foundation.server.services.dataaccess.bom.mediator.ChangeBusinessObjectPartMediator">
        					       <_config:part-mediator-implementation className="com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ChangeActivityPartMediator" />
        					       <_config:part-mediator-implementation className="com.ibm.commerce.marketing.facade.server.services.dataaccess.bom.mediator.ChangeCampaignElementPartMediator"
        					                                             updateAccessProfile="IBM_Admin_CampaignElements" />
                     </_config:part-mediator>
              </_config:mediator>		
              <_config:property-mapping logicalType="com.ibm.commerce.marketing.facade.datatypes.ActivityType"
                                 physicalType="com.ibm.commerce.marketing.facade.server.entity.datatypes.Dmactivity">
                          <_config:userDataProperty logicalPropertyName="customField1" physicalPropertyName="field1" />
                          <_config:userDataProperty logicalPropertyName="customField2" physicalPropertyName="field2" />
                          <_config:userDataProperty logicalPropertyName="customField3" physicalPropertyName="field3" />
                          <_config:userDataProperty logicalPropertyName="customField4" physicalPropertyName="field4" />
              </_config:property-mapping>    
              <_config:property-mapping logicalType="com.ibm.commerce.marketing.facade.datatypes.CampaignElementType"
                                 physicalType="com.ibm.commerce.marketing.facade.server.entity.datatypes.Dmelement">
                          <_config:userDataProperty logicalPropertyName="customField1" physicalPropertyName="field1" />
                          <_config:userDataProperty logicalPropertyName="customField2" physicalPropertyName="field2" />
                          <_config:userDataProperty logicalPropertyName="customField3" physicalPropertyName="field3" />
                          <_config:userDataProperty logicalPropertyName="customField4" physicalPropertyName="field4" />
              </_config:property-mapping>      		
           </_config:object>
        </_config:BusinessObjectMediatorConfiguration>  
        Note: IBM_Admin_ prefixes all services intended to be used by admin/CMC based services calls. Access profiles which do not follow the new naming conventions continue to function correctly, as compatibility is maintained with earlier versions. It is recommended, however, that they are followed for existing access profiles, and when making changes to future access profiles.
    4. Click Save.