Package com.elega9t.commons.shell

Source Code of com.elega9t.commons.shell.Shell

package com.elega9t.commons.shell;

import com.elega9t.commons.shell.intrprtr.Interpreter;
import com.elega9t.commons.shell.intrprtr.cmd.ExitCommand;
import com.elega9t.commons.util.ReplacementProvider;
import com.elega9t.commons.util.StringUtilities;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Shell {

    private static final Logger LOGGER = Logger.getLogger(Shell.class.getName());

    private final Environment environment = new Environment();

    private Stack<Interpreter> interpreterStack = new Stack<Interpreter>();

    private Scanner scanner;

    private Interpreter interpreter;

    private int exitVal;

    private List<String> history = new ArrayList<String>();

    private ConcurrentHashMap<String, Object> context = new ConcurrentHashMap<String, Object>();

    public Shell(@NotNull Interpreter interpreter) {
        EnvironmentProperty.init(this);
        interpreterStack.push(interpreter);
        scanner = new Scanner(System.in);
    }

    public Interpreter getInterpreter() {
        return interpreter;
    }

    public Environment getEnvironment() {
        return environment;
    }

    public int getExitVal() {
        return exitVal;
    }

    public void setExitVal(int exitVal) {
        this.exitVal = exitVal;
        EnvironmentProperty.update(this);
    }

    public void execute() {
        outln("Elega9t Shell v1.0.0");
        nextInterpreter();
        do {
            out(getEnvironmentProperty(EnvironmentProperty.PROMPT) + " ");
            String line = scanner.nextLine().trim();
            EnvironmentProperty.update(this);
            try {
                line = handleSpecialCommand(this, line);
                history.add(line);
                interpreter.execute(this, line);
            } catch (Exception e) {
                LOGGER.log(Level.FINE, "Command [" + line + "] threw exception", e);
                outln(interpreter.getName() + ": " + e.getMessage());
                setExitVal(1);
            }
        } while(interpreter != null);
    }

    public static String handleSpecialCommand(final Shell shell, String str) {
        str = StringUtilities.replace("(!!)", str, new ReplacementProvider() {
            @Override
            public String getReplacement(String match) {
                return shell.getLastFromHistory();
            }
        });
        str = StringUtilities.replace("!(\\d+)", str, new ReplacementProvider() {
            @Override
            public String getReplacement(String match) {
                int index = Integer.parseInt(match);
                return shell.getFromHistory(index);
            }
        });
        return str;
    }

    public String resolve(String str) {
        str = StringUtilities.replace("\\$\\(([. ]+)", str, new ReplacementProvider() {
            @Override
            public String getReplacement(String match) {
                return "Hi";
            }
        });
        return environment.resolve(str);
    }

    public String getLastFromHistory() {
        return getFromHistory(history.size());
    }

    public String getFromHistory(int index) {
        if(index > 0 && index <= history.size()) {
            return history.get(index - 1);
        } else {
            throw new IllegalStateException("!" + index + ": event not found.");
        }
    }

    public int getHistorySize() {
        return history.size();
    }

    public String getEnvironmentProperty(EnvironmentProperty environmentProperty) {
        return environment.resolve(environment.getValue(environmentProperty.name()));
    }

    public void out(Object msg) {
        AnsiConsole.out.print(msg);
        AnsiConsole.out().flush();
    }

    public void outln(Object msg) {
        AnsiConsole.out.println(msg);
        AnsiConsole.out().flush();
    }

    public void error(Throwable t) {
        outln(interpreter.getName() + ": " + t.getMessage());
    }

    public void nextInterpreter() {
        Interpreter nextInterpreter = interpreterStack.size() == 0 ? null : interpreterStack.pop();
        if(nextInterpreter != null) {
            outln("shell: switching to '" + nextInterpreter.getName() + "' interpreter.");
        }
        interpreter = nextInterpreter;
        EnvironmentProperty.update(this);
    }

    public void switchInterpreter(Interpreter nextInterpreter) {
        interpreterStack.push(interpreter);
        interpreterStack.push(nextInterpreter);
        nextInterpreter();
    }

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException {
        Shell shell = new Shell(new Interpreter("yok", ExitCommand.class.getPackage().getName()));
        shell.execute();
    }

    public void setContextElement(String name, Object obj) {
        context.put(name, obj);
    }

    public Object getContextElement(String name) {
        return context.get(name);
    }

}
TOP

Related Classes of com.elega9t.commons.shell.Shell

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.