%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.turbine.util.db.UUIdGenerator |
|
|
1 | package org.apache.turbine.util.db; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-2005 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; |
|
20 | import java.io.OutputStream; |
|
21 | ||
22 | import java.util.StringTokenizer; |
|
23 | ||
24 | import javax.mail.internet.MimeUtility; |
|
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 264152 2005-08-29 14:50:22Z henning $ |
|
62 | * @deprecated Use the Unique ID Service |
|
63 | */ |
|
64 | public class UUIdGenerator |
|
65 | { |
|
66 | /** Logging */ |
|
67 | 0 | private static Log log = LogFactory.getLog(UUIdGenerator.class); |
68 | ||
69 | private static final String 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 | 0 | private byte[] address = new byte[6]; |
75 | 0 | private String baseId = null; |
76 | 0 | private int counter = 0; |
77 | ||
78 | /** |
|
79 | * Constructor |
|
80 | */ |
|
81 | public UUIdGenerator() throws TurbineException |
|
82 | 0 | { |
83 | 0 | String addr = |
84 | Turbine.getConfiguration().getString(TurbineConstants.UUID_ADDRESS_KEY); |
|
85 | ||
86 | 0 | if (StringUtils.isEmpty(addr)) |
87 | { |
|
88 | 0 | 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 | 0 | for (int i = 0; i < 6; i++) |
96 | { |
|
97 | 0 | address[i] = (byte) (255 * Math.random()); |
98 | } |
|
99 | } |
|
100 | else |
|
101 | { |
|
102 | 0 | if (addr.indexOf(".") > 0) |
103 | { |
|
104 | // we should have an IP |
|
105 | 0 | StringTokenizer stok = new StringTokenizer(addr, "."); |
106 | 0 | if (stok.countTokens() != 4) |
107 | { |
|
108 | 0 | 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 | 0 | address[0] = (byte) 255; |
115 | 0 | address[1] = (byte) 255; |
116 | 0 | int i = 2; |
117 | try |
|
118 | { |
|
119 | 0 | while (stok.hasMoreTokens()) |
120 | { |
|
121 | 0 | address[i++] = |
122 | Integer.valueOf(stok.nextToken(), |
|
123 | 16).byteValue(); |
|
124 | } |
|
125 | } |
|
126 | 0 | catch (Exception e) |
127 | { |
|
128 | 0 | throw new TurbineException(errorString + addr, e); |
129 | 0 | } |
130 | } |
|
131 | 0 | else if (addr.indexOf(":") > 0) |
132 | { |
|
133 | // we should have a MAC |
|
134 | 0 | StringTokenizer stok = new StringTokenizer(addr, ":"); |
135 | 0 | if (stok.countTokens() != 6) |
136 | { |
|
137 | 0 | throw new TurbineException(errorString + addr); |
138 | } |
|
139 | 0 | int i = 0; |
140 | try |
|
141 | { |
|
142 | 0 | while (stok.hasMoreTokens()) |
143 | { |
|
144 | 0 | address[i++] = Byte.parseByte(stok.nextToken(), 16); |
145 | } |
|
146 | } |
|
147 | 0 | catch (Exception e) |
148 | { |
|
149 | 0 | throw new TurbineException(errorString + addr, e); |
150 | 0 | } |
151 | } |
|
152 | else |
|
153 | { |
|
154 | 0 | throw new TurbineException(errorString + addr); |
155 | } |
|
156 | } |
|
157 | 0 | } |
158 | ||
159 | /** |
|
160 | * Generates the new base id |
|
161 | */ |
|
162 | private void generateNewBaseId() throws Exception |
|
163 | { |
|
164 | 0 | long now = System.currentTimeMillis(); |
165 | 0 | byte[] nowBytes = org.apache.java.lang.Bytes.toBytes(now); |
166 | 0 | ByteArrayOutputStream bas = null; |
167 | 0 | OutputStream encodedStream = null; |
168 | try |
|
169 | { |
|
170 | 0 | bas = new ByteArrayOutputStream(16); |
171 | 0 | encodedStream = MimeUtility.encode(bas, "base64"); |
172 | 0 | encodedStream.write(nowBytes); |
173 | 0 | baseId = bas.toString("ISO-8859-1"); // or maybe "US-ASCII"? |
174 | 0 | baseId = baseId.replace('/', '_'); |
175 | 0 | baseId = baseId.replace('*', '-'); |
176 | 0 | } |
177 | finally |
|
178 | { |
|
179 | 0 | if (bas != null) |
180 | { |
|
181 | 0 | bas.close(); |
182 | } |
|
183 | 0 | if (encodedStream != null) |
184 | { |
|
185 | 0 | encodedStream.close(); |
186 | } |
|
187 | 0 | } |
188 | 0 | } |
189 | ||
190 | /** |
|
191 | * Gets the id |
|
192 | * @return the 18 character id |
|
193 | */ |
|
194 | public String getId() throws Exception |
|
195 | { |
|
196 | 0 | int index = ++counter; |
197 | 0 | if (index > 4095) |
198 | { |
|
199 | 0 | synchronized (this) |
200 | { |
|
201 | 0 | if (counter > 4095) |
202 | { |
|
203 | 0 | generateNewBaseId(); |
204 | 0 | counter = 0; |
205 | } |
|
206 | else |
|
207 | { |
|
208 | 0 | index = ++counter; |
209 | } |
|
210 | 0 | } |
211 | } |
|
212 | 0 | StringBuffer idbuf = new StringBuffer(18); |
213 | 0 | idbuf.append(baseId); |
214 | 0 | idbuf.append(countChar[index / 64]); |
215 | 0 | idbuf.append(countChar[index % 64]); |
216 | 0 | return idbuf.toString(); |
217 | } |
|
218 | ||
219 | /** |
|
220 | * characters used in the ID |
|
221 | */ |
|
222 | 0 | 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 |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |