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. |