/* * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser General Public License * (LGPL) version 2.1 which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl.html * * This library 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 * Lesser General Public License for more details. * * Contributors: * bstefanescu * * $Id$ */ package org.nuxeo.runtime.remoting; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import org.jboss.remoting.InvokerLocator; /** * Helps to create locators for nuxeo runtime nodes. * * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> */ public class LocatorHelper { public static final int DEFAULT_PORT = 62474; private static final String ANY = "0.0.0.0"; private static final String SERVER_BIND_ADDRESS = "jboss.bind.address"; // Utility class. private LocatorHelper() { } public static InvokerLocator getLocator(String protocol, String host, int port, String path, Map<String, String> parameters) { if (protocol == null) { protocol = "socket"; } if (port <= 0) { port = DEFAULT_PORT; } if (parameters == null) { parameters = new HashMap<String, String>(); parameters.put(InvokerLocator.DATATYPE, "nuxeo"); } else if (!"nuxeo".equals(parameters.get(InvokerLocator.DATATYPE))) { parameters.put(InvokerLocator.DATATYPE, "nuxeo"); } return new InvokerLocator(protocol, host, port, path, parameters); } public static InvokerLocator getLocator(String protocol, String host, int port) { HashMap<String, String> parameters = new HashMap<String, String>(); parameters.put(InvokerLocator.DATATYPE, "nuxeo"); return new InvokerLocator(protocol, host, port, "/", parameters); } public static InvokerLocator getLocator(String host, int port) { HashMap<String, String> parameters = new HashMap<String, String>(); parameters.put(InvokerLocator.DATATYPE, "nuxeo"); return new InvokerLocator("socket", host, port, "/", parameters); } public static InvokerLocator getLocator(String host) { HashMap<String, String> parameters = new HashMap<String, String>(); parameters.put(InvokerLocator.DATATYPE, "nuxeo"); return new InvokerLocator("socket", host, 62474, "/", parameters); } /** * Constructs the object used to identify a remoting server via simple uri * format string (e.g. socket://myhost:7000). * <p> * Note: the uri passed may not always be the one returned via call to * getLocatorURI() as may need to change if port not specified, host is * 0.0.0.0, etc. If need original uri that is passed to this constructor, * need to call getOriginalURI(). */ public static InvokerLocator parse(String uri) throws MalformedURLException { String protocol; String host; String path; int port; Map<String, String> parameters = null; int i = uri.indexOf("://"); if (i < 0) { throw new MalformedURLException("Invalid url " + uri); } String tmp = uri.substring(i + 3); protocol = uri.substring(0, i); i = tmp.indexOf("/"); int p = tmp.lastIndexOf(":"); if (p != -1) { host = resolveHost(tmp.substring(0, p).trim()); if (i > -1) { port = Integer.parseInt(tmp.substring(p + 1, i)); } else { port = Integer.parseInt(tmp.substring(p + 1)); } } else { if (i > -1) { host = resolveHost(tmp.substring(0, i).trim()); } else { host = resolveHost(tmp.substring(0).trim()); } port = -1; } // now look for any path p = tmp.indexOf("?"); if (p != -1) { path = tmp.substring(i + 1, p); String args = tmp.substring(p + 1); StringTokenizer tok = new StringTokenizer(args, "&"); parameters = new HashMap<String, String>(); while (tok.hasMoreTokens()) { String token = tok.nextToken(); int eq = token.indexOf("="); String name = (eq > -1) ? token.substring(0, eq) : token; String value = (eq > -1) ? token.substring(eq + 1) : ""; parameters.put(name, value); } } else { p = tmp.indexOf("/"); if (p != -1) { path = tmp.substring(p + 1); } else { path = ""; } } // add nuxeo parameters if none if (parameters == null) { parameters = new HashMap<String, String>(); parameters.put(InvokerLocator.DATATYPE, "nuxeo"); } else if (!"nuxeo".equals(parameters.get(InvokerLocator.DATATYPE))) { parameters.put(InvokerLocator.DATATYPE, "nuxeo"); } return new InvokerLocator(protocol, host, port, path, parameters); } public static String resolveHost(String host) { if (host.contains("0.0.0.0")) { if (System.getProperty(SERVER_BIND_ADDRESS, "0.0.0.0").equals( "0.0.0.0")) { host = fixRemoteAddress(host); } else { host = host.replaceAll("0\\.0\\.0\\.0", System.getProperty(SERVER_BIND_ADDRESS)); } } try { return InetAddress.getByName(host).getHostAddress(); } catch (Exception ex) { return host; } } public static String fixRemoteAddress(String address) { try { if (address == null || ANY.equals(address)) { boolean byHost = true; String bindByHost = System.getProperty( InvokerLocator.BIND_BY_HOST, "True"); try { byHost = Boolean.getBoolean(bindByHost); } catch (Exception e) { } if (byHost) { return InetAddress.getLocalHost().getHostName(); } else { return InetAddress.getLocalHost().getHostAddress(); } } } catch (UnknownHostException ignored) { } return address; } }