edu.uga.cs.clickminer.ClickminerCLI.java Source code

Java tutorial

Introduction

Here is the source code for edu.uga.cs.clickminer.ClickminerCLI.java

Source

/*
* Copyright (C) 2012 Chris Neasbitt
* Author: Chris Neasbitt
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package edu.uga.cs.clickminer;

import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import edu.uga.cs.clickminer.datamodel.log.InteractionRecord;
import edu.uga.cs.clickminer.exception.ProxyErrorException;
import edu.uga.cs.json.JSONWriter;

/**
 * <p>ClickminerCLI class.</p>
 *
 * @author Chris Neasbitt
 * @version $Id: ClickminerCLI.java 844 2013-10-03 16:53:41Z cjneasbitt $Id
 */
public class ClickminerCLI {

    private static final Log log = LogFactory.getLog(ClickminerCLI.class);

    @SuppressWarnings("static-access")
    private static Options initializeOptions() {
        Options retval = new Options();

        retval.addOption(OptionBuilder.isRequired(false).withDescription("Print help message.").withLongOpt("help")
                .create("?"))
                .addOption(OptionBuilder.hasArg().isRequired(false)
                        .withDescription("Path to browser binary. (Optional)").withLongOpt("firefox-binary")
                        .create("b"))
                .addOption(OptionBuilder.hasArg().isRequired(false)
                        .withDescription("Path to browser profile. (Optional)").withLongOpt("firefox-profile")
                        .create("P"))
                .addOption(OptionBuilder.hasArg().isRequired(true).withDescription("The proxy host.")
                        .withLongOpt("host").create("h"))
                .addOption(OptionBuilder.hasArg().isRequired(true).withDescription("The proxy port.")
                        .withLongOpt("proxy-port").withType(Number.class).create("p"))
                .addOption(OptionBuilder.hasArg().isRequired(true).withDescription("The instrument server port.")
                        .withLongOpt("inst-server-port").withType(Number.class).create("q"))
                .addOption(OptionBuilder.hasArg().isRequired(true)
                        .withDescription("The path to write the interaction log.").withLongOpt("clicklog")
                        .create("o"))
                .addOption(OptionBuilder.hasArg().isRequired(false)
                        .withDescription("Sets a limit to the number of times a request "
                                + "can be checked as a possible interaction request.  (Optional)")
                        .withLongOpt("check-limit").withType(Number.class).create("l"))
                .addOption(OptionBuilder.hasArgs().isRequired(false)
                        .withDescription("Prevents clickminer from considering any request with "
                                + "the supplied response MIME type as a possible interaction.  More than one "
                                + "MIME type may be supplied. (Optional)")
                        .withLongOpt("filter-mime").create("f"))
                .addOption(OptionBuilder.hasArg().isRequired(false)
                        .withDescription("Path to browser stdout/stderr debug log. (Optional)")
                        .withLongOpt("firefox-stdio-log").create("Lo"))
                .addOption(OptionBuilder.hasArg().isRequired(false)
                        .withDescription("Path to browser webdriver debug log. (Optional)")
                        .withLongOpt("firefox-webdriver-log").create("Ld"))
                .addOption(OptionBuilder.hasArg(false).isRequired(false)
                        .withDescription("Use firefox unstable loading strategy. (Optional)")
                        .withLongOpt("unstable-loading").create("u"))
                .addOption(OptionBuilder.hasArg(false).isRequired(false)
                        .withDescription("Examine the flashvars of embedded flash objects. (Optional)")
                        .withLongOpt("flash").create("F"))
                .addOption(OptionBuilder.hasArg(false).isRequired(false)
                        .withDescription("Enable dynamic execution of javascript "
                                + "Warning: this could dramatically increase execution time.  (Optional)")
                        .withLongOpt("javascript-execution").create("j"));

        return retval;
    }

    private static Pair<DesiredCapabilities, FirefoxProfile> createBrowserConfig(CommandLine cli)
            throws ParseException {
        DesiredCapabilities cap = new DesiredCapabilities();
        FirefoxProfile profile = null;
        String profilepath = cli.getOptionValue('P');
        if (profilepath != null) {
            profile = new FirefoxProfile(new File(profilepath));
        } else {
            profile = new FirefoxProfile();
        }

        setProxyConfig(cli.getOptionValue('h'), ((Number) cli.getParsedOptionValue("p")).intValue(), cap);
        setBrowserLoggingConfig(cli.getOptionValue("Lo"), cli.getOptionValue("Ld"), cap, profile);
        if (cli.hasOption("u")) {
            setUnstableLoadingConfig(profile);
        }

        return new ImmutablePair<DesiredCapabilities, FirefoxProfile>(cap, profile);
    }

    private static void setProxyConfig(String host, int port, DesiredCapabilities cap) {
        String PROXY = host + ":" + port;
        Proxy proxy = new Proxy();
        proxy.setHttpProxy(PROXY).setFtpProxy(PROXY).setSslProxy(PROXY);
        cap.setCapability(CapabilityType.PROXY, proxy);
    }

    private static void setUnstableLoadingConfig(FirefoxProfile profile) {
        profile.setPreference("webdriver.load.strategy", "unstable");
    }

    private static void setBrowserLoggingConfig(String outLog, String driverLog, DesiredCapabilities cap,
            FirefoxProfile profile) {
        if (outLog != null || driverLog != null) {
            if (driverLog != null) {
                LoggingPreferences logs = new LoggingPreferences();
                logs.enable(LogType.BROWSER, Level.ALL);
                logs.enable(LogType.DRIVER, Level.ALL);
                logs.enable(LogType.CLIENT, Level.ALL);
                logs.enable(LogType.SERVER, Level.ALL);
                logs.enable(LogType.PROFILER, Level.ALL);
                cap.setCapability(CapabilityType.LOGGING_PREFS, logs);
                profile.setPreference("webdriver.log.file", driverLog);
            }
            if (outLog != null) {
                System.setProperty("webdriver.firefox.logfile", outLog);
            }

        }

    }

    private static void run(String[] args) {
        GnuParser parser = new GnuParser();
        Options opts = ClickminerCLI.initializeOptions();
        CommandLine cli;
        RemoteWebDriver wdriver = null;
        try {
            cli = parser.parse(opts, args);

            if (cli.hasOption('?')) {
                throw new ParseException(null);
            }

            if (log.isInfoEnabled()) {
                StringBuffer arginfo = new StringBuffer("\n");
                arginfo.append("firefox-binary: " + cli.getOptionValue('b') + "\n");
                arginfo.append("firefox-profile: " + cli.getOptionValue('P') + "\n");
                arginfo.append("host: " + cli.getOptionValue('h') + "\n");
                arginfo.append("proxy-port: " + cli.getOptionValue('p') + "\n");
                arginfo.append("inst-server-port: " + cli.getOptionValue('q') + "\n");
                arginfo.append("clicklog: " + cli.getOptionValue('o') + "\n");
                arginfo.append("check-limit: " + cli.getOptionValue('l') + "\n");

                String[] mimes = cli.getOptionValues('f');
                String mimesstr = null;
                if (mimes != null) {
                    mimesstr = new String();
                    for (int i = 0; i < mimes.length; i++) {
                        if (i < mimes.length - 1) {
                            mimesstr += mimes[i] + ",";
                        } else {
                            mimesstr += mimes[i];
                        }
                    }
                }

                arginfo.append("filter-mime: " + mimesstr + "\n");
                arginfo.append("javascript-execution: " + cli.hasOption('j') + "\n");
                arginfo.append("flash: " + cli.hasOption('F') + "\n");
                arginfo.append("unstable-loading: " + cli.hasOption('u') + "\n");
                arginfo.append("firefox-stdio-log: " + cli.getOptionValue("Lo") + "\n");
                arginfo.append("firefox-webdriver-log: " + cli.getOptionValue("Ld") + "\n");

                log.info(arginfo.toString());
            }

            String binarypath = cli.getOptionValue('b');
            FirefoxBinary binary = null;
            if (binarypath != null) {
                binary = new FirefoxBinary(new File(binarypath));
            }

            Pair<DesiredCapabilities, FirefoxProfile> config = createBrowserConfig(cli);
            wdriver = new FirefoxDriver(binary, config.getRight(), config.getLeft());
            if (cli.hasOption("u")) {
                wdriver.manage().timeouts().pageLoadTimeout(1000, TimeUnit.MILLISECONDS);
                wdriver.manage().timeouts().implicitlyWait(1000, TimeUnit.MILLISECONDS);
            }

            ProxyClient pc = new ProxyClient(cli.getOptionValue('h'),
                    ((Number) cli.getParsedOptionValue("q")).intValue());

            if (cli.hasOption('l')) {
                pc.setRequestCheckLimit(((Number) cli.getParsedOptionValue("l")).intValue());
            }
            if (cli.hasOption('f')) {
                List<String> types = Arrays.asList(cli.getOptionValues('f'));
                pc.setFilteredResponseType(types);
            }

            BrowserEngine bengine = new BrowserEngine(pc, wdriver, cli.hasOption('j'), cli.hasOption('F'));
            try {
                bengine.run();
            } catch (Exception e) {
                if (log.isFatalEnabled()) {
                    log.fatal("", e);
                }
            }
            List<InteractionRecord> ilog = bengine.getInteractionLog();
            JSONWriter<InteractionRecord> writer = new JSONWriter<InteractionRecord>();
            try {
                writer.write(new File(cli.getOptionValue('o')), ilog);
            } catch (Exception e) {
                if (log.isErrorEnabled()) {
                    log.error("", e);
                }
            }
            bengine.close();
        } catch (ParseException e1) {
            PrintWriter writer = new PrintWriter(System.out);
            HelpFormatter usageFormatter = new HelpFormatter();
            usageFormatter.printHelp(writer, 80, "clickminer", "", opts, 0, 2, "");
            writer.close();
        } catch (ProxyErrorException e2) {
            String message = "Error communicating with proxy server. Aborting";
            if (log.isFatalEnabled()) {
                log.fatal(message, e2);
            }
        } finally {
            if (wdriver != null) {
                try {
                    wdriver.close();
                } catch (Exception e) {
                    if (log.isDebugEnabled()) {
                        log.debug(e);
                    }
                    System.exit(-1);
                }
            }
        }
    }

    /**
     * <p>main.</p>
     *
     * @param args an array of {@link java.lang.String} objects.
     */
    public static void main(String[] args) {
        run(args);
    }

}