001    /* ObjID.java -- Unique object id with respect to the given host.
002       Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006
003       Free Software Foundation, Inc.
004    
005    This file is part of GNU Classpath.
006    
007    GNU Classpath is free software; you can redistribute it and/or modify
008    it under the terms of the GNU General Public License as published by
009    the Free Software Foundation; either version 2, or (at your option)
010    any later version.
011     
012    GNU Classpath is distributed in the hope that it will be useful, but
013    WITHOUT ANY WARRANTY; without even the implied warranty of
014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015    General Public License for more details.
016    
017    You should have received a copy of the GNU General Public License
018    along with GNU Classpath; see the file COPYING.  If not, write to the
019    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
020    02110-1301 USA.
021    
022    Linking this library statically or dynamically with other modules is
023    making a combined work based on this library.  Thus, the terms and
024    conditions of the GNU General Public License cover the whole
025    combination.
026    
027    As a special exception, the copyright holders of this library give you
028    permission to link this library with independent modules to produce an
029    executable, regardless of the license terms of these independent
030    modules, and to copy and distribute the resulting executable under
031    terms of your choice, provided that you also meet, for each linked
032    independent module, the terms and conditions of the license of that
033    module.  An independent module is a module which is not derived from
034    or based on this library.  If you modify this library, you may extend
035    this exception to your version of the library, but you are not
036    obligated to do so.  If you do not wish to do so, delete this
037    exception statement from your version. */
038    
039    
040    package java.rmi.server;
041    
042    import java.io.DataInput;
043    import java.io.DataOutput;
044    import java.io.IOException;
045    import java.io.ObjectInput;
046    import java.io.ObjectOutput;
047    import java.io.Serializable;
048    
049    /**
050     * Represents the object identifier, unique for the host that generated it.
051     * The ObjID contains inside the integer object identifier that, if needed,
052     * may indicated that this is a reference to one of the well known objects
053     * on that host (registry, activator or dgc) and the {@link UID} that 
054     * ensures uniqueness.
055     */
056    public final class ObjID
057        implements Serializable
058    {
059    
060      /**
061       * Use serial version uid for interoperability.
062       */
063      static final long serialVersionUID = - 6386392263968365220L;
064    
065      /**
066       * The object counter, which value is assigned when creating the ordinary
067       * objects without the known object id. The counter is incremented each time
068       * the new ObjID is constructed.
069       */
070      private static long next = 0x8000000000000000L;
071    
072      /**
073       * The object to put the lock on when incrementing {@link #next}
074       */
075      private static final Object lock = ObjID.class;
076    
077      /**
078       * Defines the ID of the naming service.
079       */
080      public static final int REGISTRY_ID = 0;
081    
082      /**
083       * Defines the ID of the activator.
084       */
085      public static final int ACTIVATOR_ID = 1;
086    
087      /**
088       * Defines the ID of the distributed garbage collector.
089       */
090      public static final int DGC_ID = 2;
091    
092      /**
093       * The object Id (either well-known value or the value of the incrementing
094       * object counter.
095       */
096      long objNum;
097    
098      /**
099       * The object unique identifier, generated individually for each object.
100       */
101      UID space;
102    
103      /**
104       * Create the new object id, unique for this host.
105       */
106      public ObjID()
107      {
108        synchronized (lock)
109          {
110            objNum = next++;
111          }
112        space = new UID();
113      }
114    
115      /**
116       * Create the new object id defining the well known remotely accessible
117       * object, present in this host. The well - known objects are:
118       * <ul>
119       * <li>{@link #REGISTRY_ID} - RMI naming service.</li>
120       * <li>{@link #ACTIVATOR_ID} - activator</li>
121       * <li>{@link #DGC_ID} - distributed garbage collector (grants lease
122       * durations to keep the object before it is garbage collected.</li>
123       * </ul>
124       * 
125       * @param id the well known object id, one of the above.
126       */
127      public ObjID(int id)
128      {
129        objNum = (long) id;
130        space = new UID((short) 0);
131      }
132    
133      /**
134       * Write object id as long, then the object {@link UID}.
135       */
136      public void write(ObjectOutput out) throws IOException
137      {
138        DataOutput dout = (DataOutput) out;
139        dout.writeLong(objNum);
140        space.write(dout);
141      }
142    
143      /**
144       * Read object id (as long), then the object {@link UID}.
145       */
146      public static ObjID read(ObjectInput in) throws IOException
147      {
148        DataInput din = (DataInput) in;
149        ObjID id = new ObjID();
150        id.objNum = din.readLong();
151        id.space = UID.read(din);
152        return (id);
153      }
154    
155      /**
156       * Get the hashcode.
157       */
158      public int hashCode()
159      {
160        return space == null ? (int) objNum : space.hashCode() ^ (int) objNum;
161      }
162    
163      /**
164       * Compare for equality.
165       */
166      public boolean equals(Object obj)
167      {
168        if (obj instanceof ObjID)
169          {
170            ObjID that = (ObjID) obj;
171            return that.objNum == objNum && eq(that.space, space);
172          }
173        else
174          return false;
175      }
176    
177      /**
178       * Compare by .equals if both a and b are not null, compare directly if at
179       * least one of them is null.
180       */
181      static final boolean eq(Object a, Object b)
182      {
183        if (a == null || b == null)
184          return a == b;
185        else
186          return a.equals(b);
187      }  
188      
189      /**
190       * Get the string representation.
191       */
192      public String toString()
193      {
194        return (objNum + ":" + space);
195      }
196    
197    }