Home | History | Annotate | Download | only in jcommander
      1 /*
      2  * Copyright 2016, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * Redistributions of source code must retain the above copyright
     10  * notice, this list of conditions and the following disclaimer.
     11  * Redistributions in binary form must reproduce the above
     12  * copyright notice, this list of conditions and the following disclaimer
     13  * in the documentation and/or other materials provided with the
     14  * distribution.
     15  * Neither the name of Google Inc. nor the names of its
     16  * contributors may be used to endorse or promote products derived from
     17  * this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 package org.jf.util.jcommander;
     33 
     34 import com.beust.jcommander.JCommander;
     35 import com.beust.jcommander.ParameterDescription;
     36 import com.beust.jcommander.Parameterized;
     37 import com.beust.jcommander.Parameters;
     38 
     39 import javax.annotation.Nonnull;
     40 import javax.annotation.Nullable;
     41 import java.lang.reflect.Field;
     42 
     43 /**
     44  * Utilities related to "extended" commands - JCommander commands with additional information
     45  */
     46 public class ExtendedCommands {
     47 
     48     @Nonnull
     49     private static ExtendedParameters getExtendedParameters(Object command) {
     50         ExtendedParameters anno = command.getClass().getAnnotation(ExtendedParameters.class);
     51         if (anno == null) {
     52             throw new IllegalStateException("All extended commands should have an ExtendedParameters annotation: " +
     53                     command.getClass().getCanonicalName());
     54         }
     55         return anno;
     56     }
     57 
     58     @Nonnull
     59     public static String commandName(JCommander jc) {
     60         return getExtendedParameters(jc.getObjects().get(0)).commandName();
     61     }
     62 
     63     @Nonnull
     64     public static String commandName(Object command) {
     65         return getExtendedParameters(command).commandName();
     66     }
     67 
     68     @Nonnull
     69     public static String[] commandAliases(JCommander jc) {
     70         return commandAliases(jc.getObjects().get(0));
     71     }
     72 
     73     @Nonnull
     74     public static String[] commandAliases(Object command) {
     75         return getExtendedParameters(command).commandAliases();
     76     }
     77 
     78     public static boolean includeParametersInUsage(JCommander jc) {
     79         return includeParametersInUsage(jc.getObjects().get(0));
     80     }
     81 
     82     public static boolean includeParametersInUsage(Object command) {
     83         return getExtendedParameters(command).includeParametersInUsage();
     84     }
     85 
     86     @Nonnull
     87     public static String postfixDescription(JCommander jc) {
     88         return postfixDescription(jc.getObjects().get(0));
     89     }
     90 
     91     @Nonnull
     92     public static String postfixDescription(Object command) {
     93         return getExtendedParameters(command).postfixDescription();
     94     }
     95 
     96     public static void addExtendedCommand(JCommander jc, Command command) {
     97         jc.addCommand(commandName(command), command, commandAliases(command));
     98         command.setupCommand(command.getJCommander());
     99     }
    100 
    101     @Nonnull
    102     public static String[] parameterArgumentNames(ParameterDescription parameterDescription) {
    103         Parameterized parameterized = parameterDescription.getParameterized();
    104 
    105         Class cls = parameterDescription.getObject().getClass();
    106         Field field = null;
    107         while (cls != Object.class) {
    108             try {
    109                 field = cls.getDeclaredField(parameterized.getName());
    110             } catch (NoSuchFieldException ex) {
    111                 cls = cls.getSuperclass();
    112                 continue;
    113             }
    114             break;
    115         }
    116 
    117         assert field != null;
    118         ExtendedParameter extendedParameter = field.getAnnotation(ExtendedParameter.class);
    119         if (extendedParameter != null) {
    120             return extendedParameter.argumentNames();
    121         }
    122 
    123         return new String[0];
    124     }
    125 
    126     @Nullable
    127     public static JCommander getSubcommand(JCommander jc, String commandName) {
    128         if (jc.getCommands().containsKey(commandName)) {
    129             return jc.getCommands().get(commandName);
    130         } else {
    131             for (JCommander command : jc.getCommands().values()) {
    132                 for (String alias: commandAliases(command)) {
    133                     if (commandName.equals(alias)) {
    134                         return command;
    135                     }
    136                 }
    137             }
    138         }
    139         return null;
    140     }
    141 
    142     @Nullable
    143     public static String getCommandDescription(@Nonnull JCommander jc) {
    144         Parameters parameters = jc.getObjects().get(0).getClass().getAnnotation(Parameters.class);
    145         if (parameters == null) {
    146             return null;
    147         }
    148         return parameters.commandDescription();
    149     }
    150 }
    151