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