You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by st...@apache.org on 2004/07/26 19:11:58 UTC

cvs commit: jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/util/uuid Bytes.java Constants.java UUID.java VersionFourGenerator.java

stefan      2004/07/26 10:11:58

  Added:       proposals/jcrri/src/org/apache/slide/jcr/util/uuid
                        Bytes.java Constants.java UUID.java
                        VersionFourGenerator.java
  Log:
  jcrri
  
  Revision  Changes    Path
  1.1                  jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/util/uuid/Bytes.java
  
  Index: Bytes.java
  ===================================================================
  /*
   * Copyright 2003-2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.slide.jcr.util.uuid;
  
  /**
   * <p>Static methods for managing byte arrays (all methods follow Big
   * Endian order where most significant bits are in front).</p>
   *
   * <p>Copied from the Jakarta Commons-Id project</p>
   * <p/>
   * todo remove and use official commons-id release as soon as it is available
   * 
   * @author Commons-Id Team
   * @version $Id: Bytes.java,v 1.1 2004/07/26 17:11:58 stefan Exp $
   * {@link http://jakarta.apache.org/turbine/turbine-2.3/}
   */
  public final class Bytes {
  
      /**
       * <p>Hide constructor in utility class.</p>
       */
      private Bytes() {
      }
  
      /**
       * Appends two bytes array into one.
       *
       * @param a A byte[].
       * @param b A byte[].
       * @return A byte[].
       */
      public static byte[] append(byte[] a, byte[] b) {
          byte[] z = new byte[a.length + b.length];
          System.arraycopy(a, 0, z, 0, a.length);
          System.arraycopy(b, 0, z, a.length, b.length);
          return z;
      }
  
      /**
       * Returns a 8-byte array built from a long.
       *
       * @param n The number to convert.
       * @return A byte[].
       */
      public static byte[] toBytes(long n) {
          return toBytes(n, new byte[8]);
      }
  
      /**
       * Build a 8-byte array from a long.  No check is performed on the
       * array length.
       *
       * @param n The number to convert.
       * @param b The array to fill.
       * @return A byte[].
       */
      public static byte[] toBytes(long n, byte[] b) {
          b[7] = (byte) (n);
          n >>>= 8;
          b[6] = (byte) (n);
          n >>>= 8;
          b[5] = (byte) (n);
          n >>>= 8;
          b[4] = (byte) (n);
          n >>>= 8;
          b[3] = (byte) (n);
          n >>>= 8;
          b[2] = (byte) (n);
          n >>>= 8;
          b[1] = (byte) (n);
          n >>>= 8;
          b[0] = (byte) (n);
  
          return b;
      }
  
      /**
       * Build a long from first 8 bytes of the array.
       *
       * @param b The byte[] to convert.
       * @return A long.
       */
      public static long toLong(byte[] b) {
          return ((((long) b[7]) & 0xFF)
                  + ((((long) b[6]) & 0xFF) << 8)
                  + ((((long) b[5]) & 0xFF) << 16)
                  + ((((long) b[4]) & 0xFF) << 24)
                  + ((((long) b[3]) & 0xFF) << 32)
                  + ((((long) b[2]) & 0xFF) << 40)
                  + ((((long) b[1]) & 0xFF) << 48)
                  + ((((long) b[0]) & 0xFF) << 56));
      }
  
      /**
      * Compares two byte arrays for equality.
      *
      * @param a A byte[].
      * @param b A byte[].
      * @return True if the arrays have identical contents.
      */
      public static boolean areEqual(byte[] a, byte[] b) {
          int aLength = a.length;
          if (aLength != b.length) {
              return false;
          }
  
          for (int i = 0; i < aLength; i++) {
              if (a[i] != b[i]) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * <p>Compares two byte arrays as specified by <code>Comparable</code>.
       *
       * @param lhs - left hand value in the comparison operation.
       * @param rhs - right hand value in the comparison operation.
       * @return  a negative integer, zero, or a positive integer as <code>lhs</code>
       *  is less than, equal to, or greater than <code>rhs</code>.
       */
      public static int compareTo(byte[] lhs, byte[] rhs) {
          if (lhs == rhs) {
              return 0;
          }
          if (lhs == null) {
              return -1;
          }
          if (rhs == null) {
              return +1;
          }
          if (lhs.length != rhs.length) {
              return ((lhs.length < rhs.length) ? -1 : +1);
          }
          for (int i = 0; i < lhs.length; i++) {
              if (lhs[i] < rhs[i]) {
                  return -1;
              } else if (lhs[i] > rhs[i]) {
                  return 1;
              }
          }
          return 0;
      }
  
      /**
       * Build a short from first 2 bytes of the array.
       *
       * @param b The byte[] to convert.
       * @return A short.
       */
      public static short toShort(byte[] b) {
          return  (short) ((b[1] & 0xFF) + ((b[0] & 0xFF) << 8));
      }
  }
  
  
  
  1.1                  jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/util/uuid/Constants.java
  
  Index: Constants.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.slide.jcr.util.uuid;
  
  /**
   * <p>Constant values commonly needed in the uuid classes.</p>
   *
   * <p>Copied from the Jakarta Commons-Id project</p>
   * <p/>
   * todo remove and use official commons-id release as soon as it is available
   *
   * @author Commons-Id Team
   * @version $Revision: 1.1 $ $Date: 2004/07/26 17:11:58 $
   *
   */
  public interface Constants {
  
      //** Magic number constants
      /** Bits in a UUID. */
      int UUID_BIT_LENGTH = 128;
  
      /** Number of bytes in a UUID. */
      int UUID_BYTE_LENGTH = 16;
  
  
      //** Formatting and validation constants
      /** Chars in a UUID String. */
      int UUID_UNFORMATTED_LENGTH = 32;
  
      /** Chars in a UUID String. */
      int UUID_FORMATTED_LENGTH = 36;
  
      /** Token length of '-' separated tokens. */
      int TOKENS_IN_UUID = 5;
  
      /** Array to check tokenized UUID's segment lengths */
      int[] TOKEN_LENGTHS = {8, 4, 4, 4, 12};
  
      /** Insertion point 1 for dashes in the string format */
      int FORMAT_POSITION1 = 8;
  
      /** Insertion point 2 for dashes in the string format */
      int FORMAT_POSITION2 = 13;
  
      /** Insertion point 3 for dashes in the string format */
      int FORMAT_POSITION3 = 18;
  
      /** Insertion point 4 for dashes in the string format */
      int FORMAT_POSITION4 = 23;
  
      /** The string prefix for a urn UUID identifier. */
      String URN_PREFIX = "urn:uuid:";
  
  
      //** UUID Variant Constants
      /** UUID variant bits described in the IETF Draft MSB order,
       *  this is the "Reserved, NCS backward compatibility field" 0 x x with unknown bits as 0*/
      int VARIANT_NCS_COMPAT = 0;
  
      /** UUID variant bits described in the IETF Draft MSB order,
       *  this is the IETF Draft memo variant field 1 0 x with unknown bits as 0*/
      int VARIANT_IETF_DRAFT = 2;
  
      /** UUID variant bits described in the IETF Draft MSB order,
       *  this is the IETF Draft "Microsoft Corporation" field variant 1 1 0 x with unknown bits as 0*/
      int VARIANT_MS = (byte) 6;
  
      /** UUID variant bits described in the IETF Draft MSB order,
       *  this is the "Future Reserved variant 1 1 1 x with unknown bits as 0*/
      int VARIANT_FUTURE = 7;
  
  
      //** UUID Version Constants
      /** Version one constant for UUID version one of four */
      int VERSION_ONE = 1;
  
      /** Version two constant for UUID version two of four */
      int VERSION_TWO = 2;
  
      /** Version three constant for UUID version three of four */
      int VERSION_THREE = 3;
  
      /** Version four constant for UUID version four of four */
      int VERSION_FOUR = 4;
  
      //** Exception message constants
      /** Message indicating this is not a version one UUID */
      String WRONG_VAR_VER_MSG = "Not a ietf variant 2 or version 1 (time-based UUID)";
  
      // ** Array positions and lengths of UUID fields ** //
      /** Byte length of time low field */
      int TIME_LOW_BYTE_LEN = 4;
      /** Byte length of time low field */
      int TIME_MID_BYTE_LEN = 2;
      /** Byte length of time low field */
      int TIME_HI_BYTE_LEN = 2;
      /** Timestamp byte[] position of time low field */
      int TIME_LOW_TS_POS = 4;
      /** Timestamp byte[]  position mid field */
      int TIME_MID_TS_POS = 2;
      /** Timestamp byte[]  position hi field */
      int TIME_HI_TS_POS = 0;
      /** uuid array position start of time low field */
      int TIME_LOW_START_POS = 0;
      /** uuid array position start of mid field */
      int TIME_MID_START_POS = 4;
      /** uuid array position start of hi field */
      int TIME_HI_START_POS = 6;
      /** Byte position of the clock sequence and reserved field */
      short TIME_HI_AND_VERSION_BYTE_6 = 6;
      /** Byte position of the clock sequence and reserved field */
      short CLOCK_SEQ_HI_AND_RESERVED_BYTE_8 = 8;
  
      /**
       * XXX added by stefan@apache.org:
       * hexdigits for converting numerics to hex
       */
      char[] hexDigits = "0123456789abcdef".toCharArray();
  }
  
  
  
  1.1                  jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/util/uuid/UUID.java
  
  Index: UUID.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.slide.jcr.util.uuid;
  
  import java.io.DataInput;
  import java.io.IOException;
  import java.io.Serializable;
  import java.util.StringTokenizer;
  
  /** XXX begin modification by stefan@apache.org */
  /*import org.apache.commons.id.IdentifierUtils;
  import org.apache.commons.codec.DecoderException;
  import org.apache.commons.codec.binary.Hex;
  import org.apache.commons.codec.digest.DigestUtils;*/
  /** XXX end modification by stefan@apache.org */
  
  /**
   * <p><code>UUID</code> represents a Universally Unique Identifier per IETF
   * Draft specification. For more information regarding the IETF Draft UUID
   * specification</p>
   *
   * <p>See: http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-01.txt</p>
   *
   * <p>Copied from the Jakarta Commons-Id project</p>
   * <p/>
   * todo remove and use official commons-id release as soon as it is available
   *
   * @author Commons-Id Team
   * @version $Revision: 1.1 $ $Date: 2004/07/26 17:11:58 $
   *
   */
  
  public class UUID implements Constants, Serializable, Comparable {
  
      /** byte array to store 128-bits composing this UUID */
      private byte[] rawBytes = new byte[UUID_BYTE_LENGTH];
  
      /** Holds node identifier for this UUID */
      private Long node = null;
  
      /** Holds timestamp for this UUID */
      private long timestamp = -1;
  
      /** Holds the clock sequence field */
      private Short clockSq = null;
  
      /** Holds the version field of this UUID */
      private int version = -1;
  
      /** Holds the variant field of this UUID */
      private int variant = -1;
  
      /** Holds the internal string value of the UUID */
      private String stringValue = null;
  
      /** XXX begin modification by stefan@apache.org */
      private static VersionFourGenerator versionFourGenereator = new VersionFourGenerator();
      /** XXX end modification by stefan@apache.org */
  
      /** Constructs a nil UUID */
      public UUID() {
          super();
      }
  
      /**
       * <p>Constructs a UUID from a 128 bit java.math.BigInteger.</p>
       * <p>Method is protected as their is no standard as to the internal representation of a UUID.
       * In this case a BigInteger is used with signum always positive.</p>
       *
       *  @param bigIntValue the 128 bit BigInteger to construct this UUID from.
       *  @throws IllegalArgumentException argument must be 128 bit
       */
     /* protected UUID(BigInteger bigIntValue) throws IllegalArgumentException {
          super();
          if (bigIntValue.bitLength() > UUID.UUID_BIT_LENGTH) {
              throw new IllegalArgumentException("UUID must be contructed using a 128 bit BigInteger");
          }
          numberValue = bigIntValue;
      } */
  
      /**
       * <p>Copy constructor.</p>
       *
       * @param copyFrom the UUID to copy to create this UUID.
       */
      public UUID(UUID copyFrom) {
          super();
          rawBytes = copyFrom.getRawBytes();
      }
  
      /**
       * <p>Constructs a UUID from a 16 byte array.</p>
       *
       *  @param byteArray the 16 byte array to construct this UUID from.
       *  @throws IllegalArgumentException argument must be 16 bytes
       */
      public UUID(byte[] byteArray) throws IllegalArgumentException {
          super();
          if (byteArray.length != UUID_BYTE_LENGTH) {
              throw new IllegalArgumentException("UUID must be contructed using a 16 byte array.");
          }
          // UUID must be immutable so a copy is used.
          System.arraycopy(byteArray, 0, rawBytes, 0, UUID_BYTE_LENGTH);
      }
  
      /**
       * <p>Constructs a UUID from a DataInput. Note if 16 bytes are not available this method will block.</p>
       *
       *  @param input the datainput with 16 bytes to read in from.
       *  @throws IOException exception if there is an IO problem also argument must contain 16 bytes.
       */
      public UUID(DataInput input) throws IOException {
          super();
          input.readFully(rawBytes, 0, UUID_BYTE_LENGTH);
      }
  
      /**
       * <p>Constructs a UUID from two long values in most significant byte, and least significant bytes order.</p>
       *
       * @param mostSignificant - the most significant 8 bytes of the uuid to be constructed.
       * @param leastSignificant - the least significant 8 bytes of the uuid to be constructed.
       */
      public UUID(long mostSignificant, long leastSignificant) {
         rawBytes = Bytes.append(Bytes.toBytes(mostSignificant), Bytes.toBytes(leastSignificant));
      }
  
      /** XXX begin modification by stefan@apache.org */
      /**
       * <p>Constructs a UUID from a UUID formatted String.</p>
       *
       *  @param uuidString the String representing a UUID to construct this UUID
       *  @throws UUIDFormatException String must be a properly formatted UUID string
       */
      //public UUID(String uuidString) throws UUIDFormatException {
      public UUID(String uuidString) {
          //Calls the copy constructor
          this(UUID.fromString(uuidString));
      }
      /** XXX end modification by stefan@apache.org */
  
      /** XXX begin modification by stefan@apache.org */
      /**
       *  <p>Parses a string for a UUID.</p>
       *
       *  @param uuidString the UUID formatted String to parse.
       * XXX begin modification by stefan@apache.org
       *  @throws UUIDFormatException the String must be a properly formatted UUID String.
       * XXX end modification by stefan@apache.org
       *  @return Returns a UUID or null if the formatted string could not be parsed.
       */
      //public static UUID fromString(String uuidString) throws UUIDFormatException {
      public static UUID fromString(String uuidString) {
          String leanString = uuidString.toLowerCase();
          UUID tmpUUID = null;
  
          //Handle prefixed UUIDs
          // e.g. urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6
          int pos = uuidString.lastIndexOf(":");
          if (pos > 1) {
              leanString = uuidString.substring(++pos, uuidString.length());
          }
  
          //Check for 36 char length
          if (leanString.length() != UUID_FORMATTED_LENGTH) {
              //throw new UUIDFormatException();
  	    throw new IllegalArgumentException();
          }
  
          //Check for 5 fields
          StringTokenizer tok = new StringTokenizer(leanString, "-");
          if ( tok.countTokens() != TOKENS_IN_UUID ) {
  	    //throw new UUIDFormatException();
  	    throw new IllegalArgumentException();
          }
  
          //Remove the "-" from the formatted string and test token sizes
          StringBuffer buf = new StringBuffer(UUID_UNFORMATTED_LENGTH);
          String token = null;
          int count = 0;
          while (tok.hasMoreTokens()) {
              token = tok.nextToken();
              if (token.length() != TOKEN_LENGTHS[count++]) {
  		//throw new UUIDFormatException();
  		throw new IllegalArgumentException();
              }
              buf.append(token);
          }
  
          //Create from the hex value
  	/** XXX begin modification by stefan@apache.org */
  /*
          try {
              char[] chars = buf.toString().toCharArray();
              tmpUUID = new UUID(Hex.decodeHex(chars));
          } catch (DecoderException de) {
                throw new UUIDFormatException(de.getMessage());
         }
  */
  	String s = buf.toString();
  	byte[] bytes = new byte[UUID_BYTE_LENGTH];
  	for (int i = 0, j = 0; i < (UUID_BYTE_LENGTH * 2); i += 2) {
  	    bytes[j++] = (byte) Integer.parseInt(s.substring(i, i + 2), 16);
  	}
  	tmpUUID = new UUID(bytes);
  	/** XXX end modification by stefan@apache.org */
  
          return tmpUUID;
      }
      /** XXX end modification by stefan@apache.org */
  
      /**
       * <p>Returns a string representation of the UUID.</p>
       *
       * @return a string representation of the UUID formatted according to the specification.
       */
      public String toString() {
          //set string value if not set
          if (stringValue == null) {
  	    /** XXX begin modification by stefan@apache.org */
  /*
              StringBuffer buf = new StringBuffer(new String(Hex.encodeHex(rawBytes)));
              while (buf.length() != UUID_UNFORMATTED_LENGTH) {
                  buf.insert(0, "0");
              }
              buf.ensureCapacity(UUID_FORMATTED_LENGTH);
              buf.insert(FORMAT_POSITION1, '-');
              buf.insert(FORMAT_POSITION2, '-');
              buf.insert(FORMAT_POSITION3, '-');
              buf.insert(FORMAT_POSITION4, '-');
              stringValue = buf.toString();
  */
  	    char[] chars = new char[UUID_FORMATTED_LENGTH];
  	    for (int i = 0, j = 0; i < 16; i++) {
  		chars[j++] = hexDigits[(rawBytes[i] >> 4) & 0x0f];
  		chars[j++] = hexDigits[rawBytes[i] & 0x0f];
  		if (i == 3 || i == 5 || i == 7 || i == 9) {
  		    chars[j++] = '-';
  		}
  	    }
  	    stringValue = new String(chars);
  	    /** XXX end modification by stefan@apache.org */
          }
          return stringValue;
      }
  
      /**
       * <p>Returns a urn representation of the UUID. This is same as the
       * toString() value prefixed with <code>urn:uuid:</code></p>
       *
       * @return Returns the urn string representation of the UUID
       */
      public String toUrn() {
          return URN_PREFIX + this.toString();
      }
  
      /**
       * <p>Compares two UUID for equality.</p>
       *
       * @see java.lang.Object#equals(Object)
       */
  
      public boolean equals(Object obj) {
          if (!(obj instanceof UUID)) {
              return false;
          }
          return Bytes.areEqual( ((UUID) obj).getRawBytes(), rawBytes);
      }
  
      /**
       * <p>Returns a hash code value for the object.</p>
       *
       * @see java.lang.Object#hashCode()
       */
      public int hashCode() {
          int iConstant = 37;
          int iTotal = 17;
          for (int i = 0; i < rawBytes.length; i++) {
              iTotal = iTotal * iConstant + rawBytes[i];
          }
         return iTotal;
      }
  
      /**
       * <p>Compares two UUID's for equality</p>
       *
       * @see Comparable#compareTo(Object)
       */
      public int compareTo(Object compareTo) throws ClassCastException {
          if (!(compareTo instanceof UUID)) {
              throw new ClassCastException();
          }
          return (Bytes.compareTo(rawBytes, ((UUID) compareTo).getRawBytes()));
      }
  
      /**
       * <p>Returns the clock sequence value in the UUID. The clock sequence is a random assigned to a particular clock instance that
       * generated the time in the timestamp of a time based UUID.</p>
       *
       * @return the clock sequence value in the UUID.
       * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID.
       */
      public int clockSequence() throws UnsupportedOperationException {
          //if variant is not mealling leach salz throw unsupported operation exception
          if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) {
              throw new UnsupportedOperationException(WRONG_VAR_VER_MSG);
          }
          if (clockSq == null) {
              byte[] b = {((byte) (rawBytes[8] & 0x3F)), rawBytes[9]};
              clockSq = new Short(Bytes.toShort(b));
          }
          return clockSq.intValue();
      }
  
      /**
       * <p>Returns the version of the UUID.
       * <ul>
       *   <li>VERSION_ONE - The time-based version</li>
       *   <li>VERSION_TWO - DCE Security version, with embedded POSIX UIDs.</li>
       *   <li>VERSION_THREE - Name based UUID.</li>
       *   <li>VERSION_FOUR - Random based UUID.</li>
       * </ul>
       * </p>
       * @return the version of the UUID.
       */
      public int version() {
          if (version == -1) {
              version = ((rawBytes[6] >>> 4) & 0x0F);
          }
          return version;
      }
  
      /**
       * <p>Returns the variant field of the UUID.</p>
       *
       * @return Returns the variant field of the UUID.
       * @see UUID#VARIANT_NCS_COMPAT
       * @see UUID#VARIANT_IETF_DRAFT
       * @see UUID#VARIANT_MS
       * @see UUID#VARIANT_FUTURE
       */
      public int variant() {
          if (variant == -1) {
              if ((rawBytes[8] & 0x80) == 0x0) {
                  variant = VARIANT_NCS_COMPAT;
              } else if ((rawBytes[8] & 0x40) == 0x0) {
                  variant = VARIANT_IETF_DRAFT;
              } else if ((rawBytes[8] & 0x20) == 0x0) {
                  variant = VARIANT_MS;
              } else {
                  variant = VARIANT_FUTURE;
              }
          }
          return variant;
      }
  
      /**
       * <p>Returns the node identifier found in this UUID. The specification was written such that this value holds the IEEE 802 MAC
       * address. The specification permits this value to be calculated from other sources other than the MAC.</p>
       *
       * @return the node identifier found in this UUID.
       * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID.
       */
      public long node() throws UnsupportedOperationException {
          //if variant is not mealling leach salz throw unsupported operation exception
          if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) {
              throw new UnsupportedOperationException(WRONG_VAR_VER_MSG);
          }
          if (node == null) {
              byte[] b = new byte[8];
              System.arraycopy(rawBytes, 10, b, 2, 6);
              node = new Long((Bytes.toLong(b) & 0xFFFFFFFFFFFFL));
          }
          return node.longValue();
      }
  
      /**
       * <p>Returns the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset (00:00:00.00, 15
       * October 1582 ).</p>
       *
       * @return the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset.
       * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID.
       */
      public long timestamp() throws UnsupportedOperationException {
          //if variant is not mealling leach salz throw unsupported operation exception
          if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) {
              throw new UnsupportedOperationException(WRONG_VAR_VER_MSG);
          }
          if (timestamp == -1) {
              byte[] longVal = new byte[8];
              System.arraycopy(rawBytes, TIME_HI_START_POS, longVal, TIME_HI_TS_POS, TIME_HI_BYTE_LEN);
              System.arraycopy(rawBytes, TIME_MID_START_POS, longVal, TIME_MID_TS_POS, TIME_MID_BYTE_LEN);
              System.arraycopy(rawBytes, TIME_LOW_START_POS, longVal, TIME_LOW_TS_POS, TIME_LOW_BYTE_LEN);
              longVal[TIME_HI_TS_POS] &= 0x0F;
              timestamp = Bytes.toLong(longVal);
          }
          return timestamp;
      }
  
      /**
       * <p>Returns the least significant bits stored in the uuid's internal structure.</p>
       *
       * @return the least significant bits stored in the uuid's internal structure.
       */
      long getLeastSignificantBits()  {
          byte[] lsb = new byte[8];
          System.arraycopy(rawBytes, 8, lsb, 0, 8);
          return Bytes.toLong(lsb);
      }
  
      /**
       * <p>Returns the least significant bits stored in the uuid's internal structure.</p>
       *
       * @return the least significant bits stored in the uuid's internal structure.
       */
      long getMostSignificantBits()  {
          byte[] msb = new byte[8];
          System.arraycopy(rawBytes, 0, msb, 0, 8);
          return Bytes.toLong(msb);
      }
  
      /**
       * <p>Returns a copy of the byte values contained in this UUID.
       *
       * @return a copy of the byte values contained in this UUID.
       */
      public byte[] getRawBytes() {
          byte[] ret = new byte[UUID_BYTE_LENGTH];
          System.arraycopy(rawBytes, 0, ret, 0, UUID_BYTE_LENGTH);
          return ret;
      }
  
      /**
       * <p>Returns a new version 4 UUID, based upon Random bits.</p>
       *
       * @return a new version 4 UUID, based upon Random bits.
       */
      /** XXX begin modification by stefan@apache.org */
      //static UUID randomUUID() {
      public static UUID randomUUID() {
          //return (UUID) IdentifierUtils.UUID_VERSION_FOUR_GENERATOR.nextIdentifier();
  	return (UUID) versionFourGenereator.nextIdentifier();
      }
      /** XXX end modification by stefan@apache.org */
  
      /** XXX begin modification by stefan@apache.org */
      /**
       * <p>Returns a new version 1 UUID, based upon node identifier and time stamp.</p>
       *
       * @return a new version 1 UUID, based upon node identifier and time stamp.
       */
  /*    static UUID timeUUID() {
          return (UUID) IdentifierUtils.UUID_VERSION_ONE_GENERATOR.nextIdentifier();
      }*/
      /** XXX end modification by stefan@apache.org */
  
      /** XXX begin modification by stefan@apache.org */
      /**
       * <p>Returns a new version three UUID given a name and the namespace's UUID.</p>
       *
       * @param name String the name to calculate the UUID for.
       * @param namespace UUID assigned to this namespace.
       * @return a new version three UUID given a name and the namespace's UUID.
       */
  /*    static UUID nameUUIDFromString(String name, UUID namespace) {
          byte[] nameAsBytes = name.getBytes();
          byte[] concat = new byte[UUID_BYTE_LENGTH + nameAsBytes.length];
          System.arraycopy(namespace.getRawBytes(), 0, concat, 0, UUID_BYTE_LENGTH);
          System.arraycopy(nameAsBytes, 0, concat, UUID_BYTE_LENGTH, nameAsBytes.length);
          byte[] raw = DigestUtils.md5(concat);
          //Set version
          raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F;
          raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_THREE << 4);
          //Set variant
          raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111
          raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000
  
          return new UUID(raw);
      }*/
      /** XXX end modification by stefan@apache.org */
  }
  
  
  
  1.1                  jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/util/uuid/VersionFourGenerator.java
  
  Index: VersionFourGenerator.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.slide.jcr.util.uuid;
  
  import java.security.NoSuchAlgorithmException;
  import java.security.NoSuchProviderException;
  import java.security.SecureRandom;
  import java.util.Random;
  
  /** XXX begin modification by stefan@apache.org */
  //import org.apache.commons.id.IdentifierGenerator;
  /** XXX end modification by stefan@apache.org */
  
  /**
   * <p>Class is responsible for generating version 4 UUID's per the IETF draft
   * specification. This class attempts to use a java.security.SecureRandom with
   * the following instantiation
   * <code>SecureRandom.getInstance("SHA1PRNG", "SUN")</code>. If neither secure
   * random implementation is avialable or an Exception is raised a java.util.Random
   * is used.</p>
   * <p>Note: Instantiation of SecureRandom is an expensive operation. The
   * constructor therefore creates a static member to hold the SecureRandom.
   * The first call to getInstance may take time; subsequent calls should return
   * quickly.</p>
   *
   * <p>Copied from the Jakarta Commons-Id project</p>
   * <p/>
   * todo remove and use official commons-id release as soon as it is available
   * 
   * @author Commons-Id team
   * @version $Revision: 1.1 $ $Date: 2004/07/26 17:11:58 $
   *
   */
  /** XXX begin modification by stefan@apache.org */
  //public final class VersionFourGenerator implements IdentifierGenerator, Constants {
  public final class VersionFourGenerator implements Constants {
  /** XXX end modification by stefan@apache.org */
  
          /** Random used to generate UUID's */
          private static final Random regularRandom = new Random();
  
          /** SecureRandom used to generate UUID's */
          private static Random secureRandom;
  
          /** The pseudo-random number generator to use */
          private static String usePRNG = "SHA1PRNG";
  
          /** The pseudo-random number generator package name to use */
          private static String usePRNGPackage = "SUN";
  
          /**
           * <p>Constructs a new VersionFourGenerator.</p>
           */
          public VersionFourGenerator() {
              super();
          }
  
          /**
           * <p>Returns a new version four UUID.</p>
           *
           * @return Object a new version 4 UUID.
           */
          public Object nextIdentifier() {
              return nextUUID(false);
          }
  
          /**
           * <p>Returns a new version four UUID.</p>
           * <p>This overloaded method may produce both UUID's using a <code>SecureRandom</code> as well as using normal
           * <code>Random</code>
           * </p>
           *
           * @param secure indicates whether or not to use <code>SecureRandom</code> in generating the random bits.
           * @return a new version four UUID that was generated by either a <code>Random</code> or <code>SecureRandom</code>.
           */
          public Object nextIdentifier(boolean secure)  {
              if (secure) {
                  return nextUUID(true);
              }
              return nextUUID(false);
          }
  
          /**
          * <p>Returns a new version four UUID.</p>
          *
          * @return Object a new version 4 UUID.
          */
          private UUID nextUUID() {
              //Call nextUUID with secure = false
              return nextUUID(false);
          }
  
          /**
           * <p>Returns a new version four UUID using either <code>SecureRandom</code> or <code>Random</code>.</p>
           *
           * @param secure boolean flag indicating whether to use <code>SecureRandom</code> or <code>Random</code>.
           * @return a new version four UUID using either <code>SecureRandom</code> or <code>Random</code>.
           */
          private UUID nextUUID(boolean secure) {
              byte[] raw = new byte[UUID_BYTE_LENGTH];
              if (secure) {
                  //Initialize the secure random if null.
                  if (secureRandom == null) {
                      try {
                          if (usePRNGPackage != null) {
                              secureRandom = SecureRandom.getInstance(usePRNG, usePRNGPackage);
                          } else {
                              secureRandom = SecureRandom.getInstance(usePRNG);
                          }
                      } catch (NoSuchAlgorithmException nsae) {
                          secure = false; //Fail back to default PRNG/Random
                      } catch (NoSuchProviderException nspe) {
                          secure = false; //Fail back to default PRNG/Random
                      }
                      secureRandom.nextBytes(raw);
                  }
              }
  
              if (!secure) {
                  regularRandom.nextBytes(raw);
              }
  
              raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F;
              raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_FOUR << 4);
  
              raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111
              raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000
  
              return new UUID(raw);
          }
  
         /**
          * <p>Allows clients to set the pseudo-random number generator implementation used when generating a version four uuid with
          * the secure option. The secure option uses a <code>SecureRandom</code>. The packageName string may be null to specify
          * no preferred package.</p>
          *
          * @param prngName the pseudo-random number generator implementation name. For example "SHA1PRNG".
          * @param packageName the package name for the PRNG provider. For example "SUN".
          */
         public static void setPRNGProvider(String prngName, String packageName) {
             VersionFourGenerator.usePRNG = prngName;
             VersionFourGenerator.usePRNGPackage = packageName;
             VersionFourGenerator.secureRandom = null;
         }
      }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org