You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juddi.apache.org by sv...@apache.org on 2003/11/11 14:53:28 UTC

cvs commit: ws-juddi/src/java/org/apache/juddi/uuidgen DefaultUUIDGen.java NativeUUIDGen.java SecureUUIDGen.java UUIDGen.java UUIDGenFactory.java Win32UUIDGen.java

sviens      2003/11/11 05:53:28

  Added:       src/java/org/apache/juddi/uuidgen DefaultUUIDGen.java
                        NativeUUIDGen.java SecureUUIDGen.java UUIDGen.java
                        UUIDGenFactory.java Win32UUIDGen.java
  Log:
  Moved from jUDDI CVS at SourceForge
  
  Revision  Changes    Path
  1.1                  ws-juddi/src/java/org/apache/juddi/uuidgen/DefaultUUIDGen.java
  
  Index: DefaultUUIDGen.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "jUDDI" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.juddi.uuidgen;
  
  import java.math.BigInteger;
  import java.util.Random;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /**
   * Used to create new universally unique identifiers or UUID's (sometimes called
   * GUID's).  UDDI UUID's are allways formmated according to DCE UUID conventions.
   *
   * @author Maarten Coene
   * @author Steve Viens (sviens@apache.org)
   */
  public class DefaultUUIDGen implements UUIDGen
  {
    // private reference to the jUDDI logger
    private static Log log = LogFactory.getLog(DefaultUUIDGen.class);
  
    private static final BigInteger COUNT_START = new BigInteger("-12219292800000");  // 15 October 1582
    private static final int CLOCK_SEQUENCE = (new Random()).nextInt(16384);
    
    private Random random;
  
    /**
     *
     */
    public DefaultUUIDGen()
    {
      try {
        random = new Random();
        random.setSeed(System.currentTimeMillis());
      } catch (Exception e) {
        random = new Random();
      }
    }
  
    /**
     *
     */
    public String uuidgen()
    {
      return nextUUID();
    }
  
    /**
     *
     */
    public String[] uuidgen(int nmbr)
    {
      String[] uuids = new String[nmbr];
  
      for (int i=0; i<uuids.length; i++)
        uuids[i] = nextUUID();
  
      return uuids;
    }
  
    /**
     * Creates a new UUID. The algorithm used is described by The Open Group.
     * See <a href="http://www.opengroup.org/onlinepubs/009629399/apdxa.htm">
     * Universal Unique Identifier</a> for more details.
     *
     * Due to a lack of functionality in Java, a part of the UUID is a secure
     * random. This results in a long processing time when this method is called
     * for the first time.
     */
    private String nextUUID()
    {
      // the number of milliseconds since 1 January 1970
      BigInteger current = BigInteger.valueOf(System.currentTimeMillis());
  
      // the number of milliseconds since 15 October 1582
      BigInteger countMillis = current.subtract(COUNT_START);
  
      // the count of 100-nanosecond intervals since 00:00:00.00 15 October 1582
      BigInteger count = countMillis.multiply(BigInteger.valueOf(10000));
  
      String bitString = count.toString(2);
      if (bitString.length() < 60)
      {
        int nbExtraZeros  = 60 - bitString.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        bitString = extraZeros.concat(bitString);
      }
  
      byte[] bits = bitString.getBytes();
  
      // the time_low field
      byte[] time_low = new byte[32];
      for (int i=0; i<32; i++)
        time_low[i] = bits[bits.length - i - 1];
  
      // the time_mid field
      byte[] time_mid = new byte[16];
      for (int i=0; i<16; i++)
        time_mid[i] = bits[bits.length - 32 - i - 1];
  
      // the time_hi_and_version field
      byte[] time_hi_and_version = new byte[16];
      for (int i=0; i<12; i++)
        time_hi_and_version[i] = bits[bits.length - 48 - i - 1];
  
      time_hi_and_version[12] = ((new String("1")).getBytes())[0];
      time_hi_and_version[13] = ((new String("0")).getBytes())[0];
      time_hi_and_version[14] = ((new String("0")).getBytes())[0];
      time_hi_and_version[15] = ((new String("0")).getBytes())[0];
  
      // the clock_seq_low field
      BigInteger clockSequence = BigInteger.valueOf(CLOCK_SEQUENCE);
      String clockString = clockSequence.toString(2);
      if (clockString.length() < 14)
      {
        int nbExtraZeros  = 14 - bitString.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        clockString = extraZeros.concat(bitString);
      }
  
      byte[] clock_bits = clockString.getBytes();
      byte[] clock_seq_low = new byte[8];
      for (int i=0; i<8; i++)
        clock_seq_low[i] = clock_bits[clock_bits.length - i - 1];
  
      // the clock_seq_hi_and_reserved
      byte[] clock_seq_hi_and_reserved = new byte[8];
      for (int i=0; i<6; i++)
        clock_seq_hi_and_reserved[i] = clock_bits[clock_bits.length - 8 - i - 1];
  
      clock_seq_hi_and_reserved[6] = ((new String("0")).getBytes())[0];
      clock_seq_hi_and_reserved[7] = ((new String("1")).getBytes())[0];
  
      String timeLow = Long.toHexString((new BigInteger(new String(reverseArray(time_low)), 2)).longValue());
      if (timeLow.length() < 8)
      {
        int nbExtraZeros = 8 - timeLow.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        timeLow = extraZeros.concat(timeLow);
      }
  
      String timeMid = Long.toHexString((new BigInteger(new String(reverseArray(time_mid)), 2)).longValue());
      if (timeMid.length() < 4)
      {
        int nbExtraZeros = 4 - timeMid.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        timeMid = extraZeros.concat(timeMid);
      }
  
      String timeHiAndVersion = Long.toHexString((new BigInteger(new String(reverseArray(time_hi_and_version)), 2)).longValue());
      if (timeHiAndVersion.length() < 4)
      {
        int nbExtraZeros = 4 - timeHiAndVersion.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        timeHiAndVersion = extraZeros.concat(timeHiAndVersion);
      }
  
      String clockSeqHiAndReserved = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_hi_and_reserved)), 2)).longValue());
      if (clockSeqHiAndReserved.length() < 2)
      {
        int nbExtraZeros = 2 - clockSeqHiAndReserved.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        clockSeqHiAndReserved = extraZeros.concat(clockSeqHiAndReserved);
      }
  
      String clockSeqLow = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_low)), 2)).longValue());
      if (clockSeqLow.length() < 2)
      {
        int nbExtraZeros = 2 - clockSeqLow.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        clockSeqLow = extraZeros.concat(clockSeqLow);
      }
  
      // problem: the node should be the IEEE 802 ethernet address, but can not
      // be retrieved in Java yet.
      // see bug ID 4173528
      // workaround (also suggested in bug ID 4173528)
      // If a system wants to generate UUIDs but has no IEE 802 compliant
      // network card or other source of IEEE 802 addresses, then this section
      // describes how to generate one.
      // The ideal solution is to obtain a 47 bit cryptographic quality random
      // number, and use it as the low 47 bits of the node ID, with the most
      // significant bit of the first octet of the node ID set to 1. This bit
      // is the unicast/multicast bit, which will never be set in IEEE 802
      // addresses obtained from network cards; hence, there can never be a
      // conflict between UUIDs generated by machines with and without network
      // cards.
  
      long nodeValue = random.nextLong();
      nodeValue = Math.abs(nodeValue);
      while (nodeValue > 140737488355328L)
      {
        nodeValue = random.nextLong();
        nodeValue = Math.abs(nodeValue);
      }
  
      BigInteger nodeInt = BigInteger.valueOf(nodeValue);
      String nodeString = nodeInt.toString(2);
      if (nodeString.length() < 47)
      {
        int nbExtraZeros = 47 - nodeString.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
  
        nodeString = extraZeros.concat(nodeString);
      }
  
      byte[] node_bits = nodeString.getBytes();
      byte[] node = new byte[48];
      for (int i=0; i<47; i++)
        node[i] = node_bits[node_bits.length - i - 1];
  
      node[47] = ((new String("1")).getBytes())[0];
      String theNode = Long.toHexString((new BigInteger(new String(reverseArray(node)), 2)).longValue());
      if (theNode.length() < 12)
      {
        int nbExtraZeros = 12 - theNode.length();
        String extraZeros = new String();
        for (int i=0; i<nbExtraZeros; i++)
          extraZeros = extraZeros.concat("0");
        theNode = extraZeros.concat(theNode);
      }
  
      String result = timeLow + "-" + timeMid +"-" + timeHiAndVersion + "-" + clockSeqHiAndReserved + clockSeqLow + "-" + theNode;
  
      return result.toUpperCase();
    }
  
    /**
     *
     */
    private static byte[] reverseArray(byte[] bits)
    {
      byte[] result = new byte[bits.length];
      for (int i=0; i<result.length; i++)
        result[i] = bits[result.length - 1 - i];
  
      return result;
    }
  
  
    /***************************************************************************/
    /***************************** TEST DRIVER *********************************/
    /***************************************************************************/
  
  
    public static void main(String argc[])
    {
      DefaultUUIDGen generator = new DefaultUUIDGen();
  
      long start = System.currentTimeMillis();
  
      for (int i = 1; i <= 100; ++i)
        generator.uuidgen();
  
      long end = System.currentTimeMillis();
  
      System.out.println("QuickUUIDGen: Generation of 100 UUID's took "+(end-start)+" milliseconds.");
    }
  }
  
  
  1.1                  ws-juddi/src/java/org/apache/juddi/uuidgen/NativeUUIDGen.java
  
  Index: NativeUUIDGen.java
  ===================================================================
  /*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "jUDDI" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.juddi.uuidgen;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.juddi.util.Config;

/**
 * Used to create new universally unique identifiers or UUID's
 * (sometimes called GUID's).  UDDI UUID's are allways formmated
 * according to DCE UUID conventions.
 *
 * @author Steve Viens (sviens@apache.org)
 */
public final class NativeUUIDGen implements UUIDGen
{
  private static final String COMMAND_KEY = "juddi.uuidgenCommand";
  private static final String DEFAULT_COMMAND = "uuidgen";

  private String command = null;

  /**
   *
   */
  public NativeUUIDGen()
  {
    this.command =
        Config.getStringProperty(COMMAND_KEY,DEFAULT_COMMAND);
  }

  /**
   *
   */
  public String uuidgen()
  {
    try
    {
      Runtime r = Runtime.getRuntime();
      Process p = r.exec(command);
      BufferedReader x = new BufferedReader(
                          new InputStreamReader(
                            p.getInputStream()));

      return x.readLine();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }

    return null;
  }

  /**
   *
   */
  public String[] uuidgen(int nmbr)
  {
    String[] uuids = new String[nmbr];

    for (int i=0; i<uuids.length; i++)
      uuids[i] = uuidgen();

    return uuids;
  }


  /***************************************************************************/
  /***************************** TEST DRIVER *********************************/
  /***************************************************************************/


  public static void main(String argc[])
  {
    UUIDGen generator = new NativeUUIDGen();

    long start = System.currentTimeMillis();

    for (int i = 1; i <= 100; ++i)
      generator.uuidgen();

    long end = System.currentTimeMillis();

    System.out.println("\nNativeUUIDGen: Generation of 100 UUID's took " +
      (end-start)+" milliseconds.");
  }
}
  
  
  1.1                  ws-juddi/src/java/org/apache/juddi/uuidgen/SecureUUIDGen.java
  
  Index: SecureUUIDGen.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "jUDDI" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.juddi.uuidgen;
  
  import java.math.BigInteger;
  import java.security.SecureRandom;
  import java.util.Random;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /**
   * Used to create new universally unique identifiers or UUID's (sometimes called
   * GUID's).  UDDI UUID's are allways formmated according to DCE UUID conventions.
   *
   * @author Maarten Coene
   * @author Steve Viens (sviens@apache.org)
   */
  public class SecureUUIDGen implements UUIDGen
  {
    // private reference to the jUDDI logger
    private static Log log = LogFactory.getLog(SecureUUIDGen.class);
  
    private static final BigInteger COUNT_START = new BigInteger("-12219292800000");  // 15 October 1582
    private static final int CLOCK_SEQUENCE = (new Random()).nextInt(16384);
  
    /**
     *
     */
    public String uuidgen()
    {
      return nextUUID();
    }
  
    /**
     *
     */
    public String[] uuidgen(int nmbr)
    {
      String[] uuids = new String[nmbr];
  
      for (int i=0; i<uuids.length; i++)
        uuids[i] = nextUUID();
  
      return uuids;
    }
  
    /**
     * Creates a new UUID. The algorithm used is described by The Open Group.
     * See <a href="http://www.opengroup.org/onlinepubs/009629399/apdxa.htm">
     * Universal Unique Identifier</a> for more details.
     * <p>
     * Due to a lack of functionality in Java, a part of the UUID is a secure
     * random. This results in a long processing time when this method is called
     * for the first time.
     */
    protected String nextUUID()
    {
        // the count of 100-nanosecond intervals since 00:00:00.00 15 October 1582
        BigInteger count;
  
        // the number of milliseconds since 1 January 1970
        BigInteger current = BigInteger.valueOf(System.currentTimeMillis());
  
        // the number of milliseconds since 15 October 1582
        BigInteger countMillis = current.subtract(COUNT_START);
  
        // the result
        count = countMillis.multiply(BigInteger.valueOf(10000));
  
        String bitString = count.toString(2);
        if (bitString.length() < 60) {
            int nbExtraZeros = 60 - bitString.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
  
            bitString = extraZeros.concat(bitString);
        }
  
        byte[] bits = bitString.getBytes();
  
        // the time_low field
        byte[] time_low = new byte[32];
        for (int i = 0; i < 32; i++)
            time_low[i] = bits[bits.length - i - 1];
  
        // the time_mid field
        byte[] time_mid = new byte[16];
        for (int i = 0; i < 16; i++)
            time_mid[i] = bits[bits.length - 32 - i - 1];
  
        // the time_hi_and_version field
        byte[] time_hi_and_version = new byte[16];
        for (int i = 0; i < 12; i++)
            time_hi_and_version[i] = bits[bits.length - 48 - i - 1];
  
        time_hi_and_version[12] = ((new String("1")).getBytes())[0];
        time_hi_and_version[13] = ((new String("0")).getBytes())[0];
        time_hi_and_version[14] = ((new String("0")).getBytes())[0];
        time_hi_and_version[15] = ((new String("0")).getBytes())[0];
  
        // the clock_seq_low field
        BigInteger clockSequence = BigInteger.valueOf(CLOCK_SEQUENCE);
        String clockString = clockSequence.toString(2);
        if (clockString.length() < 14) {
            int nbExtraZeros = 14 - bitString.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
  
            clockString = extraZeros.concat(bitString);
        }
  
        byte[] clock_bits = clockString.getBytes();
        byte[] clock_seq_low = new byte[8];
        for (int i = 0; i < 8; i++)
            clock_seq_low[i] = clock_bits[clock_bits.length - i - 1];
  
        // the clock_seq_hi_and_reserved
        byte[] clock_seq_hi_and_reserved = new byte[8];
        for (int i = 0; i < 6; i++)
            clock_seq_hi_and_reserved[i] = clock_bits[clock_bits.length - 8 - i - 1];
  
        clock_seq_hi_and_reserved[6] = ((new String("0")).getBytes())[0];
        clock_seq_hi_and_reserved[7] = ((new String("1")).getBytes())[0];
  
        String timeLow = Long.toHexString((new BigInteger(new String(reverseArray(time_low)), 2)).longValue());
        if (timeLow.length() < 8) {
            int nbExtraZeros = 8 - timeLow.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
  
            timeLow = extraZeros.concat(timeLow);
        }
  
        String timeMid = Long.toHexString((new BigInteger(new String(reverseArray(time_mid)), 2)).longValue());
        if (timeMid.length() < 4) {
            int nbExtraZeros = 4 - timeMid.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
            timeMid = extraZeros.concat(timeMid);
        }
  
        String timeHiAndVersion = Long.toHexString((new BigInteger(new String(reverseArray(time_hi_and_version)), 2)).longValue());
        if (timeHiAndVersion.length() < 4) {
            int nbExtraZeros = 4 - timeHiAndVersion.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
  
            timeHiAndVersion = extraZeros.concat(timeHiAndVersion);
        }
  
        String clockSeqHiAndReserved = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_hi_and_reserved)), 2)).longValue());
        if (clockSeqHiAndReserved.length() < 2) {
            int nbExtraZeros = 2 - clockSeqHiAndReserved.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
  
            clockSeqHiAndReserved = extraZeros.concat(clockSeqHiAndReserved);
        }
  
        String clockSeqLow = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_low)), 2)).longValue());
        if (clockSeqLow.length() < 2) {
            int nbExtraZeros = 2 - clockSeqLow.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
  
            clockSeqLow = extraZeros.concat(clockSeqLow);
        }
  
        // problem: the node should be the IEEE 802 ethernet address, but can not
        // be retrieved in Java yet.
        // see bug ID 4173528
        // workaround (also suggested in bug ID 4173528)
        // If a system wants to generate UUIDs but has no IEE 802 compliant
        // network card or other source of IEEE 802 addresses, then this section
        // describes how to generate one.
        // The ideal solution is to obtain a 47 bit cryptographic quality random
        // number, and use it as the low 47 bits of the node ID, with the most
        // significant bit of the first octet of the node ID set to 1. This bit
        // is the unicast/multicast bit, which will never be set in IEEE 802
        // addresses obtained from network cards; hence, there can never be a
        // conflict between UUIDs generated by machines with and without network
        // cards.
        Random secureRandom = null;
        try {
            secureRandom = SecureRandom.getInstance("SHA1PRNG", "SUN");
        } catch (Exception e) {
            secureRandom = new Random();
        }
  
        long nodeValue = secureRandom.nextLong();
        nodeValue = Math.abs(nodeValue);
        while (nodeValue > 140737488355328L) {
            nodeValue = secureRandom.nextLong();
            nodeValue = Math.abs(nodeValue);
        }
  
        BigInteger nodeInt = BigInteger.valueOf(nodeValue);
        String nodeString = nodeInt.toString(2);
        if (nodeString.length() < 47) {
            int nbExtraZeros = 47 - nodeString.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
  
            nodeString = extraZeros.concat(nodeString);
        }
  
        byte[] node_bits = nodeString.getBytes();
        byte[] node = new byte[48];
        for (int i = 0; i < 47; i++)
            node[i] = node_bits[node_bits.length - i - 1];
  
        node[47] = ((new String("1")).getBytes())[0];
        String theNode = Long.toHexString((new BigInteger(new String(reverseArray(node)), 2)).longValue());
        if (theNode.length() < 12) {
            int nbExtraZeros = 12 - theNode.length();
            String extraZeros = new String();
            for (int i = 0; i < nbExtraZeros; i++)
                extraZeros = extraZeros.concat("0");
            theNode = extraZeros.concat(theNode);
        }
  
        String result = timeLow + "-" + timeMid + "-" + timeHiAndVersion + "-" + clockSeqHiAndReserved + clockSeqLow + "-" + theNode;
  
        return result.toUpperCase();
    }
  
    private static byte[] reverseArray(byte[] bits)
    {
      byte[] result = new byte[bits.length];
      for (int i = 0; i < result.length; i++)
        result[i] = bits[result.length - 1 - i];
  
      return result;
    }
  
  
    /***************************************************************************/
    /***************************** TEST DRIVER *********************************/
    /***************************************************************************/
  
  
    public static void main(String argc[])
    {
      SecureUUIDGen generator = new SecureUUIDGen();
  
      long start = System.currentTimeMillis();
  
      for (int i = 1; i <= 100; ++i)
        generator.uuidgen();
  
      long end = System.currentTimeMillis();
  
      System.out.println("SecureUUIDGen: Generation of 100 UUID's took "+(end-start)+" milliseconds.");
    }
  }
  
  
  
  1.1                  ws-juddi/src/java/org/apache/juddi/uuidgen/UUIDGen.java
  
  Index: UUIDGen.java
  ===================================================================
  /*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "jUDDI" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.juddi.uuidgen;

/**
 * A Universally Unique Identifier (UUID) is a 128 bit number generated
 * according to an algorithm that is garanteed to be unique in time and space
 * from all other UUIDs. It consists of an IEEE 802 Internet Address and
 * various time stamps to ensure uniqueness. For a complete specification,
 * see ftp://ietf.org/internet-drafts/draft-leach-uuids-guids-01.txt [leach].
 *
 * @author Steve Viens (sviens@apache.org)
 */
public interface UUIDGen
{
  /**
   *
   */
  String uuidgen();

  /**
   *
   */
  String[] uuidgen(int nmbr);
}
  
  
  1.1                  ws-juddi/src/java/org/apache/juddi/uuidgen/UUIDGenFactory.java
  
  Index: UUIDGenFactory.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "jUDDI" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.juddi.uuidgen;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.juddi.util.Config;
  import org.apache.juddi.util.Loader;
  
  /**
   * Used to create the org.apache.juddi.uuidgen.UUIDGen implementation
   * as specified by the 'juddi.uuidgen.impl' property. Defaults to
   * org.apache.juddi.uuidgen.SecureUUIDGen if an implementation is not
   * specified.
   *
   * @author Steve Viens (sviens@apache.org)
   */
  public abstract class UUIDGenFactory
  {
    // private reference to the jUDDI logger
    private static Log log = LogFactory.getLog(UUIDGenFactory.class);
  
    // UUIDGen property key & default implementation
    private static final String IMPL_KEY = "juddi.uuidgen";
    private static final String DEFAULT_IMPL = "org.apache.juddi.uuidgen.DefaultUUIDGen";
  
    // the shared UUIDGen instance
    private static UUIDGen uuidgen = null;
  
    /**
     * Returns a new instance of a UUIDGenFactory.
     *
     * @return UUIDGen
     */
    public static UUIDGen getUUIDGen()
    {
      if (uuidgen == null)
        uuidgen = createUUIDGen();
      return uuidgen;
    }
  
    /**
     * Returns a new instance of a UUIDGen.
     *
     * @return UUIDGen
     */
    private static synchronized UUIDGen createUUIDGen()
    {
      if (uuidgen != null)
        return uuidgen;
  
      // grab class name of the UUIDGen implementation to create
      String className = Config.getStringProperty(IMPL_KEY,DEFAULT_IMPL);
  
      // write the UUIDGen implementation name to the log
      log.debug("UUIDGen Implementation = " + className);
  
      Class uuidgenClass = null;
      try
      {
        // Use Loader to locate & load the UUIDGen implementation
        uuidgenClass = Loader.getClassForName(className);
      }
      catch(ClassNotFoundException e)
      {
        log.error("The specified UUIDGen class '" + className +
          "' was not found in classpath.");
        log.error(e);
      }
  
      try
      {
        // try to instantiate the UUIDGen implementation
        uuidgen = (UUIDGen)uuidgenClass.newInstance();
      }
      catch(Exception e)
      {
        log.error("Exception while attempting to instantiate the " +
          "implementation of UUIDGen: " + uuidgenClass.getName() +
          "\n" + e.getMessage());
        log.error(e);
      }
  
      return uuidgen;
    }
  
  
    /***************************************************************************/
    /***************************** TEST DRIVER *********************************/
    /***************************************************************************/
  
  
    public static void main(String[] args)
    {
      // number of UUID's to generate
      final int max = 100;
  
      try
      {
        UUIDGen uuidgen = UUIDGenFactory.getUUIDGen();
  
        for (int i=0; i<max; ++i)
          System.out.println( i + ":  " + uuidgen.uuidgen());
      }
      catch (Exception ex) { ex.printStackTrace(); }
    }
  }
  
  
  1.1                  ws-juddi/src/java/org/apache/juddi/uuidgen/Win32UUIDGen.java
  
  Index: Win32UUIDGen.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "jUDDI" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.juddi.uuidgen;
  
  import java.io.IOException;
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  
  /**
   * Used to create new universally unique identifiers or UUID's (sometimes called
   * GUID's).  UDDI UUID's are allways formmated according to DCE UUID conventions.
   *
   * @author Steve Viens (sviens@apache.org)
   */
  public final class Win32UUIDGen implements UUIDGen
  {
    /**
     *
     */
    public String uuidgen()
    {
      String[] uuids = this.uuidgen(1);
      return uuids[0];
    }
  
    /**
     *
     */
    public String[] uuidgen(int nmbr)
    {
      String[] uuids = new String[nmbr];
  
      try
      {
        Runtime r = Runtime.getRuntime();
        Process p = r.exec("uuidgen -n" + nmbr);
        BufferedReader x = new BufferedReader(new InputStreamReader(p.getInputStream()));
  
        for (int i = 0; i < nmbr; ++i)
          uuids[i] = x.readLine();
      }
      catch (IOException ex)
      {
        ex.printStackTrace();
        throw new RuntimeException(ex.getMessage());
      }
  
      return uuids;
    }
  
  
    /***************************************************************************/
    /***************************** TEST DRIVER *********************************/
    /***************************************************************************/
  
  
    public static void main(String argc[])
    {
      UUIDGen uuidgen = new Win32UUIDGen();
  
      long start = System.currentTimeMillis();
  
      // fast (3705 milliseconds)
      for (int i = 1; i <= 250; ++i)
        System.out.println( i + ":  " + uuidgen.uuidgen());
  
      long end = System.currentTimeMillis();
  
      System.out.println("Generation (and display) of 250 UUID's took "+(end-start)+" milliseconds.");
  
  
      start = System.currentTimeMillis();
  
      // much faster (90 milliseconds)
      String[] ids = uuidgen.uuidgen(250);
      for (int i = 1; i < 250; ++i)
        System.out.println( i + ":  " + ids[i]);
  
      end = System.currentTimeMillis();
  
      System.out.println("Generation (and display) of 250 UUID's took "+(end-start)+" milliseconds.");
    }
  }