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 }