001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/framework/util/BasicUUID.java $
002 /*
003
004 This class orginaly has been part of the apache derby project. It has
005 slightly been changed to match the requirements of deegree.
006
007 Derby - Class org.apache.derby.impl.services.uuid.BasicUUID
008
009 Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
010
011 Licensed under the Apache License, Version 2.0 (the "License");
012 you may not use this file except in compliance with the License.
013 You may obtain a copy of the License at
014
015 http://www.apache.org/licenses/LICENSE-2.0
016
017 Unless required by applicable law or agreed to in writing, software
018 distributed under the License is distributed on an "AS IS" BASIS,
019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020 See the License for the specific language governing permissions and
021 limitations under the License.
022
023 */
024 package org.deegree.framework.util;
025
026 import java.io.IOException;
027 import java.io.ObjectInput;
028 import java.io.ObjectOutput;
029 import java.io.StringReader;
030
031 /**
032 * TODO add documentation here
033 *
034 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
035 * @author last edited by: $Author: apoth $
036 *
037 * @version $Revision: 9339 $, $Date: 2007-12-27 13:31:52 +0100 (Do, 27 Dez 2007) $
038 * @deprecated use
039 * @see UUID
040 */
041 public class BasicUUID implements UUID {
042 /*
043 * * Fields of BasicUUID
044 */
045
046 private long majorId; // only using 48 bits
047
048 private long timemillis;
049
050 private int sequence;
051
052 /*
053 * * Methods of BasicUUID
054 */
055
056 /**
057 * Constructor only called by BasicUUIDFactory.
058 *
059 * @param majorId
060 * @param timemillis
061 * @param sequence
062 */
063 public BasicUUID( long majorId, long timemillis, int sequence ) {
064 this.majorId = majorId;
065 this.timemillis = timemillis;
066 this.sequence = sequence;
067 }
068
069 /**
070 * Constructor only called by BasicUUIDFactory. Constructs a UUID from the string representation
071 * produced by toString.
072 *
073 * @param uuidstring
074 * @see BasicUUID#toString
075 */
076 public BasicUUID( String uuidstring ) {
077 StringReader sr = new StringReader( uuidstring );
078 sequence = (int) readMSB( sr );
079
080 long ltimemillis = readMSB( sr ) << 32;
081 ltimemillis += readMSB( sr ) << 16;
082 ltimemillis += readMSB( sr );
083 timemillis = ltimemillis;
084 majorId = readMSB( sr );
085 }
086
087 /**
088 * Constructor only called by BasicUUIDFactory. Constructs a UUID from the byte array
089 * representation produced by toByteArrayio.
090 *
091 * @param b
092 * @see BasicUUID#toByteArray
093 */
094 public BasicUUID( byte[] b ) {
095 int lsequence = 0;
096 for ( int ix = 0; ix < 4; ix++ ) {
097 lsequence = lsequence << 8;
098 lsequence = lsequence | ( 0xff & b[ix] );
099 }
100
101 long ltimemillis = 0;
102 for ( int ix = 4; ix < 10; ix++ ) {
103 ltimemillis = ltimemillis << 8;
104 ltimemillis = ltimemillis | ( 0xff & b[ix] );
105 }
106
107 long linetaddr = 0;
108 for ( int ix = 10; ix < 16; ix++ ) {
109 linetaddr = linetaddr << 8;
110 linetaddr = linetaddr | ( 0xff & b[ix] );
111 }
112
113 sequence = lsequence;
114 timemillis = ltimemillis;
115 majorId = linetaddr;
116 }
117
118 /*
119 * Formatable methods
120 */
121
122 // no-arg constructor, required by Formatable
123 public BasicUUID() {
124 super();
125 }
126
127 /**
128 * Write this out.
129 *
130 * @param out
131 * @exception IOException
132 * error writing to log stream
133 */
134 public void writeExternal( ObjectOutput out )
135 throws IOException {
136 // RESOLVE: write out the byte array instead?
137 out.writeLong( majorId );
138 out.writeLong( timemillis );
139 out.writeInt( sequence );
140 }
141
142 /**
143 * Read this in
144 *
145 * @param in
146 * @exception IOException
147 * error reading from log stream
148 */
149 public void readExternal( ObjectInput in )
150 throws IOException {
151 majorId = in.readLong();
152 timemillis = in.readLong();
153 sequence = in.readInt();
154 }
155
156 private static void writeMSB( char[] data, int offset, long value, int nbytes ) {
157 for ( int i = nbytes - 1; i >= 0; i-- ) {
158 long b = ( value & ( 255L << ( 8 * i ) ) ) >>> ( 8 * i );
159
160 int c = (int) ( ( b & 0xf0 ) >> 4 );
161 data[offset++] = (char) ( c < 10 ? c + '0' : ( c - 10 ) + 'a' );
162 c = (int) ( b & 0x0f );
163 data[offset++] = (char) ( c < 10 ? c + '0' : ( c - 10 ) + 'a' );
164 }
165 }
166
167 /**
168 * Read a long value, msb first, from its character representation in the string reader, using
169 * '-' or end of string to delimit.
170 */
171 private static long readMSB( StringReader sr ) {
172 long value = 0;
173
174 try {
175 int c;
176 while ( ( c = sr.read() ) != -1 ) {
177 if ( c == '-' )
178 break;
179 value <<= 4;
180
181 int nibble;
182 if ( c <= '9' )
183 nibble = c - '0';
184 else if ( c <= 'F' )
185 nibble = c - 'A' + 10;
186 else
187 nibble = c - 'a' + 10;
188 value += nibble;
189 }
190 } catch ( Exception e ) {
191 }
192
193 return value;
194 }
195
196 /*
197 * * Methods of UUID
198 */
199
200 /**
201 * Implement value equality.
202 *
203 * @return
204 *
205 */
206 public boolean equals( Object otherObject ) {
207 if ( !( otherObject instanceof BasicUUID ) )
208 return false;
209
210 BasicUUID other = (BasicUUID) otherObject;
211
212 return ( this.sequence == other.sequence ) && ( this.timemillis == other.timemillis )
213 && ( this.majorId == other.majorId );
214 }
215
216 /**
217 * Provide a hashCode which is compatible with the equals() method.
218 *
219 * @return a hashCode which is compatible with the equals() method.
220 */
221 public int hashCode() {
222 long hc = majorId ^ timemillis;
223
224 return sequence ^ ( (int) ( hc >> 4 ) );
225 }
226
227 /**
228 * Produce a string representation of this UUID which can be passed to UUIDFactory.recreateUUID
229 * later on to reconstruct it. The funny representation is designed to (sort of) match the
230 * format of Microsoft's UUIDGEN utility.
231 *
232 * @return a string representation of this UUID
233 */
234 public String toString() {
235 return stringWorkhorse( '-' );
236 }
237
238 /**
239 * Produce a string representation of this UUID which is suitable for use as a unique ANSI
240 * identifier.
241 *
242 * @return a string representation of this UUID
243 */
244 public String toANSIidentifier() {
245 return stringWorkhorse( 'X' );
246 }
247
248 /**
249 * Private workhorse of the string making routines.
250 *
251 * @param separator
252 * Character to separate number blocks. Null means do not include a separator.
253 *
254 * @return string representation of UUID.
255 */
256 public String stringWorkhorse( char separator ) {
257 char[] data = new char[36];
258
259 writeMSB( data, 0, sequence, 4 );
260
261 int offset = 8;
262 if ( separator != 0 )
263 data[offset++] = separator;
264
265 long ltimemillis = timemillis;
266 writeMSB( data, offset, ( ltimemillis & 0x0000ffff00000000L ) >>> 32, 2 );
267 offset += 4;
268 if ( separator != 0 )
269 data[offset++] = separator;
270 writeMSB( data, offset, ( ltimemillis & 0x00000000ffff0000L ) >>> 16, 2 );
271 offset += 4;
272 if ( separator != 0 )
273 data[offset++] = separator;
274 writeMSB( data, offset, ( ltimemillis & 0x000000000000ffffL ), 2 );
275 offset += 4;
276 if ( separator != 0 )
277 data[offset++] = separator;
278 writeMSB( data, offset, majorId, 6 );
279 offset += 12;
280
281 return new String( data, 0, offset );
282 }
283
284 /**
285 * Store this UUID in a byte array. Arrange the bytes in the UUID in the same order the code
286 * which stores a UUID in a string does.
287 *
288 * @return UUID in a byte array.
289 *
290 * @see "org.apache.derby.catalog.UUID#toByteArray"
291 */
292 public byte[] toByteArray() {
293 byte[] result = new byte[16];
294
295 int lsequence = sequence;
296 result[0] = (byte) ( lsequence >>> 24 );
297 result[1] = (byte) ( lsequence >>> 16 );
298 result[2] = (byte) ( lsequence >>> 8 );
299 result[3] = (byte) lsequence;
300
301 long ltimemillis = timemillis;
302 result[4] = (byte) ( ltimemillis >>> 40 );
303 result[5] = (byte) ( ltimemillis >>> 32 );
304 result[6] = (byte) ( ltimemillis >>> 24 );
305 result[7] = (byte) ( ltimemillis >>> 16 );
306 result[8] = (byte) ( ltimemillis >>> 8 );
307 result[9] = (byte) ltimemillis;
308
309 long linetaddr = majorId;
310 result[10] = (byte) ( linetaddr >>> 40 );
311 result[11] = (byte) ( linetaddr >>> 32 );
312 result[12] = (byte) ( linetaddr >>> 24 );
313 result[13] = (byte) ( linetaddr >>> 16 );
314 result[14] = (byte) ( linetaddr >>> 8 );
315 result[15] = (byte) linetaddr;
316
317 return result;
318 }
319
320 /**
321 * Clone this UUID.
322 *
323 * @return a copy of this UUID
324 */
325 public UUID cloneMe() {
326 return new BasicUUID( majorId, timemillis, sequence );
327 }
328
329 /*
330 * (non-Javadoc)
331 *
332 * @see org.deegree.framework.util.UUID#toHexString()
333 */
334 public String toHexString() {
335 return stringWorkhorse( (char) 0 );
336 }
337 }