Document Tree
Document Properties
Kbid
235F47
Last Modified
04-Nov-2021
Added to KB
21-Sep-2012
Public Access
Everyone
Status
Online
Doc Type
Concepts
Product
  • ICM 7.10
  • ICM 11
  • ICM 12
Concept - Object Validation

Introduction

As business objects become increasingly complex, it is necessary to inform shop managers about invalid or incomplete objects that would result in a bad user experience of the storefront. The first steps taken into this direction include the introduction of the shop statistics feature and the enhancement of the advanced product and content search. The provided solution relies on the assumption that a validation for an object can be completely implemented via SQL queries, but, especially in regard to newer content management features, this approach is no longer sufficient.

A new framework has been introduced that is able to validate any business object according to rules of any complexity. The rules can be executed asynchronously, and the results may be stored persistently so that the shop managers can easily look into and fix the detected issues. This feature can also be used to give the back office user immediate feedback when editing single business objects.

This concept only describes the generic object validation framework. How the framework is applied for validating concrete business objects such as content pages or includes or how validation results are brought to and displayed in the back office will be covered in the concept documents for the specific business objects.

References

Please also have a look at the related cookbook for related common questions: Cookbook - Object Validation .

Glossary

BO

Business Object (see here)

PO

Persistent Object

VR

Validation Result

VRBO

Validation Result BO

VRBORepo

VRBO Repository

VRPO

Validation Result PO

Framework Overview

The framework provides:

  • a business object repository to create transient and to create/get/remove persistent validation result BO
  • a validation rule factory interface that declares functionality for creating validation rules for specific objects
  • a validation rule interface that declares operations at rules
  • a validation result implementation that holds any important information about the rule and the result of its execution
  • an interface that declares methods to persist validation results
  • a validation context implementation that provides any important information about the context/scope of the rule execution
  • an ORM abstraction layer to persist validation results
  • an XML handler to serialize/deserialize validation result meta information
  • an object validator implementation that uses a validation rule set provider and validation context to provide validation results after object validation

The diagram above shows all programming artifacts involved in object validation and their relations and dependencies. The red object is the object that is validated. The blue rectangles mark implementations provided by the framework. The green rectangles mark interfaces provided by the framework that need to be implemented in the different tracks (e.g., for content validation). Continuous lines mean that one component uses a function of another component, dashed lines mean that one component has another component as a member variable or at least parts of it (like that rule ID of a validation rule).

To validate an object, the object validator needs to know the validation rule set provider that will return a number of specific validation rule factories. Each of these factories is able to create one specific validation rule. The validation context given to the object validator is injected into the rules, so that they have a specific context for which to run.

Each rule provides a number of validation results. These can be passed on to the validation BO repository to create validation BOs and, if requested, to persist the results using a validation result persistence factory.

Validation Result Business Object Repository

The validation result business object repository (VRBORepo) is the central point of this feature. It (directly or indirectly) uses all components described below.

The VRBORepo is responsible for the following tasks:

  • create transient VRBOs for a given validation result (VR)
  • create persistent VRBOs for a given VR
  • get VRBOs by searching them via ID, the ID must be achieved from a previously created VRBO
  • remove VRBOs and their appropriate VRPOs by looking them up by the validated object and/or executed rules and/or the context of the rule execution

The repository is able to create persistent and transient validation result BOs. The transient BOs can be used to validate an object and to display the validation results if there is no need to have the results persisted - e.g., at the end of a manual business object update performed by a shop manager. The transient BO cannot be retrieved again from the repository, a request for the BO with the ID of the transient BO will result in null.

The VRBORepo will be wired at the business object repository using the component framework. An extension factory is provided that is able to create one repository per business object. This factory needs to be enhanced with two things:

  • a number of validation result persistence factories
  • a number of validation rule factories

The implementations of these factories need to be wired using the component framework. But they need to be provided by each business track (like content or product). However, on creation of a VRPORepo, the repository will get these from its factory and afterwards can use them either to return rule factories for specific objects or to create persistent validation results.

As there is a deletion propagation mechanism (see below) to remove validation result POs if the validated object is removed, there is no way to directly remove any validation result BO by the repository. But there is a feature implemented that allows for removing outdated validation results when, for example, performing a new object validation. To this end, the VRBORepo provides functions that will use the validated object, the (optional) rules for which the object was previously validated and a (optional) context for which the previous validation was executed - that is, all information one usually has when a validation process is currently running. So you can use it to remove an outdated result and create an updated one.

The validation result BO repository implementation is also registered as an object mapper. This concept allows you to use the query framework to retrieve queries that will return BOs in their result sets. The repository implementation is used to look up the VRBOs, and to find objects, an identifier class has been created: ValidationResultBOIdentifier. The following snippet demonstrates the potential usage:

<return-mappings>
    <return-mapping name="ValidationResultBO" type="bo-constructor" class="com.intershop.component.validation.capi.orm.ValidationResultBOIdentifier" mapperclass="ValidationResultPOToValidationResultBOMapper">
        <return-attribute name="uuid"/>
        <return-attribute name="factoryname" />
    </return-mapping>
</return-mappings>

Validation Result Persistence Factory

The validation result persistence factory interface defines methods to persist any incoming validation result. It creates validation result persistence objects that will be stored in the data base.

The interface should be implemented by any track (e.g., content or product) for its needs. To simplify the implementation of the VRPO, an abstract class ( com.intershop.component.validation.capi.orm.AbstractValidationResultPO<T>) is provided from which other objects should inherit. The abstract implementation is defined in its own EDL file from which the concrete implementations should inherit. This class implements the common methods of the validation result interface.

orm class MyValidationResultPO extends AbstractValidationResultPO table "MyValidationResult_VR"
{

}

The factory interface defines the isApplicable() method, which tells the caller whether the factory is able to persist the given business object (e.g., a content component). Or, clearly said, whether the factory is able to persist the relation(s) between the (to be) created VRPO and the given business object, as usually a business component does not need to be persisted by the factory (usually other factories handle the persistence of the business objects).

There is also an abstract implementation of the factory interface: com.intershop.component.validation.capi.orm.AbstractValidationResultPersistenceFactory<T extends ORMObject>. This implementation mainly helps by providing filter methods for getValidationResultPOsByOwner(T owner) using com.google.common.base.Predicate s.

A deletion propagation mechanism has been implemented that will delete all persistent validation results for you if the validated object was deleted. To automatically delete the created validation result POs, they need to inherit from AbstractValidationResultPO. While the server is started and the bc_validation cartridge is loaded, this deletion propagation mechanism is loaded and all validation result POs with their owner POs will be collected and registered.

Validation Context

The validation context holds the scope that should be checked by the rules. This means, for example, for a localized object, you can define that the rule should only check values for certain locales, or if a constraint is fulfilled for a given time frame.
Additionally the validation context can also hold variables the rule needs for rule evaluations, e.g., some domains/repositories/preferences that might be needed in evaluation of object relations.

The information is made up of:

  • locales- for which locale information the rules need to be executed
  • start date and end date- define a time span
  • additional parameters that are a map of string/object pairs and can be used to provide some other options for the rule execution

If none of this information is set, these values do not need to be taken into account by the rule execution.

Validation Rule, Validation Rule Factory and Validation Rule Set Provider

A validation rule is the class that performs the object validation. It returns a list of results (not one) depending on the context. If the context defines, for example, a list of locales the object should be checked for, the rule needs to return one result per locale. To execute the rule, the function validate(Object) has to be used.

The rules will be created by a rule factory that also has to inject the context into the created rule. One factory will only create one specific rule, but the context of the rules can differ. That means you can use the same factory two times with different contexts, and you will get the same rule but with different contexts. The factory also decides whether it is able to handle a specific business object. To this end, the function isApplicable(Object) must be used. As a rule factory only creates one single rule, the factory has knowledge about the rule ID of the rule it will create. The factory returns this ID using getRuleID().

The validation rule set provider is a container for validation rule factories. Whenever an object is validated, also a rule set provider must be given that defines the actual factories according to the object that is validated. There are currently two implementations for the ValidationRuleSetProvider interface that are both designed to be configured with rules via the component framework:

  • The validation result business object repository (that is used as a default at some places, if no specific provider is given)

      <fulfill of="ValidationResultBORepositoryExtensionFactory"
               requirement="validationRuleFactory"
               with="example.validation.rule.CategoryDisplayNames"/>
    
  • A generic container for rule factories

        <instance name="example.CategoryValidation.RuleSet" with="ValidationRuleSetProvider">
            <fulfill requirement="validationRuleFactory">
                <instance with="example.validation.rule.CategoryDisplayNames"/>
            </fulfill>
        </instance>
    

Validation Result and Validation Result Business Object

The validation result is the object that holds any relevant information about the output of the execution of a validation rule. The values are:

  • the validation time
  • the validated object
  • the ID of the rule
  • whether the rule validated the object positive or negative
  • information about the validation context: locale, start date and end date
  • meta information about the result
  • a message key and a list of message parameters

The result itself is a transient object, which can be persisted using a validation result persistence factory. Almost all values of the result are only readable, as they do not need to be changed afterwards. Only message key, message parameter and meta information can be changed once a result is created.

A validation result business object provides the business object view on the result.

XML Serialization of Meta Information

Meta information comes into play when a client wants store additional data along with a VR produced by a rule. For whatever reason such data will exist is entirely up to the client. The client in such cases can either be the rule itself or the responsible validation result persistence factory.

Suppose a validation rule for a page variant (i.e., a pagelet) wants to store the author of the object, but there is no place inside ValidationResult. Therefore the rule just needs to add the author as meta data putMetaData(String name, Object object). Along with the validation result persistence factory, the created persistent object receives the VR object (incl. meta data). If the persistent object is extending from the ORM abstract layer (i.e., AbstractValidationResultPO), then it will automatically benefit from the built-in JAXB value serializing mechanism. All that the validation result persistence factory needs to do is to call public final void applyValidationResult(ValidationResult<T> result) with the given VR object.

Meta data types
Simple meta data types, such as Integer, String, Date, etc., can be used without further administration effort. All other classes (like the author from the above example) must be registered so that a VR value containing meta-data values can be processed as an XML value. Registration is done automatically from the factory default implementation of VRBORepo. That means, when registering a ValidationRuleFactory(this step is always necessary, see the sections above) on the VRBO repository factory, meta-data types returned by ValidationRuleFactory.getMetaDataTypes() will be registered subsequently. Any custom VRBO repository factory must stick to this behavior. There is the class TypeRegistry in the capi package of bc_validation that allows a custom repository to fulfill this contract.

Object Validator

The object validator is the class that uses a rule set provider and a context to validate the given object. For any validation you need to instantiate a new object validator that will be initialized with one rule set provider and one context. Based on the given object, the object validator asks the rule set provider for a set of rule factories. The context then will be taken to create rules from these factories. After that, all created rules will be executed, and the results will be collected and returned to the caller.

Triggering Validation Within Pipelines

To actually perform object validation, two pipelets are provided: ValidateObject and ValidateObjects. They validate single objects or many objects in parallel running threads.

Validation Triggering via ORM Listening

The bc_validation cartridge provides a listener mechanism that allows to trigger a validation if any ORM object has been changed by a database transaction. This allows to keep validation results always consistent without the need of plug in pipelets in a possibly large amount set of pipelines responsible for a certain business object.

The main features are:

  • The configuration of the ORM listening triggered validation is done via the component framework. To this end, bc_validation provides a global object ORMValidator.
  • The ORMValidator can be filled with any number of (different) validation configurations.
  • Each validation configuration defines for themselves which objects are validated against defined rules.
  • Validation can occur within the modifying transaction or after that in a separate thread.

Basically, the process for a single configuration is a follows:

  1. Observe defined objects for modifications (including create and delete)
  2. Check if the application context and other conditions for the current execution context matches
  3. Map the modified persistent object to the persistent object that represents the business object that should be validated (e.g., an AttributeValuePO to its owner PO)
  4. Check if the object should be validated immediately within the same transaction or if it should be scheduled for later (both approaches can also be combined)
  5. For the immediate validation:
    1. Map the given PO object to the (BO) objects for actual validation
    2. Validate the (BO) objects and store the results
  6. For later scheduling:
    1. Create a task object
    2. Add the task object into the object validation task queue
    3. A validator thread takes the tasks from the queue and performs the validation (like for the immediate validation)
<fulfill requirement="configuration" of="ORMValidator">
	<instance with="ORMValidatorApplicationTypeConfigurationAssignment">
		<!--
		<fulfill requirement="app" with="intershop.EnterpriseBackoffice" />
		 -->
		<!-- keep the configuration in sync with configurations used in the pipelines -->
		<fulfill requirement="configuration">
			<instance with="ORMValidatorConfiguration" scope="global">
				<fulfill requirement="validationResultBORepositoryName" value="ValidationResultBORepository"/>
				<!-- <fulfill requirement="validationRuleSetProviderName" value="..."/> -->
				<!-- <fulfill requirement="validationContextProviderName" value="..."/> -->
				<fulfill requirement="storeMode" value="invalid"/>
				<fulfill requirement="removeMode" value="all"/>
				<fulfill requirement="objectListener">
					<instance with="ORMValidator.StandardListener">
						<fulfill requirement="factoryName" value="com.intershop.component.pmc.internal.pagelet.PageletPO"/>
						<fulfill requirement="factoryName" value="com.intershop.component.pmc.internal.pagelet.SlotPO"/>
					</instance>
				</fulfill>
				<fulfill requirement="immediateValidationHandler">
					<instance with="ORMValidator.DirectValidationHandler">
						<fulfill requirement="factoryName" value="com.intershop.component.pmc.internal.pagelet.PageletPO"/>
					</instance>
				</fulfill>
				<fulfill requirement="delayedValidationHandler">
					<instance with="ORMValidator.DirectValidationHandler">
						<fulfill requirement="factoryName" value="com.intershop.component.pmc.internal.pagelet.SlotPO"/>
					</instance>
				</fulfill>
				<!-- <fulfill requirement="contextFilter" >
					 <instance with="..."/>
				</fulfill> -->
			</instance>
		</fulfill>
	</instance>
</fulfill>

ORMValidator.StandardListener
Defines for which objects is listened by simple declaring the according ORM factory names. If an event occurs normally, the listened object is returned for being validated. Only if it is an attribute value PO, the owner objects is returned for validation.

ORMValidator.DirectValidationHandler
This validation handler actually does nothing other than filtering. This means, it returns the given PO as the (BO) object for validation. The filtering is needed if different PO types need another handling.

The threads for the delayed validation can be configured:

intershop.ORMValidator.DelayedValidation.TaskQueue.size = 1000
intershop.ORMValidator.DelayedValidation.Thread.count = 1
Disclaimer
The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.
Home
Knowledge Base
Product Releases
Log on to continue
This Knowledge Base document is reserved for registered customers.
Log on with your Intershop Entra ID to continue.
Write an email to supportadmin@intershop.de if you experience login issues,
or if you want to register as customer.