Package org.twdata.maven.cli

Source Code of org.twdata.maven.cli.AbstractCliMojo

package org.twdata.maven.cli;

import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.twdata.maven.cli.commands.Command;
import org.twdata.maven.cli.commands.ExitCommand;
import org.twdata.maven.cli.commands.HelpCommand;
import org.twdata.maven.cli.commands.ListProjectsCommand;
import org.twdata.maven.cli.console.JLineCliConsole;

public abstract class AbstractCliMojo extends AbstractMojo {
    /**
     * The Maven Project Object
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    protected MavenProject project;

    /**
     * The Maven Session Object
     *
     * @parameter expression="${session}"
     * @required
     * @readonly
     */
    protected MavenSession session;

    /**
     * The reactor projects.
     *
     * @parameter expression="${reactorProjects}"
     * @readonly
     */
    private List reactorProjects;

    /**
     * Command prompt text.
     *
     * @parameter
     */
    private String prompt = "maven";

    /**
     * TCP port to listen to for shell access
     *
     * @parameter expression="${cli.port}"
     */
    private String port = null;

    private boolean acceptSocket = true;
    private ServerSocket server = null;
    private CommandsCompletor commandsCompletor;
    private MultiOutputStream mos;

    protected Map<String, MavenProject> modules = new HashMap<String, MavenProject>();
    protected List<Command> cliCommands = new ArrayList<Command>();

    protected abstract void beforeExecute();
    protected abstract Command getSpecializedCliMojoCommand();

    public final void execute() throws MojoExecutionException {
       
        if(null == mos)
        {
            mos = new MultiOutputStream(System.out);
            System.setOut(new PrintStream(mos));
        }
        beforeExecute();
        resolveModulesInProject();
        buildCommands();
        buildCommandsCompletor();

        Thread consoleShell = displayConsoleCliShell();
        displaySocketCliShell();
        try {
            consoleShell.join();
        } catch (InterruptedException e) {
            // ignore
        }
    }

    private void resolveModulesInProject() {
        for (Object reactorProject : reactorProjects) {
            modules.put(((MavenProject) reactorProject).getArtifactId(),
                    (MavenProject) reactorProject);
        }
    }

    private void buildCommands() {
        cliCommands.add(getSpecializedCliMojoCommand());
        cliCommands.add(new ExitCommand());
        cliCommands.add(new ListProjectsCommand(modules.keySet()));
        cliCommands.add(new HelpCommand(cliCommands));
    }

    private void buildCommandsCompletor() {
        CommandTokenCollector collector = new CommandTokenCollector();
        for (Command command : cliCommands) {
            command.collectCommandTokens(collector);
        }

        commandsCompletor = new CommandsCompletor(collector.getCollectedTokens());
    }

    private Thread displayConsoleCliShell() {
        Thread shell = new Thread() {
            @Override
            public void run() {
                try {
                    displayShell(System.in, System.out);
                    acceptSocket = false;
                    if (server != null) {
                        server.close();
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
        shell.start();

        return shell;
    }

    private void displaySocketCliShell() {
        String foundPort = "";
        if (port != null) {
            try {
                int requestedPort = Integer.parseInt(port);
                int plusOne = requestedPort + 1;
               
                int finalPort = AvailablePortFinder.getPortOrNextAvailable(requestedPort,plusOne);
                foundPort = Integer.toString(finalPort);
               
                if(requestedPort != finalPort)
                {
                    getLog().warn("request port " + requestedPort + " was taken. Using new port: " + finalPort);   
                }
               
                server = new ServerSocket(finalPort);
                openSocket(server, finalPort);
               
            } catch (IOException e) {
                getLog().error("Cannot open port " + foundPort + " for cli server: " + e);
                return;
            }
            catch (Exception e)
            {
                getLog().error(e.getMessage());
                return;
            }
        }
    }

    private void displayShell(InputStream in, PrintStream out) {
        // Display version of Maven being used right before showing the prompt
        String version = (String)session.getSystemProperties().get("maven.build.version");
        getLog().info("Using Maven version: " + version);

        JLineCliConsole console = new JLineCliConsole(in, out, getLog(), commandsCompletor, prompt);
        new CliShell(cliCommands, console).run();
    }

    private void openSocket(ServerSocket server, int port) {
        getLog().info("Opening port " + port + " for socket cli access");
        while (acceptSocket) {
            Socket connection = null;
            try {
                connection = server.accept();
               
                PrintStream socketStream = new PrintStream(connection.getOutputStream());
                mos.addStream(socketStream);
                displayShell(connection.getInputStream(), System.out);
            } catch (IOException ex) {
                getLog().error("Server quit unexpectedly");
                ex.printStackTrace();
            }
            finally {
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (IOException e) {
                        // we really don't care
                    }
                }
            }
        }
    }
}
TOP

Related Classes of org.twdata.maven.cli.AbstractCliMojo

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.