1 /* 2 * Copyright (c) 1998-2002 The Jgroup Team. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * 17 */ 18 19 package jgroup.relacs.types; 20 21 import java.io.IOException; 22 import java.io.ObjectInput; 23 import java.io.ObjectOutput; 24 import java.net.InetAddress; 25 import java.net.UnknownHostException; 26 27 import jgroup.core.VMID; 28 import jgroup.util.Abort; 29 import jgroup.util.Network; 30 31 /** 32 * The <code>VMIDImpl</code> class implements the <code>VMID</code> 33 * interface to uniquely identify a Java Virtual Machine. 34 * 35 * @author Alberto Montresor 36 * @author Hein Meling 37 * @since Jgroup 0.7 38 */ 39 public final class VMIDImpl 40 implements VMID 41 { 42 43 //////////////////////////////////////////////////////////////////////////////////////////// 44 // Fields 45 //////////////////////////////////////////////////////////////////////////////////////////// 46 47 private static final long serialVersionUID = 6243630502385386084L; 48 49 /** IP address of the generating host */ 50 private InetAddress inetAddress; 51 52 /** Integer representation of the above IP address */ 53 private int address; 54 55 /** Random number to distinguish concurrent JVMs on the same host */ 56 private int hash; 57 58 /** Time when this <code>VMID</code> was generated */ 59 private long time; 60 61 62 //////////////////////////////////////////////////////////////////////////////////////////// 63 // Static section 64 //////////////////////////////////////////////////////////////////////////////////////////// 65 66 /** Unique virtual machine identifier for the local host */ 67 private static VMID vmid; 68 69 /* 70 * Create a virtual machine identifier for the local host. 71 */ 72 static { 73 try { 74 InetAddress inetAddress = Network.getLocalHost(); 75 long time = System.currentTimeMillis(); 76 int hash = (new Object()).hashCode(); 77 vmid = new VMIDImpl(inetAddress, time, hash); 78 } catch (Exception e) { 79 Abort.exit("Failed to generate an identifier for the virtual machine", e, 1); 80 } 81 } 82 83 84 /** 85 * Returns the <code>VMID</code> for the local Java Virtual Machine. 86 */ 87 public static VMID getLocalVMID() 88 { 89 return vmid; 90 } 91 92 93 //////////////////////////////////////////////////////////////////////////////////////////// 94 // Constructors 95 //////////////////////////////////////////////////////////////////////////////////////////// 96 97 /** 98 * Public default constructor for externalization. 99 */ 100 public VMIDImpl() 101 { 102 } 103 104 /** 105 * Private constructor. 106 */ 107 private VMIDImpl(InetAddress inetAddress, long time, int hash) 108 { 109 this.inetAddress = inetAddress; 110 this.time = time; 111 this.hash = hash; 112 this.address = Network.translate(inetAddress); 113 } 114 115 116 //////////////////////////////////////////////////////////////////////////////////////////// 117 // Methods from the VMID interface 118 //////////////////////////////////////////////////////////////////////////////////////////// 119 120 /** 121 * Returns the address of the host in which the virtual machine 122 * identified by this <code>VMID</code> is executed. 123 */ 124 public InetAddress getAddress() 125 throws UnknownHostException 126 { 127 /* 128 * If the inetAddress is null it means that this object must have 129 * been serialized, and thus we only have an integer representation 130 * of this JVMs internet address. Thus, we convert the int 131 * representation to an InetAddress representation. 132 */ 133 if (inetAddress == null) 134 inetAddress = Network.translate(address); 135 return inetAddress; 136 } 137 138 139 /** 140 * Returns the time at which this <code>VMID</code> has been created. 141 */ 142 public long getTime() 143 { 144 return time; 145 } 146 147 148 //////////////////////////////////////////////////////////////////////////////////////////// 149 // Methods from Object 150 //////////////////////////////////////////////////////////////////////////////////////////// 151 152 /** 153 * Returns a string representation of this object. 154 */ 155 public String toString() 156 { 157 StringBuilder buf = new StringBuilder(); 158 buf.append("[VMID: "); 159 buf.append(Network.translateToString(address)); 160 buf.append(", "); 161 buf.append(time); 162 buf.append(", "); 163 buf.append(hash); 164 buf.append("]"); 165 return buf.toString(); 166 } 167 168 169 /** 170 * Returns a hashcode for the <code>VMIDImpl</code>. Two 171 * <code>VMIDImpl</code>s will have the same hashcode if they are 172 * equal with respect to their content. 173 */ 174 public int hashCode() 175 { 176 return address + (int) time + hash; 177 } 178 179 180 /** 181 * Compares two objects for content equality. 182 * 183 * @param obj the object to compare with 184 * @return true if these objects are equal; false otherwise. 185 */ 186 public boolean equals(Object obj) 187 { 188 if (!(obj instanceof VMIDImpl)) 189 return false; 190 VMIDImpl vmid = (VMIDImpl) obj; 191 return (hash == vmid.hash && address == vmid.address && time == vmid.time); 192 } 193 194 195 //////////////////////////////////////////////////////////////////////////////////////////// 196 // Methods from Externalizable 197 //////////////////////////////////////////////////////////////////////////////////////////// 198 199 /** 200 * Write the content of this VMID on stream <tt>out</tt>. Note that 201 * the InetAddress is not serialized, because too inefficient. If 202 * requested, the InetAddress is retrieved through DNS lookup in 203 * method <tt>getAddress</tt>. 204 * 205 * @param out the stream to be written 206 */ 207 public void writeExternal(ObjectOutput out) 208 throws IOException 209 { 210 out.writeInt(hash); 211 out.writeLong(time); 212 out.writeInt(address); 213 } 214 215 /** 216 * Restores the content of this object from the marshalled data contained 217 * in the specified input stream. 218 * 219 * @param in the stream to be read 220 */ 221 public void readExternal(ObjectInput in) 222 throws IOException 223 { 224 hash = in.readInt(); 225 time = in.readLong(); 226 address = in.readInt(); 227 } 228 229 } // END VMIDImpl