Package com.elega9t.commons.shell.intrprtr

Source Code of com.elega9t.commons.shell.intrprtr.Interpreter

package com.elega9t.commons.shell.intrprtr;

import com.elega9t.commons.args.*;
import com.elega9t.commons.args.Parameter;
import com.elega9t.commons.cp.ClassFilter;
import com.elega9t.commons.shell.EnvironmentProperty;
import com.elega9t.commons.shell.Shell;
import com.elega9t.commons.util.ReflectionUtilities;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.elega9t.commons.util.StringUtilities.split;

public class Interpreter {

    private final String name;

    private final Map<String, Class<? extends Command>> commands;

    private final Context<Object> context = new Context<Object>();

    public Interpreter(String name) {
        this.name = name;
        this.commands = new HashMap<String, Class<? extends Command>>();
    }

    public Interpreter(String name, Class<? extends Command>... commands) throws InstantiationException, IllegalAccessException {
        this(name);
        addCommand(commands);
    }

    public Interpreter(String name, Package... commandsPackages) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException {
        this(name);
        String packageNames[] = new String[commandsPackages.length];
        for (int i = 0, commandsPackagesLength = commandsPackages.length; i < commandsPackagesLength; i++) {
            Package commandsPackage = commandsPackages[i];
            packageNames[i] = commandsPackage.getName();
        }
        addCommands(packageNames);
    }

    public Interpreter(String name, String... commandsPackages) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException {
        this(name);
        addCommands(commandsPackages);
    }

    public String getName() {
        return name;
    }

    public void addCommand(Class<? extends Command>... commands) throws IllegalAccessException, InstantiationException {
        for (Class<? extends Command> command : commands) {
            Command cmd = command.newInstance();
            this.commands.put(cmd.getName(), command);
        }
    }

    private void addCommands(String... commandsPackages) throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException {
        final List<Class> commandClasses = ReflectionUtilities.getClasses(new ClassFilter() {
            @Override
            public boolean accept(Class aClass) {
                return (aClass.getSuperclass() == Command.class);
            }
        }, commandsPackages);
        for (Class commandClass : commandClasses) {
            addCommand(commandClass);
        }
    }

    public void execute(Shell shell, String line) throws IllegalAccessException, InstantiationException, ParseException {
        String[] split = split(line, ';');
        for (int i = 0, splitLength = split.length; i < splitLength; i++) {
            String cmd = split[i].trim();
            if(i > 0) {
                shell.out(shell.getEnvironmentProperty(EnvironmentProperty.PROMPT) + " ");
                shell.outln(cmd);
            }
            executeCommand(shell, cmd);
        }
    }

    protected void executeCommand(Shell shell, String cmd) throws ParseException, InstantiationException, IllegalAccessException {
        if(cmd.trim().length() > 0) {
            String commandName;
            if (cmd != null && cmd.contains(" ")) {
                commandName = cmd.substring(0, cmd.indexOf(" "));
                cmd = cmd.substring(cmd.indexOf(" ") + 1);
            } else {
                commandName = cmd;
                cmd = "";
            }
            if (commandName != null) {
                ArgumentParser parser = new ArgumentParser(new ByteArrayInputStream(cmd.getBytes()));
                Map<String, Parameter> commandLineParameters = parser.parse();
                Class<? extends Command> commandClass = commands.get(commandName);
                if (commandClass == null) {
                    throw new CommandNotFoundException(commandName + ": command not found");
                }
                Command command = commandClass.newInstance();
                Map<NamedParameter, Field> namedParameterFieldMap = ReflectionUtilities.getDeclaredFieldsWithAnnotation(NamedParameter.class, commandClass);
                for (final NamedParameter namedParameter : namedParameterFieldMap.keySet()) {
                    Field field = namedParameterFieldMap.get(namedParameter);
                    field.setAccessible(true);
                    Parameter parameter = commandLineParameters.get(namedParameter.name());
                    if (parameter != null) {
                        field.set(command, parameter.getValue());
                    } else if (namedParameter.required()) {
                        throw new IllegalStateException("Parameter " + namedParameter.name() + " is required.");
                    }
                }
                Map<com.elega9t.commons.shell.intrprtr.Parameter, Field> parameterFieldMap = ReflectionUtilities.getDeclaredFieldsWithAnnotation(com.elega9t.commons.shell.intrprtr.Parameter.class, commandClass);
                for (final com.elega9t.commons.shell.intrprtr.Parameter param : parameterFieldMap.keySet()) {
                    Field field = parameterFieldMap.get(param);
                    field.setAccessible(true);
                    Parameter parameter = commandLineParameters.get(param.index() + "");
                    if (parameter != null) {
                        field.set(command, parameter.getValue());
                    } else if (param.required()) {
                        throw new IllegalStateException("Parameter '" + field.getName() + "' is required.");
                    }
                }
                int exitVal = command.execute(shell);
                shell.setExitVal(exitVal);
                return;
            }
        }
        shell.setExitVal(0);
    }

}
TOP

Related Classes of com.elega9t.commons.shell.intrprtr.Interpreter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.