View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.rat.tools;
20  
21  import java.util.HashMap;
22  import java.util.Locale;
23  import java.util.Map;
24  import java.util.Optional;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  import org.apache.commons.cli.Option;
29  import org.apache.commons.lang3.StringUtils;
30  import org.apache.rat.OptionCollection;
31  import org.apache.rat.commandline.Arg;
32  
33  import static java.lang.String.format;
34  
35  public abstract class AbstractOption {
36      /** The pattern to match CLI options in text */
37      protected static final Pattern PATTERN = Pattern.compile("-(-[a-z0-9]+)+");
38      /** The CLI that the Maven option is wrapping */
39      protected final Option option;
40      /** The Maven name for the option */
41      protected final String name;
42      /** The argument type for this option */
43      protected final OptionCollection.ArgumentType argumentType;
44  
45      /**
46       * Constructor.
47       *
48       * @param option The CLI option
49       */
50      AbstractOption(final Option option, final String name) {
51          this.option = option;
52          this.name = name;
53          argumentType = option.hasArg() ?
54                  option.getArgName() == null ? OptionCollection.ArgumentType.ARG :
55                  OptionCollection.ArgumentType.valueOf(option.getArgName().toUpperCase(Locale.ROOT)) :
56                  OptionCollection.ArgumentType.NONE;
57      }
58  
59      /**
60       * Return default value.
61       * @return default value or {@code null} if no argument given.
62       */
63      public String getDefaultValue() {
64          Arg arg = Arg.findArg(option);
65          return arg == null ? null : arg.defaultValue();
66      }
67  
68      protected abstract String cleanupName(Option option);
69  
70      /**
71       * Gets an example of how to use this option in the native UI.
72       * @return An example of how to use this option in the native UI.
73       */
74      public abstract String getExample();
75  
76      /**
77       * Gets this option's cleaned up name.
78       * @return This option's cleaned up name.
79       */
80      public String cleanupName() {
81          return cleanupName(option);
82      }
83      /**
84       * Replaces CLI pattern options with Maven pattern options.
85       * @param str the string to clean.
86       * @return the string with CLI names replaced with Maven names.
87       */
88      public String cleanup(final String str) {
89          String workingStr = str;
90          if (StringUtils.isNotBlank(workingStr)) {
91              Map<String, String> maps = new HashMap<>();
92              Matcher matcher = PATTERN.matcher(workingStr);
93              while (matcher.find()) {
94                  String key = matcher.group();
95                  String optKey = key.substring(2);
96                  Optional<Option> maybeResult = Arg.getOptions().getOptions().stream()
97                          .filter(o -> optKey.equals(o.getOpt()) || optKey.equals(o.getLongOpt())).findFirst();
98                  maybeResult.ifPresent(value -> maps.put(key, cleanupName(value)));
99              }
100             for (Map.Entry<String, String> entry : maps.entrySet()) {
101                 workingStr = workingStr.replaceAll(Pattern.quote(format("%s", entry.getKey())), entry.getValue());
102             }
103         }
104         return workingStr;
105     }
106 
107     /**
108      * Gets the Maven name for the CLI option.
109      * @return The Maven name for the CLI option.
110      */
111     public final String getName() {
112         return name;
113     }
114 
115     /**
116      * Gets the description escaped for XML format.
117      *
118      * @return the description or an empty string.
119      */
120     public final String getDescription() {
121         return cleanup(option.getDescription());
122     }
123 
124     /**
125      * Gets the simple class name for the data type for this option.
126      * Normally "String".
127      * @return the simple class name for the type.
128      */
129     public final Class<?> getType() {
130         return option.hasArg() ? ((Class<?>) option.getType()) : boolean.class;
131     }
132 
133     /**
134      * Gets the argument name if there is one.
135      * @return the Argument name
136      */
137     public final String getArgName() {
138         return argumentType.getDisplayName();
139     }
140 
141     /**
142      * Gets the argument type if there is one.
143      * @return the Argument name
144      */
145     public final OptionCollection.ArgumentType getArgType() {
146         return argumentType;
147     }
148 
149     /**
150      * Determines if the option is deprecated.
151      * @return {@code true} if the option is deprecated
152      */
153     public final boolean isDeprecated() {
154         return option.isDeprecated();
155     }
156 
157     /**
158      * Determines if the option is required.
159      * @return {@code true} if the option is required.
160      */
161     public final boolean isRequired() {
162         return option.isRequired();
163     }
164 
165     /**
166      * Determine if the enclosed option expects an argument.
167      * @return {@code true} if the enclosed option expects at least one argument.
168      */
169     public final boolean hasArg() {
170         return option.hasArg();
171     }
172 
173     /**
174      * Returns {@code true} if the option has multiple arguments.
175      * @return {@code true} if the option has multiple arguments.
176      */
177     public final boolean hasArgs() {
178         return option.hasArgs();
179     }
180 
181     /**
182      * Returns the number of arguments.
183      * @return The number of arguments.
184      */
185     public final int argCount() {
186         return option.getArgs();
187     }
188 
189     /**
190      * The key value for the option.
191      * @return the key value for the CLI argument map.
192      */
193     public final String keyValue() {
194         return format("\"%s\"", StringUtils.defaultIfEmpty(option.getLongOpt(), option.getOpt()));
195     }
196 
197     /**
198      * Gets the deprecated string if the option is deprecated, or an empty string otherwise.
199      * @return the deprecated string if the option is deprecated, or an empty string otherwise.
200      */
201     public final String getDeprecated() {
202         return  option.isDeprecated() ? cleanup(StringUtils.defaultIfEmpty(option.getDeprecated().toString(), StringUtils.EMPTY)) : StringUtils.EMPTY;
203     }
204 }