001/* 002 * Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining 005 * a copy of this software and associated documentation files (the 006 * "Software"), to deal in the Software without restriction, including 007 * without limitation the rights to use, copy, modify, merge, publish, 008 * distribute, sublicense, and/or sell copies of the Software, and to 009 * permit persons to whom the Software is furnished to do so, subject to 010 * the following conditions: 011 * 012 * The above copyright notice and this permission notice shall be 013 * included in all copies or substantial portions of the Software. 014 * 015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 016 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 017 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 018 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 019 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 020 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 021 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 022 */ 023 024package co.aikar.commands; 025 026import java.util.Arrays; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Locale; 030import java.util.Map; 031 032public class CommandCompletionContext<I extends CommandIssuer> { 033 private final RegisteredCommand command; 034 protected final I issuer; 035 private final String input; 036 private final String config; 037 private final Map<String, String> configs = new HashMap<>(); 038 private final List<String> args; 039 040 CommandCompletionContext(RegisteredCommand command, I issuer, String input, String config, String[] args) { 041 this.command = command; 042 this.issuer = issuer; 043 this.input = input; 044 if (config != null) { 045 String[] configs = ACFPatterns.COMMA.split(config); 046 for (String conf : configs) { 047 String[] confsplit = ACFPatterns.EQUALS.split(conf, 2); 048 this.configs.put(confsplit[0].toLowerCase(Locale.ENGLISH), confsplit.length > 1 ? confsplit[1] : null); 049 } 050 this.config = configs[0]; 051 } else { 052 this.config = null; 053 } 054 055 this.args = Arrays.asList(args); 056 } 057 058 public Map<String, String> getConfigs() { 059 return configs; 060 } 061 062 public String getConfig(String key) { 063 return getConfig(key, null); 064 } 065 066 public String getConfig(String key, String def) { 067 return this.configs.getOrDefault(key.toLowerCase(Locale.ENGLISH), def); 068 } 069 070 public boolean hasConfig(String key) { 071 return this.configs.containsKey(key.toLowerCase(Locale.ENGLISH)); 072 } 073 074 public <T> T getContextValue(Class<? extends T> clazz) throws InvalidCommandArgument { 075 return getContextValue(clazz, null); 076 } 077 078 public <T> T getContextValue(Class<? extends T> clazz, Integer paramIdx) throws InvalidCommandArgument { 079 String name = null; 080 if (paramIdx != null) { 081 if (paramIdx >= command.parameters.length) { 082 throw new IllegalArgumentException("Param index is higher than number of parameters"); 083 } 084 CommandParameter param = command.parameters[paramIdx]; 085 Class<?> paramType = param.getType(); 086 if (!clazz.isAssignableFrom(paramType)) { 087 throw new IllegalArgumentException(param.getName() + ":" + paramType.getName() + " can not satisfy " + clazz.getName()); 088 } 089 name = param.getName(); 090 } else { 091 CommandParameter[] parameters = command.parameters; 092 for (int i = 0; i < parameters.length; i++) { 093 final CommandParameter parameter = parameters[i]; 094 if (clazz.isAssignableFrom(parameter.getType())) { 095 paramIdx = i; 096 name = parameter.getName(); 097 break; 098 } 099 } 100 if (paramIdx == null) { 101 throw new IllegalStateException("Can not find any parameter that can satisfy " + clazz.getName()); 102 } 103 } 104 return getContextValueByName(clazz, name); 105 } 106 107 public <T> T getContextValueByName(Class<? extends T> clazz, String name) throws InvalidCommandArgument { 108 //noinspection unchecked 109 Map<String, Object> resolved = command.resolveContexts(issuer, args, name); 110 if (resolved == null || !resolved.containsKey(name)) { 111 ACFUtil.sneaky(new CommandCompletionTextLookupException()); 112 } 113 114 //noinspection unchecked 115 return (T) resolved.get(name); 116 } 117 118 public CommandIssuer getIssuer() { 119 return issuer; 120 } 121 122 public String getInput() { 123 return input; 124 } 125 126 public String getConfig() { 127 return config; 128 } 129 130 public boolean isAsync() { 131 return CommandManager.getCurrentCommandOperationContext().isAsync(); 132 } 133}