Return-Path: Delivered-To: apmail-jakarta-commons-user-archive@www.apache.org Received: (qmail 4172 invoked from network); 6 Jul 2005 14:07:14 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 6 Jul 2005 14:07:14 -0000 Received: (qmail 30754 invoked by uid 500); 6 Jul 2005 14:07:05 -0000 Delivered-To: apmail-jakarta-commons-user-archive@jakarta.apache.org Received: (qmail 30705 invoked by uid 500); 6 Jul 2005 14:07:04 -0000 Mailing-List: contact commons-user-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Jakarta Commons Users List" Reply-To: "Jakarta Commons Users List" Delivered-To: mailing list commons-user@jakarta.apache.org Received: (qmail 30692 invoked by uid 99); 6 Jul 2005 14:07:04 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Jul 2005 07:07:04 -0700 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [205.254.128.4] (HELO hqwss.hr.doe.gov) (205.254.128.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Jul 2005 07:07:04 -0700 Received: from 198.76.0.16 by hqwss.hr.doe.gov with SMTP (US Dept of Energy SMTP Relay (Email Firewall v6.1.1)); Wed, 06 Jul 2005 10:06:35 -0400 X-Server-Uuid: 630DDFB1-88D5-4040-B236-A52701B6986F Received: by scout.eia.doe.gov with Internet Mail Service (5.5.2657.72) id ; Wed, 6 Jul 2005 10:04:37 -0400 Message-ID: <5C8AD2C845ED3E43AEF65E40FC02A8BD07BC3D7B@emailf2.eia.doe.gov> From: "Poppe, Troy" To: "'Jakarta Commons Users List'" Subject: RE: Expressions, Collections, Filtering oh my.. Date: Wed, 6 Jul 2005 10:04:34 -0400 X-Mailer: Internet Mail Service (5.5.2657.72) MIME-Version: 1.0 X-WSS-ID: 6ED53AE32C8994011-06-01 Content-Type: text/plain Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N I actually ended up doing something like this, Tim. Thanks for your help. I did one thing slightly different, and that was to use PropertyUtils.describe(Object) to get a Map of JavaBean properties for populating the JexlContext... See below as a first cut: <-- snip --> package a.b.com; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; 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 { public String expression = null; public boolean evaluate(Object o) { boolean ret = false; try { Map objectMap = PropertyUtils.describe(o); Expression e = ExpressionFactory.createExpression(expression); JexlContext jc = JexlHelper.createContext(); jc.setVars(objectMap); Object eval = e.evaluate(jc); if ( eval != null && eval instanceof Boolean ) { ret = ((Boolean)eval).booleanValue(); } } catch ( Exception ex ) { throw new RuntimeException(ex); } return ret; } public String getExpression() { return expression; } public void setExpression(String expression) { this.expression = expression; } } <-- snip --> -----Original Message----- From: Tim O'Brien [mailto:tobrien@discursive.com] Sent: Tuesday, July 05, 2005 9:13 PM To: Jakarta Commons Users List Subject: Re: Expressions, Collections, Filtering oh my.. 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: 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(); } } 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 --------------------------------------------------------------------- To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-user-help@jakarta.apache.org