commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim O'Brien <tobr...@discursive.com>
Subject Re: Expressions, Collections, Filtering oh my..
Date Wed, 06 Jul 2005 01:12:31 GMT
Here are two ways to do this, JXPath is easier as you won't have to 
write your own Predicate.

Say you have a collection of Person objects that you created with this code:

        Person person1 = new Person();
        person1.setName( "Bill" );
        person1.setAge( 12 );

        Person person2 = new Person();
        person2.setName( "Amy" );
        person2.setAge( 18 );

        Person person3 = new Person();
        person3.setName( "Doug" );
        person3.setAge( 25 );

        List personList =
            Arrays.asList( new Person[] { person1, person2, person3 } );

You can filter this collection using JXPath and an XPath expression that 
references the age property AS IF it were an XML attribute:

        JXPathContext context = JXPathContext.newContext( personList );
        Iterator iterator = context.iterate(".[@age >= 18]");
        while( iterator.hasNext() ) {
            Object o  = (Object) iterator.next();
            System.out.println( "Person: " + ((Person) o).getName());
        }

Or, you can write a custom JexlPredicate that takes an expression and 
evaluates each element in a Collection.  Here's code that filters a 
collection of Person beans and returns only those instances that have an 
age >= 18:

       Predicate predicate = new JexlPredicate( "object", "object.age >= 
18" );
      
       Collection canVote = CollectionUtils.select( personList, predicate );
       
        for( Object o : canVote ) {
            System.out.println( "Person: " + ((Person) o).getName() );
        }

The JexlPredicate from this example would be the following class:

<JexlPredicate.java>

import org.apache.commons.collections.Predicate;
import org.apache.commons.jexl.Expression;
import org.apache.commons.jexl.ExpressionFactory;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.jexl.JexlHelper;

public class JexlPredicate implements Predicate {

    private String variable;
    private Expression e;

    public JexlPredicate(String variable, String expression) {
        this.variable = variable;
        try {
            this.e = ExpressionFactory.createExpression(expression);
        } catch (Exception e) {
            throw new RuntimeException("Error creating JEXL expression", e);
        }
    }

    public boolean evaluate(Object o) {
        JexlContext jc = JexlHelper.createContext();
        jc.getVars().put(variable, o);
       
        Boolean b;
        try {
            b = (Boolean) e.evaluate(jc);
        } catch (Exception e) {
            throw new RuntimeException("Error evaluating JEXL 
expression", e);
        }
        return b.booleanValue();
    }

}

</JexlPredicate.java>

Poppe, Troy wrote:

>I've got a collection of a JavaBeans, it could be a plain-old-Java collection or
>a Commons-Collection... Not really a concern...
>
>I'm trying to find a way to provide the ability to write a JEXL-like expression
>that would be applied against the collection of JavaBeans, and be able to
>retrieve all of the JavaBeans that match that JEXL-like expression.
>
>So far, looking at JEXL, it looks like it requires a JexlContext, but I don't see
>or know how I would adapt my JavaBean properties to this.
>
>Is there an out-of-the-binary way of filtering through my JavaBeans, and giving
>me access to those that match some expression?
>
>Thanks.
>
>Troy
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-user-help@jakarta.apache.org
>
>
>
>
>  
>




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Mime
View raw message