Add init to plugins when the console starts.
Add init to plugins when the console starts.

package com.tinkerpop.gremlin.console

import com.tinkerpop.gremlin.console.commands.RemoteCommand
import com.tinkerpop.gremlin.console.commands.SubmitCommand
import com.tinkerpop.gremlin.console.commands.UseCommand
import com.tinkerpop.gremlin.console.util.ArrayIterator
import com.tinkerpop.gremlin.groovy.GremlinLoader
import com.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
import jline.console.history.FileHistory
import org.codehaus.groovy.tools.shell.ExitNotification
import org.codehaus.groovy.tools.shell.Groovysh
import org.codehaus.groovy.tools.shell.IO
import org.codehaus.groovy.tools.shell.InteractiveShellRunner

import java.nio.charset.Charset
import java.util.concurrent.TimeUnit

/**
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
class Console {
    static {
        // this is necessary so that terminal doesn't lose focus to AWT
        System.setProperty("java.awt.headless", "true")
    }

    private static final String HISTORY_FILE = ".gremlin_groovy_history"
    private static final String STANDARD_INPUT_PROMPT = "gremlin> "
    private static final String STANDARD_RESULT_PROMPT = "==>"
    private static final String IMPORT_SPACE = "import "
    private static final String NULL = "null"
    
    private Iterator tempIterator = Collections.emptyIterator()
    
    private final IO io = new IO(System.in, System.out, System.err)
    private final Groovysh groovy = new Groovysh()

    public Console(final String initScriptFile) {
        io.out.println()
        io.out.println("         \\,,,/")
        io.out.println("         (o o)")
        io.out.println("─────oOOo─(3)─oOOo─────")

        final Mediator mediator = new Mediator()
        groovy.register(new UseCommand(groovy, mediator))
        groovy.register(new RemoteCommand(groovy, mediator))
        groovy.register(new SubmitCommand(groovy, mediator))

        // hide output temporarily while imports execute
        groovy.setResultHook(handleResultShowNothing)

        // add the default imports
        new ConsoleImportCustomizerProvider().getAllImports().stream()
                .collect{ IMPORT_SPACE + it }.each{ groovy.execute(it) }

        groovy.setResultHook(handleResultIterate)

        final InteractiveShellRunner runner = new InteractiveShellRunner(groovy, handlePrompt)
        runner.setErrorHandler(handleError)
        try {
            final FileHistory history = new FileHistory(new File(System.getProperty("user.home") + System.getProperty("file.separator") + HISTORY_FILE))
            groovy.setHistory(history)
            runner.setHistory(history)
        } catch (IOException ignored) {
            io.err.println("Unable to create history file: " + HISTORY_FILE)
        }

        GremlinLoader.load()

        // if plugins were added via :use command (or manually copied to the path) then this will try to find
        // plugins and load them
        ServiceLoader.load(GremlinPlugin.class, groovy.getInterp().getClassLoader()).each { plugin ->
            if (!mediator.loadedPlugins.containsKey(plugin.getName())) {
                plugin.init(groovy, io)
                plugin.pluginTo(new ConsolePluginAcceptor(groovy))
                mediator.loadedPlugins.put(plugin.getName(), new PluggedIn(plugin, true))

                io.out.println("loaded: " + plugin.getName())
            }
        }

        if (initScriptFile != null) initializeShellWithScript(initScriptFile)

        try {
            runner.run()
        } catch (ExitNotification ignored) {
            // occurs on exit
        } catch (Throwable t) {
            t.printStackTrace()
        } finally {
            try {
                mediator.close().get(3, TimeUnit.SECONDS)
            } catch (Exception ignored) {
                // ok if this times out - just trying to be polite on shutdown
            } finally {
                System.exit(0)
            }
        }
    }

    private def handlePrompt = {STANDARD_INPUT_PROMPT }

    private def handleResultShowNothing = { args -> null }

    private def handleResultIterate = { result ->
        try {
            // necessary to save persist history to file
            groovy.getHistory().flush()
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e)
        }
        
        while (true) {
            if (this.tempIterator.hasNext()) {
                while (this.tempIterator.hasNext()) {
                    final Object object = this.tempIterator.next()
                    io.out.println(buildResultPrompt() + ((null == object) ? NULL : object.toString()))
                }
                return null
            } else {
                try {
                    if (result instanceof Iterator) {
                        this.tempIterator = (Iterator) result
                        if (!this.tempIterator.hasNext()) return null
                    } else if (result instanceof Iterable) {
                        this.tempIterator = ((Iterable) result).iterator()
                        if (!this.tempIterator.hasNext()) return null
                    } else if (result instanceof Object[]) {
                        this.tempIterator = new ArrayIterator((Object[]) result)
                        if (!this.tempIterator.hasNext()) return null
                    } else if (result instanceof Map) {
                        this.tempIterator = ((Map) result).entrySet().iterator()
                        if (!this.tempIterator.hasNext()) return null
                    } else {
                        io.out.println(buildResultPrompt() + ((null == result) ? NULL : result.toString()))
                        return null
                    }
                } catch (final Exception e) {
                    this.tempIterator = Collections.emptyIterator()
                    throw e
                }
            }
        }
    }

    private def handleError = { err ->
        if (err instanceof Throwable) {
            try {
                final Throwable e = (Throwable) err
                String message = e.getMessage()
                if (null != message) {
                    message = message.replace("startup failed:", "")
                    io.err.println(message.trim())
                } else {
                    io.err.println(e)
                }

                io.err.print("Display stack trace? [yN] ")
                io.err.flush()
                String line = new BufferedReader(io.in).readLine()
                if (null == line)
                    line = ""
                io.err.print(line.trim())
                io.err.println()
                if (line.trim().equals("y") || line.trim().equals("Y")) {
                    e.printStackTrace(io.err)
                }
            } catch (Exception ignored) {
                io.err.println("An undefined error has occurred: " + err)
            }
        } else {
            io.err.println("An undefined error has occurred: " + err.toString())
        }

        return null
    }

    private static String buildResultPrompt() {
        final String groovyshellProperty = System.getProperty("gremlin.prompt")
        if (groovyshellProperty != null)
            return groovyshellProperty

        final String groovyshellEnv = System.getenv("GREMLIN_PROMPT")
        if (groovyshellEnv  != null)
            return  groovyshellEnv

        return STANDARD_RESULT_PROMPT
    }

    private void initializeShellWithScript(final String initScriptFile) {
        String line = ""
        try {
            final BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(initScriptFile), Charset.forName("UTF-8")))
            while ((line = reader.readLine()) != null) {
                groovy.execute(line)
            }
            reader.close()
        } catch (FileNotFoundException ignored) {
            io.err.println(String.format("Gremlin initialization file not found at [%s].", initScriptFile))
            System.exit(1)
        } catch (IOException ignored) {
            io.err.println(String.format("Bad line in Gremlin initialization file at [%s].", line))
            System.exit(1)
        }
    }

    public static void main(final String[] args) {
        new Console(args.length == 1 ? args[0] : null)
    }
}

package com.tinkerpop.gremlin.console

import com.tinkerpop.gremlin.console.commands.RemoteCommand
import com.tinkerpop.gremlin.console.commands.SubmitCommand
import com.tinkerpop.gremlin.console.commands.UseCommand
import com.tinkerpop.gremlin.console.util.ArrayIterator
import com.tinkerpop.gremlin.groovy.GremlinLoader
import com.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
import jline.console.history.FileHistory
import org.codehaus.groovy.tools.shell.ExitNotification
import org.codehaus.groovy.tools.shell.Groovysh
import org.codehaus.groovy.tools.shell.IO
import org.codehaus.groovy.tools.shell.InteractiveShellRunner

import java.nio.charset.Charset
import java.util.concurrent.TimeUnit

/**
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
class Console {
    static {
        // this is necessary so that terminal doesn't lose focus to AWT
        System.setProperty("java.awt.headless", "true")
    }

    private static final String HISTORY_FILE = ".gremlin_groovy_history"
    private static final String STANDARD_INPUT_PROMPT = "gremlin> "
    private static final String STANDARD_RESULT_PROMPT = "==>"
    private static final String IMPORT_SPACE = "import "
    private static final String NULL = "null"
    
    private Iterator tempIterator = Collections.emptyIterator()
    
    private final IO io = new IO(System.in, System.out, System.err)
    private final Groovysh groovy = new Groovysh()

    public Console(final String initScriptFile) {
        io.out.println()
        io.out.println("         \\,,,/")
        io.out.println("         (o o)")
        io.out.println("─────oOOo─(3)─oOOo─────")

        final Mediator mediator = new Mediator()
        groovy.register(new UseCommand(groovy, mediator))
        groovy.register(new RemoteCommand(groovy, mediator))
        groovy.register(new SubmitCommand(groovy, mediator))

        // hide output temporarily while imports execute
        groovy.setResultHook(handleResultShowNothing)

        // add the default imports
        new ConsoleImportCustomizerProvider().getAllImports().stream()
                .collect{ IMPORT_SPACE + it }.each{ groovy.execute(it) }

        groovy.setResultHook(handleResultIterate)

        final InteractiveShellRunner runner = new InteractiveShellRunner(groovy, handlePrompt)
        runner.setErrorHandler(handleError)
        try {
            final FileHistory history = new FileHistory(new File(System.getProperty("user.home") + System.getProperty("file.separator") + HISTORY_FILE))
            groovy.setHistory(history)
            runner.setHistory(history)
        } catch (IOException ignored) {
            io.err.println("Unable to create history file: " + HISTORY_FILE)
        }

        GremlinLoader.load()

        // if plugins were added via :use command (or manually copied to the path) then this will try to find
        // plugins and load them
        ServiceLoader.load(GremlinPlugin.class, groovy.getInterp().getClassLoader()).each { plugin ->
            if (!mediator.loadedPlugins.containsKey(plugin.getName())) {
                plugin.pluginTo(new ConsolePluginAcceptor(groovy))
                mediator.loadedPlugins.put(plugin.getName(), new PluggedIn(plugin, true))

                io.out.println("loaded: " + plugin.getName())
            }
        }

        if (initScriptFile != null) initializeShellWithScript(initScriptFile)

        try {
            runner.run()
        } catch (ExitNotification ignored) {
            // occurs on exit
        } catch (Throwable t) {
            t.printStackTrace()
        } finally {
            try {
                mediator.close().get(3, TimeUnit.SECONDS)
            } catch (Exception ignored) {
                // ok if this times out - just trying to be polite on shutdown
            } finally {
                System.exit(0)
            }
        }
    }

    private def handlePrompt = {STANDARD_INPUT_PROMPT }

    private def handleResultShowNothing = { args -> null }

    private def handleResultIterate = { result ->
        try {
            // necessary to save persist history to file
            groovy.getHistory().flush()
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e)
        }
        
        while (true) {
            if (this.tempIterator.hasNext()) {
                while (this.tempIterator.hasNext()) {
                    final Object object = this.tempIterator.next()
                    io.out.println(buildResultPrompt() + ((null == object) ? NULL : object.toString()))
                }
                return null
            } else {
                try {
                    if (result instanceof Iterator) {
                        this.tempIterator = (Iterator) result
                        if (!this.tempIterator.hasNext()) return null
                    } else if (result instanceof Iterable) {
                        this.tempIterator = ((Iterable) result).iterator()
                        if (!this.tempIterator.hasNext()) return null
                    } else if (result instanceof Object[]) {
                        this.tempIterator = new ArrayIterator((Object[]) result)
                        if (!this.tempIterator.hasNext()) return null
                    } else if (result instanceof Map) {
                        this.tempIterator = ((Map) result).entrySet().iterator()
                        if (!this.tempIterator.hasNext()) return null
                    } else {
                        io.out.println(buildResultPrompt() + ((null == result) ? NULL : result.toString()))
                        return null
                    }
                } catch (final Exception e) {
                    this.tempIterator = Collections.emptyIterator()
                    throw e
                }
            }
        }
    }

    private def handleError = { err ->
        if (err instanceof Throwable) {
            try {
                final Throwable e = (Throwable) err
                String message = e.getMessage()
                if (null != message) {
                    message = message.replace("startup failed:", "")
                    io.err.println(message.trim())
                } else {
                    io.err.println(e)
                }

                io.err.print("Display stack trace? [yN] ")
                io.err.flush()
                String line = new BufferedReader(io.in).readLine()
                if (null == line)
                    line = ""
                io.err.print(line.trim())
                io.err.println()
                if (line.trim().equals("y") || line.trim().equals("Y")) {
                    e.printStackTrace(io.err)
                }
            } catch (Exception ignored) {
                io.err.println("An undefined error has occurred: " + err)
            }
        } else {
            io.err.println("An undefined error has occurred: " + err.toString())
        }

        return null
    }

    private static String buildResultPrompt() {
        final String groovyshellProperty = System.getProperty("gremlin.prompt")
        if (groovyshellProperty != null)
            return groovyshellProperty

        final String groovyshellEnv = System.getenv("GREMLIN_PROMPT")
        if (groovyshellEnv  != null)
            return  groovyshellEnv

        return STANDARD_RESULT_PROMPT
    }

    private void initializeShellWithScript(final String initScriptFile) {
        String line = ""
        try {
            final BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(initScriptFile), Charset.forName("UTF-8")))
            while ((line = reader.readLine()) != null) {
                groovy.execute(line)
            }
            reader.close()
        } catch (FileNotFoundException ignored) {
            io.err.println(String.format("Gremlin initialization file not found at [%s].", initScriptFile))
            System.exit(1)
        } catch (IOException ignored) {
            io.err.println(String.format("Bad line in Gremlin initialization file at [%s].", line))
            System.exit(1)
        }
    }

    public static void main(final String[] args) {
        new Console(args.length == 1 ? args[0] : null)
    }
}
