package org.erlide.util; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.ericsson.otp.erlang.OtpNode; import com.google.common.base.Strings; import com.google.common.collect.Lists; public class ErlangHostnameRetriever { final String otpHome; AtomicInteger id = new AtomicInteger(); private final static boolean verbose = !SystemConfiguration .hasFeatureEnabled("erlide.ericsson.user") && !SystemConfiguration.hasFeatureEnabled("erlide.quiet"); public ErlangHostnameRetriever(final String otpHome) { this.otpHome = otpHome; } public String getErlangHostName(final boolean longHost) { final String nodeName = "foo" + System.currentTimeMillis(); final ProcessBuilder builder = new ProcessBuilder( Lists.newArrayList(otpHome + "/bin/erl", longHost ? "-name" : "-sname", nodeName, "-setcookie", "erlide")); String hostName = null; try { final Process process = builder.start(); try { final StreamListener listener = new StreamListener( process.getInputStream()); while (listener.isAlive()) { try { listener.join(); hostName = listener.getResult(); if (verbose) { ErlLogger.debug("Erlang %s hostname: %s", longHost ? "long" : "short", hostName); } } catch (final InterruptedException e) { } } } finally { process.destroy(); } } catch (final IOException e) { ErlLogger.error(e); } return hostName; } public boolean canConnect(final String hostName, final boolean longHost) { if (Strings.isNullOrEmpty(hostName)) { return false; } final String nodeName = "foo" + id.incrementAndGet(); final String fullName = nodeName + "@" + hostName; final ProcessBuilder builder = new ProcessBuilder( Lists.newArrayList(otpHome + "/bin/erl", longHost ? "-name" : "-sname", fullName, "-setcookie", "erlide")); try { final Process process = builder.start(); try { final StreamListener listener = new StreamListener( process.getInputStream()); while (listener.getResult() == null) { try { Thread.sleep(50); } catch (final InterruptedException e) { // ignore } } final OtpNode node = new OtpNode("jtest", "erlide"); final boolean result = node.ping(fullName, 2000); node.close(); return result; } finally { process.destroy(); } } catch (final Exception e) { ErlLogger.error(e); } return false; } private static class StreamListener extends Thread { private static Pattern pattern = Pattern .compile("^\\([^@]+@([^\\)]+)\\)[0-9]+>.*$"); private final InputStream stream; private String result; StreamListener(final InputStream stream) { this.stream = stream; start(); } @Override public void run() { final StringBuilder line = new StringBuilder(); try { int chr; while ((chr = stream.read()) != -1) { if (chr == 10 || chr == 13) { line.setLength(0); } else { line.append((char) chr); } final Matcher matcher = pattern.matcher(line); if (matcher.matches()) { result = matcher.group(1); return; } } } catch (final IOException e) { ErlLogger.error(e); } } public String getResult() { return result; } } }