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

Jay Balunas (JIRA) jira-events at lists.jboss.org
Thu Jan 14 10:40:39 EST 2010


    [ https://jira.jboss.org/jira/browse/RF-8262?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12505927#action_12505927 ] 

Jay Balunas commented on RF-8262:
---------------------------------

Hi Sebastian,

First thanks so much for providing a patch - that is AWESOME!!!!

We are going to investigate getting this patch into the 3.3.3 release, but we need you to sign the contributor agreement before we can.  If you could please take a look here - https://www.jboss.org/contribute for instructions.  Once I aproave it we can apply the patch.

Thanks,
Jay

> Unnecessary filtering of fields in a Richfaces DataTable
> --------------------------------------------------------
>
>                 Key: RF-8262
>                 URL: https://jira.jboss.org/jira/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
>            Assignee: Andrey Markhel
>             Fix For: 3.3.3.CR1
>
>
> 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.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the richfaces-issues mailing list