[richfaces-issues] [JBoss JIRA] Updated: (RF-8262) Unnecessary filtering of fields in a Richfaces DataTable

Jay Balunas (JIRA) jira-events at lists.jboss.org
Thu Jan 6 14:19:19 EST 2011


     [ https://issues.jboss.org/browse/RF-8262?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jay Balunas updated RF-8262:
----------------------------

    Assignee:     (was: Andrey Markhel)


> Unnecessary filtering of fields in a Richfaces DataTable
> --------------------------------------------------------
>
>                 Key: RF-8262
>                 URL: https://issues.jboss.org/browse/RF-8262
>             Project: RichFaces
>          Issue Type: Patch
>      Security Level: Public(Everyone can see) 
>          Components: component, component-ScrollableDataTable, component-tables
>    Affects Versions: 3.3.2.SR1
>            Reporter: Sebastian Rueber
>             Fix For: Future_3.X
>
>
> This patch is a solution for the DataTable problem, when using the internal filter.
> e.g.:
> <rich:dataTable value="${bean.listDataModel}" var="row">
>   <rich:column filterBy="row.name" />
> reason for this problem is the class org.richfaces.model.ModifiableModel with its method filter(...)
> the method filter(...) always calculates the filterBy value for all cells and rows in the table, which has the 
> filter expression.
> example:
> 500 rows and 7 columns leads to 3500 calculations. it depends on how complex the expressions are, but it
> may take a while.
> in some cases the expressions are calculated unnecessary.
> example 1: empty filter fields
> if the user has not entered any filter expressions in fields with a filter attribute, for example if the table is rendered initialy.
> calculated expressions 3500
> needed expressions 0
> example 2: shortcut evaluation
> the filter fields are linked by an AND logical operator. that means, if you have 7 fields and the first does not match,
> the remaining 6 field should not be evaluated.
> calculated expressions 3500
> needed expressions 3500 - x
> in our application we are using our own table model, but i would like to contribute some code, which may give you
> an idea, how to fix this quickly.
> solution code for filter method
> @Override
> protected List<Object> filter(List<FilterField> aFilterFields) {
>   List<Object> filteredCollection = new ArrayList<Object>();
>   ExpressionFactory tempFactory = new ExpressionFactory(FacesContext.getCurrentInstance(), var, aFilterFields);
>   for (Object temp : rowKeys) {
>     Integer tempKey = (Integer) temp;
>     Sample tempSample = data.get(tempKey);
>     if (accept(tempSample, aFilterFields, tempFactory)) {
>       filteredCollection.add(tempKey);
>     }
>   }
>   rowKeys = filteredCollection;
>   return rowKeys;
> }
> public boolean accept(Sample aSample, List<FilterField> aFilterList, ExpressionFactory aFactory) {
>   for (FilterField filterField : aFilterList) {
>     if (filterField instanceof ExtendedFilterField) {
>       String filterValue = ((ExtendedFilterField) filterField).getFilterValue();
>       if (filterValue != null) {
>         filterValue = filterValue.trim().toUpperCase(locale);
>         if (filterValue.length() > 0) {
>           // delayed until here, were it is really needed
>           Object property = aFactory.eval(filterField.getExpression(), aSample);
>           if (property == null || !property.toString().trim().toUpperCase(locale).startsWith(filterValue)) {
>             return false;
>           }
>         }
>       }
>     } else {
>       Object property = aFactory.eval(filterField.getExpression(), aSample);
>       if (!((Boolean) property).booleanValue()) {
>         return false;
>       }
>     }
>   }
>   return true;
> }
> solution code for the ExpressionFactory
> package org.richfaces.model.impl.expressive;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> import javax.el.ELContext;
> import javax.el.ELResolver;
> import javax.el.MethodExpression;
> import javax.el.ValueExpression;
> import javax.faces.application.Application;
> import javax.faces.component.UIViewRoot;
> import javax.faces.context.FacesContext;
> import org.richfaces.model.Field;
> public class ExpressionFactory {
>   private Map<javax.el.Expression, Expression> expressionMap;
>   public ExpressionFactory(FacesContext context, final String var, List<? extends Field> sortOrder) {
>     Application application = context.getApplication();
>     ELResolver resolver = application.getELResolver();
>     ELContext elContext = context.getELContext();
>     expressionMap = new HashMap<javax.el.Expression, Expression>();
>     for (Field field : sortOrder) {
>       javax.el.Expression elExpression = field.getExpression();
>       Expression expression;
>       if (elExpression instanceof ValueExpression) {
>         ValueExpression valueExpression = (ValueExpression) elExpression;
>         if (valueExpression.isLiteralText()) {
>           String expressionString = valueExpression.getExpressionString();
>           if (expressionString.startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
>             expression = new NullExpression(expressionString);
>           } else {
>             expression = new SimplePropertyExpression(expressionString, elContext, resolver);
>           }
>         } else {
>           expression = new ValueBindingExpression(context, valueExpression, var);
>         }
>       } else if (elExpression instanceof MethodExpression) {
>         expression = new MethodBindingExpression(context, (MethodExpression) elExpression);
>       } else {
>         throw new IllegalArgumentException();
>       }
>       expressionMap.put(elExpression, expression);
>     }
>   }
>   public Object eval(javax.el.Expression anExpression, Object anObject) {
>     return expressionMap.get(anExpression).evaluate(anObject);
>   }
> }
>  

-- 
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the richfaces-issues mailing list