001package fr.aumgn.bukkitutils.command.args; 002 003import java.util.Arrays; 004import java.util.Iterator; 005import java.util.List; 006import java.util.Map; 007import java.util.Set; 008 009import fr.aumgn.bukkitutils.command.CommandsMessages; 010import fr.aumgn.bukkitutils.command.arg.CommandArg; 011import fr.aumgn.bukkitutils.command.arg.CommandArgFactory; 012import fr.aumgn.bukkitutils.command.arg.basic.ListArg; 013import fr.aumgn.bukkitutils.command.arg.basic.EnumArg; 014 015public class CommandArgsBase { 016 017 protected final CommandsMessages messages; 018 private final Set<Character> flags; 019 private final Map<Character, String> argsFlags; 020 private final String[] args; 021 022 public CommandArgsBase(CommandsMessages messages, CommandArgsParser parser) { 023 this.messages = messages; 024 this.flags = parser.getFlags(); 025 this.argsFlags = parser.getArgsFlags(); 026 this.args = parser.getArgs(); 027 } 028 029 private boolean hasIndex(int index) { 030 return index < args.length; 031 } 032 033 /** 034 * Checks if the command has flags either 035 * boolean flag or argument flag. 036 */ 037 public boolean hasFlags() { 038 return !flags.isEmpty() || !argsFlags.isEmpty(); 039 } 040 041 /** 042 * Checks if the commands has the given boolean 043 * flag. 044 */ 045 public boolean hasFlag(char character) { 046 return flags.contains(character); 047 } 048 049 /** 050 * Checks if the commands has the given argument 051 * flag. 052 */ 053 public boolean hasArgFlag(char character) { 054 return argsFlags.containsKey(character); 055 } 056 057 /** 058 * Returns an iterable over all boolean flags. 059 */ 060 public Iterable<Character> flags() { 061 return flags; 062 } 063 064 /** 065 * Returns the number of argument. 066 */ 067 public int length() { 068 return args.length; 069 } 070 071 /** 072 * Get the argument at the given position. 073 */ 074 public String get(int index) { 075 return args[index]; 076 } 077 078 /** 079 * Get the argument at the given position or 080 * the default if argument is omitted. 081 */ 082 public String get(int index, String def) { 083 if (hasIndex(index)) { 084 return get(index); 085 } 086 087 return def; 088 } 089 090 /** 091 * Get the given argument flag value. 092 */ 093 public String get(char flag) { 094 return argsFlags.get(flag); 095 } 096 097 /** 098 * Get the given argument flag value or 099 * the default if omitted. 100 */ 101 public String get(char flag, String def) { 102 if (hasArgFlag(flag)) { 103 return get(flag); 104 } 105 106 return def; 107 } 108 109 protected String getOrNull(int index) { 110 return get(index, (String) null); 111 } 112 113 protected String getOrNull(char flag) { 114 return get(flag, (String) null); 115 } 116 117 /** 118 * Get the {@link CommandArg} corresponding to 119 * the given factory for the given index. 120 */ 121 public <T extends CommandArg<?>> T get(int index, 122 CommandArgFactory<T> factory) { 123 return factory.createCommandArg(getOrNull(index)); 124 } 125 126 /** 127 * Get the {@link CommandArg} corresponding to 128 * the given factory for the given argument flag. 129 */ 130 public <T extends CommandArg<?>> T get(char flag, 131 CommandArgFactory<T> factory) { 132 return factory.createCommandArg(getOrNull(flag)); 133 } 134 135 /** 136 * Get the {@link EnumArg} value corresponding to 137 * the given enum class for the given index. 138 */ 139 public <T extends Enum<T>> EnumArg<T> get(int index, Class<T> enumClass) { 140 return new EnumArg<T>(messages, getOrNull(index), enumClass); 141 } 142 143 /** 144 * Get the {@link EnumArg} value corresponding to 145 * the given enum class for the given flag. 146 */ 147 public <T extends Enum<T>> EnumArg<T> get(char flag, Class<T> enumClass) { 148 return new EnumArg<T>(messages, getOrNull(flag), enumClass); 149 } 150 151 /** 152 * Get the {@link ListArg} wrapping the {@link CommandArg} 153 * corresponding to the given factory for the given index. 154 */ 155 public <V, T extends CommandArg<V>> ListArg<V, T> getList(int index, 156 CommandArgFactory<T> factory) { 157 return new ListArg<V, T>(",", factory, getOrNull(index)); 158 } 159 160 /** 161 * Get the {@link ListArg} wrapping the {@link CommandArg} 162 * corresponding to the given factory for the given index 163 * using the given separator. 164 */ 165 public <V, T extends CommandArg<V>> ListArg<V, T> getList(int index, 166 CommandArgFactory<T> factory, String separator) { 167 return new ListArg<V, T>(separator, factory, getOrNull(index)); 168 } 169 170 /** 171 * Get the {@link ListArg} wrapping the {@link CommandArg} 172 * corresponding to the given factory for the given flag. 173 */ 174 public <V, T extends CommandArg<V>> ListArg<V, T> getList(char flag, 175 CommandArgFactory<T> factory) { 176 return new ListArg<V, T>(",", factory, getOrNull(flag)); 177 } 178 179 /** 180 * Get the {@link ListArg} wrapping the {@link CommandArg} 181 * corresponding to the given factory for the given flag 182 * using the given separator. 183 */ 184 public <V, T extends CommandArg<V>> ListArg<V, T> getList(char flag, 185 CommandArgFactory<T> factory, String separator) { 186 return new ListArg<V, T>(separator, factory, getOrNull(flag)); 187 } 188 189 private <T extends Enum<T>> CommandArgFactory<EnumArg<T>> 190 enumArgFactory(final Class<T> enumClass) { 191 return new CommandArgFactory<EnumArg<T>>() { 192 @Override 193 public EnumArg<T> createCommandArg(String string) { 194 return new EnumArg<T>(messages, string, enumClass); 195 } 196 }; 197 } 198 199 /** 200 * Get the {@link ListArg} wrapping the {@link EnumArg} 201 * corresponding to the given enum class for the given index. 202 */ 203 public <T extends Enum<T>> ListArg<T, EnumArg<T>> getList(int index, 204 Class<T> klass) { 205 return new ListArg<T, EnumArg<T>>(",", enumArgFactory(klass), 206 getOrNull(index)); 207 } 208 209 /** 210 * Get the {@link ListArg} wrapping the {@link EnumArg} 211 * corresponding to the given enum class for the given index 212 * using the given separator. 213 */ 214 public <T extends Enum<T>> ListArg<T, EnumArg<T>> getList(int index, 215 final Class<T> klass, String separator) { 216 return new ListArg<T, EnumArg<T>>(separator, enumArgFactory(klass), 217 getOrNull(index)); 218 } 219 220 /** 221 * Get the {@link ListArg} wrapping the {@link EnumArg} 222 * corresponding to the given enum class for the given flag. 223 */ 224 public <T extends Enum<T>> ListArg<T, EnumArg<T>> getList(char flag, 225 final Class<T> klass) { 226 return new ListArg<T, EnumArg<T>>(",", enumArgFactory(klass), 227 getOrNull(flag)); 228 } 229 230 /** 231 * Get the {@link ListArg} wrapping the {@link EnumArg} 232 * corresponding to the given enum class for the given flag 233 * using the given separator. 234 */ 235 public <T extends Enum<T>> ListArg<T, EnumArg<T>> getList(char flag, 236 final Class<T> klass, String separator) { 237 return new ListArg<T, EnumArg<T>>(separator, enumArgFactory(klass), 238 getOrNull(flag)); 239 } 240 241 /** 242 * Get the string containing all arguments from index 243 * to endIndex separated by a whitespace. 244 */ 245 public String get(int index, int rawEndIndex) { 246 int endIndex; 247 if (rawEndIndex > -1) { 248 endIndex = rawEndIndex; 249 } else { 250 endIndex = args.length - 1; 251 } 252 StringBuilder builder = new StringBuilder(); 253 for (int i = index; i < endIndex; i++) { 254 builder.append(args[i]); 255 builder.append(" "); 256 } 257 builder.append(args[endIndex]); 258 return builder.toString(); 259 } 260 261 /** 262 * Get the string containing all arguments from index 263 * to endIndex separated by a whitespace or the given default. 264 */ 265 public String get(int index, int endIndex, String def) { 266 if (hasIndex(index) && hasIndex(endIndex)) { 267 return get(index, endIndex); 268 } 269 270 return def; 271 } 272 273 /** 274 * Returns all arguments as a list. 275 */ 276 public List<String> asList() { 277 return Arrays.asList(args); 278 } 279 280 /** 281 * Returns all arguments starting from index as a list. 282 */ 283 public List<String> asList(int index) { 284 return asList(index, args.length - 1); 285 } 286 287 /** 288 * Returns all arguments from index to endIndex 289 * as a list. 290 */ 291 public List<String> asList(int index, int endIndex) { 292 int startIndex = Math.max(0, index); 293 int actualEndIndex = Math.min(args.length, endIndex + 1); 294 return asList().subList(startIndex, actualEndIndex); 295 } 296 297 /** 298 * Iterator over all arguments 299 * (does not include argument flags). 300 */ 301 public Iterator<String> iterator() { 302 return asList().iterator(); 303 } 304}