View Javadoc

1   /***************************************************************************************
2    * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved.                 *
3    * http://aspectwerkz.codehaus.org                                                    *
4    * ---------------------------------------------------------------------------------- *
5    * The software in this package is published under the terms of the LGPL license      *
6    * a copy of which has been included with this distribution in the license.txt file.  *
7    **************************************************************************************/
8   package org.codehaus.aspectwerkz.util;
9   
10  import java.net.InetAddress;
11  import java.security.SecureRandom;
12  
13  /***
14   * Generates a UUID. <p/>A Universally Unique Identifier (UUID) is a 128 bit number generated according to an algorithm
15   * that is garanteed to be unique in time A space from all other UUIDs.
16   * 
17   * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
18   */
19  public class UuidGenerator {
20      /***
21       * Random seeder.
22       */
23      private static SecureRandom s_seeder = null;
24  
25      /***
26       * Mid value, needed for calculation.
27       */
28      private static String s_midValue = null;
29  
30      /***
31       * Defines if the generator is initialized or not.
32       */
33      private static boolean s_initialized = false;
34  
35      /***
36       * Private constructor to prevent subclassing
37       */
38      private UuidGenerator() {
39      }
40  
41      /***
42       * Returns a unique uuid.
43       * 
44       * @param obj the calling object (this)
45       * @return a unique uuid
46       */
47      public static String generate(Object obj) {
48          if (!s_initialized) {
49              initialize(obj);
50          }
51          long timeNow = System.currentTimeMillis();
52  
53          // get int value as unsigned
54          int timeLow = (int) timeNow & 0xFFFFFFFF;
55          int node = s_seeder.nextInt();
56          return (hexFormat(timeLow, 8) + s_midValue + hexFormat(node, 8));
57      }
58  
59      /***
60       * Initializes the factory.
61       * 
62       * @param obj
63       */
64      private synchronized static void initialize(final Object obj) {
65          try {
66              InetAddress inet = InetAddress.getLocalHost();
67              byte[] bytes = inet.getAddress();
68              String hexInetAddress = hexFormat(getInt(bytes), 8);
69              String thisHashCode = hexFormat(System.identityHashCode(obj), 8);
70              s_midValue = hexInetAddress + thisHashCode;
71              s_seeder = new SecureRandom();
72              s_seeder.nextInt();
73          } catch (java.net.UnknownHostException e) {
74              throw new Error("can not initialize the UuidGenerator generator");
75          }
76          s_initialized = true;
77      }
78  
79      /***
80       * Utility method.
81       * 
82       * @param abyte
83       * @return
84       */
85      private static int getInt(final byte[] abyte) {
86          int i = 0;
87          int j = 24;
88          for (int k = 0; j >= 0; k++) {
89              int l = abyte[k] & 0xff;
90              i += (l << j);
91              j -= 8;
92          }
93          return i;
94      }
95  
96      /***
97       * Utility method.
98       * 
99       * @param i
100      * @param j
101      * @return
102      */
103     private static String hexFormat(final int i, final int j) {
104         String s = Integer.toHexString(i);
105         return padHex(s, j) + s;
106     }
107 
108     /***
109      * Utility method.
110      * 
111      * @param str
112      * @param i
113      * @return
114      */
115     private static String padHex(final String str, final int i) {
116         StringBuffer buf = new StringBuffer();
117         if (str.length() < i) {
118             for (int j = 0; j < (i - str.length()); j++) {
119                 buf.append('0');
120             }
121         }
122         return buf.toString();
123     }
124 }