KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > turbine > util > db > UUIdGenerator


1 package org.apache.turbine.util.db;
2
3 /*
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License")
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.io.ByteArrayOutputStream JavaDoc;
20 import java.io.OutputStream JavaDoc;
21
22 import java.util.StringTokenizer JavaDoc;
23
24 import javax.mail.internet.MimeUtility JavaDoc;
25
26 import org.apache.commons.lang.StringUtils;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import org.apache.turbine.Turbine;
32 import org.apache.turbine.TurbineConstants;
33
34 import org.apache.turbine.util.TurbineException;
35
36 /**
37  * <p>This class generates universally unique id's in the form of a String.
38  * The id has three parts. The first is supposed to be location dependent.
39  * The preferred location parameter is an ethernet (MAC) address, but an IP
40  * can be used as well. if none is supplied a Math.random generated number
41  * will be used. This part of the key will be 48 bits in length.
42  * The second part of the key is time related and will be the lower 48 bits
43  * of the long used to signify the time since Jan. 1, 1970. This will
44  * cause key rollover in the year 6429.
45  * The preceding 12 bytes are Base64 encoded with the characters / and *
46  * replaced by _ (underscore) and - (dash). Resulting in 16 characters.
47  * Finally a counter is used to hand out 4095 keys in between each
48  * timestamp.
49  * The resulting id is a String of 18 characters including:
50  * a-z,A-Z,0-9, and the previously mentioned - and _.</p>
51  *
52  * <p>Note this class does not save any state information, so it is important
53  * that time only moves forward to keep the integrity of the ids. We
54  * might want to consider saving some state info.</p>
55  *
56  * <p>To specify the MAC/Ethernet address, add a uuid.address= property to the
57  * TurbineResources.properties file.</p>
58  *
59  * @author <a HREF="mailto:jmcnally@collab.net">John D. McNally</a>
60  * @author <a HREF="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
61  * @version $Id: UUIdGenerator.java,v 1.9.2.2 2004/05/20 03:18:44 seade Exp $
62  * @deprecated Use the Unique ID Service
63  */

64 public class UUIdGenerator
65 {
66     /** Logging */
67     private static Log log = LogFactory.getLog(UUIdGenerator.class);
68
69     private static final String JavaDoc errorString = "uuid.address property in "
70             + "TurbineResources.properties should be a valid IP\n "
71             + "e.g. 18.2.3.100, or an ethernet address e.g. "
72             + "AE:10:3E:de:f5:77 uuid.address was ";
73
74     private byte[] address = new byte[6];
75     private String JavaDoc baseId = null;
76     private int counter = 0;
77
78     /**
79      * Constructor
80      */

81     public UUIdGenerator() throws TurbineException
82     {
83         String JavaDoc addr =
84             Turbine.getConfiguration().getString(TurbineConstants.UUID_ADDRESS_KEY);
85
86         if (StringUtils.isEmpty(addr))
87         {
88             log.info("UUIdGenerator is using a random number as the "
89                     + "base for id's. This is not the best method for many "
90                     + "purposes, but may be adequate in some circumstances."
91                     + " Consider using an IP or ethernet (MAC) address if "
92                     + "available. Edit TurbineResources.properties file and "
93                     + "add a uuid.address= property.");
94
95             for (int i = 0; i < 6; i++)
96             {
97                 address[i] = (byte) (255 * Math.random());
98             }
99         }
100         else
101         {
102             if (addr.indexOf(".") > 0)
103             {
104                 // we should have an IP
105
StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(addr, ".");
106                 if (stok.countTokens() != 4)
107                 {
108                     throw new TurbineException(errorString + addr);
109                 }
110                 // this is meant to insure that id's made from ip addresses
111
// will not conflict with MAC id's. I think MAC addresses
112
// will never have the highest bit set. Though this should
113
// be investigated further.
114
address[0] = (byte) 255;
115                 address[1] = (byte) 255;
116                 int i = 2;
117                 try
118                 {
119                     while (stok.hasMoreTokens())
120                     {
121                         address[i++] =
122                                 Integer.valueOf(stok.nextToken(),
123                                         16).byteValue();
124                     }
125                 }
126                 catch (Exception JavaDoc e)
127                 {
128                     throw new TurbineException(errorString + addr, e);
129                 }
130             }
131             else if (addr.indexOf(":") > 0)
132             {
133                 // we should have a MAC
134
StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(addr, ":");
135                 if (stok.countTokens() != 6)
136                 {
137                     throw new TurbineException(errorString + addr);
138                 }
139                 int i = 0;
140                 try
141                 {
142                     while (stok.hasMoreTokens())
143                     {
144                         address[i++] = Byte.parseByte(stok.nextToken(), 16);
145                     }
146                 }
147                 catch (Exception JavaDoc e)
148                 {
149                     throw new TurbineException(errorString + addr, e);
150                 }
151             }
152             else
153             {
154                 throw new TurbineException(errorString + addr);
155             }
156         }
157     }
158
159     /**
160      * Generates the new base id
161      */

162     private final void generateNewBaseId() throws Exception JavaDoc
163     {
164         long now = System.currentTimeMillis();
165         byte[] nowBytes = org.apache.java.lang.Bytes.toBytes(now);
166         ByteArrayOutputStream JavaDoc bas = null;
167         OutputStream JavaDoc encodedStream = null;
168         try
169         {
170             bas = new ByteArrayOutputStream JavaDoc(16);
171             encodedStream = MimeUtility.encode(bas, "base64");
172             encodedStream.write(nowBytes);
173             baseId = bas.toString("ISO-8859-1"); // or maybe "US-ASCII"?
174
baseId = baseId.replace('/', '_');
175             baseId = baseId.replace('*', '-');
176         }
177         finally
178         {
179             if (bas != null)
180             {
181                 bas.close();
182             }
183             if (encodedStream != null)
184             {
185                 encodedStream.close();
186             }
187         }
188     }
189
190     /**
191      * Gets the id
192      * @return the 18 character id
193      */

194     public String JavaDoc getId() throws Exception JavaDoc
195     {
196         int index = ++counter;
197         if (index > 4095)
198         {
199             synchronized (this)
200             {
201                 if (counter > 4095)
202                 {
203                     generateNewBaseId();
204                     counter = 0;
205                 }
206                 else
207                 {
208                     index = ++counter;
209                 }
210             }
211         }
212         StringBuffer JavaDoc idbuf = new StringBuffer JavaDoc(18);
213         idbuf.append(baseId);
214         idbuf.append(countChar[index / 64]);
215         idbuf.append(countChar[index % 64]);
216         return idbuf.toString();
217     }
218
219     /**
220      * characters used in the ID
221      */

222     private static final char[] countChar =
223             {
224                 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
225                 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
226                 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
227                 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
228                 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
229                 '8', '9', '-', '_'
230             };
231 }
232
233
Popular Tags