View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2001 Intersect Software Corporation
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.control;
20  
21  import java.net.InetAddress;
22  
23  /***
24  * EOTemporaryGlobalID is a network-wide unique key.
25  * This is used by EOEditingContext to construct temporary
26  * ids when new objects are created.  <br><br>
27  *
28  * The specified format of the key is a byte array: 
29  * &lt; Sequence [2], ProcessID [2], Time [4], IP Addr [4] &gt;,
30  * but because java does not allow access to the process id,
31  * the timestamp of when this class is first loaded is used
32  * to simulate a process id.
33  * 
34  *
35  * @author michael@mpowers.net
36  * @author $Author: cgruber $
37  * @version $Revision: 893 $
38  */
39  public class EOTemporaryGlobalID 
40      extends EOGlobalID 
41  {
42      /***
43      * Holds the length in bytes of the key that is generated.
44      */
45      public static final int UniqueBinaryKeyLength = 12;
46      
47      private static int sequence;
48      private static byte[] processid; // 2 bytes
49      private static byte[] ipaddr; // 4 bytes
50      
51      static // static initializer
52      {
53          // init sequence
54          sequence = 0;
55          
56          // init processid
57          processid = new byte[2];
58          long time = System.currentTimeMillis();
59          processid[1] = (byte) time;
60          time = time >> 8;
61          processid[0] = (byte) time;
62  
63          // init ipaddr
64          ipaddr = new byte[4];
65          try
66          {
67              ipaddr = InetAddress.getLocalHost().getAddress();
68          }
69          catch ( Exception exc )
70          {
71              // could not obtain ip address - use pid twice
72              ipaddr[0] = processid[0];
73              ipaddr[1] = processid[1];
74              ipaddr[2] = processid[0];
75              ipaddr[3] = processid[1];
76          }
77      }
78      
79      private byte[] key;
80      private int hashCode;
81  
82      /***
83      * Generates a new id with a unique key.
84      */    
85      public EOTemporaryGlobalID()
86      {
87          key = new byte[UniqueBinaryKeyLength];
88          
89          // init sequence (important byte first)
90          key[0] = (byte) ( sequence ); 
91          key[1] = (byte) ( sequence >> 8 );
92          sequence++;
93          
94          // populate pid (important byte first)
95          key[2] = processid[1];
96          key[3] = processid[0];
97          
98          // init time (important byte first)
99          long time = System.currentTimeMillis();
100         key[4] = (byte) time;
101         time = time >> 8;
102         key[5] = (byte) time;
103         time = time >> 8;
104         key[6] = (byte) time;
105         time = time >> 8;
106         key[7] = (byte) time;
107         
108         // populate ipaddr
109         key[8]  = ipaddr[0];
110         key[9]  = ipaddr[1];
111         key[10] = ipaddr[2];
112         key[11] = ipaddr[3];
113 
114         // use string's hash code
115         hashCode = new String( key ).hashCode();
116     }
117     
118     /***
119     * Private constructor for cloning.
120     */
121     private EOTemporaryGlobalID( byte[] aKey )
122     {
123 //        key = aKey; // this might be faster
124 
125         // make copy of key - might be safer
126         key = new byte[ UniqueBinaryKeyLength ];
127         for ( int i = 0; i < UniqueBinaryKeyLength; i++ )
128         {
129             key[i] = aKey[i];
130         }
131         
132         // use string's hash code
133         hashCode = new String( aKey ).hashCode();
134     }
135     
136     /***
137     * Returns true.
138     */
139     public boolean isTemporary()
140     {
141         return true;   
142     }
143     
144     /***
145     * Returns whether the keys are equal.
146     */
147     public boolean equals( Object anObject )
148     {
149         if ( ! ( anObject instanceof EOTemporaryGlobalID ) ) 
150             return false;   
151         
152         byte[] otherKey = ((EOTemporaryGlobalID)anObject).key;
153         
154         for ( int i = 0; i < UniqueBinaryKeyLength; i++ )
155         {
156             if ( key[i] != otherKey[i] ) return false;
157         }
158         return true;
159     }
160     
161     /***
162     * Returns a copy of this object.
163     */
164     public Object clone()
165     {
166         // faster than super.clone()
167         return new EOTemporaryGlobalID( key );
168     }
169     
170     public int hashCode()
171     {
172         return hashCode;           
173     }
174     
175     /***
176     * Returns a string representation of this key.
177     * This is a 24-character string with each pair
178     * of characters holding a hexadecimal value that
179     * is 128 more than the value of the corresponding 
180     * byte (to account for two's complement).
181     */
182     public String toString()
183     {
184         String hex;
185         StringBuffer buffer = new StringBuffer();
186         for ( int i = 0; i < key.length; i++ )
187         {
188             // get string: adjust for two's complement
189             hex = Integer.toHexString( key[i]+128 );
190             // pad with zero so we take two characters
191             if ( hex.length() == 1 ) hex = "0" + hex;
192             // append hex code
193             buffer.append( hex );
194         }
195         return buffer.toString();
196     }
197 }
198 
199 /*
200  * $Log$
201  * Revision 1.1  2006/02/16 13:19:57  cgruber
202  * Check in all sources in eclipse-friendly maven-enabled packages.
203  *
204  * Revision 1.4  2001/04/29 22:02:45  mpowers
205  * Work on id transposing between editing contexts.
206  *
207  * Revision 1.3  2001/02/15 21:13:30  mpowers
208  * First draft implementation is complete.  Now on to debugging.
209  *
210  * Revision 1.2  2001/02/14 23:03:02  mpowers
211  * A near-complete first draft of EOEditingContext.
212  *
213  * Revision 1.1  2001/02/13 23:24:29  mpowers
214  * Implementing more of editing context.
215  *
216  *
217  */
218     
219