]> sjero.net Git - linphone/blob - p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/UUIDFactory.java
remove mediastreamer2 and add it as a submodule instead.
[linphone] / p2pproxy / dependencies-src / jxse-src-2.5 / impl / src / net / jxta / impl / id / UUID / UUIDFactory.java
1 /*
2  * Copyright (c) 2001-2007 Sun Microsystems, Inc.  All rights reserved.
3  *  
4  *  The Sun Project JXTA(TM) Software License
5  *  
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions are met:
8  *  
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  
12  *  2. Redistributions in binary form must reproduce the above copyright notice, 
13  *     this list of conditions and the following disclaimer in the documentation 
14  *     and/or other materials provided with the distribution.
15  *  
16  *  3. The end-user documentation included with the redistribution, if any, must 
17  *     include the following acknowledgment: "This product includes software 
18  *     developed by Sun Microsystems, Inc. for JXTA(TM) technology." 
19  *     Alternately, this acknowledgment may appear in the software itself, if 
20  *     and wherever such third-party acknowledgments normally appear.
21  *  
22  *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must 
23  *     not be used to endorse or promote products derived from this software 
24  *     without prior written permission. For written permission, please contact 
25  *     Project JXTA at http://www.jxta.org.
26  *  
27  *  5. Products derived from this software may not be called "JXTA", nor may 
28  *     "JXTA" appear in their name, without prior written permission of Sun.
29  *  
30  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
32  *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN 
33  *  MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
34  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
36  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
37  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
38  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
39  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *  
41  *  JXTA is a registered trademark of Sun Microsystems, Inc. in the United 
42  *  States and other countries.
43  *  
44  *  Please see the license information page at :
45  *  <http://www.jxta.org/project/www/license.html> for instructions on use of 
46  *  the license in source files.
47  *  
48  *  ====================================================================
49  *  
50  *  This software consists of voluntary contributions made by many individuals 
51  *  on behalf of Project JXTA. For more information on Project JXTA, please see 
52  *  http://www.jxta.org.
53  *  
54  *  This license is based on the BSD license adopted by the Apache Foundation. 
55  */
56
57 package net.jxta.impl.id.UUID;
58
59
60 import java.security.SecureRandom;
61 import java.util.GregorianCalendar;
62 import java.util.Random;
63 import java.util.Calendar;
64 import java.util.TimeZone;
65
66 import java.util.logging.Logger;
67 import java.util.logging.Level;
68 import net.jxta.logging.Logging;
69
70
71 /**
72  * A Factory for generating random UUIDs.
73  *
74  * @see         net.jxta.impl.id.UUID.UUID
75  */
76 public final class UUIDFactory {
77     
78     /**
79      *  Log4J Logger
80      */
81     private static final transient Logger LOG = Logger.getLogger(UUIDFactory.class.getName());
82     
83     /**
84      * The point at which the Gregorian calendar rules are used, measured in
85      * milliseconds from the standard epoch.  Default is October 15, 1582
86      * (Gregorian) 00:00:00 UTC or -12219292800000L.
87      */
88     static final long GREGORIAN_MILLIS_OFFSET = 12219292800000L;
89     
90     /**
91      *  offset of this computer relative to utc
92      */
93     private long utc_offset = 0L;
94     
95     /**
96      *  Time at which we last generated a version 1 UUID in relative
97      *  milliseconds from 00:00:00.00, 15 October 1582 UTC.
98      */
99     private long lastTimeSequence = 0L;
100     
101     /**
102      *   Count of how many version 1 UUIDs we have generated at this time
103      *  sequence value.
104      */
105     private long inSequenceCounter = 0L;
106     
107     /**
108      *  pseudo random value to prevent clock collisions on the same computer.
109      */
110     private long clock_seq = 0L;
111     
112     /**
113      *  pseudo random value. If available, this should be seeded with the MAC
114      *  address of a local network interface.
115      */
116     private long node = 0L;
117     
118     /**
119      *  Random number generator for UUID generation.
120      */
121     private Random randNum = null;
122     
123     /**
124      *  We have to catch exceptions from construct of JRandom so we
125      *  have to init it inline.
126      */
127     private static UUIDFactory factory = new UUIDFactory();
128     
129     /**
130      *  Generate a new random UUID value. The UUID returned is a version 4 IETF
131      *  variant random UUID.
132      *
133      *  <p/>This member must be synchronized because it makes use of shared
134      *  internal state.
135      *
136      *  @return UUID returns a version 4 IETF variant random UUID.
137      */
138     public synchronized static UUID newUUID() {
139         
140         return newUUID(factory.randNum.nextLong(), factory.randNum.nextLong());
141     }
142     
143     /**
144      *  Returns a formatted time sequence field containing the elapsed time in
145      *  100 nano units since 00:00:00.00, 15 October 1582. Since the normal
146      *  clock resolution is coarser than 100 nano than this value, the lower
147      *  bits are generated in sequence for each call within the same milli.
148      *
149      *  @return time sequence value
150      */
151     private synchronized long getTimeSequence() {
152         long now = (System.currentTimeMillis() - GREGORIAN_MILLIS_OFFSET + utc_offset) * 10000L; // convert to 100 nano units;
153         
154         if (now > lastTimeSequence) {
155             lastTimeSequence = now;
156             // XXX bondolo@jxta.org It might be better to set this to a random
157             // value and just watch for rollover. The reason is that there may
158             // be more than one instance running on the same computer which is
159             // generating UUIDs, but is not excluded by our synchronization.
160             // A random value would reduce collisions.
161             inSequenceCounter = 0;
162         } else {
163             inSequenceCounter++;
164             if (inSequenceCounter >= 10000L) {
165                 // we allow the clock to skew forward rather than wait. It's
166                 // really unlikely that anyone will be continuously generating
167                 // more than 10k UUIDs per milli for very long.
168                 lastTimeSequence += 10000L;
169                 inSequenceCounter = 0;
170             }
171         }
172         
173         return (lastTimeSequence + inSequenceCounter);
174     }
175     
176     /**
177      *  Generate a new UUID value. The UUID returned is a version 1 IETF
178      *  variant UUID.
179      *
180      *  <p/>The node value used is currently a random value rather than the
181      *  normal ethernet MAC address because the MAC address is not directly
182      *  accessible in to java.
183      *
184      *  @return UUID returns a version 1 IETF variant UUID.
185      */
186     public static UUID newSeqUUID() {
187         long mostSig = 0L, leastSig = 0L;
188         
189         long timeSeq = factory.getTimeSequence();
190         
191         mostSig |= (timeSeq & 0x0FFFFFFFFL) << 32;
192         mostSig |= ((timeSeq >> 32) & 0x0FFFFL) << 16;
193         mostSig |= (0x01L) << 12; // version 1;
194         mostSig |= ((timeSeq >> 48) & 0x00FFFL);
195         
196         leastSig |= (0x02L) << 62; // ietf variant
197         leastSig |= ((factory.clock_seq >> 8) & 0x03FL) << 56;
198         leastSig |= (factory.clock_seq & 0x0FFL) << 48;
199         leastSig |= factory.node & 0x0FFFFFFFFFFFFL;
200         
201         return new UUID(mostSig, leastSig);
202     }
203     
204     /**
205      *  Generate a new UUID value. The values provided are masked to produce a
206      *  version 4 IETF variant random UUID.
207      *
208      *  @param bytes the 128 bits of the UUID
209      *  @return UUID returns a version 4 IETF variant random UUID.
210      */
211     public static UUID newUUID(byte[] bytes) {
212         if (bytes.length != 16) {
213             throw new IllegalArgumentException("bytes must be 16 bytes in length");
214         }
215         
216         long mostSig = 0;
217
218         for (int i = 0; i < 8; i++) {
219             mostSig = (mostSig << 8) | (bytes[i] & 0xff);
220         }
221         
222         long leastSig = 0;
223
224         for (int i = 8; i < 16; i++) {
225             leastSig = (leastSig << 8) | (bytes[i] & 0xff);
226         }
227         
228         return newUUID(mostSig, leastSig);
229     }
230     
231     /**
232      *  Generate a new UUID value. The values provided are masked to produce a
233      *  version 3 IETF variant UUID.
234      *
235      *  @param mostSig High-long of UUID value.
236      *  @param leastSig Low-long of UUID value.
237      *  @return UUID returns a version 3 IETF variant random UUID.
238      */
239     public static UUID newHashUUID(long mostSig, long leastSig) {
240         
241         mostSig &= 0xFFFFFFFFFFFF0FFFL;
242         mostSig |= 0x0000000000003000L; // version 3
243         leastSig &= 0x3FFFFFFFFFFFFFFFL;
244         leastSig |= 0x8000000000000000L; // IETF variant
245         
246         return new UUID(mostSig, leastSig);
247     }
248     
249     /**
250      *  Generate a new UUID value. The values provided are masked to produce a
251      *  version 4 IETF variant random UUID.
252      *
253      *  @param mostSig High-long of UUID value.
254      *  @param leastSig Low-long of UUID value.
255      *  @return UUID returns a version 4 IETF variant random UUID.
256      */
257     public static UUID newUUID(long mostSig, long leastSig) {
258         
259         mostSig &= 0xFFFFFFFFFFFF0FFFL;
260         mostSig |= 0x0000000000004000L; // version 4
261         leastSig &= 0x3FFFFFFFFFFFFFFFL;
262         leastSig |= 0x8000000000000000L; // IETF variant
263         
264         leastSig &= 0xFFFF7FFFFFFFFFFFL;
265         leastSig |= 0x0000800000000000L; // multicast bit
266         
267         return new UUID(mostSig, leastSig);
268     }
269     
270     /**
271      *  Singleton class
272      */
273     private UUIDFactory() {
274         
275         randNum = new SecureRandom();
276         
277         String[] tz_ids = TimeZone.getAvailableIDs(0);
278         Calendar gregorianCalendar = new GregorianCalendar();
279         
280         // FIXME 20031024 bondolo@jxta.org In theory we should be doing this
281         // EVERY time we generate a UUID. In practice because of we use a random
282         // clock_seq we don't have to.
283         utc_offset = gregorianCalendar.get(Calendar.ZONE_OFFSET) + gregorianCalendar.get(Calendar.DST_OFFSET);
284         
285         // Generate a random clock seq
286         clock_seq = randNum.nextInt() & 0x03FFL;
287         
288         // Generate a random node ID since we can't get the MAC Address
289         node = (randNum.nextLong() & 0x0000FFFFFFFFFFFFL);
290         node |= 0x0000800000000000L; // mask in the multicast bit since we don't know if its unique.
291     }
292 }