In ATG we come under various scenarios when we have to filter out a collection of the repositoryItems returned as part of an action/query based on specific conditions like RepositoryItems falling under a specific date range or repositoryItems falling under a particular site group or repositoryItems belonging to a paritcular user group etc. The respositoryItem could be anything ranging from products or Promotions or correspond to any custom repository.
This filtering is made possible in ATG by components of atg.service.collections.filter.ValidatorFilter class (we call them Filters) which extends CachedCollectionFitler class and component of classes that implement atg.service.collections.validator.CollectionObjectValidator (we call them validators).
The Filter components have validators property which is an array of Validator Components. These Filters are in turn used by a servlet beans to actually perform the filtration. As an example in CRS /atg/store/droplet/PromotionFilterDroplet uses /atg/store/collections/filter/PromotionFilter via “filter” property for filtering which in turn uses array of following Validators /atg/store/collections/validator/PromotionSiteValidator, /atg/store/collections/validator/PromotionDateValidator via “validators” property.
A Validator class implements the validateObject method of CollectionObjectValidator interface. This method takes an Object as parameter and should work only for the Objects of type RepositoryItem. It returns true if the repositoryItem passed fulfils the desired business logic(and hence will be included in final collection) else false (hence will be dropped from final collection).
A Filter usually overrides the generateFilteredCollection method of the CachedCollectionFitler which is understood to be returning null by default. The generateFilteredCollection method takes 3 parameters – A Collection object referring to the collection of repositoryItems to be filtered upon,a String object referring to items cache and RepositoryItem representing a profile. I don’t know what are the String and RepositoryItem are for but its ok to send them as null . Just pass the Collection that you want to filter. This method should have logic to loop through all the repositoryItems collection and for each repositoryItem loop through all the validators linked to the Filter and based on if it returns true or false keep the repositoryItem or drop it respectively. The final collection is returned.
The droplet/servlet bean from which the Filter is to be called, just call the filterCollection method of the Filter component and passing 3 parameters – collection(of repositoryItems) to be filtered, null , null. The filterCollection method of CachedCollectionFitler in turn would be calling generateFilteredCollection method of ValidatorFilter if hierarchy and component configuration is done correctly and return the Collection of filtered RepositoryItems.
All this info is good to understand but , For development you should just follow below steps :
- Find/Create Servlet bean/droplet where you want to filter a collection. Lets call it FilterThisDroplet
- Define a ‘filter’ property in FilterThisDroplet pointing to a filter component called CustomFilter
- CustomFilter component should point to atg.service.collections.filter.ValidatorFilter class
- Define a ‘validators’ property in CusomFilter component which should be an array of Validators Component. Lets say 2 validators for our case. Lets call these components CustomValidator1,CustomValidator2
- Build validator Classes for these Validator components. These classes should implement atg.service.collections.validator.CollectionObjectValidator interface. Lets call them CustomValidatorClass1, CustomValidatorClass2
- Each of these validator classes implement abstract method ofCollectionObjectValidator interface which accepts Object (this represents the RepositorItem).
- Apply your business logic to check if the passed Object fulfils the condition you want to set for filtering. If fits your filter return true else false.
- Finally in your servlet bean FilterThisDroplet call following – getFilter().filterCollection(collectionToFilter,null,null)
P.S. – The Validators and Filters are very commonly used for Promotions but can be applied anywhere you need. You can also define only the filters without validators for small logics.