001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.cli2.option; 018 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.Comparator; 022import java.util.HashSet; 023import java.util.Iterator; 024import java.util.List; 025import java.util.ListIterator; 026import java.util.Set; 027 028import org.apache.commons.cli2.Argument; 029import org.apache.commons.cli2.DisplaySetting; 030import org.apache.commons.cli2.Group; 031import org.apache.commons.cli2.OptionException; 032import org.apache.commons.cli2.WriteableCommandLine; 033import org.apache.commons.cli2.resource.ResourceConstants; 034import org.apache.commons.cli2.resource.ResourceHelper; 035 036/** 037 * Represents a cvs "update" style command line option. 038 * 039 * Like all Parents, Commands can have child options and can be part of 040 * Arguments 041 */ 042public class Command 043 extends ParentImpl { 044 /** The display name for the command */ 045 private final String preferredName; 046 047 /** The aliases for this command */ 048 private final Set aliases; 049 050 /** All the names for this command */ 051 private final Set triggers; 052 053 /** 054 * Creates a new Command instance. 055 * 056 * @param preferredName 057 * The name normally used to refer to the Command 058 * @param description 059 * A description of the Command 060 * @param aliases 061 * Alternative names for the Command 062 * @param required 063 * Whether the Command is required 064 * @param argument 065 * An Argument that the command takes 066 * @param children 067 * The Group of child options for this Command 068 * @param id 069 * A unique id for the Command 070 * 071 * @see ParentImpl#ParentImpl(Argument, Group, String, int, boolean) 072 */ 073 public Command(final String preferredName, 074 final String description, 075 final Set aliases, 076 final boolean required, 077 final Argument argument, 078 final Group children, 079 final int id) { 080 super(argument, children, description, id, required); 081 082 // check the preferred name is valid 083 if ((preferredName == null) || (preferredName.length() < 1)) { 084 throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.COMMAND_PREFERRED_NAME_TOO_SHORT)); 085 } 086 087 this.preferredName = preferredName; 088 089 // gracefully and defensively handle aliases 090 this.aliases = 091 (aliases == null) ? Collections.EMPTY_SET 092 : Collections.unmodifiableSet(new HashSet(aliases)); 093 094 // populate the triggers Set 095 final Set newTriggers = new HashSet(); 096 newTriggers.add(preferredName); 097 newTriggers.addAll(this.aliases); 098 this.triggers = Collections.unmodifiableSet(newTriggers); 099 } 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}