Thread: [Japi-cvs] SF.net SVN: japi: [249] libs/swing-action/trunk/src/net/sf/japi/swing/ ReflectionAction.
Status: Beta
Brought to you by:
christianhujer
|
From: <chr...@us...> - 2006-12-03 16:23:39
|
Revision: 249
http://svn.sourceforge.net/japi/?rev=249&view=rev
Author: christianhujer
Date: 2006-12-03 08:23:37 -0800 (Sun, 03 Dec 2006)
Log Message:
-----------
Improved error handling: Replaced assert with IllegalAccessError.
Modified Paths:
--------------
libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
Modified: libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
===================================================================
--- libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-03 14:10:26 UTC (rev 248)
+++ libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-03 16:23:37 UTC (rev 249)
@@ -139,14 +139,15 @@
* If the method is null, it is reflected upon the instance usign the method name. If the method name is null, the method returns.
* Finally the method is invoked upon the instance, which may be null for static methods.
* @throws RuntimeException with cause in case the invocation of the method threw an exception and there was no handler for that exception.
+ * @throws IllegalAccessError In case the target method is non-public.
*/
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(final ActionEvent e) throws RuntimeException {
if (!isEnabled()) { return; }
final Object instance = getValue(REFLECTION_TARGET);
try {
getMethod(instance).invoke(instance);
} catch (final IllegalAccessException ex) {
- assert false : ACTION_FACTORY.format("ReflectionAction.nonPublicMethod", ex);
+ throw new IllegalAccessError(ACTION_FACTORY.format("ReflectionAction.nonPublicMethod", ex));
} catch (final InvocationTargetException ex) {
final ActionFactory actionFactory = (ActionFactory) getValue(REFLECTION_MESSAGE_PROVIDER);
final Throwable cause = ex.getCause();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <chr...@us...> - 2006-12-03 22:16:24
|
Revision: 250
http://svn.sourceforge.net/japi/?rev=250&view=rev
Author: christianhujer
Date: 2006-12-03 14:16:22 -0800 (Sun, 03 Dec 2006)
Log Message:
-----------
Minor improvements.
Modified Paths:
--------------
libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
Modified: libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
===================================================================
--- libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-03 16:23:37 UTC (rev 249)
+++ libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-03 22:16:22 UTC (rev 250)
@@ -26,9 +26,10 @@
import java.lang.reflect.Method;
import javax.swing.AbstractAction;
import javax.swing.Icon;
-import org.jetbrains.annotations.Nullable;
import net.sf.japi.lang.SuperClassIterator;
import static net.sf.japi.swing.ActionFactory.ACTION_ID;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
/** Action implementation which invokes the desired method using Reflection.
* Usage example:
@@ -90,6 +91,18 @@
putValue(REFLECTION_TARGET, target);
}
+ /** Defines an <code>Action</code> object with the specified description string and a the specified icon.
+ * @param name description string
+ * @param icon icon
+ * @param methodName Name of method to invoke
+ * @param target Target object to invoke method at
+ */
+ public ReflectionAction(final String name, final Icon icon, final String methodName, final Object target) {
+ super(name, icon);
+ putValue(REFLECTION_METHOD_NAME, methodName);
+ putValue(REFLECTION_TARGET, target);
+ }
+
/** {@inheritDoc}
* This implementation checks the type of <var>newValue</var> if the <var>key</var> is {@link #REFLECTION_METHOD_NAME} or {@link
* #REFLECTION_METHOD}, so you'll know of errors quite soon.
@@ -119,18 +132,6 @@
super.putValue(key, newValue);
}
- /** Defines an <code>Action</code> object with the specified description string and a the specified icon.
- * @param name description string
- * @param icon icon
- * @param methodName Name of method to invoke
- * @param target Target object to invoke method at
- */
- public ReflectionAction(final String name, final Icon icon, final String methodName, final Object target) {
- super(name, icon);
- putValue(REFLECTION_METHOD_NAME, methodName);
- putValue(REFLECTION_TARGET, target);
- }
-
/** {@inheritDoc}
* The implementation of this method first looks whether the Action is enabled.
* If it isn't, the method simply returns.
@@ -156,7 +157,8 @@
final String dialogKey = getValue(ACTION_ID) + ".exception." + c.getName();
final String title = actionFactory.getString(dialogKey + ".title");
if (title != null) {
- final Object source = e.getSource();
+ // source cannot be null because the ActionEvent constructor will not allow a null source.
+ @NotNull final Object source = e.getSource();
final Component parent = source instanceof Component ? (Component) source : null; // TODO: find better alternative to null
actionFactory.showMessageDialog(parent, dialogKey, cause.getLocalizedMessage());
return;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <chr...@us...> - 2006-12-06 21:48:35
|
Revision: 255
http://svn.sourceforge.net/japi/?rev=255&view=rev
Author: christianhujer
Date: 2006-12-06 13:48:26 -0800 (Wed, 06 Dec 2006)
Log Message:
-----------
Implemented support for ActionMethods which use different keys than their name and take arguments.
Modified Paths:
--------------
libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
Modified: libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
===================================================================
--- libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-06 21:40:33 UTC (rev 254)
+++ libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-06 21:48:26 UTC (rev 255)
@@ -53,6 +53,9 @@
*/
public final class ReflectionAction extends AbstractAction {
+ /** The empty object array used to denote zero arguments. */
+ private static final Object[] NO_ARGUMENTS = new Object[0];
+
/** Action Factory for reading strings. */
private static final ActionFactory ACTION_FACTORY = ActionFactory.getFactory("net.sf.japi.swing");
@@ -61,7 +64,7 @@
*/
public static final String REFLECTION_TARGET = "ReflectionTarget";
- /** The key used for storing the method name to use when searching for a method using reflection.
+ /** The key used for storing the method key to use when searching for a method using reflection.
* Value Type: {@link String} (checked).
*/
public static final String REFLECTION_METHOD_NAME = "ReflectionMethodName";
@@ -71,6 +74,12 @@
*/
public static final String REFLECTION_METHOD = "ReflectionMethod";
+ /**
+ * The key used for storing the method arguments to use when invoking the method.
+ * Value Type: {@link Object[]} (checked).
+ */
+ public static final String REFLECTION_ARGUMENTS = "ReflectionArguments";
+
/** The key used for storing the action factory that provides access to error handlers strings. */
public static final String REFLECTION_MESSAGE_PROVIDER = "ActionFactory";
@@ -80,6 +89,7 @@
/** Create an uninitialized ReflectionAction. */
public ReflectionAction() {
+ putValue(REFLECTION_ARGUMENTS, NO_ARGUMENTS);
}
/** Create a ReflectionAction with method and target.
@@ -87,6 +97,7 @@
* @param target Target object to invoke method at
*/
public ReflectionAction(final String methodName, final Object target) {
+ putValue(REFLECTION_ARGUMENTS, NO_ARGUMENTS);
putValue(REFLECTION_METHOD_NAME, methodName);
putValue(REFLECTION_TARGET, target);
}
@@ -99,6 +110,7 @@
*/
public ReflectionAction(final String name, final Icon icon, final String methodName, final Object target) {
super(name, icon);
+ putValue(REFLECTION_ARGUMENTS, NO_ARGUMENTS);
putValue(REFLECTION_METHOD_NAME, methodName);
putValue(REFLECTION_TARGET, target);
}
@@ -146,7 +158,7 @@
if (!isEnabled()) { return; }
final Object instance = getValue(REFLECTION_TARGET);
try {
- getMethod(instance).invoke(instance);
+ getMethod(instance).invoke(instance, (Object[]) getValue(REFLECTION_ARGUMENTS));
} catch (final IllegalAccessException ex) {
throw new IllegalAccessError(ACTION_FACTORY.format("ReflectionAction.nonPublicMethod", ex));
} catch (final InvocationTargetException ex) {
@@ -187,8 +199,7 @@
return null;
}
try {
- final Class<? extends Object> clazz = instance.getClass();
- method = clazz.getMethod(methodName);
+ method = getActionMethod(instance, methodName);
putValue(REFLECTION_METHOD, method);
} catch (final NoSuchMethodException ex) {
assert false : "Action Method not found: " + ex;
@@ -198,6 +209,31 @@
return method;
}
+ /** Get the named action method from the target class.
+ * @param clazz Class to search for method
+ * @param methodName Method name to get
+ * @return Method found
+ * @throws NoSuchMethodException In case the method was not found.
+ */
+ @Nullable public static Method getActionMethod(@NotNull final Class<?> clazz, @NotNull final String methodName) throws NoSuchMethodException {
+ for (final Method method : clazz.getMethods()) {
+ if (method.getName().equals(methodName) || method.isAnnotationPresent(ActionMethod.class) && method.getAnnotation(ActionMethod.class).value().equals(methodName)) {
+ return method;
+ }
+ }
+ throw new NoSuchMethodException(methodName + " (error: no public method named " + methodName + " and annotated as @ActionMethod found)");
+ }
+
+ /** Get the named action method from the target object.
+ * @param target Object to search for method
+ * @param methodName Method name to get
+ * @return Method found
+ * @throws NoSuchMethodException In case the method was not found or is not annotated as @{@link ActionMethod}.
+ */
+ @Nullable public static Method getActionMethod(@NotNull final Object target, @NotNull final String methodName) throws NoSuchMethodException {
+ return getActionMethod(target.getClass(), methodName);
+ }
+
/** {@inheritDoc} */
@Override protected Object clone() throws CloneNotSupportedException {
return super.clone();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <chr...@us...> - 2006-12-06 22:00:06
|
Revision: 256
http://svn.sourceforge.net/japi/?rev=256&view=rev
Author: christianhujer
Date: 2006-12-06 14:00:00 -0800 (Wed, 06 Dec 2006)
Log Message:
-----------
Improved argument passing mechanism.
Modified Paths:
--------------
libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
Modified: libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
===================================================================
--- libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-06 21:48:26 UTC (rev 255)
+++ libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2006-12-06 22:00:00 UTC (rev 256)
@@ -48,6 +48,9 @@
* </pre>
* Note that because of Reflection this Action is slightly slower than implementing your own Action instance, but in most cases this really does not matter at all.
* Usually you won't use ReflectionAction yourself. Instead you'll let {@link ActionFactory} create an instance for you.
+ * <p />
+ * You can use {@link #REFLECTION_ARGUMENTS} for providing arguments for the action method that's called via Reflection.
+ * Because that Object[] is not cloned, you can keep the reference and dynamically change the arguments of the invoked method.
* @author <a href="mailto:ch...@ri...">Christian Hujer</a>
* @todo ReflectionAction should be able to invoke methods with parameters, three variants: Object..., ActionEvent or void
*/
@@ -141,7 +144,14 @@
putValue(REFLECTION_METHOD, null);
}
}
- super.putValue(key, newValue);
+ if (REFLECTION_ARGUMENTS.equals(key)) {
+ if (newValue != null && !(newValue instanceof Object[])) {
+ throw new IllegalArgumentException("Value for key REFLECTION_ARGUMENTS must be of type " + Object[].class.getName() + " but was " + newValue.getClass().getName());
+ }
+ super.putValue(key, newValue == null ? NO_ARGUMENTS : newValue);
+ } else {
+ super.putValue(key, newValue);
+ }
}
/** {@inheritDoc}
@@ -158,6 +168,10 @@
if (!isEnabled()) { return; }
final Object instance = getValue(REFLECTION_TARGET);
try {
+ // TODO: Special value for REFLECTION_ARGUMENTS which determines whether to use ActionEvent.
+ final Method method = getMethod(instance);
+ final Object[] arguments = getArguments(method, e);
+ method.invoke(instance, arguments);
getMethod(instance).invoke(instance, (Object[]) getValue(REFLECTION_ARGUMENTS));
} catch (final IllegalAccessException ex) {
throw new IllegalAccessError(ACTION_FACTORY.format("ReflectionAction.nonPublicMethod", ex));
@@ -184,6 +198,20 @@
}
}
+ /**
+ * Returns the arguments suited for invoking the specified method.
+ * @param method Method to invoke
+ * @param e ActionEvent which eventually might be used as method argument.
+ * @return Argument array.
+ */
+ @NotNull private Object[] getArguments(@NotNull final Method method, @NotNull final ActionEvent e) {
+ final Class<?>[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes.length == 1 && parameterTypes[0].equals(ActionEvent.class)) {
+ return new Object[] { e };
+ }
+ return (Object[]) getValue(REFLECTION_ARGUMENTS);
+ }
+
/** Get the method associated with this action.
* @param instance Instance to get method for
* @return associated method or <code>null</code> if no method could be found
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <chr...@us...> - 2007-01-07 17:44:37
|
Revision: 276
http://svn.sourceforge.net/japi/?rev=276&view=rev
Author: christianhujer
Date: 2007-01-07 09:44:34 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Fixed bug: Duplicate invocation of target method.
Modified Paths:
--------------
libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
Modified: libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
===================================================================
--- libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2007-01-07 16:07:36 UTC (rev 275)
+++ libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2007-01-07 17:44:34 UTC (rev 276)
@@ -172,7 +172,6 @@
final Method method = getMethod(instance);
final Object[] arguments = getArguments(method, e);
method.invoke(instance, arguments);
- getMethod(instance).invoke(instance, (Object[]) getValue(REFLECTION_ARGUMENTS));
} catch (final IllegalAccessException ex) {
throw new IllegalAccessError(ACTION_FACTORY.format("ReflectionAction.nonPublicMethod", ex));
} catch (final InvocationTargetException ex) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <chr...@us...> - 2007-01-15 19:29:53
|
Revision: 302
http://svn.sourceforge.net/japi/?rev=302&view=rev
Author: christianhujer
Date: 2007-01-15 11:29:48 -0800 (Mon, 15 Jan 2007)
Log Message:
-----------
Changed method lookup to prefer ActionMethods over normal methods.
Modified Paths:
--------------
libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
Modified: libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java
===================================================================
--- libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2007-01-14 23:21:34 UTC (rev 301)
+++ libs/swing-action/trunk/src/net/sf/japi/swing/ReflectionAction.java 2007-01-15 19:29:48 UTC (rev 302)
@@ -243,11 +243,19 @@
* @throws NoSuchMethodException In case the method was not found.
*/
@Nullable public static Method getActionMethod(@NotNull final Class<?> clazz, @NotNull final String methodName) throws NoSuchMethodException {
+ // First search for explicit ActionMethods.
for (final Method method : clazz.getMethods()) {
- if (method.getName().equals(methodName) || method.isAnnotationPresent(ActionMethod.class) && method.getAnnotation(ActionMethod.class).value().equals(methodName)) {
+ if (method.isAnnotationPresent(ActionMethod.class) && (method.getName().equals(methodName) || method.getAnnotation(ActionMethod.class).value().equals(methodName))) {
return method;
}
}
+ // Second, if no explicit ActionMethod was found, try implicit.
+ // This could be improved.
+ for (final Method method : clazz.getMethods()) {
+ if (method.getName().equals(methodName)) {
+ return method;
+ }
+ }
throw new NoSuchMethodException(methodName + " (error: no public method named " + methodName + " and annotated as @ActionMethod found)");
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|