/*
* JBoss, Home of Professional Open Source.
* Copyright 2015, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.cli;
/**
* Utility to resolve the address to use to connect to a controller based on a user supplied address, a default address from the
* command line, a default address from the configuration and a hard coded default address.
*
* @author <a href="mailto:darran.lofthouse@jboss.com">Darran Lofthouse</a>
*/
public class ControllerAddressResolver {
private final CliConfig config;
private final String defaultController;
private ControllerAddressResolver(final CliConfig config, final String defaultController) {
this.config = config;
this.defaultController = defaultController;
}
public static ControllerAddressResolver newInstance(final CliConfig config, final String defaultController) {
return new ControllerAddressResolver(config, defaultController);
}
public ControllerAddress resolveAddress(final String controller) throws CommandLineException {
ControllerAddress intermediate;
if (controller != null) {
intermediate = convert(controller);
} else if (defaultController != null) {
intermediate = convert(defaultController);
} else {
intermediate = config.getDefaultControllerAddress();
}
return finish(intermediate);
}
private ControllerAddress finish(final ControllerAddress toFinish) throws CommandLineException {
String protocol = toFinish.getProtocol();
String host = toFinish.getHost();
int port = toFinish.getPort();
if (protocol == null) {
if (config.isUseLegacyOverride() && port == 9999) {
protocol = "remoting";
} else {
protocol = config.getDefaultControllerProtocol();
}
}
if (host == null) {
throw new CommandLineException("null host encountered");
}
if (port < 0) {
switch (protocol) {
case "remote":
case "remoting":
port = 9999;
break;
case "remote+http":
case "http-remoting":
port = 9990;
break;
case "remote+https":
case "https-remoting":
port = 9993;
break;
default:
throw new CommandLineException("Unexpected protocol '" + protocol + "'");
}
}
return new ControllerAddress(protocol, host, port);
}
private ControllerAddress convert(final String controller) throws CommandLineException {
ControllerAddress alias = config.getAliasedControllerAddress(controller);
if (alias != null) {
return alias;
}
String protocol = null;
String host = null;
int port = -1;
String parsing;
final int protocolEnd = controller.lastIndexOf("://");
if (protocolEnd == -1) {
parsing = controller;
} else {
parsing = controller.substring(protocolEnd + 3);
protocol = controller.substring(0, protocolEnd);
}
String portStr = null;
int colonIndex = parsing.lastIndexOf(':');
if (colonIndex < 0) {
// default port
host = parsing;
} else if (colonIndex == 0) {
// default host
portStr = parsing.substring(1).trim();
} else {
final boolean hasPort;
int closeBracket = parsing.lastIndexOf(']');
if (closeBracket != -1) {
// possible ip v6
if (closeBracket > colonIndex) {
hasPort = false;
} else {
hasPort = true;
}
} else {
// probably ip v4
hasPort = true;
}
if (hasPort) {
host = parsing.substring(0, colonIndex).trim();
portStr = parsing.substring(colonIndex + 1).trim();
} else {
host = parsing;
}
}
if (portStr != null) {
try {
port = Integer.parseInt(portStr);
} catch (NumberFormatException e) {
throw new CommandFormatException("The port must be a valid non-negative integer: '" + parsing + "'");
}
if (port < 0) {
throw new CommandFormatException("The port must be a valid non-negative integer: '" + parsing + "'");
}
}
return new ControllerAddress(protocol, host, port);
}
}