1 /*
2  * JaLingo, http://jalingo.sourceforge.net/
3  *
4  * Copyright (c) 2002-2006 Oleksandr Shyshko
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 package ja.centre.gui.actionbinder;
22 
23 import ja.centre.util.assertions.Arguments;
24 
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 
28 class Invokers {
Invokers()29     private Invokers() {
30     }
31 
action( Object instance, Method actionMethod )32     public static Invoker action( Object instance, Method actionMethod ) {
33         return new ActionMethodInvoker( instance, actionMethod );
34     }
35 
condition( Object instance, Method actionMethod, Invoker delegateMethodInvoker )36     public static Invoker condition( Object instance, Method actionMethod, Invoker delegateMethodInvoker ) {
37         return new ConditionMethodInvoker( instance, actionMethod, delegateMethodInvoker );
38     }
39 
40     private static class ActionMethodInvoker implements Invoker {
41         private Object instance;
42         private Method method;
43 
ActionMethodInvoker( Object instance, Method method )44         public ActionMethodInvoker( Object instance, Method method ) {
45             Arguments.assertNotNull( "instance", instance );
46             Arguments.assertNotNull( "method", method );
47 
48             this.instance = instance;
49             this.method = method;
50         }
51 
invoke( Object... args )52         public Object invoke( Object... args ) throws InvokerException {
53             // adjust arguments for no-arg case
54             if ( method.getParameterTypes().length == 0 ) {
55                 args = new Object[] { };
56             }
57 
58             // invoke
59             try {
60                 return method.invoke( instance, args );
61             } catch ( IllegalAccessException e ) {
62                 throw new InvokerException( instance, method, e );
63             } catch ( InvocationTargetException e ) {
64                 throw new InvokerException( instance, method, e );
65             }
66         }
67     }
68 
69     private static class ConditionMethodInvoker implements Invoker {
70         private Object instance;
71 
72         private Method method;
73         private Invoker delegateMethodInvoker;
74 
ConditionMethodInvoker( Object instance, Method method, Invoker delegateMethodInvoker )75         public ConditionMethodInvoker( Object instance, Method method, Invoker delegateMethodInvoker ) {
76             Arguments.assertNotNull( "instance", instance );
77             Arguments.assertNotNull( "method", method );
78             Arguments.assertNotNull( "delegateMethodInvoker", delegateMethodInvoker );
79 
80             // check method returns boolean
81             if ( !Boolean.class.equals( method.getReturnType() ) && !boolean.class.equals( method.getReturnType() ) ) {
82                 Arguments.doThrow( "Method \"" + method.getName()
83                         + "(...)\" of class \"" + instance.getClass().getName()
84                         + "\" expected to have return value of type \"" + Boolean.class.getName()
85                         + "\" or \"boolean\", but found type of return value is \""
86                         + method.getReturnType().getName() + "\"" );
87             }
88 
89             this.instance = instance;
90             this.method = method;
91             this.delegateMethodInvoker = delegateMethodInvoker;
92         }
93 
invoke( Object... args )94         public Object invoke( Object... args ) throws InvokerException {
95             // adjust arguments for no-arg case
96             if ( method.getParameterTypes().length == 0 ) {
97                 args = new Object[] { };
98             }
99 
100             // invoke condition
101             Boolean isConditionPassed;
102             try {
103                 isConditionPassed = (Boolean) method.invoke( instance, args );
104             } catch ( IllegalAccessException e ) {
105                 throw new InvokerException( e );
106             } catch ( InvocationTargetException e ) {
107                 throw new InvokerException( e );
108             }
109 
110             // invoke nested action with same arguments if condition is passed
111             if ( isConditionPassed.booleanValue() ) {
112                 return delegateMethodInvoker.invoke( args );
113             }
114 
115             // do nothing
116             return null;
117         }
118     }
119 }
120