cc.osint.graphd.client.ProtographClient.java Source code

Java tutorial

Introduction

Here is the source code for cc.osint.graphd.client.ProtographClient.java

Source

/*
 * Copyright 2011 John Muellerleile
 *
 * This file is licensed to you under the Apache License, version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package cc.osint.graphd.client;

import java.lang.*;
import java.util.*;
import java.util.concurrent.*;
import org.json.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.ChannelHandlerContext;
import java.util.logging.*;
import jline.*;

import cc.osint.graphd.client.handlers.*;

public class ProtographClient implements Runnable {
    static class ConsoleLogFormatter extends java.util.logging.Formatter {
        public String format(LogRecord lr) {
            return lr.getMessage() + "\n";
        }
    }

    private static final Logger log = Logger.getLogger("protographClient");
    static ConsoleLogFormatter consoleLogFormatter;
    static ConsoleHandler consoleHandler;
    static {
        log.setUseParentHandlers(false);
        consoleHandler = new ConsoleHandler();
        log.addHandler(consoleHandler);
        log.setLevel(Level.ALL);
        consoleLogFormatter = new ConsoleLogFormatter();
        consoleHandler.setFormatter((java.util.logging.Formatter) consoleLogFormatter);
    }

    private String host;
    private int port;
    private boolean connected;
    private boolean shutdown;

    private ClientBootstrap bootstrap;
    private Channel channel;
    private ChannelFuture lastWriteFuture;

    private ProtographClientHandler protographClientHandler;
    private ProtographClientEventHandler eventHandler;

    final LinkedBlockingQueue<ClientCommand> clientCommandQueue;
    final Thread clientCommandThread;

    public ProtographClient(String host, int port) throws Exception {
        this(host, port, null);
    }

    public ProtographClient(String host, int port, ProtographClientEventHandler eventHandler) throws Exception {
        this.host = host;
        this.port = port;
        connected = false;
        shutdown = false;
        bootstrap = null;
        channel = null;
        lastWriteFuture = null;
        this.eventHandler = eventHandler;
        ProtographClientHandler protographClientHandler = new ProtographClientHandler(this);
        protographClientHandler.setProtographClient(this);
        clientCommandQueue = new LinkedBlockingQueue<ClientCommand>();
        clientCommandThread = new Thread(this);
        clientCommandThread.start();
        connect();
    }

    public boolean connect() throws Exception {
        bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(),
                Executors.newCachedThreadPool()));
        ProtographClientPipelineFactory pipelineFactory = new ProtographClientPipelineFactory(this);
        bootstrap.setPipelineFactory(pipelineFactory);

        ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
        channel = future.awaitUninterruptibly().getChannel();

        if (!future.isSuccess()) {
            connected = false;
            future.getCause().printStackTrace();
            bootstrap.releaseExternalResources();
            log.info("Connection failure: " + host + ":" + port);
        } else {
            connected = true;
            log.info("Connection success: " + host + ":" + port);
        }
        return connected;
    }

    public void disconnect() throws Exception {
        shutdown = true;
        clientCommandThread.interrupt();
        channel.getCloseFuture().awaitUninterruptibly();
        bootstrap.releaseExternalResources();
        shutdown = true;
    }

    public boolean isConnected() {
        return connected;
    }

    protected Channel getChannel() {
        return channel;
    }

    protected ProtographClientHandler getProtographClientHandler() {
        if (null == protographClientHandler) {
            protographClientHandler = new ProtographClientHandler(this);
        }
        return protographClientHandler;
    }

    protected ProtographClientEventHandler getEventHandler() {
        return eventHandler;
    }

    private void send(String str) throws Exception {
        send(str, false);
    }

    private void send(String str, boolean waitForFlush) throws Exception {
        lastWriteFuture = channel.write(str);
        if (waitForFlush)
            lastWriteFuture.awaitUninterruptibly();
    }

    /*
     * async command processing thread
    */

    class ClientCommand {
        private String command;
        private ProtographClientResultHandler handler;

        public ClientCommand(String command, ProtographClientResultHandler handler) {
            this.command = command;
            this.handler = handler;
        }

        public String getCommand() {
            return command;
        }

        public ProtographClientResultHandler getHandler() {
            return handler;
        }
    }

    public void run() {
        try {
            while (true) {
                try {
                    ClientCommand clientCommand = clientCommandQueue.take();
                    protographClientHandler.setResultHandler(clientCommand.getHandler());
                    send(clientCommand.getCommand(), true);
                    while (!clientCommand.getHandler().isComplete())
                        ;
                } catch (java.lang.InterruptedException interruptedEx) {
                    log.info("Interrupted!  Exiting...");
                    break;
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        } catch (Exception ex1) {
            ex1.printStackTrace();
        }
    }

    /*
     * send a raw command and block until a result
    */

    public List<JSONObject> exec(String str) throws Exception {
        StandardResultHandler resultHandler = new StandardResultHandler();
        exec(str, resultHandler);
        List<String> resultList = resultHandler.waitForResults();
        if (resultHandler.isSuccessful()) {
            return interpretResults(resultList);
        } else {
            resultHandler.getException().printStackTrace();
            return null;
        }
    }

    /*
     * send a raw command and do not block until a result
    */

    public void exec(String str, ProtographClientResultHandler resultHandler) throws Exception {
        clientCommandQueue.put(new ClientCommand(str, resultHandler));
    }

    public static List<JSONObject> interpretResults(List<String> resultList) throws Exception {
        List<JSONObject> res = new ArrayList<JSONObject>();
        if (resultList.size() == 0) {
            return res;
        } else {
            for (String str : resultList) {
                if (str.charAt(0) == '{') {
                    res.add(new JSONObject(str));
                } else if (str.charAt(0) == '[') {
                    JSONObject result = new JSONObject();
                    JSONArray resultArray = new JSONArray(str);
                    result.put("results", resultArray);
                    res.add(result);
                } else {
                    JSONObject result = new JSONObject();
                    result.put("value", str);
                    res.add(result);
                }
            }
        }
        return res;
    }

    /*
     * console client interface
    */

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.println("Usage: " + ProtographClient.class.getSimpleName() + " <host> <port>");
            return;
        }
        String host = args[0];
        int port = Integer.parseInt(args[1]);
        ProtographClient client = new ProtographClient(host, port);

        // Read commands from the stdin.
        ConsoleReader reader = new ConsoleReader();
        for (;;) {
            String line = reader.readLine();
            if (line == null) {
                break;
            }

            // Sends the received line to the server.
            //client.send(line + "\r\n");
            List<JSONObject> results = client.exec(line.trim() + "\n");
            if (null == results) {
                log.info("no result!");
            } else {
                if (results.size() == 0) {
                    log.info("OK");
                } else {
                    int c = 0;
                    for (JSONObject result : results) {
                        c++;
                        log.info(c + ": " + result.toString(4));
                    }
                }
            }

            // If user typed the 'bye' command, wait until the server closes
            // the connection.
            if (line.toLowerCase().equals("bye")) {
                client.disconnect();
                break;
            }
        }
        client.disconnect();
    }
}