KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > uk > co > jezuk > mango > Adapt


1 package uk.co.jezuk.mango;
2
3 import java.lang.reflect.Method JavaDoc;
4
5 /**
6  * Object method adaptors.
7  * @see Bind
8  * @author Jez Higgins, jez@jezuk.co.uk
9  * @version $Id: Adapt.java 79 2003-04-03 11:34:24Z jez $
10  */

11 public class Adapt
12 {
13   /**
14    * Compose is a unary function adaptor. If <code>f</code> and <code>g</code>
15    * are <code>UnaryFunctions</code>, then <code>Compose</code> creates a new
16    * function <code>h</code>, where <code>h(x)</code> is equal to <code>f(g(x))</code>.
17    */

18   static public UnaryFunction Compose(UnaryFunction f, UnaryFunction g)
19   {
20     final UnaryFunction ff = f;
21     final UnaryFunction gg = g;
22     return new UnaryFunction() {
23     public Object JavaDoc fn(Object JavaDoc x)
24     {
25       return ff.fn(gg.fn(x));
26     } // fn
27
};
28   } // Compose
29

30   /**
31    * Compose is a function adaptor. If <code>f</code> is a <code>BinaryFunction</code>
32    * and <code>g1</code> and <code>g2</code> are <code>UnaryFunctions</code>, then Compose
33    * returns a new <code>BinaryFunction</code> <code>h</code> such that <code>h(x, y)</code>
34    * is <code>f(g1(x), g2(y))</code>
35    */

36   static public BinaryFunction Compose(BinaryFunction f, UnaryFunction g1, UnaryFunction g2)
37   {
38     final BinaryFunction ff = f;
39     final UnaryFunction gg1 = g1;
40     final UnaryFunction gg2 = g2;
41     return new BinaryFunction() {
42     public Object JavaDoc fn(Object JavaDoc x, Object JavaDoc y)
43     {
44       return ff.fn(gg1.fn(x), gg2.fn(y));
45     } // fn
46
};
47   } // Compose
48

49   /**
50    * Adapts member functions as <code>UnaryFunction</code> objects, allowing them
51    * to be passed to algorithms.
52    * <br>
53    * e.g. to print all the elements in a list<br>
54    * <code>Mango.forEach(list, Adapt.Method(System.out, "println"));</code><br>
55    * is equivalent to <br>
56    * <code>for(int i = 0; i < list.size(); ++i)</code><br>
57    * <code> System.out.println(list.get(i));</code>
58    * <p>
59    * If the named method is not found, or its signature is incorrect throws a
60    * RuntimeException. If multiple methods have the correct name, and take a single
61    * parameter one of them will be called, but you can't determine which.
62    */

63   static public UnaryFunction Method(final Object JavaDoc obj, String JavaDoc methodName)
64   {
65     return wrapMethod(obj.getClass(), obj, methodName);
66   } // Method
67

68   /**
69    * Adapts static member functions as <code>UnaryFunction</code> objects, allowing them
70    * to be passed to algorithms.
71    * <p>
72    * If the named method is not found, or its signature is incorrect throws a
73    * RuntimeException. If multiple methods have the correct name, and take a single
74    * parameter one of them will be called, but you can't determine which.
75    */

76   static public UnaryFunction Method(final Class JavaDoc klass, String JavaDoc methodName)
77   {
78     return wrapMethod(klass, null, methodName);
79   } // Method
80

81   static private class UnaryMethodNamed implements Predicate
82   {
83       UnaryMethodNamed(String JavaDoc name, int argCount)
84       {
85     name_ = name;
86     argCount_ = argCount;
87       } // UnaryMethodNamed
88
public boolean test(Object JavaDoc obj)
89       {
90         java.lang.reflect.Method JavaDoc m = (java.lang.reflect.Method JavaDoc)obj;
91     return (m.getName().equals(name_) && (m.getParameterTypes().length == argCount_));
92       } // test
93
private String JavaDoc name_;
94       private int argCount_;
95   } // UnaryMethodNamed
96

97   static private UnaryFunction wrapMethod(final Class JavaDoc klass, final Object JavaDoc obj, String JavaDoc methodName)
98   {
99     Method JavaDoc[] methods = klass.getMethods();
100     final Method JavaDoc m = (Method JavaDoc)Algorithms.findIf(java.util.Arrays.asList(methods).iterator(), new UnaryMethodNamed(methodName, 1));
101     if(m == null)
102       throw new RuntimeException JavaDoc(new NoSuchMethodException JavaDoc());
103
104     return new UnaryFunction() {
105       private Object JavaDoc obj_;
106       private Method JavaDoc method_;
107       { obj_ = obj; method_ = m; }
108       public Object JavaDoc fn(Object JavaDoc arg)
109       {
110         Object JavaDoc[] args = new Object JavaDoc[]{ arg };
111         try {
112       return method_.invoke(obj_, args);
113         } // try
114
catch(Exception JavaDoc e) {
115       throw new RuntimeException JavaDoc(e);
116     } // catch
117
} // fn
118
}; // UnaryFunction
119
} // wrapMethod
120

121   /**
122    * Creates a <code>UnaryFunction</code> which will call a method on the
123    * object passed as the argument to <code>UnaryFunction.fn</code> method.
124    * <br>
125    * e.g. to print all the elements in a list<br>
126    * <code>interface Something { void persist(); }<br>
127    * // fill list with Somethings
128    * Mango.forEach(list, Bind.ArgumentMethod("persist"));</code><br>
129    * is equivalent to <br>
130    * <code>for(int i = 0; i < list.size(); ++i)<br>
131    * {<br>
132    * &nbsp;&nbsp;Something s = (Something)list.get(i);<br>
133    * &nbsp;&nbsp;s.persist();<br>
134    * }</code>
135    * <p>
136    * If the named method is not found, or its signature is incorrect throws a
137    * RuntimeException.
138    * @see UnaryFunction
139    */

140   static public UnaryFunction ArgumentMethod(final String JavaDoc methodName)
141   {
142     return new UnaryFunction() {
143       private String JavaDoc methodName_;
144       private Class JavaDoc lastClass_;
145       private Method JavaDoc method_;
146       { methodName_ = methodName; }
147       public Object JavaDoc fn(Object JavaDoc arg)
148       {
149     if(!arg.getClass().equals(lastClass_))
150     {
151       lastClass_ = arg.getClass();
152       Method JavaDoc[] methods = lastClass_.getMethods();
153       method_ = (Method JavaDoc)Algorithms.findIf(java.util.Arrays.asList(methods).iterator(), new UnaryMethodNamed(methodName, 0));
154       if(method_ == null)
155         throw new RuntimeException JavaDoc(new NoSuchMethodException JavaDoc());
156     } // if ...
157

158     try {
159       return method_.invoke(arg, null);
160     } // try
161
catch(Exception JavaDoc e) {
162       throw new RuntimeException JavaDoc(e);
163     } // catch
164
} // fn
165
}; // UnaryFunction
166
} // ArgumentMethod
167

168   //////////////////////////////////////////
169
private Adapt() { }
170 } // Adapt
171
Popular Tags