1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 * < Sequence [2], ProcessID [2], Time [4], IP Addr [4] >,
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;
49 private static byte[] ipaddr;
50
51 static
52 {
53
54 sequence = 0;
55
56
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
64 ipaddr = new byte[4];
65 try
66 {
67 ipaddr = InetAddress.getLocalHost().getAddress();
68 }
69 catch ( Exception exc )
70 {
71
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
90 key[0] = (byte) ( sequence );
91 key[1] = (byte) ( sequence >> 8 );
92 sequence++;
93
94
95 key[2] = processid[1];
96 key[3] = processid[0];
97
98
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
109 key[8] = ipaddr[0];
110 key[9] = ipaddr[1];
111 key[10] = ipaddr[2];
112 key[11] = ipaddr[3];
113
114
115 hashCode = new String( key ).hashCode();
116 }
117
118 /***
119 * Private constructor for cloning.
120 */
121 private EOTemporaryGlobalID( byte[] aKey )
122 {
123
124
125
126 key = new byte[ UniqueBinaryKeyLength ];
127 for ( int i = 0; i < UniqueBinaryKeyLength; i++ )
128 {
129 key[i] = aKey[i];
130 }
131
132
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
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
189 hex = Integer.toHexString( key[i]+128 );
190
191 if ( hex.length() == 1 ) hex = "0" + hex;
192
193 buffer.append( hex );
194 }
195 return buffer.toString();
196 }
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219