Пример #1
0
  public boolean prepareDelegate(
      Object subject, CommandSession session, List<Object> params, CommandArguments args)
      throws Exception {
    args.subject = subject;
    // Introspect
    for (Class type = subject.getClass(); type != null; type = type.getSuperclass()) {
      for (Field field : type.getDeclaredFields()) {
        Option option = field.getAnnotation(Option.class);
        if (option != null) {
          args.options.put(option, field);
        }
        Argument argument = field.getAnnotation(Argument.class);
        if (argument != null) {
          if (Argument.DEFAULT.equals(argument.name())) {
            final Argument delegate = argument;
            final String name = field.getName();
            argument =
                new Argument() {
                  public String name() {
                    return name;
                  }

                  public String description() {
                    return delegate.description();
                  }

                  public boolean required() {
                    return delegate.required();
                  }

                  public int index() {
                    return delegate.index();
                  }

                  public boolean multiValued() {
                    return delegate.multiValued();
                  }

                  public String valueToShowInHelp() {
                    return delegate.valueToShowInHelp();
                  }

                  public Class<? extends Annotation> annotationType() {
                    return delegate.annotationType();
                  }
                };
          }
          args.arguments.put(argument, field);
          int index = argument.index();
          while (args.orderedArguments.size() <= index) {
            args.orderedArguments.add(null);
          }
          if (args.orderedArguments.get(index) != null) {
            throw new IllegalArgumentException("Duplicate argument index: " + index);
          }
          args.orderedArguments.set(index, argument);
        }
      }
    }
    // Check indexes are correct
    for (int i = 0; i < args.orderedArguments.size(); i++) {
      if (args.orderedArguments.get(i) == null) {
        throw new IllegalArgumentException("Missing argument for index: " + i);
      }
    }
    // Populate
    Map<Option, Object> optionValues =
        new TreeMap<Option, Object>(CommandArguments.OPTION_COMPARATOR);
    Map<Argument, Object> argumentValues = new HashMap<Argument, Object>();
    boolean processOptions = true;
    int argIndex = 0;
    for (Iterator<Object> it = params.iterator(); it.hasNext(); ) {
      Object param = it.next();
      // Check for help
      if (HELP.name().equals(param) || Arrays.asList(HELP.aliases()).contains(param)) {
        printUsageDelegate(session, subject, args.options, args.arguments, System.out);
        return false;
      }
      if (processOptions && param instanceof String && ((String) param).startsWith("-")) {
        boolean isKeyValuePair = ((String) param).indexOf('=') != -1;
        String name;
        Object value = null;
        if (isKeyValuePair) {
          name = ((String) param).substring(0, ((String) param).indexOf('='));
          value = ((String) param).substring(((String) param).indexOf('=') + 1);
        } else {
          name = (String) param;
        }
        Option option = null;
        for (Option opt : args.options.keySet()) {
          if (name.equals(opt.name()) || Arrays.asList(opt.aliases()).contains(name)) {
            option = opt;
            break;
          }
        }
        if (option == null) {
          throw new CommandException(
              Ansi.ansi()
                  .fg(Ansi.Color.RED)
                  .a("Error executing command ")
                  .a(scope)
                  .a(":")
                  .a(Ansi.Attribute.INTENSITY_BOLD)
                  .a(name)
                  .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                  .a(" undefined option ")
                  .a(Ansi.Attribute.INTENSITY_BOLD)
                  .a(param)
                  .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                  .fg(Ansi.Color.DEFAULT)
                  .toString(),
              "Undefined option: " + param);
        }
        Field field = args.options.get(option);
        if (value == null
            && (field.getType() == boolean.class || field.getType() == Boolean.class)) {
          value = Boolean.TRUE;
        }
        if (value == null && it.hasNext()) {
          value = it.next();
        }
        if (value == null) {
          throw new CommandException(
              Ansi.ansi()
                  .fg(Ansi.Color.RED)
                  .a("Error executing command ")
                  .a(scope)
                  .a(":")
                  .a(Ansi.Attribute.INTENSITY_BOLD)
                  .a(name)
                  .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                  .a(" missing value for option ")
                  .a(Ansi.Attribute.INTENSITY_BOLD)
                  .a(param)
                  .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                  .fg(Ansi.Color.DEFAULT)
                  .toString(),
              "Missing value for option: " + param);
        }
        if (option.multiValued()) {
          List<Object> l = (List<Object>) optionValues.get(option);
          if (l == null) {
            l = new ArrayList<Object>();
            optionValues.put(option, l);
          }
          l.add(value);
        } else {
          optionValues.put(option, value);
        }
      } else {
        processOptions = false;
        if (argIndex >= args.orderedArguments.size()) {
          throw new CommandException(
              Ansi.ansi()
                  .fg(Ansi.Color.RED)
                  .a("Error executing command ")
                  .a(scope)
                  .a(":")
                  .a(Ansi.Attribute.INTENSITY_BOLD)
                  .a(name)
                  .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                  .a(": too many arguments specified")
                  .fg(Ansi.Color.DEFAULT)
                  .toString(),
              "Too many arguments specified");
        }
        Argument argument = args.orderedArguments.get(argIndex);
        if (!argument.multiValued()) {
          argIndex++;
        }
        if (argument.multiValued()) {
          List<Object> l = (List<Object>) argumentValues.get(argument);
          if (l == null) {
            l = new ArrayList<Object>();
            argumentValues.put(argument, l);
          }
          l.add(param);
        } else {
          argumentValues.put(argument, param);
        }
      }
    }
    // Check required arguments / options
    for (Option option : args.options.keySet()) {
      if (option.required() && optionValues.get(option) == null) {
        throw new CommandException(
            Ansi.ansi()
                .fg(Ansi.Color.RED)
                .a("Error executing command ")
                .a(scope)
                .a(":")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(name)
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(": option ")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(option.name())
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(" is required")
                .fg(Ansi.Color.DEFAULT)
                .toString(),
            "Option " + option.name() + " is required");
      }
    }
    for (Argument argument : args.arguments.keySet()) {
      if (argument.required() && argumentValues.get(argument) == null) {
        throw new CommandException(
            Ansi.ansi()
                .fg(Ansi.Color.RED)
                .a("Error executing command ")
                .a(scope)
                .a(":")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(name)
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(": argument ")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(argument.name())
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(" is required")
                .fg(Ansi.Color.DEFAULT)
                .toString(),
            "Argument " + argument.name() + " is required");
      }
    }
    // Convert and inject values
    for (Map.Entry<Option, Object> entry : optionValues.entrySet()) {
      Field field = args.options.get(entry.getKey());
      Object value;
      try {
        value = convert(subject, entry.getValue(), field.getGenericType());
      } catch (Exception e) {
        throw new CommandException(
            Ansi.ansi()
                .fg(Ansi.Color.RED)
                .a("Error executing command ")
                .a(scope)
                .a(":")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(name)
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(": unable to convert option ")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(entry.getKey().name())
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(" with value '")
                .a(entry.getValue())
                .a("' to type ")
                .a(new GenericType(field.getGenericType()).toString())
                .fg(Ansi.Color.DEFAULT)
                .toString(),
            "Unable to convert option "
                + entry.getKey().name()
                + " with value '"
                + entry.getValue()
                + "' to type "
                + new GenericType(field.getGenericType()).toString(),
            e);
      }
      field.setAccessible(true);
      field.set(subject, value);
    }
    for (Map.Entry<Argument, Object> entry : argumentValues.entrySet()) {
      Field field = args.arguments.get(entry.getKey());
      Object value;
      try {
        value = convert(subject, entry.getValue(), field.getGenericType());
      } catch (Exception e) {
        throw new CommandException(
            Ansi.ansi()
                .fg(Ansi.Color.RED)
                .a("Error executing command ")
                .a(scope)
                .a(":")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(name)
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(": unable to convert argument ")
                .a(Ansi.Attribute.INTENSITY_BOLD)
                .a(entry.getKey().name())
                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
                .a(" with value '")
                .a(entry.getValue())
                .a("' to type ")
                .a(new GenericType(field.getGenericType()).toString())
                .fg(Ansi.Color.DEFAULT)
                .toString(),
            "Unable to convert argument "
                + entry.getKey().name()
                + " with value '"
                + entry.getValue()
                + "' to type "
                + new GenericType(field.getGenericType()).toString(),
            e);
      }
      field.setAccessible(true);
      field.set(subject, value);
    }
    return true;
  }