Example #1
0
 /**
  * Add an additional configuration object containing CmdOption-specific annotations to the
  * configuration.
  *
  * @param objects
  */
 public void addObject(final Object... objects) {
   for (final Object object : objects) {
     if (object.getClass().getAnnotation(CmdCommand.class) != null) {
       scanCommand(object);
     } else {
       scanOptions(object);
     }
   }
 }
Example #2
0
  protected CmdlineParser(
      final CmdlineParser parent, final String commandName, final Object commandObject) {
    this.parent = parent;
    debugAllowed = parent.debugAllowed;
    debugMode = parent.debugMode;
    programName = commandName;
    handlerRegistry = parent.handlerRegistry;
    resourceBundle = parent.resourceBundle;
    argsFromFilePrefix = parent.argsFromFilePrefix;
    usageFormatter = parent.usageFormatter;

    // TODO: should we set the commands description as about line?

    scanOptions(commandObject);
  }
Example #3
0
  protected void scanOptions(final Object object) {
    final Class<?> class1 = object.getClass();

    final List<Field> fields = new LinkedList<Field>();
    final List<Method> privateMethods = new LinkedList<Method>();

    final List<Method> otherPackageNonPrivateMethods = new LinkedList<Method>();

    final List<Method> currentPackageNonPrivateMethods = new LinkedList<Method>();

    Class<?> parentClass = class1;
    while (parentClass != null && !parentClass.equals(Object.class)) {
      // We cannot override fields in child classes, so we simple collect
      // all fields we found
      fields.addAll(Arrays.asList(parentClass.getDeclaredFields()));

      // for methods, we need to respect overridden methods when
      // inspecting the parent classes
      for (final Method method : parentClass.getDeclaredMethods()) {
        if (isPrivate(method)) {
          privateMethods.add(method);
        } else if (isPublicOrProtected(method)) {
          if (!containsMethod(otherPackageNonPrivateMethods, method)
              && !containsMethod(currentPackageNonPrivateMethods, method)) {
            currentPackageNonPrivateMethods.add(method);
          }
        } else if (isPackagePrivate(method)) {
          // if (!containsMethod(publicOrProtectedMethods, method)) {
          // method not overloaded
          if (isPackagePrivate(method)) {
            if (!containsMethod(currentPackageNonPrivateMethods, method)) {
              currentPackageNonPrivateMethods.add(method);
            }
          }
        }
      }

      final Package pack = parentClass.getPackage();
      parentClass = parentClass.getSuperclass();
      if ((pack == null && parentClass.getPackage() != null)
          || (pack != null && !pack.equals(parentClass.getPackage()))) {
        otherPackageNonPrivateMethods.addAll(currentPackageNonPrivateMethods);
        currentPackageNonPrivateMethods.clear();
      }
    }

    // inspect elements
    final Set<AccessibleObject> elements = new LinkedHashSet<AccessibleObject>();
    elements.addAll(fields);
    elements.addAll(privateMethods);
    elements.addAll(otherPackageNonPrivateMethods);
    elements.addAll(currentPackageNonPrivateMethods);

    for (final AccessibleObject element : elements) {

      if (element instanceof Field && element.getAnnotation(CmdOptionDelegate.class) != null) {
        debug("Found delegate object at: {0}", element);
        try {
          final boolean origAccessibleFlag = element.isAccessible();
          if (!origAccessibleFlag) {
            element.setAccessible(true);
          }
          final Object delegate = ((Field) element).get(object);
          if (!origAccessibleFlag) {
            // do not leave doors open
            element.setAccessible(origAccessibleFlag);
          }
          if (delegate != null) {
            scanOptions(delegate);
          }
        } catch (final IllegalArgumentException e) {
          debug("Could not scan delegate object at: {0}", element);
        } catch (final IllegalAccessException e) {
          debug("Could not scan delegate object at: {0}", element);
        }
        continue;
      }

      final CmdOption anno = element.getAnnotation(CmdOption.class);
      if (anno == null) {
        continue;
      }

      if (element instanceof Field && Modifier.isFinal(((Field) element).getModifiers())) {
        debug("Detected option on final field: {0}", element);
        // continue;
      }

      final String[] names = anno.names();

      final CmdOptionHandler handler = findHandler(element, anno.args().length, anno.handler());
      if (handler == null) {
        final PreparedI18n msg =
            i18n.preparetr(
                "No suitable handler found for option(s): {0} ({1} argument(s))",
                FList.mkString(anno.names(), ","), anno.args().length);
        throw new CmdlineParserException(msg.notr(), msg.tr());
      }

      if (names == null || names.length == 0) {
        // No names means this is the ONLY parameter
        if (parameter != null) {
          final PreparedI18n msg =
              i18n.preparetr(
                  "More than one parameter definition found. First definition: {0} Second definition: {1}",
                  parameter.getElement(), element);
          throw new CmdlineParserException(msg.notr(), msg.tr());
        }
        // TODO: should we ignore the help parameter?
        final OptionHandle paramHandle =
            new OptionHandle(
                new String[] {},
                anno.description(),
                handler,
                object,
                element,
                anno.args(),
                anno.minCount(),
                anno.maxCount(),
                false /*
                       * cannot
                       * be
                       * a
                       * help
                       * option
                       */,
                anno.hidden(),
                anno.requires(),
                anno.conflictsWith());

        if (paramHandle.getArgsCount() <= 0) {
          final PreparedI18n msg =
              i18n.preparetr("Parameter definition must support at least on argument.");
          throw new CmdlineParserException(msg.notr(), msg.tr());
        }
        parameter = paramHandle;

      } else {
        final OptionHandle option =
            new OptionHandle(
                names,
                anno.description(),
                handler,
                object,
                element,
                anno.args(),
                anno.minCount(),
                anno.maxCount(),
                anno.isHelp(),
                anno.hidden(),
                anno.requires(),
                anno.conflictsWith());

        for (final String name : names) {
          if (quickCommandMap.containsKey(name) || quickOptionMap.containsKey(name)) {
            final PreparedI18n msg =
                i18n.preparetr(
                    "Duplicate command/option name \"{0}\" found in: {1}", name, element);
            throw new CmdlineParserException(msg.notr(), msg.tr());
          }
          quickOptionMap.put(name, option);
        }
        options.add(option);
      }
    }
  }