View Javadoc

1   package org.lsst.ccs.command;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   
6   /**
7    * Takes a single object and builds a command set from its annotated methods.
8    * The command set consists of two parts, the CommandDictionary, which is
9    * serializable and the command invoker, which contains references to the object
10   * and methods and is not serializable.
11   *
12   * @author tonyj
13   */
14  public class CommandSetBuilder {
15  
16      private final InputConversionEngine engine = new InputConversionEngine();
17  
18      /**
19       * Build a command set from an objects annotations.
20       *
21       * @param object The object from which annotations will be extracted, and to
22       * which invocation requests will be forwarded.
23       * @return A CommandSet representing the commands found in the object.
24       */
25      public CommandSet buildCommandSet(Object object) {
26          Class targetClass = object.getClass();
27          CommandDictionaryBuilder dictionary = new CommandDictionaryBuilder(targetClass);
28          CommandSetImplementation commandSet = new CommandSetImplementation(dictionary, object);
29          return commandSet;
30      }
31  
32      private class CommandSetImplementation implements CommandSet {
33  
34          private final CommandDictionaryBuilder dict;
35          private final Object target;
36  
37          private CommandSetImplementation(CommandDictionaryBuilder dict, Object target) {
38              this.dict = dict;
39              this.target = target;
40          }
41  
42          @Override
43          public Dictionary getCommandDictionary() {
44              return dict.getCommandDictionary();
45          }
46  
47          @Override
48          public Object invoke(BasicCommand command) throws CommandInvocationException {
49              Method method = dict.getMethod(command);
50              if (method == null) {
51                  throw new CommandInvocationException("Error: No handler found for command %s with %d arguments", command.getCommand(), command.getArgumentCount());
52              }
53              return invoke(target, method, command);
54          }
55  
56          private Object invoke(Object target, Method method, BasicCommand command) throws CommandInvocationException {
57  
58              try {
59                  RawCommand raw = RawCommand.toRawCommand(command, method, engine);
60                  return method.invoke(target, raw.getArguments());
61              } catch (IllegalAccessException | IllegalArgumentException ex) {
62                  throw new CommandInvocationException("Error: Can't invoke command", ex);
63              } catch (InvocationTargetException ex) {
64                  throw new CommandInvocationException(ex);
65              }
66          }
67      }
68  }