-
-
Notifications
You must be signed in to change notification settings - Fork 109
/
Copy pathGenerators.java
320 lines (291 loc) · 12.3 KB
/
Generators.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/* JUG Java UUID Generator
*
* Copyright (c) 2002- Tatu Saloranta, [email protected]
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* 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 com.fasterxml.uuid;
import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;
import java.util.*;
import com.fasterxml.uuid.impl.NameBasedGenerator;
import com.fasterxml.uuid.impl.RandomBasedGenerator;
import com.fasterxml.uuid.impl.TimeBasedEpochGenerator;
import com.fasterxml.uuid.impl.TimeBasedReorderedGenerator;
import com.fasterxml.uuid.impl.TimeBasedGenerator;
/**
* Root factory class for constructing UUID generators.
*
* @author tatu
*
* @since 3.0
*/
public class Generators
{
/**
* If no explicit timer (and synchronizer it implicitly uses) is specified,
* we will create and use a single lazily-constructed timer, which uses in-JVM
* synchronization but no external file-based syncing.
*/
protected static UUIDTimer _sharedTimer;
/**
* The hardware address of the egress network interface.
*/
protected static EthernetAddress _preferredIfAddr = null;
// // Random-based generation
/**
* Factory method for constructing UUID generator that uses default (shared)
* random number generator for constructing UUIDs according to standard
* method number 4.
*/
public static RandomBasedGenerator randomBasedGenerator() {
return randomBasedGenerator(null);
}
/**
* Factory method for constructing UUID generator that uses specified
* random number generator for constructing UUIDs according to standard
* method number 4.
*/
public static RandomBasedGenerator randomBasedGenerator(Random rnd) {
return new RandomBasedGenerator(rnd);
}
// // Name-based generation
/**
* Factory method for constructing UUID generator that uses specified
* random number generator for constructing UUIDs according to standard
* method number 5, but without using a namespace.
* Digester to use will be SHA-1 as recommened by UUID spec.
*/
public static NameBasedGenerator nameBasedGenerator() {
return nameBasedGenerator(null);
}
/**
* Factory method for constructing UUID generator that uses specified
* random number generator for constructing UUIDs according to standard
* method number 5, with specified namespace (or without one if null
* is specified).
* Digester to use will be SHA-1 as recommened by UUID spec.
*
* @param namespace UUID that represents namespace to use; see
* {@link NameBasedGenerator} for 'standard' namespaces specified by
* UUID specs
*/
public static NameBasedGenerator nameBasedGenerator(UUID namespace) {
return nameBasedGenerator(namespace, null);
}
/**
* Factory method for constructing UUID generator that uses specified
* random number generator for constructing UUIDs according to standard
* method number 3 or 5, with specified namespace (or without one if null
* is specified), using specified digester.
* If digester is passed as null, a SHA-1 digester will be constructed.
*
* @param namespace UUID that represents namespace to use; see
* {@link NameBasedGenerator} for 'standard' namespaces specified by
* UUID specs
* @param digester Digester to use; should be a MD5 or SHA-1 digester.
*/
public static NameBasedGenerator nameBasedGenerator(UUID namespace, MessageDigest digester)
{
UUIDType type = null;
if (digester == null) {
ThreadLocal<MessageDigest> threadLocalDisgester = new ThreadLocal<MessageDigest>() {
@Override
protected MessageDigest initialValue() {
try {
return MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException nex) {
throw new IllegalArgumentException("Couldn't instantiate SHA-1 MessageDigest instance: "+ nex.toString());
}
}
};
digester = threadLocalDisgester.get();
type = UUIDType.NAME_BASED_SHA1;
}
return new NameBasedGenerator(namespace, digester, type);
}
// // Epoch Time+random generation
/**
* Factory method for constructing UUID generator that generates UUID using
* version 7 (Unix Epoch time+random based).
*/
public static TimeBasedEpochGenerator timeBasedEpochGenerator()
{
return timeBasedEpochGenerator(null);
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 7 (Unix Epoch time+random based), using specified {@link Random}
* number generator.
* No additional external synchronization is used.
*/
public static TimeBasedEpochGenerator timeBasedEpochGenerator(Random random)
{
return new TimeBasedEpochGenerator(random);
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 7 (Unix Epoch time+random based), using specified {@link Random}
* number generato.
* Timestamp to use is accessed using specified {@link UUIDClock}
*
* No additional external synchronization is used.
*
* @since 4.3
*/
public static TimeBasedEpochGenerator timeBasedEpochGenerator(Random random,
UUIDClock clock)
{
return new TimeBasedEpochGenerator(random, clock);
}
// // Time+location-based generation
/**
* Factory method for constructing UUID generator that generates UUID using version 1
* (time+location based). This method will use the ethernet address of the interface
* that routes to the default gateway, or if that cannot be found, then the address of
* an indeterminately selected non-loopback interface. For most simple and common
* networking configurations this will be the most appropriate address to use. The
* default interface is determined by the calling {@link
* EthernetAddress#fromPreferredInterface()} method. Note that this will only
* identify the preferred interface once: if you have a complex network setup where
* your outbound routes/interfaces may change dynamically. If you want your UUIDs to
* accurately reflect a deterministic selection of network interface, you should
* instead use a generator implementation that uses an explicitly specified address,
* such as {@link #timeBasedGenerator(EthernetAddress)}.
*
* @since 4.2
*/
public static TimeBasedGenerator defaultTimeBasedGenerator()
{
return timeBasedGenerator(preferredInterfaceAddress());
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 1 (time+location based).
* Since no Ethernet address is passed, a bogus broadcast address will be
* constructed for purpose of UUID generation; usually it is better to
* instead access one of host's NIC addresses using
* {@link EthernetAddress#fromInterface} which will use one of available
* MAC (Ethernet) addresses available.
*/
public static TimeBasedGenerator timeBasedGenerator()
{
return timeBasedGenerator(null);
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 1 (time+location based), using specified Ethernet address
* as the location part of UUID.
* No additional external synchronization is used.
*/
public static TimeBasedGenerator timeBasedGenerator(EthernetAddress ethernetAddress)
{
return timeBasedGenerator(ethernetAddress, (UUIDTimer) null);
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 1 (time+location based), using specified Ethernet address
* as the location part of UUID, and specified synchronizer (which may add
* additional restrictions to guarantee system-wide uniqueness).
*
* @param ethernetAddress (optional) MAC address to use; if null, a transient
* random address is generated.
*
* @see com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer
*/
public static TimeBasedGenerator timeBasedGenerator(EthernetAddress ethernetAddress,
TimestampSynchronizer sync)
{
UUIDTimer timer;
try {
timer = new UUIDTimer(new Random(System.currentTimeMillis()), sync);
} catch (IOException e) {
throw new IllegalArgumentException("Failed to create UUIDTimer with specified synchronizer: "+e.getMessage(), e);
}
return timeBasedGenerator(ethernetAddress, timer);
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 1 (time+location based), using specified Ethernet address
* as the location part of UUID, and specified {@link UUIDTimer} instance
* (which includes embedded synchronizer that defines synchronization behavior).
*/
public static TimeBasedGenerator timeBasedGenerator(EthernetAddress ethernetAddress,
UUIDTimer timer)
{
if (timer == null) {
timer = sharedTimer();
}
return new TimeBasedGenerator(ethernetAddress, timer);
}
// // DB Locality Time+location-based generation
/**
* Factory method for constructing UUID generator that generates UUID using
* version 6 (time+location based, reordered for DB locality). Since no Ethernet
* address is passed, a bogus broadcast address will be constructed for purpose
* of UUID generation; usually it is better to instead access one of host's NIC
* addresses using {@link EthernetAddress#fromInterface} which will use one of
* available MAC (Ethernet) addresses available.
*/
public static TimeBasedReorderedGenerator timeBasedReorderedGenerator()
{
return timeBasedReorderedGenerator(null);
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 6 (time+location based, reordered for DB locality), using specified
* Ethernet address as the location part of UUID. No additional external
* synchronization is used.
*/
public static TimeBasedReorderedGenerator timeBasedReorderedGenerator(EthernetAddress ethernetAddress)
{
return timeBasedReorderedGenerator(ethernetAddress, (UUIDTimer) null);
}
/**
* Factory method for constructing UUID generator that generates UUID using
* version 6 (time+location based, reordered for DB locality), using specified
* Ethernet address as the location part of UUID, and specified
* {@link UUIDTimer} instance (which includes embedded synchronizer that defines
* synchronization behavior).
*/
public static TimeBasedReorderedGenerator timeBasedReorderedGenerator(EthernetAddress ethernetAddress,
UUIDTimer timer)
{
if (timer == null) {
timer = sharedTimer();
}
return new TimeBasedReorderedGenerator(ethernetAddress, timer);
}
/*
/**********************************************************************
/* Internal methods
/**********************************************************************
*/
private static synchronized UUIDTimer sharedTimer()
{
if (_sharedTimer == null) {
try {
_sharedTimer = new UUIDTimer(new java.util.Random(System.currentTimeMillis()), null);
} catch (IOException e) {
throw new IllegalArgumentException("Failed to create UUIDTimer with specified synchronizer: "+e.getMessage(), e);
}
}
return _sharedTimer;
}
private static synchronized EthernetAddress preferredInterfaceAddress()
{
if (_preferredIfAddr == null) {
_preferredIfAddr = EthernetAddress.fromPreferredInterface();
}
return _preferredIfAddr;
}
}