1 15 package org.apache.tapestry.listener; 16 17 import java.lang.reflect.InvocationTargetException ; 18 import java.lang.reflect.Method ; 19 20 import org.apache.hivemind.ApplicationRuntimeException; 21 import org.apache.hivemind.util.Defense; 22 import org.apache.tapestry.IPage; 23 import org.apache.tapestry.IRequestCycle; 24 import org.apache.tapestry.Tapestry; 25 26 35 public class ListenerMethodInvokerImpl implements ListenerMethodInvoker 36 { 37 41 42 private final Method [] _methods; 43 44 47 48 private final String _name; 49 50 public ListenerMethodInvokerImpl(String name, Method [] methods) 51 { 52 Defense.notNull(name, "name"); 53 Defense.notNull(methods, "methods"); 54 55 _name = name; 56 _methods = methods; 57 } 58 59 public void invokeListenerMethod(Object target, IRequestCycle cycle) 60 { 61 Object [] listenerParameters = cycle.getListenerParameters(); 62 63 if (searchAndInvoke(target, false, true, cycle, listenerParameters)) 65 return; 66 67 if (searchAndInvoke(target, true, true, cycle, listenerParameters)) 69 return; 70 71 if (searchAndInvoke(target, false, false, cycle, listenerParameters)) 73 return; 74 75 if (searchAndInvoke(target, true, false, cycle, listenerParameters)) 77 return; 78 79 throw new ApplicationRuntimeException(ListenerMessages.noListenerMethodFound( 80 _name, 81 listenerParameters, 82 target), target, null, null); 83 } 84 85 private boolean searchAndInvoke(Object target, boolean includeCycle, boolean includeParameters, 86 IRequestCycle cycle, Object [] listenerParameters) 87 { 88 int listenerParameterCount = Tapestry.size(listenerParameters); 89 int methodParameterCount = includeParameters ? listenerParameterCount : 0; 90 91 if (includeCycle) 92 methodParameterCount++; 93 94 for (int i = 0; i < _methods.length; i++) 95 { 96 Method m = _methods[i]; 97 98 101 Class [] parameterTypes = m.getParameterTypes(); 102 103 if (parameterTypes.length < methodParameterCount) 104 break; 105 106 if (parameterTypes.length != methodParameterCount) 107 continue; 108 109 boolean firstIsCycle = parameterTypes.length > 0 110 && parameterTypes[0] == IRequestCycle.class; 111 112 120 if (includeCycle != firstIsCycle) 121 continue; 122 123 invokeListenerMethod( 124 m, 125 target, 126 includeCycle, 127 includeParameters, 128 cycle, 129 listenerParameters); 130 131 return true; 132 } 133 134 return false; 135 } 136 137 private void invokeListenerMethod(Method listenerMethod, Object target, boolean includeCycle, 138 boolean includeParameters, IRequestCycle cycle, Object [] listenerParameters) 139 { 140 Object [] parameters = new Object [listenerMethod.getParameterTypes().length]; 141 int cursor = 0; 142 143 if (includeCycle) 144 parameters[cursor++] = cycle; 145 146 if (includeParameters) 147 for (int i = 0; i < Tapestry.size(listenerParameters); i++) 148 parameters[cursor++] = listenerParameters[i]; 149 150 try 151 { 152 Object methodResult = invokeTargetMethod(target, listenerMethod, parameters); 153 154 156 if (methodResult == null) 157 return; 158 159 163 if (methodResult instanceof String ) 164 { 165 cycle.activate((String ) methodResult); 166 return; 167 } 168 169 cycle.activate((IPage) methodResult); 170 } 171 catch (InvocationTargetException ex) 172 { 173 Throwable targetException = ex.getTargetException(); 174 175 if (targetException instanceof ApplicationRuntimeException) 176 throw (ApplicationRuntimeException) targetException; 177 178 throw new ApplicationRuntimeException(ListenerMessages.listenerMethodFailure( 179 listenerMethod, 180 target, 181 targetException), target, null, targetException); 182 } 183 catch (Exception ex) 184 { 185 throw new ApplicationRuntimeException(ListenerMessages.listenerMethodFailure( 186 listenerMethod, 187 target, 188 ex), target, null, ex); 189 190 } 191 } 192 193 197 198 protected Object invokeTargetMethod(Object target, Method listenerMethod, Object [] parameters) 199 throws IllegalAccessException , InvocationTargetException 200 { 201 return listenerMethod.invoke(target, parameters); 202 } 203 } | Popular Tags |