package net.hivecell.hive.support;
import java.net.*;
import java.io.Serializable;
import java.rmi.Naming;
import net.hivecell.hive.Global;
import net.hivecell.hive.cell.RemoteCell;
public class CellAddress implements Serializable {
public static final int DEFAULT_PORT = Global.defaultPort;
public static final String PROTOCOL = "hive";
public static final String RMI_NAME = "cell";
private int port;
private String host;
private String file;
private String ref;
private int hashCode;
public CellAddress(String cellAddress) throws MalformedHiveURLException {
int hostIndex = 0; boolean portPresent = true; int portIndex; boolean filePresent = true; int fileIndex; boolean refPresent = true; int refIndex;
if (cellAddress == null)
throw new MalformedHiveURLException();
if (cellAddress.indexOf("://") >= 0) {
if (cellAddress.indexOf(PROTOCOL + "://") != 0) {
throw new MalformedHiveURLException();
}
else {
hostIndex = 7;
}
}
else
throw new MalformedHiveURLException();
try {
fileIndex = cellAddress.indexOf('/', hostIndex);
refIndex = cellAddress.indexOf('#', hostIndex) + 1;
}
catch (StringIndexOutOfBoundsException e) {
throw new MalformedHiveURLException();
}
if (refIndex == 0) {
refIndex = cellAddress.length();
refPresent = false;
}
if ((fileIndex == -1) || ((refPresent) && (refIndex < fileIndex))) {
fileIndex = refIndex;
filePresent = false;
}
if (refIndex == 0) {
refPresent = false;
refIndex = fileIndex + 1;
}
portIndex = cellAddress.indexOf(':', hostIndex) + 1;
if ((portIndex == 0) || (portIndex > fileIndex) || (portIndex > refIndex)) {
portIndex = fileIndex;
portPresent = false;
}
try {
if (portPresent) {
host = cellAddress.substring(hostIndex, portIndex - 1);
int endPort;
if ((!filePresent) && (!refPresent)) {
port = Integer.parseInt(cellAddress.substring(portIndex));
}
else if (fileIndex < refIndex)
port = Integer.parseInt(cellAddress.substring(portIndex,
fileIndex));
else
port = Integer.parseInt(cellAddress.
substring(portIndex, refIndex - 1));
}
else {
host = cellAddress.substring(hostIndex, portIndex);
port = DEFAULT_PORT;
}
if (filePresent) {
if (refPresent) {
file = cellAddress.substring(fileIndex, refIndex - 1);
ref = cellAddress.substring(refIndex);
}
else {
file = cellAddress.substring(fileIndex, refIndex);
ref = "";
}
}
else {
file = "";
if (refPresent) {
ref = cellAddress.substring(refIndex);
}
else {
ref = "";
}
}
}
catch (NumberFormatException e) {
throw new MalformedHiveURLException(); }
catch(StringIndexOutOfBoundsException e) {
throw new MalformedHiveURLException(); }
try {
String address = InetAddress.getByName(host).getHostAddress();
host = InetAddress.getByName(address).getHostName();
}
catch (UnknownHostException e) {
throw new MalformedHiveURLException("Bad hostname");
}
if (port == -1) {
port = DEFAULT_PORT; }
else if (port < -1) {
throw new MalformedHiveURLException(); }
calculateHashCode();
}
public CellAddress(String host, int port, String file, String ref) throws MalformedHiveURLException {
if ((host == null) || (host.equals(""))) {
throw new MalformedHiveURLException();
}
try {
String address = InetAddress.getByName(host).getHostAddress();
this.host = InetAddress.getByName(address).getHostName();
}
catch (UnknownHostException e) {
throw new MalformedHiveURLException("Bad hostname");
}
;
if (port == -1) {
port = DEFAULT_PORT; }
else if (port < -1) {
throw new MalformedHiveURLException();
}
this.port = port;
if (file == null) {
this.file = "";
}
else {
this.file = file;
}
if (ref == null) {
this.ref = "";
}
else {
this.ref = ref;
}
calculateHashCode();
}
public CellAddress(String host, int port) throws MalformedHiveURLException {
this(host, port, null, null);
}
public static CellAddress createLocalCellAddress(int port) {
String host;
try {
host = InetAddress.getByName(InetAddress.getLocalHost().getHostAddress()).getHostName();
}
catch (UnknownHostException e) {
Debug.error("Unable to lookup own address.");
return null;
}
try {
return new CellAddress(host, port);
}
catch (MalformedHiveURLException e) {
Debug.error("Somehow cannot create a CellAddress for the local machine.");
return null;
}
}
public static CellAddress createLocalCellAddress() {
return createLocalCellAddress(DEFAULT_PORT);
}
private void calculateHashCode() {
hashCode = getProtocol().hashCode() ^ getHost().toLowerCase().hashCode() ^ getPort() ^ file.hashCode() ^ ref.hashCode();
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getFile() {
return file;
}
public String getRef() {
return ref;
}
public String getProtocol() {
return PROTOCOL;
}
public boolean equals(Object obj) {
if (obj instanceof CellAddress) {
CellAddress ca = (CellAddress) obj;
return (host.equalsIgnoreCase(ca.getHost()) &&
(port == ca.getPort()) &&
(file.equals(ca.getFile())) &&
(ref.equals(ca.getRef())));
}
return false;
}
public int hashCode() {
return hashCode;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(PROTOCOL);
sb.append("://");
sb.append(host);
if (port != DEFAULT_PORT) {
sb.append(":");
sb.append(port);
}
if (!file.equals("")) {
sb.append(file);
}
if (!ref.equals("")) {
sb.append("#");
sb.append(ref);
}
return sb.toString();
}
public boolean isLocal() {
try {
return InetAddress.getByName(host).equals(InetAddress.getLocalHost());
}
catch (UnknownHostException e) {
return false;
}
}
public RemoteCell getRemoteCell() throws CellConnectException {
String name = "//" + host + ":" + port + "/" + RMI_NAME;
try {
RemoteCell rs = (RemoteCell)Naming.lookup( name );
return rs;
}
catch( Exception error ) {
throw new CellConnectException( error );
}
}
private static void test(String str) {
System.out.println("Attempting to parse: " + str);
try{
CellAddress ca = new CellAddress(str);
System.out.println("Protocol: " + ca.getProtocol());
System.out.println("Host: " + ca.getHost());
System.out.println("Port: " + ca.getPort());
System.out.println("File: " + ca.getFile());
System.out.println("Ref: " + ca.getRef());
System.out.println(ca.toString());
System.out.println();
}
catch(MalformedHiveURLException e) {
System.out.println("Unparseable: " + str);
e.printStackTrace();
}
}
public static final void main(String[] args) {
try {
System.out.println(InetAddress.getByName("18.244.1.37").getHostName());
}
catch(Throwable e) {
}
CellAddress.test("hive://oroup:23235/");
CellAddress.test("hive://oroup:23237");
CellAddress.test("oroup:23237/");
CellAddress.test("oroup");
CellAddress.test("oroup/");
CellAddress.test("oroup/sds#dfsdf");
CellAddress.test("hive://oroup.mit.edu:23235/34:53#21:24");
CellAddress.test("hive://oroup:23/sdfdf#sdfdf");
CellAddress.test("hi://oroup:23235/");
CellAddress.test("hive://oroup:232435");
CellAddress.test("hive://oroup:232435#sdffd");
CellAddress.test("4334:232435#sd/ffd");
}
}