View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.cli2.option;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.Comparator;
22  import java.util.HashSet;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.ListIterator;
26  import java.util.Set;
27  
28  import org.apache.commons.cli2.Argument;
29  import org.apache.commons.cli2.DisplaySetting;
30  import org.apache.commons.cli2.Group;
31  import org.apache.commons.cli2.OptionException;
32  import org.apache.commons.cli2.WriteableCommandLine;
33  import org.apache.commons.cli2.resource.ResourceConstants;
34  import org.apache.commons.cli2.resource.ResourceHelper;
35  
36  /**
37   * Represents a cvs "update" style command line option.
38   *
39   * Like all Parents, Commands can have child options and can be part of
40   * Arguments
41   */
42  public class Command
43      extends ParentImpl {
44      /** The display name for the command */
45      private final String preferredName;
46  
47      /** The aliases for this command */
48      private final Set aliases;
49  
50      /** All the names for this command */
51      private final Set triggers;
52  
53      /**
54       * Creates a new Command instance.
55       *
56       * @param preferredName
57       *            The name normally used to refer to the Command
58       * @param description
59       *            A description of the Command
60       * @param aliases
61       *            Alternative names for the Command
62       * @param required
63       *            Whether the Command is required
64       * @param argument
65       *            An Argument that the command takes
66       * @param children
67       *            The Group of child options for this Command
68       * @param id
69       *            A unique id for the Command
70       *
71       * @see ParentImpl#ParentImpl(Argument, Group, String, int, boolean)
72       */
73      public Command(final String preferredName,
74                     final String description,
75                     final Set aliases,
76                     final boolean required,
77                     final Argument argument,
78                     final Group children,
79                     final int id) {
80          super(argument, children, description, id, required);
81  
82          // check the preferred name is valid
83          if ((preferredName == null) || (preferredName.length() < 1)) {
84              throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.COMMAND_PREFERRED_NAME_TOO_SHORT));
85          }
86  
87          this.preferredName = preferredName;
88  
89          // gracefully and defensively handle aliases
90          this.aliases =
91              (aliases == null) ? Collections.EMPTY_SET
92                                : Collections.unmodifiableSet(new HashSet(aliases));
93  
94          // populate the triggers Set
95          final Set newTriggers = new HashSet();
96          newTriggers.add(preferredName);
97          newTriggers.addAll(this.aliases);
98          this.triggers = Collections.unmodifiableSet(newTriggers);
99      }
100 
101     public void processParent(final WriteableCommandLine commandLine,
102                               final ListIterator arguments)
103         throws OptionException {
104         // grab the argument to process
105         final String arg = (String) arguments.next();
106 
107         // if we can process it
108         if (canProcess(commandLine, arg)) {
109             // then note the option
110             commandLine.addOption(this);
111 
112             // normalise the argument list
113             arguments.set(preferredName);
114         } else {
115             throw new OptionException(this, ResourceConstants.UNEXPECTED_TOKEN, arg);
116         }
117     }
118 
119     public Set getTriggers() {
120         return triggers;
121     }
122 
123     public void validate(WriteableCommandLine commandLine)
124         throws OptionException {
125         if (isRequired() && !commandLine.hasOption(this)) {
126             throw new OptionException(this, ResourceConstants.OPTION_MISSING_REQUIRED,
127                                       getPreferredName());
128         }
129 
130         super.validate(commandLine);
131     }
132 
133     public void appendUsage(final StringBuffer buffer,
134                             final Set helpSettings,
135                             final Comparator comp) {
136         // do we display optionality
137         final boolean optional =
138             !isRequired() && helpSettings.contains(DisplaySetting.DISPLAY_OPTIONAL);
139         final boolean displayAliases = helpSettings.contains(DisplaySetting.DISPLAY_ALIASES);
140 
141         if (optional) {
142             buffer.append('[');
143         }
144 
145         buffer.append(preferredName);
146 
147         if (displayAliases && !aliases.isEmpty()) {
148             buffer.append(" (");
149 
150             final List list = new ArrayList(aliases);
151             Collections.sort(list);
152 
153             for (final Iterator i = list.iterator(); i.hasNext();) {
154                 final String alias = (String) i.next();
155                 buffer.append(alias);
156 
157                 if (i.hasNext()) {
158                     buffer.append(',');
159                 }
160             }
161 
162             buffer.append(')');
163         }
164 
165         super.appendUsage(buffer, helpSettings, comp);
166 
167         if (optional) {
168             buffer.append(']');
169         }
170     }
171 
172     public String getPreferredName() {
173         return preferredName;
174     }
175 }