- // If action as property didn't work, try as method.
- try
- {
- actionMethod =
- target.getClass().getMethod(action, new Class[] {propertyType});
- }
- catch (NoSuchMethodException e1)
- {
- // When event property is null, we may call action with no args
- if (property == null)
- {
- actionMethod =
- target.getClass().getMethod(action, null);
- return actionMethod.invoke(target, null);
- }
- else
- throw e1;
- }
+ // If action as property didn't work, try as method later.
+ }
+
+ argTypes[0] = nextClass(argTypes[0]);
+ }
+
+ // We could not find a suitable setter method. Now we try again interpreting
+ // action as the method name itself.
+ // Since we probably have changed the block local argTypes array
+ // we need to rebuild it.
+ argTypes = new Class[] { initClass((Class) v[1]) };
+
+ // Tries to find a setter method to which we can apply the
+ while(argTypes[0] != null) {
+ try
+ {
+ actionMethod = targetClass.getMethod(action, argTypes);
+
+ return actionMethod.invoke(target, args);
+ }
+ catch (NoSuchMethodException e)
+ {
+ }
+
+ argTypes[0] = nextClass(argTypes[0]);
+ }
+
+ throw new RuntimeException("Method not called: Could not find a public method named '"
+ + action + "' in target " + targetClass + " which takes a '"
+ + v[1] + "' argument or a property of this type.");
+ }
+
+ // If property was null we will search for a no-argument method here.
+ // Note: The ordering of method lookups is important because we want to prefer no-argument
+ // calls like the JDK does. This means if we have actionMethod() and actionMethod(Event) we will
+ // call the first *EVEN* if we have a valid argument for the second method. This is behavior compliant
+ // to the JDK.
+ // If actionMethod() is not available but there is a actionMethod(Event) we take this. That makes us
+ // more specification compliant than the JDK itself because this one will fail in such a case.
+ try
+ {
+ actionMethod = targetClass.getMethod(action, null);
+ }
+ catch(NoSuchMethodException nsme)
+ {
+ // Note: If we want to be really strict the specification says that a no-argument method should
+ // accept an EventObject (or subclass I guess). However since the official implementation is broken
+ // anyways, it's more flexible without the EventObject restriction and we are compatible on everything
+ // else this can stay this way.
+ if(arguments != null && arguments.length >= 1/* && arguments[0] instanceof EventObject*/) {
+ Class[] targetArgTypes = new Class[] { initClass(arguments[0].getClass()) };
+
+ while(targetArgTypes[0] != null) {
+ try
+ {
+ // If no property exists we expect the first element of the arguments to be
+ // an EventObject which is then applied to the target method.
+
+ actionMethod = targetClass.getMethod(action, targetArgTypes);
+
+ return actionMethod.invoke(target, new Object[] { arguments[0] });
+ }
+ catch(NoSuchMethodException nsme2)
+ {
+
+ }
+
+ targetArgTypes[0] = nextClass(targetArgTypes[0]);
+ }
+
+ }