Reference » Filters

Filters

Last modified by Andreas Hahn on 2011/06/10 22:23

A shept filter gets instantiated when the subForm is created. It becomes part of the subforms backing 'subCommand' object via the filter property. As such it takes part in springs form binding and all the filters member variables will be exposed to the view in the same way as model entity objects in a data grid through the source property. In a default configuration you should have one filter per subform.

In a shept context filters are registered on a segment or on a chain.

<bean name="addresses" parent="sheptDataGridTemplate">
 <!-- all your other segment properties
    ...
  -->

 <property name="filterClass"
  value="com.company.yourapp.web.controller.filters.YourExampleFilter" />
</bean>

A shept filter is an instance of FilterDefinition and basically wraps a hibernate query or criteria interface and adds an interface to enforce compliant object creation rules. It has two roles: it serves to 1) query objects in the traditional way from the database and it serves as a template to 2) create new objects. This way any of the forms you create are not limited to object query and editing but also allow object creation by default.

The FilterDefiition interface defines one abstract method

 public abstract ModelCreation getNewModelTemplate();

ModelCreation and ModelDeletion are the 2 entity lifecycle interfaces. It's just a tagged model entity object. It depends on the context if #getNewModelTemplate() in your implementation of FilterDefinition must comply to the rules of the filter. If it's a filter based on a relation or you are working on a multi-tenant application then of course you must honor the filters parameters. That should usually be straightforward as we will see in a few examples because it is a natural way to keep both the querying and creation information tightly together. 

The SheptDemo tutorial illustrates how to set up a simple PersonFilter. Now let's extend that to synchronize object creation with the filter parameters entered by the user. Here we extend the examples #getNewModelTemplate() definition (for illustration side by side with our filter definition):

@Override
public ModelCreation getNewModelTemplate() {
 // here we might as well do:
 // Person person = new Person();
 Person person = (Person) super.getNewModelTemplate();
  person.setFirstName(firstName);
  person.setName(name);
return person;
}
@Override
public DetachedCriteria getCriteria(SortDefinition sortDefinition) {
  DetachedCriteria crit = super.getCriteria(sortDefinition);
 if (StringUtils.hasText(name)) {
    crit.add(Restrictions.ilike("name", "%"+name+"%"));
 }
 if (StringUtils.hasText(firstName)) {
    crit.add(Restrictions.ilike("firstName", "%"+firstName+"%"));
 }
 return crit;
}

Keep in mind - it's just a template and the user input might override this 'suggested' person attributes. If we want to forbid a mismatch between filter criteria and new model creation we can do that on the view level.

<td>
 <form:input path="firstName" disabled="${isTransient}" cssErrorClass="fieldError" />
</td>
<td>
 <form:input path="name" disabled="${isTransient}" cssErrorClass="fieldError" />
</td>

This is an excerpt from the view definition in WEB-INF/tags/segments/tables/person.tagx. Note the disabled="${isTransient}" attribute we have added for the name and firstName attributes that have already been defined in the template. Now the user cannot overwrite the template input for new object creation - if he wants to change the name he has to resubmit a search with new parameters.

Note that you can tweak the conditions when and how a new object shall be created in every detail. The other places to customize behavior are the model lifecylce interface (ignoring incomplete objects), validators (forceful rejection also in the context of the result set) and transactions (silent failures and full rollbacks).

During a chain operation (e.g. the user clicks on a chain to open the next subForm) the filter of the newly created subForm will get initialized with the senders entity. When the subForm gets created it checks for an appropriate #initialize() method and then it will be exceuted.

Example Objects

Example Objects are the simplest form of declaring a filter. If your entityClass implements ExampleDefinition interface (which is a descendant of FilterDefinition and only a marker interface) you can even omit specifying a filterClass at all. Example objects are very easy to use but they are also very limited because they will only return exact matches. Wildcard searches or searches accross multiple entities are not possible. Moreover you can't define an initial sort order on the result set.

1:N N:M Relationships

Relationships are also easy to use as in many cases they have already been defined by the code generation process when you have created your object model from the database or you have added the relation to your entity model.
Let's have a look at an excerpt from the Person class and its 1:N relationship to Address in the SheptDemo:


private List<Address> addresses = new ArrayList<Address>();

/**
 * @return the addresses
 */

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person")
public List<Address> getAddresses() {
return addresses;
}

/**
 * @param addresses the addresses to set
 */

public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}

Relationships are always declared between the 2 entities of their enclosing segments entityClass properties. During a chain operation the relationship filter will be instantiate by default as a ReloadableAssociation and initialized with the source entity object. Filters on a relation usually do not require any programming.
-> Read more about the details of the subform lifecycle.
-> Read more about the Configuration.

Criteria API

The Criteria API is most commonly used when the user shall enter selection criteria into the filters form fields allowing flexible operations. The user can be provided with a broad range of selection options including the option to specify ranges, exclusions, wildcard searches ... Writing a criteria filter means implementing the HibernateCriteriaDefinition or subclassing the HibernateCriteriaFilter that already provides some default behavior in a shept application. The rich criteria API reliefs you from the burdon and ambiguity to write selection criteria as string manipulation operations. The HibernateTools Eclipse Plugin provide a test environment to check out your criteria code before integrating it into the application.

Query API

The query API is particularly helpful when your query has a limited set of parameters but spans multiple tables for building the resultset. Writing a query filter means implementing the QueryDefinition filter. The HibernateTools Eclipse Plugin provide a test environment to check out your query code before integrating it into the application. 

Filter decision matrix

The decision matrix helps to decide when to use which filter

 ExampleDefinition Relationships Query API Criteria API
Requires custom coding (almost) no - all that is required to mark the example entity with the ExampleDefinition interface (and implement #getNewModelTemplate()no yes, a query specification used in a custom QueryDefinition implementation yes, a criteria specification that is an implementation of HibernateCriteriaDefinition
Filter definition set filterClass property to example entity class set relation property to the name of the relation set filterClass property to custom implementation of QueryDefinition set filterClass property to custom implementation of HibernateCriteriaDefinition
Filter def. in segments.xml
/ chains.xml 
yes / yes (override segment)n.a. / yes yes / yes (override segment) yes / yes (override segment)
Needs a filter view (UI) for the user to enter parameters yes no yes yes
New row creation support yes yes ! yes yes
Column sorting any column but limited to in-memory for the loaded results any column (because the results get fully loaded) as defined by the 'order-by' query spec - other rows sorting limited to in-memory for the loaded results any columns sortable by the database as the sort column is passed as an argument to the criteria
Filter parameters attributes of the example entity no custom parameters as supported by the query custom parameters of almost unlimited complexity (=not limited to the entity)
Supports wildcards no n.a. yes yes
Supports ranges
'< <= > >=' e.t.c.
no n.a 'hardwired' in the queryyes - highly customizable through user interface
Typical use case simple ad hoc filter visualize relations defined in entity model define simple to complex queries with HQL that typically support few parameters but can span many entities (joins) define simple to complex queries that can contain many query parameters and a varying number of operators.
Support Result transformations n.a. n.a. yes yes
Created by Andreas Hahn on 2011/01/07 14:38

© 2011 shept.org - Andreas Hahn