001    /* VMID.java -- The object ID, unique between all virtual machines.
002       Copyright (c) 1996, 1997, 1998, 1999, 2006 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package java.rmi.dgc;
039    
040    import gnu.java.lang.CPStringBuilder;
041    
042    import java.io.Serializable;
043    import java.net.InetAddress;
044    import java.net.UnknownHostException;
045    import java.rmi.server.UID;
046    import java.util.Arrays;
047    
048    /**
049     * An identifier that is unique accross the all virtual machines. This class is
050     * used by distributed garbage collector to identify the virtual machine of
051     * the client, but may also be used in various other cases, when such identifier
052     * is required. This class separately stores and transfers the host IP
053     * address, but will try to do its best also for the case if it failed to
054     * determine it. The alternative algorithms are used in {@link UID} that is
055     * part of this class. The VMID's, created on the same host, but in the two
056     * separately (parallely) running virtual machines are different.
057     */
058    public final class VMID implements Serializable
059    {
060      /**
061       * Use SVUID for interoperability.
062       */
063      static final long serialVersionUID = -538642295484486218L;
064    
065      /**
066       * If true, the IP of this host can ve reliably determined.
067       */
068      static boolean areWeUnique;
069    
070      /**
071       * The IP address of the local host.
072       */
073      static byte[] localAddr;
074    
075      /**
076       * The IP address of the local host.
077       */
078      private byte[] addr;
079    
080      /**
081       * The cached hash code.
082       */
083      transient int hash;
084    
085      /**
086       * The UID of this VMID.
087       */
088      private UID uid;
089    
090      static
091        {
092          // This "local host" value usually indicates that the local
093          // IP address cannot be reliably determined.
094          byte[] localHost = new byte[] { 127, 0, 0, 1 };
095    
096          try
097            {
098              localAddr = InetAddress.getLocalHost().getAddress();
099              areWeUnique = !Arrays.equals(localHost, localAddr);
100            }
101          catch (UnknownHostException uhex)
102            {
103              localAddr = localHost;
104              areWeUnique = false;
105            }
106        }
107    
108      /**
109       * Create the new VMID. All VMID's are unique accross tha all virtual
110       * machines.
111       */
112      public VMID()
113      {
114        addr = localAddr;
115        uid = new UID();
116      }
117    
118      /**
119       * Return true if it is possible to get the accurate address of this host.
120       * If false is returned, the created VMID's are less reliable, but the
121       * starting time and possibly the memory allocation are also taken into
122       * consideration in the incorporated UID. Hence the VMID's, created on the
123       * different virtual machines, still should be different.
124       *
125       * @deprecated VMID's are more or less always reliable.
126       *
127       * @return false if the local host ip address is 127.0.0.1 or unknown,
128       * true otherwise.
129       */
130      public static boolean isUnique ()
131      {
132        return areWeUnique;
133      }
134    
135      /**
136       * Get the hash code of this VMID.
137       */
138      public int hashCode ()
139      {
140        if (hash==0)
141          {
142            for (int i = 0; i < localAddr.length; i++)
143                hash += addr[i];
144            hash = hash ^ uid.hashCode();
145          }
146        return hash;
147      }
148    
149      /**
150       * Returns true if the passed parameter is also VMID and it is equal to this
151       * VMID. The VMID should only be equal to itself (also if the passed value is
152       * another instance, cloned by serialization).
153       */
154      public boolean equals(Object obj)
155      {
156        if (obj instanceof VMID)
157          {
158            VMID other = (VMID) obj;
159    
160            // The UID's are compared faster than arrays.
161            return uid.equals(other.uid) && Arrays.equals(addr, other.addr);
162          }
163        else
164          return false;
165    
166      }
167    
168      /**
169       * Get the string representation of this VMID.
170       */
171      public String toString ()
172      {
173        CPStringBuilder buf = new CPStringBuilder ("[VMID: ");
174    
175        for (int i = 0; i < addr.length; i++)
176          {
177            if (i > 0)
178              {
179                buf.append (".");
180              }
181    
182            buf.append (Integer.toString (addr [i]));
183          }
184    
185        buf.append (" ");
186        buf.append (uid.toString ());
187        buf.append ("]");
188    
189        return buf.toString();
190      }
191    }