/******************************************************************************* * Copyright (c) 2008 Vlad Dumitrescu and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Vlad Dumitrescu *******************************************************************************/ package org.erlide.backend.runtimeinfo; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.erlide.jinterface.ErlLogger; import com.ericsson.otp.erlang.RuntimeVersion; import com.google.common.base.Strings; public class RuntimeInfo { public static final String DEFAULT_MARKER = "*DEFAULT*"; private String homeDir = ""; private String args = ""; private String name; private List<String> codePath; private String cookie = ""; private String nodeName = ""; private String workingDir = ""; private boolean managed; // will it be started/stopped by us? private RuntimeVersion version; private String suffix = ""; private boolean longName = true; private boolean startShell = false; private boolean console = true; private boolean loadAllNodes = false; public RuntimeInfo() { super(); codePath = new ArrayList<String>(); codePath.add(DEFAULT_MARKER); } public static RuntimeInfo copy(final RuntimeInfo o, final boolean mkCopy) { if (o == null) { return null; } final RuntimeInfo rt = new RuntimeInfo(); rt.name = o.name; if (mkCopy) { rt.name += "_copy"; } rt.args = o.args; rt.codePath = new ArrayList<String>(o.codePath); rt.managed = o.managed; rt.homeDir = o.homeDir; rt.workingDir = o.workingDir; rt.nodeName = o.nodeName; rt.version = o.version; rt.longName = o.longName; rt.startShell = o.startShell; rt.loadAllNodes = o.loadAllNodes; return rt; } public String getArgs() { return args; } public void setArgs(final String args) { this.args = args.trim(); } public String getCookie() { if ("".equals(cookie)) { cookie = null; } return cookie; } public void setCookie(final String cookie) { this.cookie = cookie.trim(); } public String getNodeName() { return nodeName + suffix; } public void setNodeNameSuffix(final String suffix) { this.suffix = suffix; } public void setNodeName(final String nodeName) { if (validateNodeName(nodeName)) { this.nodeName = nodeName; } else { // TODO this still can create a name that isn't valid this.nodeName = nodeName.replaceAll("[^a-zA-Z0-9_-]", ""); } } public boolean isManaged() { return managed; } public void setManaged(final boolean managed) { this.managed = managed; } public List<String> getPathA() { return getPathA(DEFAULT_MARKER); } public List<String> getPathZ() { return getPathZ(DEFAULT_MARKER); } public String getWorkingDir() { return workingDir; } public void setWorkingDir(final String workingDir) { this.workingDir = Strings.isNullOrEmpty(workingDir) ? "." : workingDir; } @Override public String toString() { return String.format("Backend<%s/%s (%s) %s [%s]>", getName(), getNodeName(), getOtpHome(), version, getArgs()); } public String[] getCmdLine() { final List<String> result = new ArrayList<String>(); String erl = getOtpHome() + "/bin/erl"; if (erl.indexOf(' ') >= 0) { erl = "\"" + erl + "\""; } result.add(erl); for (final String pathA : getPathA()) { if (!empty(pathA)) { result.add("-pa"); result.add(pathA); } } for (final String pathZ : getPathZ()) { if (!empty(pathZ)) { result.add("-pz"); result.add(pathZ); } } if (!startShell) { result.add("-noshell"); } final boolean globalLongName = System.getProperty("erlide.longname", "false").equals("true"); final String nameTag = longName || globalLongName ? "-name" : "-sname"; String nameOption = ""; if (!getNodeName().equals("")) { nameOption = RuntimeInfo .buildLocalNodeName(getNodeName(), longName); result.add(nameTag); result.add(nameOption); final String cky = getCookie(); if (cky != null) { result.add("-setcookie"); result.add(cky); } } final String gotArgs = getArgs(); if (!empty(gotArgs)) { final String[] xargs = split(gotArgs); for (final String a : xargs) { result.add(a); } } return result.toArray(new String[result.size()]); } /** * split on spaces but respect quotes * * @param theArgs * @return */ private String[] split(final String theArgs) { final Pattern p = Pattern.compile("(\"[^\"]*?\"|'[^']*?'|\\S+)"); final Matcher m = p.matcher(theArgs); final List<String> tokens = new ArrayList<String>(); while (m.find()) { tokens.add(m.group(1)); } return tokens.toArray(new String[tokens.size()]); } private boolean empty(final String str) { if (str == null || str.length() == 0) { return true; } return false; } public String getOtpHome() { return homeDir; } public void setOtpHome(final String otpHome) { homeDir = otpHome; version = RuntimeVersion.getVersion(otpHome); } public String getName() { return name; } public void setName(final String name) { this.name = name; } public List<String> getCodePath() { return codePath; } public void setCodePath(final List<String> path) { codePath = path; } protected List<String> getPathA(final String marker) { if (codePath != null) { final List<String> list = codePath; final int i = list.indexOf(marker); if (i < 0) { return list; } return list.subList(0, i); } return Collections.emptyList(); } protected List<String> getPathZ(final String marker) { if (codePath != null) { final List<String> list = codePath; final int i = list.indexOf(marker); if (i < 0) { return Collections.emptyList(); } return list.subList(i + 1, codePath.size()); } return Collections.emptyList(); } public static boolean validateNodeName(final String name) { return name != null && name.matches("[a-zA-Z0-9_-]+(@[a-zA-Z0-9_.-]+)?"); } public static boolean validateLocation(final String path) { final String v = RuntimeVersion.getRuntimeVersion(path); return v != null; } public static boolean isValidOtpHome(final String otpHome) { // Check if it looks like a ERL_TOP location: if (otpHome == null) { return false; } if (otpHome.length() == 0) { return false; } final File d = new File(otpHome); if (!d.isDirectory()) { return false; } final boolean hasErl = hasExecutableFile(otpHome + "/bin/erl"); final File lib = new File(otpHome + "/lib"); final boolean hasLib = lib.isDirectory() && lib.exists(); return hasErl && hasLib; } private static boolean hasExecutableFile(final String fileName) { final File simpleFile = new File(fileName); final File exeFile = new File(fileName + ".exe"); return simpleFile.exists() || exeFile.exists(); } public static boolean hasCompiler(final String otpHome) { // Check if it looks like a ERL_TOP location: if (otpHome == null) { return false; } if (otpHome.length() == 0) { return false; } final File d = new File(otpHome); if (!d.isDirectory()) { return false; } final boolean hasErlc = hasExecutableFile(otpHome + "/bin/erlc"); return hasErlc; } protected static String cvt(final Collection<String> path) { final StringBuilder result = new StringBuilder(); for (String s : path) { if (s.length() > 0) { if (s.contains(" ")) { s = "\"" + s + "\""; } result.append(s).append(';'); } } return result.toString(); } public RuntimeVersion getVersion() { return version; } public void useLongName(final boolean useLongName) { longName = useLongName; } public boolean getLongName() { return longName; } public void setStartShell(final boolean startShell) { this.startShell = startShell; } public boolean isStartShell() { return startShell; } public void setHasConsole(final boolean console) { this.console = console; } public boolean hasConsole() { return console; } public void setLoadAllNodes(final boolean loadAllNodes) { this.loadAllNodes = loadAllNodes; } public boolean loadOnAllNodes() { return loadAllNodes; } public static String buildLocalNodeName(final String label, final boolean longName) { if (label.indexOf('@') > 0) { // ignore unique here? return label; } if (longName) { final String host = getHost(); return label + "@" + host; } else { return label; } } public static String getHost() { String host; try { host = InetAddress.getLocalHost().getHostName(); if (System.getProperty("erlide.host") != null) { final int dot = host.indexOf("."); if (dot != -1) { host = host.substring(0, dot); } } } catch (final IOException e) { host = "localhost"; ErlLogger.error(e); } return host; } }