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 }