copyright © 2002, david a. hall writing and using java tm programming language-based predicates...

Post on 30-Jan-2016

216 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

copyright © 2002, David A. Hall

Writing and Using JavaTM Programming Language-Based

Predicates ('Java Predicates')

David Hall

copyright © 2002, David A. Hall

Functor

Functor: an Object that represents a function Evaluated as function: passed runtime arguments Functors can be passed as arguments Instantiated at runtime based on configuration Serialized or Persisted

copyright © 2002, David A. Hall

Functors vs. Method Objects

public void evaluate(Method m) { Object[] args = { arg1, arg2, etc }; try { Object val = m.invoke(args); } catch(IllegalAccessException x) { ... } catch(IllegalArgumentException x) { ... } catch(InvocationTargetException x) { ... }}

Number, types of arguments known in advance Compiler cannot check method's signature

copyright © 2002, David A. Hall

Functors vs. Method Objects

Functors can be nestedMethods are not dependent on each other

Functors are open for examinationMethods are opaque (no way to examine code)

Functors can be assembled at runtimeMethods must written prior to compilation

copyright © 2002, David A. Hall

Unary and Binary Functor

Unary Functorpublic interface UnaryFunctor { public Object fn(Object arg);}

BinaryFunctorpublic interface BinaryFunctor { public Object fn(Object arg1, Object arg2);}

Trinary, etc. are possible

copyright © 2002, David A. Hall

Predicate

Predicate: a Functor that returns a Boolean UnaryPredicate

public interface UnaryPredicate { public Boolean p(Object arg);}

BinaryPredicatepublic interface BinaryPredicate { public Boolean p(Object arg1, Object arg2) ;}

copyright © 2002, David A. Hall

Prolog

grandmother(G,S) :- parent(P,S), mother(G,P).mother(sarah,issac).parent(issac, jacob).

?- grandmother(sarah, jacob)yes?- grandmother(sarah, issac)no

copyright © 2002, David A. Hall

STL

Part of C++ Standard Library Contains a number of template based collections

classes and common algorithms Functors/Predicates used as arguments for many

of the algorithmscount_if(InputIterator first, InputIterator last, Predicate pred);

copyright © 2002, David A. Hall

STLArithmeticPlus(x, y)Minus(x, y)Multiplies(x, y)Divides(x, y)Modulus(x, y)Negate(x)

Comparisonmin(x, y)max(x, y)EqualTo(x, y)NotEqualTo(x, y)Less(x, y)LessEqual(x, y)Greater(x, y)GreaterEqual(x, y)

LogicalLogicalAnd(x, y)LogicalOr(x, y)LogicalNot(x, y)

ConstructionIdentity(x)ConstantUnary(x) ConstantBinary(x,y)Bind1st(x)Bind2nd(x)UnaryCompose(x)BinaryCompose(x)Project1st(x, y)Project2nd(x, y)

copyright © 2002, David A. Hall

jgl

Adaptation of STL in Java Originally created by ObjectSpace, inc Now owned by Recursion Software, Inc

http://www.recursionsw.com/

copyright © 2002, David A. Hall

Building Predicates

Primitives are easy to use, but of limited utilityPredicate andP = new LogicalAnd();Boolean flag = andP.p(Boolean.TRUE, Boolean.FALSE)

STL/JGL provide for assembly of compound expressions

copyright © 2002, David A. Hall

Bind1st & Bind2nd

Binders allow use of constant values with binary functors

Require BinaryFunctor, Constant at constructionUnaryFunctor discounter = new Bind1st(new Multiplies(), 1 - discountPct);UnaryFunctor taxer = new Bind1st(new Multiplies(), 1 + salesTaxRate);...salesPrice = discounter.fn(markedPrice);total = taxer.fn(salesPrice);

copyright © 2002, David A. Hall

Unary Compose

UnaryCompose allows result of one functor to be input to another

Requires two UnaryFunctors at constructionUnaryCompose netPrice = new UnaryCompose(taxer, discounter);...total = netPrice.fn(markedPrice);

copyright © 2002, David A. Hall

BinaryCompose

BinaryCompose is itself a UnaryFunctor BinaryCompose passes the results of two

UnaryFunctors as arguments to a BinaryFunctor Requires BinaryFunctor, two UnaryFunctors at

construction BinaryCompose cappedDiscount =

new BinaryCompose(new min(), discounter, new ConstantUnary(10.0));

copyright © 2002, David A. Hall

Miscellaneous

Constant returns value passed at construction Identity returns the runtime argument Project returns one of two runtime arguments

copyright © 2002, David A. Hall

Application Level Predicates

Primitives and assemblies provide support for built in reference types:

Arithmetic Functors require Number args Logical Functors require Boolean args Comparison Functors require Comparable args

No support for user/business level objects

copyright © 2002, David A. Hall

Custom Predicates

You can build customized functors for your business objects

public class GetStatusFn implements UnaryFunctor { public Object fn(Object arg) { PurchaseOrder po = (PurchaseOrder) arg; return po.getStatus(); }}

copyright © 2002, David A. Hall

GetPropertyFn

Alternatively, you can reflect using bean idiomspublic class GetPropertyFn implements UnaryFunctor { private String methName; public GetPropertyFn(String propName) { if (propName.startsWith("get")) methName = propName; else methName = "get" + propName; }...

copyright © 2002, David A. Hall

GetPropertyFn (cont.)

...public Object fn(Object arg) { try { Object[] parm = new Object[0]; Class[] types = new Class[0]; Class argclass = arg.getClass(); Method meth = argclass.getMethod(methName,types); return getMethod(arg).invoke(arg, parm); } catch (IllegalAccessException x) {...} catch (IllegalArgumentException x) {...} catch (InvocationTargetException x) {...} catch (NoSuchMethodException x) {...}}

copyright © 2002, David A. Hall

Business Rule Example

Business Rule exampleUnaryPredicate requiresApproval = new BinaryCompose(new GreaterThan(), new GetPropertyFn("Amount"), new ConstantUnary(500.00));

copyright © 2002, David A. Hall

SimpleCompare

public class SimpleCompare implements UnaryPredicate{ BinaryCompose bc; public SimpleCompare(BinaryPredicate comp, String propName, Object value) { fn = new BinaryCompose(comp, new GetPropertyFn(propName), new ConstantUnary(value); } public Boolean p(Object arg) { return (Boolean) bc.fn(arg); }}

copyright © 2002, David A. Hall

SimpleCompare

Same Business RuleUnaryPredicate requiresApproval = new SimpleCompare(new GreaterThan(), "Amount", 500.00);

copyright © 2002, David A. Hall

SimpleKey

Most SimpleCompare objects will use Equality comparisons, so create a special implementation

public class SimpleKey extends SimpleCompare { public SimpleKey(String propName, Object value){ super(new EqualTo(), propName,value); } }...UnaryPredicate pendingOrders = new SimpleKey("Status", "PENDING");

copyright © 2002, David A. Hall

Applications

Collections Swing: ListCellRenderer Dynamic Query & Query-By-Example EJB: BMP Finder methods Symbolic Set Manipulation

copyright © 2002, David A. Hall

Filtered Iterator

public class FilteredIterator implements Iterator { private Object next; private Iterator base; private UnaryPredicate pred; public FilteredIterator(Iterator iter, UnaryPredicate p) { base = iter; pred = p } ...

copyright © 2002, David A. Hall

Filtered Iterator (cont) ...

public boolean hasNext() { while (iter.hasNext() { Object obj = iter.next(); if (pred == null || pred.p(obj)) { next = obj; return true; } } return false; }...

copyright © 2002, David A. Hall

Filtered Iterator (cont)

... public Object next() { if (next != null) { Object val = next; next = null; return val; } throw new NoSuchElementException(); }}

copyright © 2002, David A. Hall

Collections & Algorithms

public Iterator findAll (Collecton coll, UnaryPredicate p) { return new FilteredIterator(coll.iterator(), p);}

public int countIf (Collection coll, UnaryPredicate p){ Iterator iter = new FilteredIterator(coll.iterator() , p); int ct = 0; while(iter.hasNext()) { iter.next(); ++ct; } return ct;}

copyright © 2002, David A. Hall

Swing Example

Swing provides many default models that work with built in primitives and/or collections of primitives.

You are expected to provide implementations that map your business objects within Swing defaults

By default, Swing hijacks toString() method

copyright © 2002, David A. Hall

ListCellRenderer

public class FunctorRenderer extends DefaultListCellRenderer{ private UnaryFunctor func; public FunctorRenderer(UnaryFunctor fn) { func = fn; } public Component getListCellRendererComponent( JList list, Object value, int index, boolean sel, boolean focus)

{ setText(func.fn(value).toString()); setBackground(sel ? Color.red : Color.white); setForeground(sel ? Color.white : Color.black); return this; }}

copyright © 2002, David A. Hall

ListCellRenderer Usage

JList list = new JList();UnaryFunctor fn = new GetPropertyFn("Id");list.setCellRenderer(new FunctorRenderer(fn)); getContentPane().add(list);

copyright © 2002, David A. Hall

Dynamic Query

Visitable and Visitor interfacespublic interface Visitable { public void accept(Visitor visitor);}public interface Visitor { public void visit(Visitable visitable);}

copyright © 2002, David A. Hall

Implementing Acyclic Visitor

Add Visitation support to SimpleKeypublic class SimpleKey extends SimpleCompare, implements Visitable{ ... public void accept(Visitor v) { if (v instanceof SimpleKey.Viz) ((SimpleKey.Viz)v).visit(this); } public interface Viz extends Visitor { public void visit(SimpleKey host); }}

copyright © 2002, David A. Hall

Translation Visitor

public class CloudscapeTranslator implements SimpleKey.Viz, ... { StringBuffer buf; public String translate(UnaryPredicate p) { buf = new StringBuffer(256); try { p.accept(this); } catch (Exception x) { x.printStackTrace(); } return buf.toString(); }...

copyright © 2002, David A. Hall

Translation Visitor

... public void visit(Visitable host) {} public void visit(SimpleKey host) { buf.append('"'); buf.append(host.getPropName()); buf.append("\" = "); host.getPredicate().accept(this); quote(host.getValue()); }...

copyright © 2002, David A. Hall

Translation Visitor

... private void quote(Object val) { if (val instanceof Number) { buf.append(val); } else if (val instanceof String) { buf.append("'"); buf.append(val); buf.append("'"); } // plus any other cases: Dates, Booleans, // Objects, etc }

copyright © 2002, David A. Hall

Translator Usage

private Collection selectIf(UnaryPredicate p) throws SQLException {

CloudscapeTranslator trans = new CloudscapeTranslator();

String selectStatement = "select \"poId\" from \"PurchaseOrderEJBTable\“” +” where " + trans.translate(p); PreparedStatement prepStmt = getDBConnection().prepareStatement(selectStatement);...

copyright © 2002, David A. Hall

Translator Usage (cont)

...ResultSet rs = prepStmt.executeQuery();ArrayList a = new ArrayList();while (rs.next()) { a.add(rs.getString(1));}prepStmt.close();return a;

}

copyright © 2002, David A. Hall

Predicates and Entity Beans

public interface OrderHome extends EJBHome { public Order create(String id, String userId, Date date, BigDecimal amount, String status) throws RemoteException, CreateException; public Order findByPrimaryKey(UnaryPredicate p) throws RemoteException, FinderException; public Collection findByPredicate(UnaryPredicate p) throws RemoteException, FinderException;

}

copyright © 2002, David A. Hall

Set Manipulation

Predicate implicitly defines a set (the set of all values for which the Predicate will return true)

Define set manipulation operations in terms of Predicates

Allows program to work with sets of values without having to instantiate them

copyright © 2002, David A. Hall

Set Manipulation

public class Predicates {

static public UnaryPredicate union(UnaryPredicate p1, UnaryPredicate p2) { return new BinaryCompose(new LogicalOr(), p1, p2);

/* thank you to the guy in the back row */}// intersection, set difference, etc

}

copyright © 2002, David A. Hall

References

Prolog http://mini.net/cetus/oo_prolog.html

STL http://www.yrl.co.uk/~phil/stl/

stl.htmlx#Algorithms_and_Functions http://www.byte.com/art/9510/sec12/art3.htm http://www.sgi.com/tech/stl/

JGL: Recursion Software, Inc http://www.recursionsw.com/

copyright © 2002, David A. Hall

References (cont)

Acyclic Visitor Patternhttp://www.objectmentor.com/resources/articles/acv.pdf

James O. Coplien. Advanced C++ Programming Styles and Idioms. Addison-Wesley, Reading, MA, 1992

Erich Gamma, et al. Design Patterns Elements of Reusable Object-Oriented Software. Addison-Wesley, Reading, MA, 1995

Kenneth P. Bogart. Discrete Mathematics. D. C. Heath and Company, Lexington, MA, 1988

top related