org.eclim.Eclim.java Source code

Java tutorial

Introduction

Here is the source code for org.eclim.Eclim.java

Source

/**
 * Copyright (C) 2005 - 2012  Eric Van Dewoestine
 *
 * 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 3 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 org.eclim;

import java.io.File;
import java.io.FileInputStream;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import org.apache.tools.ant.taskdefs.condition.Os;

import org.eclim.util.CommandExecutor;
import org.eclim.util.IOUtils;

import static org.junit.Assert.assertNotNull;

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;

/**
 * Utility class to executing eclim commands and returning the results.
 *
 * @author Eric Van Dewoestine
 */
public class Eclim {
    public static final String TEST_PROJECT = "eclim_unit_test";

    private static final String ECLIM = System.getProperty("eclipse.home") + "/eclim";
    private static final String PORT = System.getProperty("eclimd.port");
    private static final String PRETTY = "-pretty";
    private static final String COMMAND = "-command";

    private static final JsonParser JSON_PARSER = new JsonParser();

    private static String workspace;

    /**
     * Executes eclim using the supplied arguments.
     * <p/>
     * The "-command" argument will be prepended to the argument array you supply.
     *
     * @param args The arguments to pass to eclim.
     * @return The result of the command execution as a string.
     */
    public static Object execute(String[] args) {
        return execute(args, -1, true);
    }

    /**
     * Executes eclim using the supplied arguments.
     * <p/>
     * The "-command" argument will be prepended to the argument array you supply.
     *
     * @param args The arguments to pass to eclim.
     * @param failOnError True to fail on error, false to return the output
     * regardless of whether the command failed or not.
     * @return The result of the command execution as a string.
     */
    public static Object execute(String[] args, boolean failOnError) {
        return execute(args, -1, failOnError);
    }

    /**
     * Executes eclim using the supplied arguments.
     * <p/>
     * The "-command" argument will be prepended to the argument array you supply.
     *
     * @param args The arguments to pass to eclim.
     * @param timeout Timeout in milliseconds.
     * @return The result of the command execution as a string.
     */
    public static Object execute(String[] args, long timeout) {
        return execute(args, timeout, true);
    }

    /**
     * Executes eclim using the supplied arguments.
     * <p/>
     * The "-command" argument will be prepended to the argument array you supply.
     *
     * @param args The arguments to pass to eclim.
     * @param timeout Timeout in milliseconds.
     * @param failOnError True to fail on error, false to return the output
     * regardless of whether the command failed or not.
     * @return The result of the command execution as a string.
     */
    public static Object execute(String[] args, long timeout, boolean failOnError) {
        assertNotNull("Please configure property eclimd.port", PORT);
        assertNotNull("Please configure property eclipse.home", ECLIM);

        String[] arguments = null;
        if (Os.isFamily(Os.FAMILY_WINDOWS)) {
            String eclimCmd = ECLIM + ".bat";
            String drive = eclimCmd.substring(0, 2);
            arguments = new String[3];
            arguments[0] = "cmd.exe";
            arguments[1] = "/c";
            arguments[2] = drive + " && \"" + eclimCmd + "\" --nailgun-port " + PORT + " " + PRETTY + " " + COMMAND
                    + " \"" + StringUtils.join(args, "\" \"") + "\"";
        } else {
            arguments = new String[args.length + 5];
            System.arraycopy(args, 0, arguments, 5, args.length);
            arguments[0] = ECLIM;
            arguments[1] = "--nailgun-port";
            arguments[2] = PORT;
            arguments[3] = PRETTY;
            arguments[4] = COMMAND;
        }

        System.out.println("Command: " + StringUtils.join(arguments, ' '));

        CommandExecutor process = null;
        try {
            process = CommandExecutor.execute(arguments, timeout);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        if (process.getReturnCode() == -1) {
            process.destroy();
            throw new RuntimeException("Command timed out.");
        }

        String result = process.getResult().trim();
        String error = process.getErrorMessage();
        if (process.getReturnCode() != 0) {
            if (!failOnError) {
                System.out.println("Result: " + result);
                if (!StringUtils.EMPTY.equals(error)) {
                    System.out.println("Error: " + error);
                }
                return result;
            }
            System.out.println("OUT: " + result);
            System.out.println("ERR: " + error);
            throw new RuntimeException("Command failed: " + process.getReturnCode());
        }

        System.out.println("Result: " + result);
        if (!StringUtils.EMPTY.equals(error)) {
            System.out.println("Error: " + error);
        }

        if (result.equals(StringUtils.EMPTY)) {
            result = "\"\"";
        }
        try {
            return toType(JSON_PARSER.parse(result));
        } catch (JsonSyntaxException jse) {
            if (!failOnError) {
                return result;
            }
            throw jse;
        }
    }

    public static Object toType(JsonElement json) {
        // null
        if (json.isJsonNull()) {
            return null;

            // int, double, boolean, String
        } else if (json.isJsonPrimitive()) {
            JsonPrimitive prim = json.getAsJsonPrimitive();
            if (prim.isBoolean()) {
                return prim.getAsBoolean();
            } else if (prim.isString()) {
                return prim.getAsString();
            } else if (prim.isNumber()) {
                if (prim.getAsString().indexOf('.') != -1) {
                    return prim.getAsDouble();
                }
                return prim.getAsInt();
            }

            // List
        } else if (json.isJsonArray()) {
            ArrayList<Object> type = new ArrayList<Object>();
            for (JsonElement element : json.getAsJsonArray()) {
                type.add(toType(element));
            }
            return type;

            // Map
        } else if (json.isJsonObject()) {
            HashMap<String, Object> type = new HashMap<String, Object>();
            for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
                type.put(entry.getKey(), toType(entry.getValue()));
            }
            return type;
        }

        return null;
    }

    /**
     * Gets the path to the current workspace.
     *
     * @return The workspace path.
     */
    public static String getWorkspace() {
        if (workspace == null) {
            workspace = ((String) execute(new String[] { "workspace_dir" })).replace('\\', '/');
        }
        return workspace;
    }

    /**
     * Gets the path to the specified project.
     *
     * @param name The project name.
     * @return The project path.
     */
    @SuppressWarnings("unchecked")
    public static String getProjectPath(String name) {
        Object result = execute(new String[] { "project_info", "-p", name });
        if (result instanceof Map) {
            Map<String, String> info = (Map<String, String>) result;
            if (info.containsKey("path")) {
                return info.get("path");
            }
        }
        return null;
    }

    /**
     * Determines if a project with the supplied name exists.
     *
     * @return true if the project exists, false otherwise.
     */
    public static boolean projectExists(String name) {
        return getProjectPath(name) != null;
    }

    /**
     * Gets the value of a project setting.
     *
     * @param project The project name.
     * @param name The setting name.
     * @return The setting value.
     */
    public static String getProjectSetting(String project, String name) {
        return (String) execute(new String[] { "project_setting", "-p", project, "-s", name, });
    }

    /**
     * Sets the value of a project setting.
     *
     * @param project The project name.
     * @param name The setting name.
     * @param value The setting value.
     */
    public static void setProjectSetting(String project, String name, String value) {
        execute(new String[] { "project_setting", "-p", project, "-s", name, "-v", value, });
    }

    /**
     * Constructs a full path for the given project relative file.
     *
     * @param file The project relative file path.
     * @return The absolute path to the file.
     */
    public static String resolveFile(String file) {
        return resolveFile(TEST_PROJECT, file);
    }

    /**
     * Constructs a full path for the given project relative file.
     *
     * @param project The name of the project the file belongs to.
     * @param file The project relative file path.
     * @return The absolute path to the file.
     */
    public static String resolveFile(String project, String file) {
        return new StringBuffer().append(getProjectPath(project)).append('/').append(file).toString();
    }

    /**
     * Reads the project relative file into a string which is then returned.
     *
     * @param project The name of the project the file belongs to.
     * @param file The project relative file path.
     * @return The file contents as a string.
     */
    public static String fileToString(String project, String file) {
        String path = resolveFile(project, file);
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(path);
            return IOUtils.toString(fin);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            IOUtils.closeQuietly(fin);
        }
    }

    /**
     * Recursively delete the supplied directory.
     *
     * @param dir The directory to delete.
     */
    public static void deleteDirectory(File dir) {
        if (!dir.exists()) {
            return;
        }

        for (File f : dir.listFiles()) {
            if (f.isDirectory()) {
                deleteDirectory(f);
            } else {
                f.delete();
            }
        }
        dir.delete();
    }
}