    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}