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.Map; 030 031public class CommandCompletionContext<I extends CommandIssuer> { 032 private final RegisteredCommand command; 033 protected final I issuer; 034 private final String input; 035 private final String config; 036 private final Map<String, String> configs = new HashMap<>(); 037 private final List<String> args; 038 039 CommandCompletionContext(RegisteredCommand command, I issuer, String input, String config, String[] args) { 040 this.command = command; 041 this.issuer = issuer; 042 this.input = input; 043 if (config != null) { 044 String[] configs = ACFPatterns.COMMA.split(config); 045 for (String conf : configs) { 046 String[] confsplit = ACFPatterns.EQUALS.split(conf, 2); 047 this.configs.put(confsplit[0].toLowerCase(), confsplit.length > 1 ? confsplit[1] : null); 048 } 049 this.config = configs[0]; 050 } else { 051 this.config = null; 052 } 053 054 this.args = Arrays.asList(args); 055 } 056 057 public Map<String, String> getConfigs() { 058 return configs; 059 } 060 061 public String getConfig(String key) { 062 return getConfig(key, null); 063 } 064 065 public String getConfig(String key, String def) { 066 return this.configs.getOrDefault(key.toLowerCase(), def); 067 } 068 069 public boolean hasConfig(String key) { 070 return this.configs.containsKey(key.toLowerCase()); 071 } 072 073 public <T> T getContextValue(Class<? extends T> clazz) throws InvalidCommandArgument { 074 return getContextValue(clazz, null); 075 } 076 077 public <T> T getContextValue(Class<? extends T> clazz, Integer paramIdx) throws InvalidCommandArgument { 078 String name = null; 079 if (paramIdx != null) { 080 if (paramIdx >= command.parameters.length) { 081 throw new IllegalArgumentException("Param index is higher than number of parameters"); 082 } 083 CommandParameter param = command.parameters[paramIdx]; 084 Class<?> paramType = param.getType(); 085 if (!clazz.isAssignableFrom(paramType)) { 086 throw new IllegalArgumentException(param.getName() + ":" + paramType.getName() + " can not satisfy " + clazz.getName()); 087 } 088 name = param.getName(); 089 } else { 090 CommandParameter[] parameters = command.parameters; 091 for (int i = 0; i < parameters.length; i++) { 092 final CommandParameter parameter = parameters[i]; 093 if (clazz.isAssignableFrom(parameter.getType())) { 094 paramIdx = i; 095 name = parameter.getName(); 096 break; 097 } 098 } 099 if (paramIdx == null) { 100 throw new IllegalStateException("Can not find any parameter that can satisfy " + clazz.getName()); 101 } 102 } 103 //noinspection unchecked 104 Map<String, Object> resolved = command.resolveContexts(issuer, args, args.size() - 1); 105 if (resolved == null || paramIdx > resolved.size()) { 106 ACFUtil.sneaky(new CommandCompletionTextLookupException()); 107 } 108 109 //noinspection unchecked 110 return (T) resolved.get(name); 111 } 112 113 public CommandIssuer getIssuer() { 114 return issuer; 115 } 116 117 public String getInput() { 118 return input; 119 } 120 121 public String getConfig() { 122 return config; 123 } 124 125 public boolean isAsync() { 126 return CommandManager.getCurrentCommandOperationContext().isAsync(); 127 } 128}