Java tutorial
/** * 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(); } }