Source Code Cross Referenced for AUID.java in  » Database-ORM » JPOX » org » jpox » store » poid » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » JPOX » org.jpox.store.poid 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**********************************************************************
0002:        Copyright (c) 2004 Ralf Ullrich and others. All rights reserved. 
0003:        Licensed under the Apache License, Version 2.0 (the "License");
0004:        you may not use this file except in compliance with the License.
0005:        You may obtain a copy of the License at
0006:
0007:            http://www.apache.org/licenses/LICENSE-2.0
0008:
0009:        Unless required by applicable law or agreed to in writing, software
0010:        distributed under the License is distributed on an "AS IS" BASIS,
0011:        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012:        See the License for the specific language governing permissions and
0013:        limitations under the License.
0014:         
0015:
0016:        Contributors:
0017:        ...
0018:         **********************************************************************/package org.jpox.store.poid;
0019:
0020:        import java.util.Date;
0021:        import java.util.GregorianCalendar;
0022:        import java.util.Random;
0023:
0024:        import org.jpox.util.JPOXLogger;
0025:
0026:        /**
0027:         * An almost unique ID.
0028:         * 
0029:         * This class represents a best possible derivate of a DCE UUID as is possible
0030:         * with the standard Java API, which provides no way to determine the IEEE 802
0031:         * address of a system and only provides a time with a granularity of
0032:         * milliseconds instead of the required 100nanoseconds.
0033:         * 
0034:         * It therefore uses random node values and also does not use non-volatile
0035:         * storage for internal state fields.
0036:         * 
0037:         * The uuid is internally stored as two 64 bit long values. This allows a fast
0038:         * implementation of the <code>equals</code> method, but provides possibly
0039:         * poor performance for the <code>compare</code> method due to the required
0040:         * unpacking of the data.
0041:         * 
0042:         * To create "real" UUIDs the default implementations of <code>loadState</code>
0043:         * and <code>saveState</code> have to be overridden to provide hardware
0044:         * derived node values and non-volatile generator state storage. The first is
0045:         * not possible with Java's standard API and there is no standard way to do the
0046:         * latter, therefore this class was called AUID = "almost unique id", as it
0047:         * tries to circumvent these short comings by random initializations.
0048:         * 
0049:         * Note: Due to the construction of the time stamp included in an AUID as a
0050:         * 60-bit value of 100-nanosecond intervals since 00:00:00.00, 15 October 1582
0051:         * (the date of Gregorian reform to the Christian Calendar), this implementation
0052:         * will break due to field overflow on 23:21:00 CEST of March 31st in the year
0053:         * 5236, that is when we are long gone and became ashes.
0054:         * 
0055:         * @version $Revision: 1.4 $
0056:         */
0057:        class AUID implements  Comparable {
0058:            /**
0059:             * This class represents the current state of the AUID generator.
0060:             */
0061:            protected static class State {
0062:                /** The last time stamp used to create a AUID. */
0063:                private long lastTime;
0064:                /**
0065:                 * The time adjustment to be added to the last time stamp to create the
0066:                 * next AUID.
0067:                 */
0068:                private long adjustTime;
0069:                /** The current clock sequence. */
0070:                private int clockSequence;
0071:                /** The node value. */
0072:                private long node;
0073:                /** The version to use when constructing new AUIDs. */
0074:                private int version;
0075:                /** The variant to use when constructing new AUIDs. */
0076:                private int variant;
0077:                /** A random generator to be use for random initialization of fields. */
0078:                private Random random;
0079:                /**
0080:                 * A flag indicating if security attributes should be included in time
0081:                 * low field.
0082:                 */
0083:                private boolean includeSecurityAttributes;
0084:
0085:                /**
0086:                 * Sets the last time stamp used to create an AUID.
0087:                 * 
0088:                 * @param lastTime
0089:                 *            the last time stamp used to create an AUID.
0090:                 */
0091:                public void setLastTime(long lastTime) {
0092:                    this .lastTime = lastTime;
0093:                }
0094:
0095:                /**
0096:                 * Returns the last time stamp used to create an AUID.
0097:                 * 
0098:                 * @return the last time stamp used to create an AUID.
0099:                 */
0100:                public long getLastTime() {
0101:                    return lastTime;
0102:                }
0103:
0104:                /**
0105:                 * Sets the time adjustment to be added to the last time stamp to create
0106:                 * the next AUID.
0107:                 * 
0108:                 * @param adjustTime
0109:                 *            The time adjustment to be added to the last time stamp to
0110:                 *            create the next AUID.
0111:                 */
0112:                public void setAdjustTime(long adjustTime) {
0113:                    this .adjustTime = adjustTime;
0114:                }
0115:
0116:                /**
0117:                 * Returns the time adjustment to be added to the last time stamp to
0118:                 * create the next AUID.
0119:                 * 
0120:                 * @return The time adjustment to be added to the last time stamp to
0121:                 *         create the next AUID.
0122:                 */
0123:                public long getAdjustTime() {
0124:                    return adjustTime;
0125:                }
0126:
0127:                /**
0128:                 * Returns the time adjustment to be added to the last time stamp to
0129:                 * create the next AUID and increments it.
0130:                 * 
0131:                 * @return The time adjustment to be added to the last time stamp to
0132:                 *         create the next AUID before incrementation.
0133:                 */
0134:                public long incrementAdjustTime() {
0135:                    return adjustTime++;
0136:                }
0137:
0138:                /**
0139:                 * Sets the current clock sequence.
0140:                 * 
0141:                 * @param clockSequence
0142:                 *            the current clock sequence.
0143:                 */
0144:                public void setClockSequence(int clockSequence) {
0145:                    this .clockSequence = clockSequence;
0146:                }
0147:
0148:                /**
0149:                 * Returns the current clock sequence.
0150:                 * 
0151:                 * @return the current clock sequence.
0152:                 */
0153:                public int getClockSequence() {
0154:                    return clockSequence;
0155:                }
0156:
0157:                /**
0158:                 * Set the node value.
0159:                 * 
0160:                 * @param node
0161:                 *            the node value.
0162:                 */
0163:                public void setNode(long node) {
0164:                    this .node = node;
0165:                }
0166:
0167:                /**
0168:                 * Returns the node value.
0169:                 * 
0170:                 * @return the node value.
0171:                 */
0172:                public long getNode() {
0173:                    return node;
0174:                }
0175:
0176:                /**
0177:                 * Sets the version to use when constructing new AUIDs.
0178:                 * 
0179:                 * @param version
0180:                 *            the version to use when constructing new AUIDs.
0181:                 */
0182:                public void setVersion(int version) {
0183:                    this .version = version;
0184:                }
0185:
0186:                /**
0187:                 * Returns the version to use when constructing new AUIDs.
0188:                 * 
0189:                 * @return the version to use when constructing new AUIDs.
0190:                 */
0191:                public int getVersion() {
0192:                    return version;
0193:                }
0194:
0195:                /**
0196:                 * Sets the variant to use when constructing new AUIDs.
0197:                 * 
0198:                 * @param variant
0199:                 *            the variant to use when constructing new AUIDs.
0200:                 */
0201:                public void setVariant(int variant) {
0202:                    this .variant = variant;
0203:                }
0204:
0205:                /**
0206:                 * Returns the variant to use when constructing new AUIDs.
0207:                 * 
0208:                 * @return the variant to use when constructing new AUIDs.
0209:                 */
0210:                public int getVariant() {
0211:                    return variant;
0212:                }
0213:
0214:                /**
0215:                 * Sets the random generator used for initialization of fields.
0216:                 * 
0217:                 * @param random
0218:                 *            the random generator to use for initialization of fields.
0219:                 */
0220:                public void setRandom(Random random) {
0221:                    this .random = random;
0222:                }
0223:
0224:                /**
0225:                 * Returns the random generator used for initialization of fields.
0226:                 * 
0227:                 * @return the random generator used for initialization of fields.
0228:                 */
0229:                public Random getRandom() {
0230:                    return random;
0231:                }
0232:
0233:                /**
0234:                 * Sets if security attributes have to be included in time low field.
0235:                 * 
0236:                 * @param includeSecurityAttributes
0237:                 *            if <code>true</code> security attributes will included.
0238:                 */
0239:                public void setIncludeSecurityAttributes(
0240:                        boolean includeSecurityAttributes) {
0241:                    this .includeSecurityAttributes = includeSecurityAttributes;
0242:                }
0243:
0244:                /**
0245:                 * Returns wether security attribute have to be included.
0246:                 * 
0247:                 * @return <code>true</code> if security attributes have to be
0248:                 *         included.
0249:                 */
0250:                public boolean getIncludeSecurityAttributes() {
0251:                    return includeSecurityAttributes;
0252:                }
0253:            }
0254:
0255:            // These two are commented out since not enabled in the code
0256:            //  private static final int VERSION_DCE = 1;
0257:            //  private static final int VERSION_DCE_SECURE = 2;
0258:
0259:            private static final int VERSION_RANDOM_NODE = 3;
0260:            private static final int VARIANT_NCS = 0x0000;
0261:            private static final int VARIANT_DCE = 0x8000;
0262:            private static final int VARIANT_MICROSOFT = 0xc000;
0263:            private static final int VARIANT_RESERVED = 0xe000;
0264:            private static final int CS_MASK_NCS = 0x7fff;
0265:            private static final int CS_MASK_DCE = 0x3fff;
0266:            private static final int CS_MASK_MICROSOFT = 0x1fff;
0267:            private static final int CS_MASK_RESERVED = 0x1fff;
0268:            private static final long MAXIMUM_ENTROPIC_TIME_MS = 5000;
0269:
0270:            /**
0271:             * Scale from System.currentTimeMillis() granularity to that of AUID.
0272:             */
0273:            private static final long TIME_SCALE = 10000;
0274:
0275:            /**
0276:             * The offset between UTC and the AUID timestamps in 100-nanosecond
0277:             * intervals since 00:00:00.00, 15 October 1582 (the date of Gregorian
0278:             * reform to the Christian Calendar).
0279:             */
0280:            private static final long UTC_OFFSET = new GregorianCalendar()
0281:                    .getGregorianChange().getTime()
0282:                    * TIME_SCALE;
0283:            /**
0284:             * An array of chars for Hex conversion.
0285:             */
0286:            private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4',
0287:                    '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
0288:
0289:            /**
0290:             * The state of the AUID generator.
0291:             */
0292:            private static State auidState = null;
0293:
0294:            /**
0295:             * The first 64 bits of the uuid value.
0296:             */
0297:            private long firstHalf;
0298:
0299:            /**
0300:             * The last 64 bits of the uuid value.
0301:             */
0302:            private long secondHalf;
0303:
0304:            /**
0305:             * Constructs an AUID with new values.
0306:             */
0307:            public AUID() {
0308:                makeUnique(0, false);
0309:            }
0310:
0311:            /**
0312:             * Constructs an AUID with new values and the specified security attributes.
0313:             * The subclass which calls this constructor MUST set the state accordingly.
0314:             * 
0315:             * @param securityAttributes
0316:             *            the security attributes to include in the new AUID.
0317:             */
0318:            protected AUID(int securityAttributes) {
0319:                makeUnique(securityAttributes, true);
0320:            }
0321:
0322:            /**
0323:             * Constructs an AUID from the specified values. This constructor is for
0324:             * subclasses only and should not be made available to API users.
0325:             * 
0326:             * @param time
0327:             *            the time field of the new AUID
0328:             * @param version
0329:             *            the version of the new AUID
0330:             * @param clockSeq
0331:             *            the clock sequence of the new AUID
0332:             * @param variant
0333:             *            the variant of the new AUID
0334:             * @param node
0335:             *            the node of the new AUID
0336:             */
0337:            protected AUID(long time, int version, int clockSeq, int variant,
0338:                    long node) {
0339:                packFirstHalf(time, version);
0340:                packSecondHalf(clockSeq, variant, node);
0341:            }
0342:
0343:            /**
0344:             * Constructs an AUID from the specified original DCE field values. This
0345:             * constructor is for subclasses only and should not be made available to
0346:             * API users.
0347:             * 
0348:             * @param timeLow
0349:             *            the time low field of the new AUID
0350:             * @param timeMid
0351:             *            the time mid field of the new AUID
0352:             * @param timeHiAndVersion
0353:             *            the packed time high and version field of the new AUID
0354:             * @param clockSeqHiAndVariant
0355:             *            the packed clock sequence high and variant field of the new
0356:             *            AUID
0357:             * @param clockSeqLow
0358:             *            the clock sequence low field of the new AUID
0359:             * @param node
0360:             *            the node field of the new AUID
0361:             */
0362:            protected AUID(long timeLow, long timeMid, long timeHiAndVersion,
0363:                    int clockSeqHiAndVariant, int clockSeqLow, long node) {
0364:                packDCEFieldsFirstHalf(timeLow, timeMid, timeHiAndVersion);
0365:                packDCEFieldsSecondHalf(clockSeqHiAndVariant, clockSeqLow, node);
0366:            }
0367:
0368:            /**
0369:             * Constructs an AUID with the same values as the specified AUID.
0370:             * 
0371:             * @param auid
0372:             *            the AUID to clone
0373:             */
0374:            protected AUID(AUID auid) {
0375:                firstHalf = auid.firstHalf;
0376:                secondHalf = auid.secondHalf;
0377:            }
0378:
0379:            /**
0380:             * Constructs an AUID from the specified string representation.
0381:             * 
0382:             * @param auid string in the format "LLLLLLLL-MMMM-HHHH-CCCC-NNNNNNNNNNNN"
0383:             * @throws NumberFormatException
0384:             *             if <code>auid</code> does not match the pattern
0385:             *             "LLLLLLLL-MMMM-HHHH-CCCC-NNNNNNNNNNNN" where 'L', 'M', 'H',
0386:             *             'C' and 'N' are time low, mid, high, clock sequence and node
0387:             *             fields respectively.
0388:             *            a string representation of an AUID
0389:             */
0390:            public AUID(String auid) {
0391:                try {
0392:                    firstHalf = parseFirstHalf(auid.subSequence(0, 18));
0393:                    secondHalf = parseSecondHalf(auid.subSequence(18, 36));
0394:                } catch (IndexOutOfBoundsException ioobe) {
0395:                    throw new NumberFormatException();
0396:                } catch (NumberFormatException nfe) {
0397:                    throw new NumberFormatException();
0398:                }
0399:            }
0400:
0401:            /**
0402:             * Constructs an AUID from the specified string representation in
0403:             * CharSequence.
0404:             * 
0405:             * @param auid
0406:             *            a string representation of an AUID
0407:             * @throws NumberFormatException
0408:             *             if <code>auid</code> does not match the pattern
0409:             *             "LLLLLLLL-MMMM-HHHH-CCCC-NNNNNNNNNNNN" where 'L', 'M', 'H',
0410:             *             'C' and 'N' are time low, mid, high, clock sequence and node
0411:             *             fields respectively.
0412:             */
0413:            public AUID(CharSequence auid) {
0414:                try {
0415:                    firstHalf = parseFirstHalf(auid.subSequence(0, 18));
0416:                    secondHalf = parseSecondHalf(auid.subSequence(18, 36));
0417:                } catch (IndexOutOfBoundsException ioobe) {
0418:                    throw new NumberFormatException();
0419:                } catch (NumberFormatException nfe) {
0420:                    throw new NumberFormatException();
0421:                }
0422:            }
0423:
0424:            /**
0425:             * Constructs an AUID from the specified byte array representation, which is
0426:             * in the same format as returned by <code>getBytes(dst, dstBegin)</code>.
0427:             * This constructor is equal to <code>AUID(bytes, 0)</code>.
0428:             * 
0429:             * @param bytes
0430:             *            a byte array representation of an AUID
0431:             */
0432:            public AUID(byte[] bytes) {
0433:                this (bytes, 0);
0434:            }
0435:
0436:            /**
0437:             * Constructs an AUID from the specified byte array representation, which is
0438:             * in the same format as returned by <code>getBytes(dst, dstBegin)</code>.
0439:             * 
0440:             * @param bytes
0441:             *            a byte array representation of an AUID
0442:             * @param offset
0443:             *            the offset at which the byte array representation is located
0444:             *            in the byte array.
0445:             */
0446:            public AUID(byte[] bytes, int offset) {
0447:                long timeLow = getOctets(4, bytes, 0 + offset, true);
0448:                long timeMid = getOctets(2, bytes, 4 + offset, true);
0449:                long timeHAV = getOctets(2, bytes, 6 + offset, true);
0450:                int csHAV = (int) getOctets(1, bytes, 8 + offset, true);
0451:                int csLow = (int) getOctets(1, bytes, 9 + offset, true);
0452:                long node = getOctets(6, bytes, 10 + offset, true);
0453:                packDCEFieldsFirstHalf(timeLow, timeMid, timeHAV);
0454:                packDCEFieldsSecondHalf(csHAV, csLow, node);
0455:            }
0456:
0457:            /**
0458:             * Parse a String representation of an AUID. Equal to
0459:             * <code>new AUID(auid)</code>.
0460:             * 
0461:             * @param auid
0462:             *            a string representation of an AUID
0463:             * @return the AUID represented by <code>auid</code>.
0464:             * @throws NumberFormatException
0465:             *             if <code>auid</code> does not match the pattern
0466:             *             "LLLLLLLL-MMMM-HHHH-CCCC-NNNNNNNNNNNN" where 'L', 'M', 'H',
0467:             *             'C' and 'N' are time low, mid, high, clock sequence and node
0468:             *             fields respectively.
0469:             */
0470:            public static AUID parse(String auid) {
0471:                return new AUID(auid);
0472:            }
0473:
0474:            /**
0475:             * Parse a String representation of an AUID. Equal to
0476:             * <code>new AUID(auid)</code>.
0477:             * 
0478:             * @param auid string in the format "LLLLLLLL-MMMM-HHHH-CCCC-NNNNNNNNNNNN"
0479:             * @return the AUID represented by <code>auid</code>.
0480:             * @throws NumberFormatException
0481:             *             if <code>auid</code> does not match the pattern
0482:             *             "LLLLLLLL-MMMM-HHHH-CCCC-NNNNNNNNNNNN" where 'L', 'M', 'H',
0483:             *             'C' and 'N' are time low, mid, high, clock sequence and node
0484:             *             fields respectively.
0485:             *            a string representation of an AUID
0486:             */
0487:            public static AUID parse(CharSequence auid) {
0488:                return new AUID(auid);
0489:            }
0490:
0491:            /**
0492:             * Identifies the variant from the combined clock sequence and variant
0493:             * value, as it is returned by <code>getClockSeqAndVariant()</code>.
0494:             * 
0495:             * May be overridden to support new variants.
0496:             * 
0497:             * @param clockSeqAndVariant
0498:             *            the combined clock sequence and variant value, as it is
0499:             *            returned by <code>getClockSeqAndVariant()</code>.
0500:             * @return the variant identified in the specified combined value.
0501:             * @throws IllegalArgumentException
0502:             *             if variant could not be identified.
0503:             */
0504:            protected int identifyVariant(int clockSeqAndVariant) {
0505:                if ((clockSeqAndVariant & ~CS_MASK_NCS) == VARIANT_NCS) {
0506:                    return VARIANT_NCS;
0507:                }
0508:                if ((clockSeqAndVariant & ~CS_MASK_DCE) == VARIANT_DCE) {
0509:                    return VARIANT_DCE;
0510:                }
0511:                if ((clockSeqAndVariant & ~CS_MASK_MICROSOFT) == VARIANT_MICROSOFT) {
0512:                    return VARIANT_NCS;
0513:                }
0514:                if ((clockSeqAndVariant & ~CS_MASK_RESERVED) == VARIANT_RESERVED) {
0515:                    return VARIANT_RESERVED;
0516:                }
0517:                // should not occur
0518:                throw new IllegalArgumentException();
0519:            }
0520:
0521:            /**
0522:             * This returns the bit mask to be applied to a clock sequence before it is
0523:             * ORed with the variant value.
0524:             * 
0525:             * May be overridden to support new variants.
0526:             * 
0527:             * @param variant
0528:             *            the variant for which the mask shall be returned.
0529:             * @return the mask to apply to a sequence when combining values.
0530:             */
0531:            public int getClockSeqMaskForVariant(int variant) {
0532:                switch (variant) {
0533:                case VARIANT_NCS:
0534:                    return CS_MASK_NCS;
0535:                case VARIANT_DCE:
0536:                    return CS_MASK_DCE;
0537:                case VARIANT_MICROSOFT:
0538:                    return CS_MASK_MICROSOFT;
0539:                case VARIANT_RESERVED:
0540:                    return CS_MASK_RESERVED;
0541:                default:
0542:                    throw new IllegalArgumentException();
0543:                }
0544:            }
0545:
0546:            /**
0547:             * Returns the current time as 100-nanosecond intervals since 00:00:00.00,
0548:             * 15 October 1582 (the date of Gregorian reform to the Christian Calendar).
0549:             * This may be overridden to support high resolution time devices.
0550:             * 
0551:             * @return a time stamp for use in an AUID
0552:             */
0553:            protected long getCurrentTime() {
0554:                return System.currentTimeMillis() * TIME_SCALE - UTC_OFFSET;
0555:            }
0556:
0557:            /**
0558:             * Loads the generator state from non-volatile storage into the provided
0559:             * State object or creates a new one if <code>null</code>.
0560:             * 
0561:             * Overriding this method allows to actually add persistent storage
0562:             * facilities for the generator state and may also support non-random node
0563:             * that have been retrieved from the hardware. <br />
0564:             * To override this method follow this pattern:
0565:             * 
0566:             * <pre>
0567:             * protected State loadState(State state)
0568:             * {
0569:             *     State loadInto = state;
0570:             *     if (loadInto == null)
0571:             *     {
0572:             *         if (staticStateField == null)
0573:             *         {
0574:             *             loadInto = staticStateField = new State();
0575:             *         }
0576:             *         state = staticStateField;
0577:             *     }
0578:             *     if (loadInto != null)
0579:             *     {
0580:             *         if (loadInto.random == null)
0581:             *         {
0582:             *             // set loadInto.random to a customized Random generator if possible
0583:             *             // YOUR CODE TO SET RANDOM GENERATOR GOES HERE (OPTIONAL)
0584:             *         }
0585:             *         // call super implementation to initialize with defaults.
0586:             *         super(loadInto);
0587:             *         // load state into loadInto (consider to use getClass() to distinguish
0588:             *         // between multiple stored versions).
0589:             *         // always load lastTime and adjustTime
0590:             *         // load clock sequence only if node value is retrieved from hardware that
0591:             *         // cannot be moved to another system and is guaranteed to be unique between
0592:             *         // different systems
0593:             *         // Do not modify the above values if loading failed (for example due to 
0594:             *         // I/O failure).
0595:             *         // YOUR CODE TO LOAD CLOCK RELATED VALUES GOES HERE (REQUIRED)
0596:             *         // Set node, version, variant and security attribute inclusion as required.
0597:             *         // YOUR CODE TO SET NODE, VERSION, VARIANT VALUES GOES HERE (RECOMMENDED)
0598:             *     }
0599:             *     return state;
0600:             * }
0601:             * </pre>
0602:             * 
0603:             * @param state
0604:             *            the State object into which the state has to be loaded.
0605:             * @return an initialized State object
0606:             */
0607:            protected State loadState(State state) {
0608:                State loadInto = state;
0609:                if (loadInto == null) {
0610:                    if (auidState == null) {
0611:                        loadInto = auidState = new State();
0612:                    }
0613:                    state = auidState;
0614:                }
0615:                if (loadInto != null) {
0616:                    if (loadInto.getRandom() == null) {
0617:                        // set random generator
0618:                        //loadInto.setRandom(new Random(System.currentTimeMillis()));
0619:                        //loadInto.setRandom(new Random(EntropicSeed.calculate(32)));
0620:                        loadInto.setRandom(new Random(entropicSeed(32, System
0621:                                .currentTimeMillis())));
0622:                    }
0623:                    // no super implementation to call
0624:                    // initialize clock related
0625:                    loadInto.setLastTime(getCurrentTime());
0626:                    loadInto.setAdjustTime(0);
0627:                    loadInto.setClockSequence(loadInto.getRandom().nextInt());
0628:                    // initialize attribute fields
0629:                    loadInto
0630:                            .setNode(loadInto.getRandom().nextLong() & 0x0000ffffffffffffL);
0631:                    loadInto.setVersion(VERSION_RANDOM_NODE);
0632:                    loadInto.setVariant(VARIANT_DCE);
0633:                    loadInto.setIncludeSecurityAttributes(false);
0634:                }
0635:                return state;
0636:            }
0637:
0638:            /**
0639:             * Can be overridden together with <code>loadState</code> to provide
0640:             * persistent storage for the auid generator state. The default
0641:             * implementation does nothing.
0642:             * 
0643:             * @param state
0644:             *            the State object to persist.
0645:             */
0646:            protected void saveState(State state) {
0647:            }
0648:
0649:            /**
0650:             * This is the implementation of <code>getBytes(dst, dstBegin)</code>,
0651:             * however, the endianess can be specified through the boolean argument.
0652:             * Subclasses can use this to provide little endian byte array
0653:             * representations. If this is done, there should also be a constructor
0654:             * using this byte array order. If this method is overridden to provide a
0655:             * different field order, the new field order will also be used by the
0656:             * <code>getBytes(dst, dstBegin)</code> method.
0657:             * 
0658:             * @param dst
0659:             *            the destination byte array, if <code>null</code> a new array
0660:             *            will be created
0661:             * @param dstBegin
0662:             *            the offset to use when writing into the destination byte
0663:             *            array, ignored if dst is <code>null</code>
0664:             * @param bigendian
0665:             *            if <code>true</code> big endian byte order is used
0666:             * @return a byte array
0667:             */
0668:            protected byte[] getBytes(byte[] dst, int dstBegin,
0669:                    boolean bigendian) {
0670:                if (dst == null) {
0671:                    dst = new byte[16];
0672:                    dstBegin = 0;
0673:                }
0674:                putOctets(getTimeLow(), 4, dst, dstBegin, bigendian);
0675:                putOctets(getTimeMid(), 2, dst, dstBegin + 4, bigendian);
0676:                putOctets(getTimeHighAndVersion(), 2, dst, dstBegin + 6,
0677:                        bigendian);
0678:                putOctets(getClockSeqHighAndVariant(), 1, dst, dstBegin + 8,
0679:                        bigendian);
0680:                putOctets(getClockSeqLow(), 1, dst, dstBegin + 9, bigendian);
0681:                putOctets(getNode(), 6, dst, dstBegin + 10, bigendian);
0682:                return dst;
0683:            }
0684:
0685:            /**
0686:             * Returns the AUID value as byte array. The array will be filled with the
0687:             * original DCE fields in big endian order, that is each field starts with
0688:             * the most significant byte:
0689:             * 
0690:             * <pre>
0691:             * 
0692:             *  
0693:             *   +---------------------------+---------+---+---+-------+-------+
0694:             *   ! FIELD DESCRIPTION         ! OCTETS  !    LENGTH in bits     !
0695:             *   +---------------------------+---------+---------------+-------+
0696:             *   ! time low                  !  0 -  3 !       32      !
0697:             *   +---------------------------+---------+-------+-------+
0698:             *   ! time mid                  !  4 -  5 !   16  !
0699:             *   +---------------------------+---------+-------+
0700:             *   ! time hi and version       !  6 -  7 !   16  !
0701:             *   +---------------------------+---------+---+---+
0702:             *   ! clock seq hi and reserved !    8    ! 8 !
0703:             *   +---------------------------+---------+---+
0704:             *   ! clock seq low             !    9    ! 8 !
0705:             *   +---------------------------+---------+---+-------------------+
0706:             *   ! node                      ! 10 - 15 !           48          !
0707:             *   +---------------------------+---------+-----------------------+
0708:             *   
0709:             *  
0710:             * </pre>
0711:             * 
0712:             * This implementation just returns
0713:             * <code>getBytes(dst, dstBegin, true)</code>.
0714:             * @param dst
0715:             *            the destination byte array, if <code>null</code> a new array
0716:             *            will be created
0717:             * @param dstBegin
0718:             *            the offset to use when writing into the destination byte
0719:             *            array, ignored if dst is <code>null</code>
0720:             * @return a byte array     
0721:             */
0722:            public byte[] getBytes(byte[] dst, int dstBegin) {
0723:                return getBytes(dst, dstBegin, true);
0724:            }
0725:
0726:            /**
0727:             * Appends the String representation of this AUID to the specified
0728:             * StringBuffer or if null to a new created StringBuffer and returns the
0729:             * StringBuffer. This method is called by <code>toString</code>,
0730:             * therefore it is sufficient to override this method together with
0731:             * providing new parse methods to create a new string representation of an
0732:             * AUID.
0733:             * 
0734:             * @param sb
0735:             *            the StringBuffer to use
0736:             * @return a StringBuffer to which this AUID has been appended
0737:             */
0738:            public StringBuffer toStringBuffer(StringBuffer sb) {
0739:                if (sb == null) {
0740:                    sb = new StringBuffer();
0741:                }
0742:                toHex(sb, getTimeLow(), 8);
0743:                sb.append('-');
0744:                toHex(sb, getTimeMid(), 4);
0745:                sb.append('-');
0746:                toHex(sb, getTimeHighAndVersion(), 4);
0747:                sb.append('-');
0748:                toHex(sb, getClockSeqAndVariant(), 4);
0749:                sb.append('-');
0750:                toHex(sb, getNode(), 12);
0751:                return sb;
0752:            }
0753:
0754:            /**
0755:             * Packs time and version into the first 64 bits (octets 0-7).
0756:             */
0757:            private void packFirstHalf(long time, int version) {
0758:                firstHalf = ((long) version << 60)
0759:                        | (time & 0x0fffffffffffffffL);
0760:            }
0761:
0762:            /**
0763:             * Packs the original DCE fields time low, mid and hiAndVersion into the
0764:             * first 64 bits (octets 0-7).
0765:             */
0766:            private void packDCEFieldsFirstHalf(long timeLow, long timeMid,
0767:                    long timeHiAndVersion) {
0768:                firstHalf = (timeHiAndVersion << 48) | (timeMid << 32)
0769:                        | timeLow;
0770:            }
0771:
0772:            /**
0773:             * Packs clock sequence, variant and node into the second 64 bits (octets
0774:             * 8-15).
0775:             */
0776:            private void packSecondHalf(int clockSeq, int variant, long node) {
0777:                int csMasked = clockSeq & getClockSeqMaskForVariant(variant);
0778:                int csLow = csMasked & 0xff;
0779:                int csHigh = (variant | csMasked) >>> 8;
0780:                secondHalf = (node << 16) | (csLow << 8) | csHigh;
0781:            }
0782:
0783:            /**
0784:             * Packs the original DCE fields clockSeqHiAndVariant, clockSeqLow and node
0785:             * into the second 64 bits (octets 8-15).
0786:             */
0787:            private void packDCEFieldsSecondHalf(int clockSeqHiAndVariant,
0788:                    int clockSeqLow, long node) {
0789:                secondHalf = (node << 16) | (clockSeqLow << 8)
0790:                        | clockSeqHiAndVariant;
0791:            }
0792:
0793:            /**
0794:             * Contains the algorithm to create an AUID.
0795:             */
0796:            private void makeUnique(int securityAttributes,
0797:                    boolean hasSecurityAttributes) {
0798:                synchronized (AUID.class) {
0799:                    // prepare generation
0800:                    State state = loadState(null);
0801:                    // DCE algorithm to generate UUID:
0802:                    // 1. determine time stamp and clock sequence
0803:                    long now = getCurrentTime();
0804:                    if (now < state.getLastTime()) {
0805:                        state.setClockSequence(state.getClockSequence() + 1);
0806:                        state.setAdjustTime(0);
0807:                        state.setLastTime(now);
0808:                    } else if (now != state.getLastTime()) {
0809:                        if (now < (state.getLastTime() + state.getAdjustTime())) {
0810:                            throw new IllegalStateException(
0811:                                    "Clock overrun occured.");
0812:                        }
0813:                        state.setAdjustTime(0);
0814:                        state.setLastTime(now);
0815:                    }
0816:                    now += state.incrementAdjustTime();
0817:                    // 2a. replace time-low with security attributes if version is
0818:                    // DCE_SECURE
0819:                    if (state.getIncludeSecurityAttributes()) {
0820:                        if (hasSecurityAttributes) {
0821:                            now = (now & 0xffffffff00000000L)
0822:                                    | securityAttributes;
0823:                        } else {
0824:                            throw new IllegalArgumentException(
0825:                                    "Required to include security attributes as declared in state.");
0826:                        }
0827:                    } else {
0828:                        if (hasSecurityAttributes) {
0829:                            throw new IllegalArgumentException(
0830:                                    "Cannot include security attributes if not declared in state.");
0831:                        }
0832:                    }
0833:                    // 2b., 3., 4., 5. set time low, mid high and version fields
0834:                    packFirstHalf(now, state.getVersion());
0835:                    // 6., 7., 8. set clock sequence and variant fields
0836:                    packSecondHalf(state.getClockSequence(),
0837:                            state.getVariant(), state.getNode());
0838:                    saveState(state);
0839:                }
0840:            }
0841:
0842:            /**
0843:             * Converts <code>nibbles</code> least significant nibbles of
0844:             * <code>value</code> into a hex representation and appends it to
0845:             * <code>result</code>.
0846:             */
0847:            private void toHex(StringBuffer result, long value, int nibbles) {
0848:                if (nibbles > 0) {
0849:                    toHex(result, value >>> 4, nibbles - 1);
0850:                    result.append(HEX_CHARS[(int) value & 0xf]);
0851:                }
0852:            }
0853:
0854:            /**
0855:             * Converts a hex character into the corresponding nibble value.
0856:             * 
0857:             * @return the nibble value.
0858:             * @throws NumberFormatException
0859:             *             if <code>c</code> is not a valid hex character.
0860:             */
0861:            private long parseNibble(char c) {
0862:                switch (c) {
0863:                case '0':
0864:                    return 0;
0865:                case '1':
0866:                    return 1;
0867:                case '2':
0868:                    return 2;
0869:                case '3':
0870:                    return 3;
0871:                case '4':
0872:                    return 4;
0873:                case '5':
0874:                    return 5;
0875:                case '6':
0876:                    return 6;
0877:                case '7':
0878:                    return 7;
0879:                case '8':
0880:                    return 8;
0881:                case '9':
0882:                    return 9;
0883:                case 'a':
0884:                case 'A':
0885:                    return 10;
0886:                case 'b':
0887:                case 'B':
0888:                    return 11;
0889:                case 'c':
0890:                case 'C':
0891:                    return 12;
0892:                case 'd':
0893:                case 'D':
0894:                    return 13;
0895:                case 'e':
0896:                case 'E':
0897:                    return 14;
0898:                case 'f':
0899:                case 'F':
0900:                    return 15;
0901:                default:
0902:                    throw new NumberFormatException();
0903:                }
0904:            }
0905:
0906:            /**
0907:             * Tests wether <code>c</code> is a hyphen '-' character.
0908:             * 
0909:             * @throws NumberFormatException
0910:             *             if <code>c</code> is not a hyphen '-' character.
0911:             */
0912:            private void parseHyphen(char c) {
0913:                if (c != '-') {
0914:                    throw new NumberFormatException();
0915:                }
0916:            }
0917:
0918:            /**
0919:             * Parses the character sequence <code>cs</code> from begin to end as hex
0920:             * string.
0921:             * 
0922:             * @throws NumberFormatException
0923:             *             if <code>cs</code> contains non-hex characters.
0924:             */
0925:            private long parseHex(CharSequence cs) {
0926:                long retval = 0;
0927:                for (int i = 0; i < cs.length(); i++) {
0928:                    retval = (retval << 4) + parseNibble(cs.charAt(i));
0929:                }
0930:                return retval;
0931:            }
0932:
0933:            /**
0934:             * Parses the character sequence <code>cs</code> from begin to end as the
0935:             * first 18 charcters of a string representation of an AUID.
0936:             * 
0937:             * @return the first 64 bits represented by <code>cs</code>.
0938:             * @throws NumberFormatException
0939:             *             if <code>cs</code> does no match the pattern
0940:             *             "LLLLLLLL-MMMM-HHHH" where 'L', 'M', 'H' are time low, mid
0941:             *             and high fields respectively.
0942:             */
0943:            private long parseFirstHalf(CharSequence charSequence) {
0944:                long timeLow = parseHex(charSequence.subSequence(0, 8));
0945:                parseHyphen(charSequence.charAt(8));
0946:                long timeMid = parseHex(charSequence.subSequence(9, 13));
0947:                parseHyphen(charSequence.charAt(13));
0948:                long timeHi = parseHex(charSequence.subSequence(14, 18));
0949:                return (timeHi << 48) | (timeMid << 32) | timeLow;
0950:            }
0951:
0952:            /**
0953:             * Parses the character sequence <code>cs</code> from begin to end as the
0954:             * second 18 charcters of a string representation of an AUID.
0955:             * 
0956:             * @return the second 64 bits represented by <code>cs</code>.
0957:             * @throws NumberFormatException
0958:             *             if <code>cs</code> does no match the pattern
0959:             *             "-CCCC-NNNNNNNNNNNN" where 'C', 'N' are clock sequence and
0960:             *             node fields respectively.
0961:             */
0962:            private long parseSecondHalf(CharSequence charSequence) {
0963:                parseHyphen(charSequence.charAt(0));
0964:                long clockSeq = parseHex(charSequence.subSequence(1, 5));
0965:                parseHyphen(charSequence.charAt(5));
0966:                long node = parseHex(charSequence.subSequence(6, 18));
0967:                return (node << 16) | ((clockSeq & 0xff) << 8)
0968:                        | (clockSeq >>> 8);
0969:            }
0970:
0971:            /**
0972:             * Gets a value from the specified byte array starting at begin with the
0973:             * specified number of octets and endianess.
0974:             * @param octets
0975:             *            the number of octets
0976:             * @param bytes
0977:             *            the array to get the value from
0978:             * @param begin
0979:             *            the offset to use when writing into the destination byte
0980:             *            array, ignored if dst is <code>null</code>
0981:             * @param bigendian
0982:             *            if <code>true</code> big endian byte order is used
0983:             * @return the octet
0984:             */
0985:            protected static final long getOctets(int octets, byte[] bytes,
0986:                    int begin, boolean bigendian) {
0987:                if (octets > 1) {
0988:                    if (bigendian) {
0989:                        return ((bytes[begin] & 0xffL) << (8 * (octets - 1)))
0990:                                | getOctets(octets - 1, bytes, begin + 1,
0991:                                        bigendian);
0992:                    } else {
0993:                        return getOctets(octets - 1, bytes, begin, bigendian)
0994:                                | ((bytes[begin + octets - 1] & 0xffL) << (8 * (octets - 1)));
0995:                    }
0996:                } else {
0997:                    return bytes[begin] & 0xffL;
0998:                }
0999:            }
1000:
1001:            /**
1002:             * Puts the specified value into the byte array in the specified endianess.
1003:             * @param value
1004:             *            the value
1005:             * @param octets
1006:             *            the number of octets
1007:             * @param dst
1008:             *            the destination array
1009:             * @param dstBegin
1010:             *            the offset to use when writing into the destination byte
1011:             *            array, ignored if dst is <code>null</code>
1012:             * @param bigendian
1013:             *            if <code>true</code> big endian byte order is used
1014:             */
1015:            protected static final void putOctets(long value, int octets,
1016:                    byte[] dst, int dstBegin, boolean bigendian) {
1017:                if (bigendian) {
1018:                    if (octets > 1) {
1019:                        putOctets(value >>> 8, octets - 1, dst, dstBegin,
1020:                                bigendian);
1021:                    }
1022:                    dst[dstBegin + octets - 1] = (byte) (value & 0xff);
1023:                } else {
1024:                    dst[dstBegin] = (byte) (value & 0xff);
1025:                    if (octets > 1) {
1026:                        putOctets(value >>> 8, octets - 1, dst, dstBegin + 1,
1027:                                bigendian);
1028:                    }
1029:                }
1030:            }
1031:
1032:            /**
1033:             * Returns time low octets 0-3 (unsigned) int in a signed long.
1034:             * 
1035:             * @return the time low field (original DCE field).
1036:             */
1037:            public final long getTimeLow() {
1038:                return firstHalf & 0xffffffff;
1039:            }
1040:
1041:            /**
1042:             * Returns time mid octets 4-5 (unsigned) int in a signed long.
1043:             * 
1044:             * @return the time mid field (original DCE field).
1045:             */
1046:            public final long getTimeMid() {
1047:                return (firstHalf >>> 32) & 0xffff;
1048:            }
1049:
1050:            /**
1051:             * Returns time high octets 6-7 (unsigned) int in a signed long.
1052:             * 
1053:             * @return the time high field with version masked out.
1054:             */
1055:            public final long getTimeHigh() {
1056:                return (firstHalf >>> 48) & 0x0fff;
1057:            }
1058:
1059:            /**
1060:             * Returns octets 6-7 (unsigned) int in a signed long.
1061:             * 
1062:             * @return the time high and version field (original DCE field).
1063:             */
1064:            public final long getTimeHighAndVersion() {
1065:                return (firstHalf >>> 48);
1066:            }
1067:
1068:            /**
1069:             * Returns octets 0-7 time only.
1070:             * 
1071:             * @return the complete time value.
1072:             */
1073:            public final long getTime() {
1074:                return firstHalf & 0x0fffffffffffffffL;
1075:            }
1076:
1077:            /**
1078:             * Returns the time of the AUID as Date. This is a narrowing conversion
1079:             * because Date only supports a granularity of milliseconds, while the time
1080:             * value represents 100 nanosecond intervals. Use <code>getNanos</code> to
1081:             * retrieve the truncated nanoseconds.
1082:             * 
1083:             * @return the complete time value as Date truncated to the next
1084:             *         millisecond.
1085:             */
1086:            public final Date getDate() {
1087:                return new Date((getTime() + UTC_OFFSET) / TIME_SCALE);
1088:            }
1089:
1090:            /**
1091:             * Returns the nanoseconds truncated from the time of the AUID by
1092:             * <code>getDate</code>.
1093:             * 
1094:             * @return the nanoseconds truncated from the time of the AUID by
1095:             *         <code>getDate</code>.
1096:             */
1097:            public final long getNanos() {
1098:                return (getTime() + UTC_OFFSET) % TIME_SCALE;
1099:            }
1100:
1101:            /**
1102:             * Returns octets 6-7 version only.
1103:             * 
1104:             * @return the version field.
1105:             */
1106:            public final int getVersion() {
1107:                return (int) (firstHalf >>> 60);
1108:            }
1109:
1110:            /**
1111:             * Returns clock sequence high and variant octet 8 (unsigned) small in a
1112:             * signed int.
1113:             * 
1114:             * @return the clock seq hi and reserved (variant) field (original DCE
1115:             *         field).
1116:             */
1117:            public final int getClockSeqHighAndVariant() {
1118:                return (int) (secondHalf & 0xff);
1119:            }
1120:
1121:            /**
1122:             * Returns clock sequence low octet 9 (unsigned) small in a signed int.
1123:             * 
1124:             * @return the clock seq low field (original DCE field).
1125:             */
1126:            public final int getClockSeqLow() {
1127:                return (int) ((secondHalf >>> 8) & 0xff);
1128:            }
1129:
1130:            /**
1131:             * Returns clock sequence and variant octets 8-9 (unsigned) short in a
1132:             * signed int.
1133:             * 
1134:             * @return the clock sequence and variant field.
1135:             */
1136:            public final int getClockSeqAndVariant() {
1137:                return (getClockSeqHighAndVariant() << 8) | getClockSeqLow();
1138:            }
1139:
1140:            /**
1141:             * Returns clock sequence.
1142:             * 
1143:             * @return the clock sequence field.
1144:             */
1145:            public final int getClockSeq() {
1146:                int csv = getClockSeqAndVariant();
1147:                return csv & getClockSeqMaskForVariant(identifyVariant(csv));
1148:            }
1149:
1150:            /**
1151:             * Returns the variant.
1152:             * 
1153:             * @return the variant field.
1154:             */
1155:            public final int getVariant() {
1156:                return identifyVariant(getClockSeqAndVariant());
1157:            }
1158:
1159:            /**
1160:             * Returns node value octets 10-15 (unsigned) 48-bit in a signed long.
1161:             * 
1162:             * @return the node field (original DCE field).
1163:             */
1164:            public final long getNode() {
1165:                return secondHalf >>> 16;
1166:            }
1167:
1168:            /**
1169:             * Conveniance method just returns <code>getBytes(null, 0)</code>.
1170:             * 
1171:             * @return <code>getBytes(null, 0)</code>.
1172:             */
1173:            public final byte[] getBytes() {
1174:                return getBytes(null, 0);
1175:            }
1176:
1177:            /*
1178:             * Object methods
1179:             */
1180:            public boolean equals(Object obj) {
1181:                if (obj instanceof  AUID) {
1182:                    AUID other = (AUID) obj;
1183:                    return (firstHalf == other.firstHalf)
1184:                            && (secondHalf == other.secondHalf);
1185:                }
1186:                return false;
1187:            }
1188:
1189:            public int hashCode() {
1190:                return (int) (firstHalf ^ (firstHalf >>> 32) ^ secondHalf ^ (secondHalf >>> 32));
1191:            }
1192:
1193:            public String toString() {
1194:                return toStringBuffer(null).toString();
1195:            }
1196:
1197:            /*
1198:             * Comparable methods
1199:             */
1200:            public int compareTo(Object o) {
1201:                AUID other = (AUID) o;
1202:                long cmp = getTimeLow() - other.getTimeLow();
1203:                if (cmp != 0) {
1204:                    cmp = getTimeMid() - other.getTimeMid();
1205:                    if (cmp != 0) {
1206:                        cmp = getTimeHighAndVersion()
1207:                                - other.getTimeHighAndVersion();
1208:                        if (cmp != 0) {
1209:                            cmp = getClockSeqHighAndVariant()
1210:                                    - other.getClockSeqHighAndVariant();
1211:                            if (cmp != 0) {
1212:                                cmp = getClockSeqLow() - other.getClockSeqLow();
1213:                                if (cmp != 0) {
1214:                                    cmp = getNode() - other.getNode();
1215:                                }
1216:                            }
1217:                        }
1218:                    }
1219:                }
1220:                return (cmp == 0 ? 0 : (cmp < 0 ? -1 : 1));
1221:            }
1222:
1223:            /*
1224:             * Utility method for "real" random seed
1225:             */
1226:            private static long entropicSeed(int bits, long initialSeed) {
1227:                if (bits > 63) {
1228:                    bits = 63;
1229:                } else if (bits < 1) {
1230:                    bits = 1;
1231:                }
1232:                final long startTime = System.currentTimeMillis();
1233:                final int[] counters = new int[bits + 1];
1234:                final Random[] randoms = new Random[bits];
1235:                final Thread[] threads = new Thread[bits];
1236:                final int endvalue = bits * 128;
1237:                final int lastindex = bits;
1238:                // create threads
1239:                Random random = new Random(initialSeed);
1240:                for (int i = 0; i < bits; i++) {
1241:                    final int this index = i;
1242:                    long nextSeed = random.nextLong();
1243:                    randoms[i] = new Random(nextSeed);
1244:                    threads[i] = new Thread() {
1245:                        public void run() {
1246:                            try {
1247:                                while (counters[lastindex] < endvalue) {
1248:                                    long value = randoms[this index].nextLong();
1249:                                    int loop = ((int) (value & 255)) + 16;
1250:                                    for (int a = 0; a < loop; a++) {
1251:                                        randoms[this index].nextLong();
1252:                                        if (System.currentTimeMillis()
1253:                                                - startTime > MAXIMUM_ENTROPIC_TIME_MS) {
1254:                                            break;
1255:                                        }
1256:                                    }
1257:                                    counters[this index]++;
1258:                                    if (System.currentTimeMillis() - startTime > MAXIMUM_ENTROPIC_TIME_MS) {
1259:                                        break;
1260:                                    }
1261:                                }
1262:                            } catch (Throwable t) {
1263:                                JPOXLogger.POID.error(t);
1264:                                counters[this index] = endvalue;
1265:                            } finally {
1266:                                threads[this index] = null;
1267:                            }
1268:                        }
1269:                    };
1270:                    threads[i].start();
1271:                }
1272:                // check if all threads revolved at least bits times
1273:                for (int i = 0; i < bits; i++) {
1274:                    while (counters[i] < bits) {
1275:                        Thread.yield();
1276:                        if (System.currentTimeMillis() - startTime > MAXIMUM_ENTROPIC_TIME_MS) {
1277:                            break;
1278:                        }
1279:                    }
1280:                }
1281:                // check if all threads together revolved often enough
1282:                while (counters[lastindex] < endvalue) {
1283:                    Thread.yield();
1284:                    int sum = 0;
1285:                    for (int i = 0; i < bits; i++) {
1286:                        sum += counters[i];
1287:                    }
1288:                    counters[lastindex] = sum;
1289:                    if (System.currentTimeMillis() - startTime > MAXIMUM_ENTROPIC_TIME_MS) {
1290:                        break;
1291:                    }
1292:                }
1293:                // check if all threads stopped
1294:                for (int i = 0; i < bits; i++) {
1295:                    while (threads[i] != null) {
1296:                        Thread.yield();
1297:                    }
1298:                }
1299:                // create a new seed
1300:                long seed = 0;
1301:                for (int i = 0; i < bits; i++) {
1302:                    //seed = (seed << 1) + (randoms[i].nextLong() & 1);
1303:                    seed += randoms[i].nextLong();
1304:                }
1305:                return seed;
1306:            }
1307:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.