FileDocCategorySizeDatePackage
Command.javaAPI DocExample8850Sat Jan 24 10:44:30 GMT 2004je3.reflect

Command

public class Command extends Object implements ActionListener, InvocationHandler
This class represents a Method, the list of arguments to be passed to that method, and the object on which the method is to be invoked. The invoke() method invokes the method. The actionPerformed() method does the same thing, allowing this class to implement ActionListener and be used to respond to ActionEvents generated in a GUI or elsewhere. The static parse() method parses a string representation of a method and its arguments.

Fields Summary
Method
m
Object
target
Object[]
args
static final Object[]
nullargs
Constructors Summary
public Command(Object target, Method m)
This constructor creates a Command object for a no-arg method

    
               
          this(target, m, nullargs); 
public Command(Object target, Method m, Object[] args)
This constructor creates a Command object for a method that takes the specified array of arguments. Note that the parse() method provides another way to create a Command object

 
	this.target = target;
	this.m = m;
	if (args == null) args = nullargs;
	this.args = args;
    
public Command(Object target, String methodName, Object[] args)
This construct specifies the method to call by name. It looks for a method of the target object with the specified name and specified number of arguments. It does not attempt to verify the types of the arguments, since wrapper object (Integer, Boolean, etc) in the args[] array could represent reference or primitive arguments.

	this.target = target;
	if (args == null) args = nullargs;
	this.args = args;
	
	Method[] methods = target.getClass().getMethods();
	for(int i = 0; i < methods.length; i++) {
	    Method m = methods[i];
	    if (m.getParameterTypes().length == args.length && 
		m.getName().equals(methodName)) {
		this.m = m;
		break;
	    }
	}
	
	// If we didn't find a method, throw an exceptoin
	if (this.m == null)
	    throw new IllegalArgumentException("Unknown method " + methodName);

    
Methods Summary
public voidactionPerformed(java.awt.event.ActionEvent e)
This method implements the ActionListener interface. It is like invoke() except that it catches the exceptions thrown by that method and rethrows them as an unchecked RuntimeException

	try {
	    invoke();                          // Call the invoke method
	}
	catch (InvocationTargetException ex) { // But convert to unchecked
	    throw new RuntimeException(ex);    // exceptions.  Note that we
	}                                      // chain to the original 
	catch (IllegalAccessException ex) {    // exception.
	    throw new RuntimeException(ex);
	}
    
public voidinvoke()
Invoke the Command by calling the method on its target, and passing the arguments. See also actionPerformed() which does not throw the checked exceptions that this method does.

	m.invoke(target, args);  // Use reflection to invoke the method
    
public java.lang.Objectinvoke(java.lang.Object p, java.lang.reflect.Method m, java.lang.Object[] a)
This method implements the InvocationHandler interface, so that a Command object can be used with Proxy objects. Note that it simply calls the no-argument invoke() method, ignoring its arguments and returning null. This means that it is only useful for proxying interfaces that define a single no-arg void method.

	invoke();
	return null;
    
public static je3.reflect.Commandparse(java.lang.Object target, java.lang.String text)
This static method creates a Command using the specified target object, and the specified string. The string should contain method name followed by an optional parenthesized comma-separated argument list and a semicolon. The arguments may be boolean, integer or double literals, or double-quoted strings. The parser is lenient about missing commas, semicolons and quotes, but throws an IOException if it cannot parse the string.

	String methodname;                 // The name of the method
	ArrayList args = new ArrayList();  // Hold arguments as we parse them.
	ArrayList types = new ArrayList(); // Hold argument types.

	Tokenizer t = new CharSequenceTokenizer(text);
	t.skipSpaces(true).tokenizeWords(true).tokenizeNumbers(true);
	t.quotes("\"'", "\"'");

	if (t.next() != Tokenizer.WORD)
	    throw new IOException("Missing method name for command");
	methodname = t.tokenText();
	t.next();
	if (t.tokenType() == '(") {
	    t.next(); 
	    for(;;) { // Loop through all arguments 
		int c = t.tokenType();
		if (c == ')") {
		    // Consume closing paren
		    t.next();
		    break;  // and break out of list
		}
		
		if (c == Tokenizer.WORD) {
		    String word = t.tokenText();
		    if (word.equals("true")) {
			args.add(Boolean.TRUE);
			types.add(boolean.class);
		    }
		    else if (word.equals("false")) {
			args.add(Boolean.FALSE);
			types.add(boolean.class);
		    }
		    else {  // Treat unquoted identifiers as strings...
			args.add(word);
			types.add(String.class);
		    }
		}
		else if (c == '"") {  // double-quoted string
		    args.add(t.tokenText());
		    types.add(String.class);
		}
		else if (c == '\'") { // single-quoted character
		    args.add(new Character(t.tokenText().charAt(0)));
		    types.add(char.class);
		}
		else if (c == Tokenizer.NUMBER) {  // An integer
		    args.add(new Integer(Integer.parseInt(t.tokenText())));
		    types.add(int.class);
		}
		else {  // Anything else is a syntax error
		    throw new IOException("Unexpected token " + t.tokenText() +
					  " in argument list of " +
					  methodname + "().");
		}
		
		// Consume the token we just parse, and then consume an
		// optional comma.  
		if (t.next() == ',") t.next();
	    }
	}

	// Consume optional semicolon after method name or argument list
	if (t.tokenType() == ';") t.next();


	// We've parsed the argument list.
	// Next, convert the lists of argument values and types to arrays
	Object[] argValues = args.toArray();
	Class[] argtypes = (Class[])types.toArray(new Class[argValues.length]);

	// At this point, we've got a method name, and arrays of argument
	// values and types.  Use reflection on the class of the target object
	// to find a method with the given name and argument types.  Throw
	// an exception if we can't find the named method.
	Method method;
	try { method = target.getClass().getMethod(methodname, argtypes); }
	catch (Exception e) {
	    throw new IOException("No such method found, or wrong argument " +
				  "types: " + methodname);
	}

	// Finally, create and return a Command object, using the target object
	// passed to this method, the Method object we obtained above, and
	// the array of argument values we parsed from the string.
	return new Command(target, method, argValues);