diff -Nru jug-2.0.0/build.xml jug-3.1.5/build.xml --- jug-2.0.0/build.xml 2005-10-29 16:39:19.000000000 +0000 +++ jug-3.1.5/build.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru jug-2.0.0/debian/changelog jug-3.1.5/debian/changelog --- jug-2.0.0/debian/changelog 2011-05-30 14:31:40.000000000 +0000 +++ jug-3.1.5/debian/changelog 2018-04-17 14:56:00.000000000 +0000 @@ -1,3 +1,20 @@ +jug (3.1.5-1) unstable; urgency=medium + + * Team upload. + * New upstream release + - Built with Maven instead of Ant + - Build depend on junit4 instead of junit + * Removed the -java-doc package + * Moved the package to Git + * Removed the deprecated DM-Upload-Allowed field + * Updated the Homepage field + * Standards-Version updated to 4.1.4 + * Switch to debhelper level 11 + * Track and download the new releases from GitHub + * Converted deian/copyright to the Copyright Format 1.0 + + -- Emmanuel Bourg Tue, 17 Apr 2018 16:56:00 +0200 + jug (2.0.0-2) unstable; urgency=low * debian/control diff -Nru jug-2.0.0/debian/compat jug-3.1.5/debian/compat --- jug-2.0.0/debian/compat 2011-05-12 14:52:11.000000000 +0000 +++ jug-3.1.5/debian/compat 2018-04-17 14:21:06.000000000 +0000 @@ -1 +1 @@ -5 +11 diff -Nru jug-2.0.0/debian/control jug-3.1.5/debian/control --- jug-2.0.0/debian/control 2011-05-30 14:31:40.000000000 +0000 +++ jug-3.1.5/debian/control 2018-04-17 14:22:45.000000000 +0000 @@ -3,32 +3,24 @@ Priority: optional Maintainer: Debian Java Maintainers Uploaders: Onkar Shinde -Build-Depends-Indep: default-jdk, default-jdk-doc, liblog4j1.2-java, junit -Build-Depends: ant (>= 1.8.2), ant-optional (>= 1.8.2), debhelper (>= 5), cdbs (>= 0.4.5.3) -Standards-Version: 3.9.2 -Vcs-Svn: svn://svn.debian.org/pkg-java/trunk/jug/ -Vcs-Browser: http://svn.debian.org/viewsvn/pkg-java/trunk/jug/ -Homepage: http://jug.safehaus.org/ -DM-Upload-Allowed: yes +Build-Depends: + debhelper (>= 11), + default-jdk, + junit4, + liblog4j1.2-java, + libmaven-bundle-plugin-java, + maven-debian-helper +Standards-Version: 4.1.4 +Vcs-Git: https://anonscm.debian.org/git/pkg-java/jug.git +Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/jug.git +Homepage: http://wiki.fasterxml.com/JugHome Package: libjug-java Architecture: all -Depends: ${misc:Depends} -Suggests: liblog4j1.2-java, libjug-java-doc (= ${binary:Version}) +Depends: ${misc:Depends}, ${maven:Depends} +Suggests: ${maven:OptionalDepends} Description: Pure java UUID generator JUG is a pure java UUID generator that generates UUIDs according to the IETF UUID draft specification. . This package contains the library. - -Package: libjug-java-doc -Architecture: all -Section: doc -Depends: ${misc:Depends} -Recommends: default-jdk-doc -Suggests: libjug-java (= ${binary:Version}) -Description: Pure java UUID generator (API documentation) - JUG is a pure java UUID generator that generates UUIDs according to the IETF - UUID draft specification. - . - This package contains API documentation. diff -Nru jug-2.0.0/debian/copyright jug-3.1.5/debian/copyright --- jug-2.0.0/debian/copyright 2011-05-12 14:52:11.000000000 +0000 +++ jug-3.1.5/debian/copyright 2018-04-17 14:21:06.000000000 +0000 @@ -1,52 +1,20 @@ -This package was debianized by Thierry Carrez on -Tue, 30 Jun 2009 15:12:11 +0200 - -Source tarballs were downloaded from http://jug.safehaus.org/Download - -Copyright: - Copyright (c) 2002-2004 Tatu Saloranta, tatu.saloranta@iki.fi - Portions Copyright (c) 2003 Eric Bie - Portions Copyright (c) 2001 Paul Blankenbaker - -Authors: - Tatu Saloranta - Leonid Kunin - Paul Blankenbaker - Gernot Koller - Dominique Jean-Prost - Jeff Woodward - D.J Hagberg - Göran Löwkrantz - Eric Bie - Bill Sarra - Ralf S. Engelschall - Wolfgang Hoschek - Jonas Fogedi - David Pawson - Pekka Enberg - Thomas Wernitz - Asher Glynn - Wim Deblauwe - Klaus Rheinwald - -License: - JUG is dual-licensed under 2 alternative licenses: LGPL 2.1 and ASL 2.0: - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - 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. - -On Debian GNU/Linux and Ubuntu systems, the complete text of the Apache 2.0 -License can be found in the /usr/share/common-licenses/Apache-2.0 file. -The same license and copyright applies to the Debian packaging. - -The complete text of the GNU Lesser General Public License version 2.1 can -be found in the /usr/share/common-licenses/LGPL-2.1 file. +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: Java UUID Generator +Source: https://github.com/cowtowncoder/java-uuid-generator +Files-Excluded: jug-native + +Files: * +Copyright: 2002-2004, Tatu Saloranta + 2003, Eric Bie + 2001, Paul Blankenbaker +License: Apache-2.0 + +Files: debian/* +Copyright: 2009, Thierry Carrez + 2009-2011, Onkar Shinde + 2018, Emmanuel Bourg +License: Apache-2.0 + +License: Apache-2.0 + On Debian systems, the full text of the Apache-2.0 license + can be found in the file '/usr/share/common-licenses/Apache-2.0' diff -Nru jug-2.0.0/debian/libjug-java-doc.install jug-3.1.5/debian/libjug-java-doc.install --- jug-2.0.0/debian/libjug-java-doc.install 2011-05-30 14:31:40.000000000 +0000 +++ jug-3.1.5/debian/libjug-java-doc.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -javadoc/* usr/share/doc/libjug-java/api/ diff -Nru jug-2.0.0/debian/libjug-java.poms jug-3.1.5/debian/libjug-java.poms --- jug-2.0.0/debian/libjug-java.poms 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/debian/libjug-java.poms 2018-04-17 14:21:17.000000000 +0000 @@ -0,0 +1 @@ +pom.xml --no-parent --has-package-version --java-lib diff -Nru jug-2.0.0/debian/maven.ignoreRules jug-3.1.5/debian/maven.ignoreRules --- jug-2.0.0/debian/maven.ignoreRules 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/debian/maven.ignoreRules 2018-04-17 14:21:17.000000000 +0000 @@ -0,0 +1,2 @@ +org.apache.maven.plugins maven-javadoc-plugin +org.apache.maven.plugins maven-source-plugin diff -Nru jug-2.0.0/debian/maven.rules jug-3.1.5/debian/maven.rules --- jug-2.0.0/debian/maven.rules 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/debian/maven.rules 2018-04-17 14:21:17.000000000 +0000 @@ -0,0 +1 @@ +junit junit * s/.*/4.x/ * * diff -Nru jug-2.0.0/debian/patches/01-ignore-network-interface-test.patch jug-3.1.5/debian/patches/01-ignore-network-interface-test.patch --- jug-2.0.0/debian/patches/01-ignore-network-interface-test.patch 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/debian/patches/01-ignore-network-interface-test.patch 2018-04-17 14:21:17.000000000 +0000 @@ -0,0 +1,14 @@ +Description: Disables a test requiring a non-loopback network interface (not available on the builders) +Author: Emmanuel Bourg +Forwarded: not-needed +--- a/src/test/java/com/fasterxml/uuid/EthernetAddressTest.java ++++ b/src/test/java/com/fasterxml/uuid/EthernetAddressTest.java +@@ -1302,7 +1302,7 @@ + * + * @since 3.0 + */ +- public void testFromInterface() throws Exception ++ public void _testFromInterface() throws Exception + { + EthernetAddress addr = EthernetAddress.fromInterface(); + assertNotNull(addr); diff -Nru jug-2.0.0/debian/patches/build-xml.diff jug-3.1.5/debian/patches/build-xml.diff --- jug-2.0.0/debian/patches/build-xml.diff 2011-05-30 14:31:40.000000000 +0000 +++ jug-3.1.5/debian/patches/build-xml.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -Description: Various fixes to build.xml. -Forwarded: not-needed -Author: Thierry Carrez ---- a/build.xml 2011-05-18 20:36:41.000000000 +0530 -+++ b/build.xml 2011-05-19 09:32:33.000000000 +0530 -@@ -104,6 +104,7 @@ - - - -+ - - - -@@ -115,7 +116,6 @@ - - - -- - - - -@@ -148,6 +148,7 @@ - - - -+ - - - -@@ -208,6 +209,7 @@ - - - -+ - - - -@@ -254,9 +256,11 @@ - - - -- -+ - - -+ -+ - - - -@@ -264,7 +268,7 @@ - - - -- -+ - - - diff -Nru jug-2.0.0/debian/patches/series jug-3.1.5/debian/patches/series --- jug-2.0.0/debian/patches/series 2011-05-12 14:52:11.000000000 +0000 +++ jug-3.1.5/debian/patches/series 2018-04-17 14:21:17.000000000 +0000 @@ -1 +1 @@ -build-xml.diff +01-ignore-network-interface-test.patch diff -Nru jug-2.0.0/debian/rules jug-3.1.5/debian/rules --- jug-2.0.0/debian/rules 2011-05-30 14:31:40.000000000 +0000 +++ jug-3.1.5/debian/rules 2018-04-17 14:21:17.000000000 +0000 @@ -1,17 +1,4 @@ #!/usr/bin/make -f -include /usr/share/cdbs/1/rules/debhelper.mk -include /usr/share/cdbs/1/class/ant.mk - -JARNAME := jug-asl -JAVA_HOME := /usr/lib/jvm/default-java -DEB_ANT_BUILD_TARGET := jar.asl javadoc -DEB_ANT_CHECK_TARGET := test -DEB_JARS := log4j-1.2 ant-junit junit - -binary-post-install/lib$(DEB_SOURCE_PACKAGE)-java:: - dh_install build/$(JARNAME)-$(DEB_UPSTREAM_VERSION).jar usr/share/java - dh_link usr/share/java/$(JARNAME)-$(DEB_UPSTREAM_VERSION).jar usr/share/java/$(JARNAME).jar - -get-orig-source: - wget -O ../jug_$(DEB_UPSTREAM_VERSION).orig.tar.gz http://jug.safehaus.org/curr/jug-src.tar.gz +%: + dh $@ diff -Nru jug-2.0.0/debian/watch jug-3.1.5/debian/watch --- jug-2.0.0/debian/watch 2011-05-12 14:52:11.000000000 +0000 +++ jug-3.1.5/debian/watch 2018-04-17 14:21:06.000000000 +0000 @@ -1,2 +1,3 @@ version=3 -http://jug.safehaus.org/Download http://jug.safehaus.org/curr/jug-asl-([\d\.]+).jar +opts="repack,compression=xz" +https://github.com/cowtowncoder/java-uuid-generator/tags .*/java-uuid-generator-([\d\.]+).tar.gz diff -Nru jug-2.0.0/.gitignore jug-3.1.5/.gitignore --- jug-2.0.0/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/.gitignore 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,14 @@ +# Skip maven 'target' directory +target + +# plus eclipse crap +.classpath +.project +.settings + +# plus IDEA crap +*.iml +*.ipr +.idea + +*~ diff -Nru jug-2.0.0/index.html jug-3.1.5/index.html --- jug-2.0.0/index.html 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/index.html 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,82 @@ + + + + + + + cowtowncoder/java-uuid-generator @ GitHub + + + + + + + Fork me on GitHub + +
+ +
+ + + + +
+ +

java-uuid-generator + by cowtowncoder

+ +
+ Java Uuid Generator (JUG) +
+ +

Java Uuid Generator (JUG) is a library for generating all (3) types of UUIDs on Java. And perhaps .NET/Mono as well: MUG is in the making!

License

+

Apache License 2.0 or LGPL 2.1

+

Authors

+

Tatu Saloranta

+

Contact

+

Tatu Saloranta (tsaloranta@gmail.com)

+ + +

Download

+

+ You can download this project in either + zip or + tar formats. +

+

You can also clone the project with Git + by running: +

$ git clone git://github.com/cowtowncoder/java-uuid-generator
+

+ + + +
+ + + + diff -Nru jug-2.0.0/pom.xml jug-3.1.5/pom.xml --- jug-2.0.0/pom.xml 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/pom.xml 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,193 @@ + + + + + 4.0.0 + + com.fasterxml + oss-parent + 31 + + com.fasterxml.uuid + java-uuid-generator + bundle + Java UUID Generator + 3.1.5 + +Java UUID Generator (JUG) is a Java library for generating +Universally Unique IDentifiers, UUIDs (see http://en.wikipedia.org/wiki/UUID). +It can be used either as a component in a bigger application, or as a standalone command line tool. +JUG generates UUIDs according to the IETF UUID draft specification. +JUG supports all 3 official UUID generation methods. + + + scm:git:git://github.com/cowtowncoder/java-uuid-generator.git + scm:git:git@github.com:cowtowncoder/java-uuid-generator.git + scm:git:git@github.com:cowtowncoder/java-uuid-generator.git + java-uuid-generator-3.1.5 + + + + cowtowncoder + Tatu Saloranta + tatu.saloranta@iki.fi + + + http://wiki.fasterxml.com/JugHome + + http://github.com/cowtowncoder/java-uuid-generator/issues + + + + 2.2.1 + + + UTF-8 + 1.2.13 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + FasterXML.com + http://fasterxml.com + + + + + + + log4j + log4j + ${log4j.version} + provided + + + + junit + junit + 4.12 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-source-plugin + 2.1.2 + + + attach-sources + + jar + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${version.plugin.javadoc} + + + attach-javadocs + verify + + jar + + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.name} + ${project.artifactId} + ${project.description} + FasterXML.com + + com.fasterxml.uuid;version="${project.version}", + com.fasterxml.uuid.ext;version="${project.version}", + com.fasterxml.uuid.impl;version="${project.version}" + + + com.fasterxml.uuid;version="[${project.version},${project.version}]", + com.fasterxml.uuid.ext;version="[${project.version},${project.version}]", + com.fasterxml.uuid.impl;version="[${project.version},${project.version}]" + + + + org.apache.log4j;version="[${log4j.version},1.3)" + + + + + + + + + org.apache.maven.plugins + maven-release-plugin + + forked-path + + + + + + + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.1 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + diff -Nru jug-2.0.0/README.md jug-3.1.5/README.md --- jug-2.0.0/README.md 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/README.md 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,86 @@ +# Java Uuid Generator (JUG) + +JUG is a set of Java classes for working with UUIDs: generating UUIDs using any of standard methods, outputting +efficiently, sorting and so on. +It generates UUIDs according to the [UUID specification (RFC-4122)](https://tools.ietf.org/html/rfc4122) +(also see [Wikipedia UUID page](http://en.wikipedia.org/wiki/UUID) for more explanation) + +JUG was written by Tatu Saloranta () originally in 2002 and has been updated over years. +In addition, many other individuals have helped fix bugs and implement new features: please see `release-notes/CREDITS` +for the complete list. + +JUG is licensed under [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). + +## Usage + +JUG can be used as a command-line tool (via class 'com.fasterxml.uuid.Jug`), or as a pluggable component. +Maven coordinates are: + +```xml + + com.fasterxml.uuid + java-uuid-generator + 3.1.3 + +``` + +For direct downloads, check out [Project Wiki](../../wiki). + +Generation itself is done by first selecting a kind of generator to use, and then calling its `generate()` method, +for example: + +```java +UUID uuid = Generators.randomBasedGenerator().generate(); +UUID uuid = Generators.timeBasedGenerator().generate(); +``` + +If you want customize generators, you may also just want to hold on to generator instance, for example: +```java +TimeBasedGenerator gen = Generators.timeBasedGenerator(EthernetAddress.fromInterface()); +UUID uuid = gen.generate(); +UUID anotherUuid = gen.generate(); +``` + +Generators are fully thread-safe, so a single instance may be shared among multiple threads. + +JavaDocs for project can be found from [Project Wiki](../../wiki). + +## Compatibility + +JUG version 3.1 requires JDK 1.6 to work, mostly to be able to access local Ethernet MAC address. +Earlier versions (3.0 and before) worked on 1.4 (which introduced `java.util.UUID`). + +## Known Issues + +JDK's `java.util.UUID` has flawed implementation of `compareTo()`, which uses naive comparison +of 64-bit values. This does NOT work as expected, given that underlying content is for all purposes +unsigned. For example two UUIDs: + +``` +7f905a0b-bb6e-11e3-9e8f-000000000000 +8028f08c-bb6e-11e3-9e8f-000000000000 +``` + +would be ordered with second one first, due to sign extension (second value is considered to +be negative, and hence "smaller"). + +Because of this, you should always use external comparator, such as +`com.fasterxml.uuid.UUIDComparator`, which implements expected sorting order that is simple +unsigned sorting, which is also same as lexicographic (alphabetic) sorting of UUIDs (when +assuming uniform capitalization). + +## Alternative JVM UUID generators + +There are many other publicly available UUID generators. For example: + +* [Apache Commons IO](http://commons.apache.org/sandbox/commons-id/uuid.html) has UUID generator +* [eaio-uuid](http://stephenc.github.io/eaio-uuid/) +* JDK has included `java.util.UUID` since 1.4, but omits generation methods (esp. time/location based ones), has sub-standard performance for many operations and implements comparison in useless way +* [ohannburkard.de UUID generator](http://johannburkard.de/software/uuid/) + +Note that although some packages claim to be faster than others, it is not clear whether: + +1. Claims have been properly verified (or, if they have, can be independently verified), AND +2. It is not likely that performance differences truly matter: JUG, for example, can generate a millions of UUID per second per core (sometimes hitting the theoretical limit of 10 million per second), and it seems unlikely that generation will be bottleneck for about any use case + +so it is often best to choose based on stability of packages and API. diff -Nru jug-2.0.0/release-notes/BUGS jug-3.1.5/release-notes/BUGS --- jug-2.0.0/release-notes/BUGS 2005-07-21 05:25:45.000000000 +0000 +++ jug-3.1.5/release-notes/BUGS 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -== Open Issues == - -As of version 2.0 here is the list of known problems. -Help in solving problems would be greatly appreciated, especially -on platforms I don't have access to (Windows 2000, Mac OS X). - -#1. When reloading code through different class loaders (something - application servers and servlet containers do), you may get - "library already loaded error". If you encounter this problem, - you can try to catch the exception. - Main problem in trying to fix this problem is that since all classes - are potentially reloaded, information about loaded status of - native libs would have to be stored externally (to a file), and - that could have other problems (lock files left behind etc.). - [reported by Andy Stratton] - -== Fixed Issues from Previous Versions == - -#1. Trying to access all interfaces (via getAllInterfaces()) does - not work on Win2K platform (SP 3); it gets into infinite loop. - [first reported by Florian Scharinger]. - Fixed in v1.1 -#2. Mac OS X JNI code shoulf now properly implement getAllInterfaces(). - (same is true for FreeBSD since it's built from same source). - Fixed in v2.0 diff -Nru jug-2.0.0/release-notes/CREDITS jug-3.1.5/release-notes/CREDITS --- jug-2.0.0/release-notes/CREDITS 2005-08-17 04:32:40.000000000 +0000 +++ jug-3.1.5/release-notes/CREDITS 2018-02-21 02:29:25.000000000 +0000 @@ -5,51 +5,51 @@ Leonid Kunin: suggested adding 2 constructors (that were missing); needed when storing binary representations of UUIDs (added to v0.9.2) - [v 0.9.2] + [0.9.2] Paul Blankenbaker: provided the native code for accessing Ethernet MAC-addresses (on linux/x86, Solaris/sparc, Windows); first included in 1.0.0 release. - [v 1.0.0] + [1.0.0] Gernot Koller: pointed out a bug in UUID.toByteArray() method; was not using offset (fixed in 1.0.1) - [v 1.0.1] + [1.0.1] Dominique Jean-Prost: Suggested that there should be alternate method of loading native libs (implemented in 1.0.2). Also pointed out that method 'setLibDir' should be public, not protected (fixed in 1.0.2). - [v 1.0.2] + [1.0.2] Jeff Woodward: Pointed and fixed a bug in UUID.toByteArray() method (not sure if Gernot's fix was somehow overwritten in codebase or what...). - [v 1.0.3] + [1.0.3] D.J Hagberg: Submitted native code to use with Mac OS X, to use for accessing MAC address of primary network interface (code should also work with *BSDs?). Also contributed improvements to Ant's build.xml. - [v 1.0.3] + [1.0.3] -Göran Löwkrantz: Submitted native code for FreeBSD/x86 - [v 1.1] +G�ran L�wkrantz: Submitted native code for FreeBSD/x86 + [1.1] Eric Bie: Wrote full unit test suite, using JUnit! Really REALLY useful addition (old ad hoc tests needed replacement). Also cleaned up ant build file significantly. - [v 1.1] + [1.1] Bill Sarra: Pointed out and fix Windows native code bug that would under some circumstances cause infinite looping when trying to access MAC addresses of all interfaces. - [v 1.1] + [1.1] Ralf S. Engelschall: Pointed out and fixed a bug in generating dummy broadcast ethernet addresses; interpretation of LSB/MSB was incorrect with respect to ethernet broadcast & structs. - [v 1.1] + [1.1] Wolfgang Hoschek: Suggested useful improvement to random UUIDs; there's no requirement for API to enforce use of SecureRandom. @@ -59,34 +59,47 @@ of UUID generation, depending on how quickly Random instance can be initialized & generates new numbers. -Jonas Fügedi: Contributed the patch to check for FreeBSD platform +Jonas F�gedi: Contributed the patch to check for FreeBSD platform (which actually was part of an earlier patch that I somehow had managed not to get in... :-/ ) - [v 1.1.1] + [1.1.1] David Pawson: Pointed out that the jar file was missing the necessary Main-Class definition, which prevented it from being invoked from command line using -jar switch. - [v 1.1.2] + [1.1.2] Pekka Enberg: Pointed out a bug in Linux JNI code; the socket was not properly closed - [v 2.0.0] + [2.0.0] Thomas Wernitz: Pointed out a problem with MacOS JNI code; wasn't properly looping through the interfaces - [v 2.0.0] + [2.0.0] Asher Glynn: Suggested usefulness of external file-based synchronization, to ensure that system clock moving backwards during reboot does not compromise uniqueness of produced UUIDs (which is obviously also mentioned in UUID specs, but previously not implemented in Jug). - [v 2.0.0] + [2.0.0] Wim Deblauwe: Pointed out problems with 2.0rc3 jars (missing com.ccg.net.ethernet package, no downloadable JNI code). - [v 2.0rc3] + [2.0rc3] Klaus Rheinwald: Contributed non-netbios Windows JNI code for accessing Ethernet addresses - [v 2.0rc5] + [2.0rc5] + +Fran�ois Berenger: + Pointed out a method signature problem that prevent unit test compilation + [2.1] + +Tarusawa Hiroyuki: + Reported missing Maven(2) jars for JUG. + +Ed Anuff: + Reported Issue #7: Bytes of clock sequence were switched (unlikely to cause + problems, but incorrect -- regression from 2.x) + [3.1.3] + diff -Nru jug-2.0.0/release-notes/FAQ jug-3.1.5/release-notes/FAQ --- jug-2.0.0/release-notes/FAQ 2005-09-25 18:45:14.000000000 +0000 +++ jug-3.1.5/release-notes/FAQ 2018-02-21 02:29:25.000000000 +0000 @@ -1,4 +1,4 @@ -== "JUG" - Java Uuid Generator == +== Java Uuid Generator ("JUG") == === 1. Why JUG? Don't we already have "uuidgen"? === @@ -10,11 +10,12 @@ may be tricky (since its location in native OS filesystem depends on OS and possibly other factors). -So, portability is one benefit; Jug works if you have Java 1.2. +So, portability is one benefit; JUG works if you have Java 1.2 (version 2.0) +or Java 1.6 (version 3.0). -Performance may be another benefit when using Jug from Java. Interfacing +Performance may be another benefit when using JUG from Java. Interfacing to native functionality (either via uuidgen or directly to libuuigen) -is likely to be slower than calling Jug methods, even if generation +is likely to be slower than calling JUG methods, even if generation itself was faster. === 2. Why NOT use JUG? === @@ -25,63 +26,50 @@ happen (due to clock sequence field etc), but potentially a problem. Uuidgen usually solves this by having a system-wide global lock to prevent possibility of using same timestamps; -but with Java the best Jug can guarantee is that there's always -max. 1 Jug instance per JVM; other JVMs may have their own copies. +but with Java the best JUG can guarantee is that there's always +max. 1 JUG instance per JVM; other JVMs may have their own copies. [note: in theory it would be possible to add native support for locking, for platforms that have locking functionality... but then it might also be easy to just use native uuidgen functionality as well] Note, though, that with random- and name-based methods multiple -instance of Jug are not a problem; name-based methods base the +instance of JUG are not a problem; name-based methods base the uniqueness on the name, not timing, and random-based method is based on quality of the random number generator. In latter case it all depends on how random one considers SecureRandom to be. Additionally, although generating UUIDs is straight-forward, -Jug has not been extensively tested; it just seems to generate +JUG has not been extensively tested; it just seems to generate unique UUIDs as is. :-) === 3. What is the fastest method to use for generating UUIDs? === It depends on your system, random number generators used etc. etc., -but here are some quick test results from my work station (Ultra-60 -dual 450Mhz SparcII; JDK 1.3.1, default JIT == client) -(measurements done using Jug command-line tool, generating 1000 -UUIDs for each type): - -Time-based: 0.03 msec / UUID -Random-based: 0.08 msec / UUID -Name-based: 0.18 msec / UUID -TagURI, no date: 0.18 msec / UUID -TagURI, with date: 0.43 msec / UUID - -Creating datestamps for tag uris (new Calendar instances for each URI) -slows the last entry significantly down it seems. Note also that -names & namespaces for the last three methods were relatively short, -so the 'real' numbers might be bit worse for them too (esp. since -generating the separate names will add cost; for this test 3. and 4. -used the same namespace + name for each UUID which is not too realistic) - -So, it seems that for default settings, time-based algorithm is the -fastest, followed by random-number based one. Name-based algorithms -are slow probably due to MD5-hashing cost associated. -[as a sidenote, at home on my 800mhz AMD system times were about -half of those presented above] + +But here are some numbers, running on a MacBook (2.5 GHz dual CPU) + +Time-based: 5 million/second +Random-based: 0.25 million/second (when using SecureRandom) +Name-based: 1 million/second (depends on length, namespace etc; this with MD5) + +So with default settings, time-based algorithm is by far the fastest; +usually followed by name/hash based alternative (for short/medium +names at least), and random-based variant being slowest. Finally, if performance _really_ is very important for you, there is a further complication when using time-based algorithm; Java's system clock has max. resolution of 1 millisecond, instead of 100ns required by UUID specification. This is solved by using additional -counter (in Jug), but the downside is that for each separate +counter (in JUG), but the downside is that for each separate Java 'time slice' (time period when system clock returns same timestamp) can produce at most 10000 UUIDs. If JDK on the platform does advance in 1 msec ticks, this is good enough for generating -up to 10 million UUIDs per second, but on many platforms resolution -is coarser (on Windows it used to be 55 msec, meaning max. rate -of 180 kUUIDs per second). +up to 10 million UUIDs per second, but on some platforms resolution +is coarser: on Windows granularity used to be 55 msec, meaning +max. rate would be 180 kUUIDs per second. -... which all means that for generating more than, say, ten thousand +... which all means that for generating more than, say, hundred thousand UUIDs per second, you may need to look at native implementations. But often with system like that you aren't really using Java in the first place. @@ -93,6 +81,7 @@ from single JVM (and won't be using other UUID-tools at the same time). If so, uniqueness is pretty much guaranteed and algorithm is fast as well. + One potential drawback is that in case you consider giving out ethernet address a security problem (which in theory it could be, although there probably aren't any major immediate problems), @@ -102,9 +91,13 @@ solution so it's not implemented yet) If there will be multiple UUID generators (different JVMs, using -native uuidgen), using random-based method may be the best option. -It should be reasonably safe to use (provided JDK's default -SecureRandom is implemented as well as it should). +native uuidgen), using random-based method may be the best option; +although there is a file-locking base synchronizer available for +time-based generation. This works with multiple JVMs, but may not +be applicable to synchronize with non-Java generators. +Random-number based variant should be safe to use, as long as the +underlying random number generator is good (which SecureRandom by +JDK should be). Finally, if it's easy to generate unique names from system (say, URL combined with a sequence number guaranteed to be unique), and @@ -115,35 +108,10 @@ === 5. How can I obtain the Ethernet MAC-address of the machine JUG runs on? === -Before version 1.0, your options would be limited to using native -tools and passing address to JUG, or using dummy randomly generated -broadcast addresses. - -However, beginning from version 1.0, there exists limited support -for C/JNI - based native access for obtaining interface addresses. - -To obtain MAC-address of the primary interface, just call: - -EthernetAddress primary = NativeInterfaces.getPrimaryInterface(); - -[Note that if there's a problem in loading the JNI library, an -Error is thrown]. - -Currently there exists binary library files for Linux/x86, -Windows 32 / x86 (ie. 98, ME, NT, 2K, XP), Solaris/Sparc -and Mac OS X platforms. -Help with compiling/developing more versions would be greatly -appreciated. In some cases existing native code might be usable -as is; for example BSD unixes might be able to use Mac OS X -code after recompilation. - -(1.0.2): Now it is possible to load native code both by using 'standard' -library loading methods (which rely on java env. variable -'java.library.path' for locating libs), as well as application-specific -loading from any given directory (default being 'jug-native' in current -directory). Default is still app-specific method; to enable standard -loading, call NativeInterfaces.setUseStdLibDir(). +Easiest way with version 3.x and above is to use EthernetAddress class, +which internally uses method that JDK 1.6 introduced. +Earlier versions of JUG relied on JNI-access native libraries. === 6. What if system clock/time goes backward? === @@ -158,7 +126,7 @@ While this was unlikely to happen (due to additional randomness injected via clock sequence field eetc.), this -potential problem can now be resolved in Jug 2.0 and onwards using +potential problem can now be resolved in JUG 2.0 and onwards using external synchronization. UUIDGenerator can be configured with TimestampSynchronizer instances; the default implementation, FileBasedTimestampSynchronizer works by using 2 files that are used @@ -171,15 +139,12 @@ this can happen with application servers on context reloads) from running concurrently (assuming they are configured to use same files). -Note: FileBasedTimestampSynchronized requireds JDK 1.4 or above, since it -needs NIO functionality for reliable file locking and synchronization. - === 7. How do I configure (or disable) logging === Starting with 2.0 release, JUG now has a simple configurable logging sub-system. You can start by looking at javadocs for: - org.safehaus.uuid.Logger + com.fasterxml.uuid.Logger class. diff -Nru jug-2.0.0/release-notes/lgpl/LGPL2.1 jug-3.1.5/release-notes/lgpl/LGPL2.1 --- jug-2.0.0/release-notes/lgpl/LGPL2.1 2005-07-21 05:25:45.000000000 +0000 +++ jug-3.1.5/release-notes/lgpl/LGPL2.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff -Nru jug-2.0.0/release-notes/lgpl/LICENSE jug-3.1.5/release-notes/lgpl/LICENSE --- jug-2.0.0/release-notes/lgpl/LICENSE 2005-07-21 05:25:45.000000000 +0000 +++ jug-3.1.5/release-notes/lgpl/LICENSE 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -This copy of Java Uuid/guid Generator (JUG) is licensed under the -Lesser General Public License (LGPL), version 2.1 ("the License"). -See the License for details about distribution rights, and the -specific rights regarding derivate works. - -You may obtain a copy of the License at: - -http://www.gnu.org/licenses/licenses.html - -A copy is also included in the downloadable source code package -containing JUG, in file "LGPL2.1", under the same directory -as this file. - diff -Nru jug-2.0.0/release-notes/README jug-3.1.5/release-notes/README --- jug-2.0.0/release-notes/README 2005-10-29 16:32:12.000000000 +0000 +++ jug-3.1.5/release-notes/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -== "JUG" - Java Uuid Generator == - -JUG is a set of Java classes for generating UUIDs. It generates -UUIDs according to the UUID specification (IETF draft), found -(for example) at: - -http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/draft-leach-uuids-guids-01.txt -[draft id being ''] - -Alternatively you can also read newer IETF draft that described URN -name space for UUIDs, as it contains UUID definition: - -http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-00.txt - -JUG can be used as a command-line tool (via class org.doomdark.uuid.Jug), -or as a pluggable component; see file USAGE for details. - -JUG was created by Tatu Saloranta (). -Code portions related to native access of Ethernet interfaces -(code under jug-native and com/ccg) were written by -Paul Blankenbaker (Windows, Linux, Solaris) and DJ Hagberg (Mac OS X). -In addition, many other individuals have helped fix bugs and implement -new feeatures: please see CREDITS for the complete list. - -Jug licensing is explained in file LICENSE; basically you have either -a choice of oneof 2 common Open Source licenses (when downloading source -package); or choose one of these licenses (when downloading specific jar -file). -Please read LICENSE to understand requirements of the license you choose. - -Contributions to the source code need to be made as specified by -the License; so that they can be distributed according to the -License terms. diff -Nru jug-2.0.0/release-notes/TODO jug-3.1.5/release-notes/TODO --- jug-2.0.0/release-notes/TODO 2005-10-30 02:24:45.000000000 +0000 +++ jug-3.1.5/release-notes/TODO 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ - --- No pending tasks -- - diff -Nru jug-2.0.0/release-notes/USAGE jug-3.1.5/release-notes/USAGE --- jug-2.0.0/release-notes/USAGE 2005-07-21 05:25:45.000000000 +0000 +++ jug-3.1.5/release-notes/USAGE 2018-02-21 02:29:25.000000000 +0000 @@ -9,56 +9,47 @@ === Pluggable component === - -As a pluggable component, UUIDs are created through factory methods -in org.safehaus.uuid.UUIDGenerator; the JVM-wide singleton UUIDGenerator -instance is gotten via UUIDGenerator.getInstance(). UUIDGenerator -is singleton to minimize chance of getting duplicate UUIDs when using -time-based UUID generation methods. If separate JVMs are used (with -their own UUIDGenerators) it's best to either not use time-based -UUID generation, or to give them separate ethernet addresses (possibly -including using one or more dummy addresses). +As a pluggable component, UUID generator instances are created through factory +methods in com.fasterxml.uuid.Generators. +Returned generators are by default properly synchronized to avoid duplicate UUID +generation within a single JVM. If separate JVMs are used (with +their own UUIDGenerators) it's best to either use time-based +UUID generation with external synchronization (look at 'ext' package, +TimestampSyncronizer), or to give them separate ethernet addresses +(possibly including using one or more dummy addresses). UUIDs can be converted to and from strings, can be compared for equality, and should hash nicely so they can be used as keys in hash tables (same applies to class EthernetAddress). -The trickiest part about creating time-based UUIDs is usually how to obtain -the ethernet address; this is briefly covered in javadocs for class -org.safehaus.uuid.NativeInterfaces. - - === Running unit tests === - -Components can be unit tested using 'ant' build tool (which is also needed -for compiling JUG from sources). Use 'ant' without arguments to get -listing of available options, including how to run unit tests. +Components can be unit tested using 'maven' build tool (which is also needed +for compiling JUG from sources). Before submitting patches, unit tests need to be run succesfully, to minimize risk of unintended bugs. Similarly, for all new functionality (if any), new unit tests should be added. - === Command-line tool === - To get list of options and arguments, you can start the command line tool without any arguments, something like: - java -jar jug.jar + java -jar java-uuid-generator-VERSION.jar or - java -cp jug.jar org.safehaus.uuid.Jug + java -cp java-uuid-generator-3.1.0.jar com.fasterxml.uuid.Jug This lists actual usage information. When used as a command-line tool there are some caveats, because of the way a new JVM is usually instantiated between calls: -* Generating the first UUID is usually remarkably slow. This is because - a new secure random number generator is initialized at that time. +* Generating the first UUID can be remarkably slow. This is because + a new secure random number generator is initialized at that time (if + using random number based variant) Subsequent calls are faster, but this has to be done using --count command-line argument, to create multiple UUIDs with same invocation. * Generating time-based UUIDs is not as secure due to JVM being re-initialized @@ -66,10 +57,8 @@ enough, this shouldn't be a problem in practice; clock should have different value between invocations (and inside one invocation clock counter is used to guarantee uniqueness). -* If you want to generate UUIDs that can be 'verified', use either - name-based UUID generation, or tagURI-based UUID generation without - time stamps. These will give reproducible UUIDs (ie. given same - name and namespace options, same UUID is returned). In this case +* If you want to generate UUIDs that can be 'verified', use + name-based UUID generation. In this case UUID generation is actually just used to produce 128-bit hash value of name and namespace arguments. diff -Nru jug-2.0.0/release-notes/VERSION jug-3.1.5/release-notes/VERSION --- jug-2.0.0/release-notes/VERSION 2005-10-30 02:24:29.000000000 +0000 +++ jug-3.1.5/release-notes/VERSION 2018-02-21 02:29:25.000000000 +0000 @@ -1,18 +1,64 @@ -Version: 2.0.0 +Project: java-uuid-generator -Release date: 29-Oct-2005 +============================================================================ +Releases +============================================================================ -Description: - The official 2.0 release. No functional changes since rc6, just - documentation updates. +3.1.5 (21-Feb-2018) - -History: - 2.0-rc6: (25-Sep-2005): +#19: LICENSE file refers to the Java Classmate library instead of Java UUID Generator (JUG) + (reported by Roger Aird, rogeraird@github) +#22: UUIDTimer is not extendable which is not consistent with it's Javadoc + (reported by Spikhalskiy@github, mazurkin@github) - Added simple logger wrappers for log4j and java.util.logging: now it - should be trivial to make JUG use either of these logging sub-systems, - when integrating it to an existing system. +3.1.4 (15-Dec-2014) + +#4: Add LICENSE file in resulting jar. +#15: Please make log4j "provided" rather than compile if it's really optionally + (requested by ymenager@github) + +3.1.3 (04-Nov-2011) + +* [#3] Make sure UUIDUtil has convenience factory methods, conversions, + to make it easier to work with java.util.UUID. +* [#7] Bytes of clock sequence were switched (unlikely to cause problems, + but incorrect -- regressions from 2.x) + (reported by Ed A) +* [#8] A potential race condition for RandomBasedGenerator + (reported by "facboy") + +3.1.2 (25-Jun-2011): + +* Fixed a packaging problem (missing sources) + +3.1.1 (05-Apr-2011): + +* [#5]: NPE when calling "Generators.randomBasedGenerator().generate()" second time + (reported by oswaldo) + +3.1.0 (14-Oct-2010): + +Rewrite of Java Uuid Generator, to bring it up to date. Changes include: + +* Use Maven for build +* Jars built as OSGi bundles with appropriate metadata +* Converted to use java.util.UUID as the UUID value type +* Change from using static UUIDGenerator into typed generator instances + accessed via com.fasterxml.uuid.Generators factory class +* Allow using JDK 1.6 Ethernet address access code (exposed via + EthernetAddress class) +* Made generators fully synchronized + +2.0.0 (29-Oct-2005): + +The official 2.0 release. No functional changes since rc6, just +documentation updates. + +2.0-rc6: (25-Sep-2005): + +Added simple logger wrappers for log4j and java.util.logging: now it +should be trivial to make JUG use either of these logging sub-systems, +when integrating it to an existing system. 2.0-rc5: (05-Sep-2005): @@ -50,7 +96,7 @@ (of Jug command-line functionality) from jar. 1.1.1: Minor fixes: - - Added FreeBSD recognition check suggested by Jonas Fügedi. + - Added FreeBSD recognition check suggested by Jonas F�gedi. 1.1: Better native support, full unit test suite. - Fixed a bug in Windows MAC address access, which would cause diff -Nru jug-2.0.0/run.sh jug-3.1.5/run.sh --- jug-2.0.0/run.sh 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/run.sh 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,3 @@ +#!/bin/sh + +java -classpath target/classes $* diff -Nru jug-2.0.0/src/c/EthernetAddress_linux.c jug-3.1.5/src/c/EthernetAddress_linux.c --- jug-2.0.0/src/c/EthernetAddress_linux.c 2005-07-21 05:25:50.000000000 +0000 +++ jug-3.1.5/src/c/EthernetAddress_linux.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* Implementation of the Ethernet MAC address access code for generic - * Linux platform. Tested with 2.2.x and 2.4.x kernels; should be generic - * enough to work on most all distributions and kernel versions. - */ -JNIEXPORT jboolean JNICALL -Java_com_ccg_net_ethernet_EthernetAddress_getLocalEthernet(JNIEnv *env, jobject obj, jint id, jbyteArray ea) -{ - int s, err; - struct ifreq ifr; - - /* open a socket */ - s = socket(PF_INET, SOCK_DGRAM, 0); - if (s == -1) { - return JNI_FALSE; - } - - sprintf(ifr.ifr_name,"eth%d",id); - - /* query information for a particular ethernet device */ - /* !!! 28-Mar-2005, TSa: Hmmh. This is a kludge, not only hard-coding the - * ethernet interface name, but assuming they are always consequtively - * numbered? - */ - err = ioctl(s, SIOCGIFHWADDR, &ifr); - /* 28-Mar-2005, TSa: need to close the socket in any case - * (as pointed out by Pekka Enberg) - */ - close(s); - - if (err < 0) { - return JNI_FALSE; - } - - { - /* transfer information into byte array passed */ - jbyte* ba = (*env)->GetByteArrayElements(env,ea,0); - struct sockaddr* sa = (struct sockaddr *) &ifr.ifr_addr; - int i; - for (i = 0; i < 6; i++) { - ba[i] = sa->sa_data[i]; - } - - (*env)->ReleaseByteArrayElements(env,ea,ba,0); - } - - return JNI_TRUE; -} diff -Nru jug-2.0.0/src/c/EthernetAddress_macosx.c jug-3.1.5/src/c/EthernetAddress_macosx.c --- jug-2.0.0/src/c/EthernetAddress_macosx.c 2005-08-10 03:04:25.000000000 +0000 +++ jug-3.1.5/src/c/EthernetAddress_macosx.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -#include - -#include -#include -#include -#include - -/* - * These calls should work for any of the *BSD variants that have - * a "getifaddrs" call. Info gathered from the freebsd-hackers list: - * http://docs.freebsd.org/cgi/getmsg.cgi?fetch=358524+0+archive/2001/freebsd-hackers/20010805.freebsd-hackers - * which indicates that the code originally came from NetBSD's ifconfig.c. - * - * build library with: - -cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers EthernetAddress_macosx.c -cc -dynamiclib -o libMacOSX_ppc_EtherAddr.jnilib EthernetAddress_macosx.o -framework JavaVM - - */ - -JNIEXPORT jboolean JNICALL -Java_com_ccg_net_ethernet_EthernetAddress_getLocalEthernet(JNIEnv *env, jobject obj, jint id, jbyteArray ea) -{ - struct ifaddrs *ifap, *ifaphead; - const struct sockaddr_dl *sdl; - int rtnerr, alen, i; - caddr_t ap; - - rtnerr = getifaddrs(&ifaphead); - if (rtnerr) { - return JNI_FALSE; - } - - for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) { - if( ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_LINK) { - sdl = (const struct sockaddr_dl*)ifap->ifa_addr; - ap = ((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)); - alen = sdl->sdl_alen; - /* 28-Mar-2005, TSa: Fixed as suggested by Thomas Wernitz - * (and DJ Hagberg, Klaus Rheinwald) - */ - if (ap && alen > 0 && --id < 1) { - /* transfer info into java byte array */ - jbyte* ba = (*env)->GetByteArrayElements(env,ea,0); - for (i=0; i < 6 && i < alen; i++, ap++) { - ba[i] = 0xff&*ap; - } - (*env)->ReleaseByteArrayElements(env,ea,ba,0); - freeifaddrs(ifaphead); - return JNI_TRUE; - } - } - } - - freeifaddrs(ifaphead); - return JNI_FALSE; -} diff -Nru jug-2.0.0/src/c/EthernetAddress_solaris.c jug-3.1.5/src/c/EthernetAddress_solaris.c --- jug-2.0.0/src/c/EthernetAddress_solaris.c 2005-07-21 05:25:50.000000000 +0000 +++ jug-3.1.5/src/c/EthernetAddress_solaris.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -JNIEXPORT jboolean JNICALL -Java_com_ccg_net_ethernet_EthernetAddress_getLocalEthernet(JNIEnv *env, jobject obj, jint id, jbyteArray ea) -{ - struct hostent hostentBuf; - struct hostent *phost; - char **paddrs; - struct arpreq ar; - struct sockaddr_in * psa; - int s,i,herr; - char name[MAXHOSTNAMELEN]; - char hbuf[512]; - - /* !!! 28-Mar-2005, TSa: Hmmh. This is not right, actually; won't return - * anything but the first interface's MAC address? - */ - if ((id != 0) || gethostname(name,sizeof(name))) { - return JNI_FALSE; - } - - /* get this host name */ - phost = gethostbyname_r(name, &hostentBuf, hbuf, sizeof(hbuf), &herr); - if (phost == 0) return JNI_FALSE; - - /* open a socket */ - s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (s == -1) return JNI_FALSE; - - paddrs = phost->h_addr_list; - psa = ( struct sockaddr_in * )&( ar.arp_pa ); - memset( &ar, 0, sizeof( struct arpreq ) ); - psa->sin_family = AF_INET; - memcpy( &( psa->sin_addr ), *paddrs, sizeof( struct in_addr ) ); - if ( ioctl( s, SIOCGARP, &ar ) == -1 ) { - perror("ioctl"); - close(s); - return JNI_FALSE; - } - close(s); - { - /* transfer information into byte array passed */ - jbyte* ba = (*env)->GetByteArrayElements(env,ea,0); - int i; - for (i = 0; i < 6; i++) { - ba[i] = ar.arp_ha.sa_data[i]; - } - - (*env)->ReleaseByteArrayElements(env,ea,ba,0); - } - - return JNI_TRUE; -} diff -Nru jug-2.0.0/src/c/EthernetAddress_win.c jug-3.1.5/src/c/EthernetAddress_win.c --- jug-2.0.0/src/c/EthernetAddress_win.c 2005-08-17 02:20:04.000000000 +0000 +++ jug-3.1.5/src/c/EthernetAddress_win.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -/* change following to 1 to get console output */ -#define ENABLE_DEBUG_OUTPUT 0 - -JNIEXPORT jint JNICALL -JNI_OnLoad(JavaVM *vm, void *reserved) { - return JNI_VERSION_1_1; -} - -JNIEXPORT void JNICALL -JNI_OnUnload(JavaVM *vm, void *reserved) { -} - - -JNIEXPORT jboolean JNICALL -Java_com_ccg_net_ethernet_EthernetAddress_getLocalEthernet(JNIEnv *env, jobject obj, jint id, jbyteArray ea) { - - PIP_ADAPTER_INFO pAdapterInfo, pAdapter; - ULONG ulOutBufLen; - - jboolean rc = JNI_FALSE; - - - pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) ); - ulOutBufLen = sizeof(IP_ADAPTER_INFO); - - // Make an initial call to GetAdaptersInfo to get - // the necessary size into the ulOutBufLen variable - if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { - free(pAdapterInfo); - pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); - } - - if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == NO_ERROR) { - - // We have now a linked list of adapters. Go through that list... - int adapter = 0; - pAdapter = pAdapterInfo; - while (pAdapter && adapter < id) { - pAdapter = pAdapter->Next; - adapter++; - } - - if (pAdapter && adapter == id) { - -#if ENABLE_DEBUG_OUTPUT - printf("\tAdapter Name: \t%s\n", pAdapter->AdapterName); - printf("\tAdapter Desc: \t%s\n", pAdapter->Description); - printf("\tAdapter Addr: \t%02X:%02X:%02X:%02X:%02X:%02X\n", - pAdapter->Address[0], pAdapter->Address[1], pAdapter->Address[2], - pAdapter->Address[3], pAdapter->Address[4], pAdapter->Address[5]); -#endif - - /* Transfer ethernet info */ - jbyte* ba = (*env)->GetByteArrayElements(env,ea,0); - memcpy(ba,pAdapter->Address,6); - (*env)->ReleaseByteArrayElements(env,ea,ba,0); - - rc = JNI_TRUE; - } - } - - free(pAdapterInfo); - -#if ENABLE_DEBUG_OUTPUT - printf("Returning: %i\n", rc); -#endif - - return rc; -} diff -Nru jug-2.0.0/src/c/makefile jug-3.1.5/src/c/makefile --- jug-2.0.0/src/c/makefile 2005-08-17 04:26:13.000000000 +0000 +++ jug-3.1.5/src/c/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -# ---------------------------------------------------------- -*- Makefile -*- # -# $Id: makefile,v 1.2 2001/10/11 21:13:28 pkb Exp $ -# --------------------------------------------------------------------------- # - -# Note: does not contain MacOS build - -ALL.M4 := $(wildcard *.m4) - -ALL.JAVA := $(wildcard *.java) - -ALL.DIRS = doc-files-src - -JAVA_CLASS_DIR = ../../build/classes - -# Set this manually if JAVA_HOME not defined...? -JDKHOME = $(JAVA_HOME) - -# --------------------------------------------- # -# Common stuff for EthernetAddress native library -# --------------------------------------------- # - -all: native - -EthernetAddress.h:: makefile - javah -classpath ${JAVA_CLASS_DIR} -jni com.ccg.net.ethernet.EthernetAddress - -ARCH=x86 -ifdef HOSTTYPE -ifeq ($(findstring 86,$(HOSTTYPE)),) -ARCH=$(HOSTTYPE) -endif -endif - -OS=linux -ifdef OSTYPE -ifeq ($(findstring inux,$(OSTYPE)),) -OS=$(OSTYPE) -endif -endif - -ifneq ($(findstring ind,$(OSTYPE)),) -LIB_NAME=Win_$(ARCH)_EtherAddr.dll -else -LIB_NAME=lib$(OS)_$(ARCH)_EtherAddr.so -endif - -COMMON_DEP_FILES=com_ccg_net_ethernet_EthernetAddress.h - -# GNU/Linux gcc compiler -# -# gcc -O2 -shared -I$JDKHOME/include -I$JDKHOME/include/linux MachineId.c -o libMachineId.so - -LINUX_FILES=EthernetAddress_linux.c -LINUX_LIB=liblinux_$(ARCH)_EtherAddr.so -LINUX_DEP_FILES=$(LINUX_FILES) $(COMMON_DEP_FILES) - -$(LINUX_LIB):: $(LINUX_DEP_FILES) - gcc -O2 -shared -I$(JDKHOME)/include $(LINUX_FILES) -o $@ - -# Sparc compiler: -# cc -G -I$(JDKHOME)/include EthernetAddress.c -o libEthernetAddress.so - -SOLARIS_FILES=EthernetAddress_solaris.c -SOLARIS_LIB=libsolaris_$(ARCH)_EtherAddr.so -SOLARIS_DEP_FILES=$(SOLARIS_FILES) $(COMMON_DEP_FILES) - -$(SOLARIS_LIB):: $(SOLARIS_DEP_FILES) - cc -O2 -G -I$(JDKHOME)/include $(SOLARIS_FILES) -o $@ - -# Windows: -# cl /Ox /G3 -I%JDKHOME%\include -I%JDKHOME%\include\win32 -LD EthernetAddress.c -FeEthernetAddress_win_x86.dll netapi32.lib - -WINDOWS_FILES=EthernetAddress_win.c -WINDOWS_LIB=win_$(ARCH)_EtherAddr.dll -WINDOWS_DEP_FILES=$(WINDOWS_FILES) $(COMMON_DEP_FILES) - -$(WINDOWS_LIB):: $(WINDOWS_DEP_FILES) - cl -O -LD -I%JDKHOME%\include -I%JDKHOME%\include\win32 \ - $(WINDOWS_FILES) -Fe$@ netapi32.lib - - -native:: $(LIB_NAME) - -help:: - @echo native - build native library $(LIB_NAME) os [$(OS)] arch [$(ARCH)] hosttype [$(HOSTTYPE)] ostype [$(OSTYPE)] oscap [$(OSCAP)] diff -Nru jug-2.0.0/src/c/README.macosx jug-3.1.5/src/c/README.macosx --- jug-2.0.0/src/c/README.macosx 2005-07-21 05:25:50.000000000 +0000 +++ jug-3.1.5/src/c/README.macosx 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -I didn't bother to update the makefile with the steps to build the -Mac OS X JNI library. Note that this code is not OS X specific -- it -should work on any of the modern *BSD variants. See the source file -for attribution. - -These steps were taken from developer.apple.com: -http://developer.apple.com/documentation/Java/Conceptual/Java141Development/Core_APIs/chapter_6_section_4.html - - javah -classpath .. -jni com.ccg.net.ethernet.EthernetAddress - cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers \ - EthernetAddress_macosx.c - cc -dynamiclib -o libMacOSX_ppc_EtherAddr.jnilib EthernetAddress_macosx.o \ - -framework JavaVM - diff -Nru jug-2.0.0/src/java/com/ccg/net/ethernet/BadAddressException.java jug-3.1.5/src/java/com/ccg/net/ethernet/BadAddressException.java --- jug-2.0.0/src/java/com/ccg/net/ethernet/BadAddressException.java 2005-07-21 05:25:50.000000000 +0000 +++ jug-3.1.5/src/java/com/ccg/net/ethernet/BadAddressException.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/*---------------------------------------------------------------- - * $Id: BadAddressException.java,v 1.1 2001/10/04 19:42:33 pkb Exp $ - * - * (c)2001 - - * - * Revision Log - * - * $Log: BadAddressException.java,v $ - * Revision 1.1 2001/10/04 19:42:33 pkb - * - * Added package related to Ethernet addresses (turns out to be a - * non-trivial exercise to get a ethernet address in a cross platform - * manner). Currently uses native code (as I don't know of another way) - * and supports Windows, Linux, Solaris. Tested on (Windows 98, RedHat - * 7.1 and Solaris 8). - * - * - */ -//---------------------------------------------------------------- - -package com.ccg.net.ethernet; - -//---------------------------------------------------------------- -/** Exception thrown when passed a bad value to decode a ethernet - * address from. - * - *

The {@link EthernetAddress} class provides several methods to - * construct ethernet address objects from. If one passes a bad - * parameter to these methods, this type of exception might occur. - * - * @version $Revision: 1.1 $ - * - * @since 1.0 - * - * @author $Author: pkb $ - * - * @see EthernetAddress */ -//---------------------------------------------------------------- - -public final class BadAddressException extends IllegalArgumentException { - - //---------------------------------------------------------------- - /** Construct exception with a particular message. - * - * @param text - * - * Text message to associate with exception - * - * @since 1.0 */ - //---------------------------------------------------------------- - - BadAddressException(String message) { - super(message); - } - -} diff -Nru jug-2.0.0/src/java/com/ccg/net/ethernet/EthernetAddress.java jug-3.1.5/src/java/com/ccg/net/ethernet/EthernetAddress.java --- jug-2.0.0/src/java/com/ccg/net/ethernet/EthernetAddress.java 2005-07-21 05:25:50.000000000 +0000 +++ jug-3.1.5/src/java/com/ccg/net/ethernet/EthernetAddress.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,558 +0,0 @@ -/*---------------------------------------------------------------- - * $Id: EthernetAddress.java,v 1.2 2001/10/11 21:13:28 pkb Exp $ - * - * (c)2001 - Paul Blankenbaker - * - * Revision Log - * - * $Log: EthernetAddress.java,v $ - * Revision 1.2 2001/10/11 21:13:28 pkb - * Changed organization of native code - moved binaries to - * $COMHOME/native/OS/ARCH directories - * - * Revision 1.1 2001/10/04 19:42:33 pkb - * - * Added package related to Ethernet addresses (turns out to be a - * non-trivial exercise to get a ethernet address in a cross platform - * manner). Currently uses native code (as I don't know of another way) - * and supports Windows, Linux, Solaris. Tested on (Windows 98, RedHat - * 7.1 and Solaris 8). - * - * - */ -//---------------------------------------------------------------- - -package com.ccg.net.ethernet; - -import java.util.*; - - -//---------------------------------------------------------------- -/** Manage ethernet address objects and provide a means to determine - * the ethernet address of the machine the JVM is running on. - * - *

This class is used to examine (work with) ethernet addresses. It - * was primarily created to provide a means to determine the ethernet - * address(es) of the local machine (which turned out to be a - * non-trivial project). - * - *

IMPORTANT INSTALLATION INSTRUCTIONS

- * - *

This class relies on native code when determining the ethernet - * address. Because of this, a shared library module needs to be - * installed BEFORE you will be able to use the methods in this class - * related to the local ethernet address of the machine. - * - *

To do the installation, you need to: - * - *

    - *
  • Determine which shared library module you need. - *
  • Copy the shared library module to its final location. - *
- * - *

It is important to note that the shared libraries need to be - * copied to a location that is within the library search path for - * your environment. I've found that the $(JREHOME)/bin directory - * tends to always be in the search path (at least for - * Linux/Windows). For Sun's JRE installation, look for - * $(JREHOME)/lib/ARCH (like "/opt/jdk/jre/lib/sparc"). If you are - * unable to copy the library to this location, you may need to update - * your library search path before executing code. - * - *

The source code for each of the libraries is available, however, - * it is often easier not to have to locate a compiler and simply use - * one of the pre-compiled binary files. The following binary files - * are available: - * - *

- * - *
$COMHOME/ccg/native/linux/x86/libEthernetAddress.so
This - * library is intended for use on Intel x86 based Linux - * platforms. This file needs to be installed within your shared - * library search path with a final name of "libEthernetAddress.so". A - * developer can typically install this library with the following - * command (as root): - * - *
- * cp $COMHOME/ccg/native/linux/x86/libEthernetAddress.so \
- *   $JREHOME/bin/libEthernetAddress.so
- * - *
$COMHOME/ccg/native/solaris/sparc/libEthernetAddress.so
This - * library is intended for use on Sparc based Solaris platforms. This - * file needs to be installed within your shared library search path - * with a final name of "libEthernetAddress.so". A developer can - * typically install this library with the following command (as - * root): - * - *
- * cp $COMHOME/ccg/native/solaris/sparc/libEthernetAddress.so \
- *   $JREHOME/lib/sparc/libEthernetAddress.so
- * - *
$COMHOME/native/win/x86/EthernetAddress.dll
This - * library is intended for use on Intel x86 based Windows - * platforms. This file needs to be installed within your shared - * library search path with a final name of "EthernetAddress.dll". If - * you put this file in the same directory as your "java.exe" file, it - * seems to be found. A developer can typically install this library - * with the following command: - * - *
- * copy %COMHOME%/ccg/native/win/x86/EthernetAddress.dll \
- *   %JREHOME%/bin/EthernetAddress.dll
- * - *
- * - *

Developer Notes:

- * - *

If you need to add support for additional platforms (such as a - * Mac/Beos/etc), you should take one of the source 'C' files (like - * EthernetAddress_linux.c) as your starting point and create a new - * 'C' source file for the native platform you'd like to support. - * - * @version $Revision: 1.2 $ - * - * @since 1.0 - * - * @author $Author: pkb $ - * - * @see #getPrimaryAdapter - * @see PrintMAC.java */ -//---------------------------------------------------------------- - -public final class EthernetAddress { - - //---------------------------------------------------------------- - /** Native method to look up the ethernet address for a adapter. - * - * @param i - * - * ID of the next ethernet address you want to check. - * - * @param ea - * - * Byte array which is at least 6 bytes long to store the - * ethernet address in. - * - * @return - * - * true if able to determine address for adapter, false if not. - * - * @since 1.0 */ - //---------------------------------------------------------------- - - private static native boolean getLocalEthernet(int i, byte[] ea); - - - - //---------------------------------------------------------------- - /** Tries to create a EthernetAddress object for adapter N. - * - * @param n - * - * ID of adapter you want to get address of (start at 0). - * - * @return - * - * EthernetAddress object if able to determine, or null if not. - * - * @since 1.0 */ - //---------------------------------------------------------------- - - private static EthernetAddress getLocalEthernetAddress(int i) { - // load native code - - // load ALL adapters we can find on the system - byte[] ea = new byte[6]; - - if (!getLocalEthernet(i,ea)) return null; - - return fromBytes(ea); - - } - - - //---------------------------------------------------------------- - /** Check to see if all bytes of the ethernet address are zero. - * - *

This method checks all of the bytes of a ethernet address to - * see if they are zero. If they are, then the ethernet address is - * "0:0:0:0:0:0", which we consider the "null" ethernet address. - * - * @return - * - * true if all bytes of the ethernet address are 0. - * - * @since 1.0 - * - * @see #NULL */ - //---------------------------------------------------------------- - - public boolean isNull() { - for (int i = 0; i < _Bytes.length; i++) if (_Bytes[i] != 0) return false; - return true; - } - - - //---------------------------------------------------------------- - /** Constant ethernet address object which has the "null address". - * - *

This constant can be used when you want a non-null - * EthernetAddress object reference, but want a invalid (or null) - * ethernet address contained. - * - *

The {@link #isNull isNull()} method will ALWAYS return true - * for this constant. - * - * @serial - * - * @since 1.0 - * - * @see #isNull */ - //---------------------------------------------------------------- - - public static final EthernetAddress NULL=new EthernetAddress(); - - - //---------------------------------------------------------------- - /** Try to determine the primary ethernet address of the machine. - * - *

This method will try to return the primary ethernet address of - * the machine. In order for this to succeed: - * - *

    - * - *
  • The necessary native library must be installed (as - * described in the {@link EthernetAddress class overview}. - * - *
  • The native code must find at least one ethernet address for - * the system. - * - *
- * - * @throws UnsatisfiedLinkError - * - * This exception is thrown if we are unable to load the native - * library (like: libEthernetAddress.so or EthernetAddress.dll) - * which is required to query the system for the ethernet - * address. - * - * @return - * - * Ethernet address of the machine if able to determine/guess - - * otherwise null. - * - * @since 1.0 - * - * @see #getAllAdapters */ - //---------------------------------------------------------------- - - public static EthernetAddress getPrimaryAdapter() - throws UnsatisfiedLinkError { - - return getLocalEthernetAddress(0); - } - - - //---------------------------------------------------------------- - /** Get all of the ethernet addresses associated with the local machine. - * - *

This method will try and find ALL of the ethernet adapters - * which are currently available on the system. This is heavily OS - * dependent and may not be supported on all platforms. When not - * supported, you should still get back a collection with the {@link - * #getPrimaryAdapter primary adapter} in it. - * - * @throws UnsatisfiedLinkError - * - * This exception is thrown if we are unable to load the native - * library (like: libEthernetAddress.so or EthernetAddress.dll) - * which is required to query the system for the ethernet - * address. - * - * @return - * - * Array of all ethernet adapters (never returns null, but may - * return a 0 length array if no adapters could be found). - * - * @see #getPrimaryAdapter */ - //---------------------------------------------------------------- - - public static Collection getAllAdapters() - throws UnsatisfiedLinkError { - - // allocate vector to hold info - Vector av = new Vector(); - EthernetAddress ea=null; - for (int i = 0; (ea = getLocalEthernetAddress(i)) != null; i++) { - av.addElement(ea); - } - - return av; - } - - - //---------------------------------------------------------------- - /** Constructs object with "null values" (address of "0:0:0:0:0:0"). - * - * @since 1.0 */ - //---------------------------------------------------------------- - - EthernetAddress() { - _Bytes = new byte[6]; - } - - - //---------------------------------------------------------------- - /** Holds the binary ID of your ethernet adapter. - * - * @serial - * - * @since 1.0 */ - //---------------------------------------------------------------- - - private byte[] _Bytes; - - - //---------------------------------------------------------------- - /** Set the binary ID of your ethernet adapter. - * - * @param val - * - * New byte[] value to assign. - * - * @see #getBytes */ - //---------------------------------------------------------------- - - public static EthernetAddress fromBytes(byte[] val) - throws BadAddressException { - if (val == null || val.length != 6) { - throw new BadAddressException("ethernet address not 6 bytes long"); - } - - EthernetAddress ea = new EthernetAddress(); - for (int i = 0; i < val.length; i++) ea._Bytes[i] = val[i]; - return ea; - } - - - //---------------------------------------------------------------- - /** Get the binary ID of your ethernet adapter. - * - * @return - * - * Copy of the current byte[] value assigned. - * - * @see #fromBytes */ - //---------------------------------------------------------------- - - public byte[] getBytes() { - return (byte[]) _Bytes.clone(); - } - - - //---------------------------------------------------------------- - /** Parse a ethernet address object from a string. - * - *

Ethernet addresses are typically shown as 6 hexadecimal values - * (range: [0,ff]) separated by colons. They have the form: - * - *

-   * x:x:x:x:x:x
-   * 
- * - *

This method is fairly lenient in its parsing. It allows any - * character (and omission) of the separator (shown above). And each - * hex value may be one or two digits long and upper or lower case. - * - *

The following shows several different ways to list the same - * ethernet address: - * - *

-   * 00:E0:98:06:92:0E
-   * 0:e0:98:6:92:e
-   * 0-e0-98 6-92-e
-   * 00e0980692e0
-   * 
- * - * @param sval - * String value to try and parse a ethernet address from (must - * not be null). - * - * @throws BadAddressException - * If we could not parse a ethernet address from the string you - * passed. - * - * @see #toString */ - //---------------------------------------------------------------- - - public static EthernetAddress fromString(String sval) - throws BadAddressException { - - byte[] eab = new byte[6]; - int ei = 0; - boolean needHiNyb = true; - - boolean lastWasSep = true; - - int val = -1; - - int slen = sval.length(); - for (int i = 0; i < slen; i++) { - char c = sval.charAt(i); - int cval = Character.digit(c,16); - - if (cval == -1) { // if not hex digit - if (lastWasSep) { // if last char was separator - ei = 0; // reset to zero bytes - } - else if (val != -1) { // if we have value to store - if (ei >= eab.length) { - throw new BadAddressException("too many bytes in \""+sval+"\""); - } - eab[ei++] = (byte) val; - val = -1; - needHiNyb = true; - } - } - else { // got hex digit - lastWasSep = false; - if (needHiNyb) { // if need hi-nybble, save value - val = cval; - needHiNyb = false; - } - else { // if lo-nybble, then update array - val <<= 4; - val += cval; - needHiNyb = true; - if (ei >= eab.length) { - throw new BadAddressException("too many bytes in \""+sval+"\""); - } - eab[ei++] = (byte) val; - val = -1; - } - } - } - - // if last byte value is single digit, - // catch it here outside of loop - if ((val != -1) && !needHiNyb) { - if (ei >= eab.length) { - throw new BadAddressException("too many bytes in \""+sval+"\""); - } - eab[ei++] = (byte) val; - } - - if (ei != eab.length) { - throw new BadAddressException("not enough bytes in \""+sval+"\""); - } - - EthernetAddress ea = new EthernetAddress(); - ea._Bytes = eab; - return ea; - - } - - - //---------------------------------------------------------------- - /** Get a hash code for the object. - * - *

This method obeys the hash code contract and returns a hash - * value that will try to be random, but will be identical for - * objects which are {@link #equals equal}. - * - * @return - * - * A reasonable hash code for the object. - * - * @since 1.0 */ - //---------------------------------------------------------------- - - public int hashCode() { - - int blen = _Bytes.length; - - if (blen == 0) return 0; - - int hc = _Bytes[0]; - for (int i = 1; i < blen; i++) { - hc *= 37; - hc += _Bytes[i]; - } - - return hc; - - } - - - //---------------------------------------------------------------- - /** Determine if two ethernet address objects are "equal". - * - * @param o - * - * Other object to compare to (you can pass null). - * - * @return - * - * true if two objects have same Ethernet address, false if not. - * - * @since 1.0 */ - //---------------------------------------------------------------- - - public boolean equals(Object o) { - - if (!(o instanceof EthernetAddress)) return false; - - byte[] bao = ((EthernetAddress) o)._Bytes; - if (bao.length != _Bytes.length) return false; - - for (int i = 0; i < bao.length; i++) if (bao[i] != _Bytes[i]) return false; - return true; - } - - - //---------------------------------------------------------------- - /** Get the string representation of the ethernet address. - * - * @return - * - * String representation of ehternet address in form: - * "xx:xx:xx:xx:xx:xx". - * - * @see #fromString */ - //---------------------------------------------------------------- - - public String toString() { - int blen = _Bytes.length; - StringBuffer sb = new StringBuffer(blen*3); - for (int i = 0; i < blen; i++) { - int lo = _Bytes[i]; - int hi = ((lo >> 4) & 0xF); - lo &= 0xF; - if (i != 0) sb.append(':'); - sb.append(Character.forDigit(hi,16)); - sb.append(Character.forDigit(lo,16)); - } - return sb.toString(); - } - - //---------------------------------------------------------------- - // Static class method to load native library first time class is - // loaded - //---------------------------------------------------------------- - - /* 08-Sep-2002, TSa: Commented out to allow for alternative - * dynamic library loading (loading is handled from outside this - * class now, to allow dynamically choosing the correct lib as well - * as catching possible exceptions) - */ - /* - static { - try { - System.loadLibrary("EthernetAddress"); - } catch (Throwable t) { - com.ccg.util.Log.error("problem loading \"EthernetAddress"+ - "\" native library",t); - } - } - */ -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/EthernetAddress.java jug-3.1.5/src/java/org/safehaus/uuid/EthernetAddress.java --- jug-2.0.0/src/java/org/safehaus/uuid/EthernetAddress.java 2005-08-10 03:34:06.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/EthernetAddress.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,418 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.Serializable; - -/** - * EthernetAddress encapsulates the 6-byte Mac address defined in - * IEEE 802.1 standard. - */ - -public class EthernetAddress - implements Serializable, Cloneable, Comparable -{ - private final static String kHexChars = "0123456789abcdefABCDEF"; - - private final byte[] mAddress = new byte[6]; - - /* *** Creation methods *** */ - - /** - * String constructor; given a 'standard' ethernet MAC address string - * (like '00:C0:F0:3D:5B:7C'), constructs an EthernetAddress instance. - * - * Note that string is case-insensitive, and also that leading zeroes - * may be omitted. Thus '00:C0:F0:3D:5B:7C' and '0:c0:f0:3d:5b:7c' are - * equivalent, and a 'null' address could be passed as ':::::' as well - * as '00:00:00:00:00:00' (or any other intermediate combination). - * - * @param addrStr String representation of the ethernet address - */ - public EthernetAddress(String addrStr) - throws NumberFormatException - { - byte[] addr = mAddress; - int len = addrStr.length(); - - /* Ugh. Although the most logical format would be the 17-char one - * (12 hex digits separated by colons), apparently leading zeroes - * can be omitted. Thus... Can't just check string length. :-/ - */ - for (int i = 0, j = 0; j < 6; ++j) { - if (i >= len) { - // Is valid if this would have been the last byte: - if (j == 5) { - addr[5] = (byte) 0; - break; - } - throw new NumberFormatException("Incomplete ethernet address (missing one or more digits"); - } - - char c = addrStr.charAt(i); - ++i; - int value; - - // The whole number may be omitted (if it was zero): - if (c == ':') { - value = 0; - } else { - // No, got at least one digit? - if (c >= '0' && c <= '9') { - value = (c - '0'); - } else if (c >= 'a' && c <= 'f') { - value = (c - 'a' + 10); - } else if (c >= 'A' && c <= 'F') { - value = (c - 'A' + 10); - } else { - throw new NumberFormatException("Non-hex character '"+c+"'"); - } - - // How about another one? - if (i < len) { - c = addrStr.charAt(i); - ++i; - if (c != ':') { - value = (value << 4); - if (c >= '0' && c <= '9') { - value |= (c - '0'); - } else if (c >= 'a' && c <= 'f') { - value |= (c - 'a' + 10); - } else if (c >= 'A' && c <= 'F') { - value |= (c - 'A' + 10); - } else { - throw new NumberFormatException("Non-hex character '"+c+"'"); - } - } - } - } - - addr[j] = (byte) value; - - if (c != ':') { - if (i < len) { - if (addrStr.charAt(i) != ':') { - throw new NumberFormatException("Expected ':', got ('" - + addrStr.charAt(i) - +"')"); - } - ++i; - } else if (j < 5) { - throw new NumberFormatException("Incomplete ethernet address (missing one or more digits"); - } - } - } - } - - /** - * Binary constructor that constructs an instance given the 6 byte - * (48-bit) address. Useful if an address is saved in binary format - * (for saving space for example). - */ - public EthernetAddress(byte [] addr) - throws NumberFormatException - { - if (addr.length != 6) { - throw new NumberFormatException("Ethernet address has to consist of 6 bytes"); - } - for (int i = 0; i < 6; ++i) { - mAddress[i] = addr[i]; - } - } - - /** - * Another binary constructor; constructs an instance from the given - * long argument; the lowest 6 bytes contain the address. - * - * @param addr long that contains the MAC address in 6 least significant - * bytes. - */ - public EthernetAddress(long addr) - { - for (int i = 0; i < 6; ++i) { - mAddress[5 - i] = (byte) addr; - addr >>>= 8; - } - } - - /** - * Package internal constructor for creating an 'empty' ethernet address - */ - EthernetAddress() - { - byte z = (byte) 0; - for (int i = 0; i < 6; ++i) { - mAddress[i] = z; - } - } - - /** - * Default cloning behaviour (bitwise copy) is just fine... - */ - public Object clone() - { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - // shouldn't happen - return null; - } - } - - /* *** Comparison methods *** */ - - public boolean equals(Object o) - { - if (!(o instanceof EthernetAddress)) { - return false; - } - byte[] otherAddress = ((EthernetAddress) o).mAddress; - byte[] thisAddress = mAddress; - for (int i = 0; i < 6; ++i) { - if (otherAddress[i] != thisAddress[i]) { - return false; - } - } - return true; - } - - /** - * Method that compares this EthernetAddress to one passed in as - * argument. Comparison is done simply by comparing individual - * address bytes in the order. - * - * @return -1 if this EthernetAddress should be sorted before the - * one passed in, 1 if after and 0 if they are equal. - */ - public int compareTo(Object o) - { - byte[] thatA = ((EthernetAddress) o).mAddress; - byte[] thisA = mAddress; - - for (int i = 0; i < 6; ++i) { - int cmp = (((int) thisA[i]) & 0xFF) - - (((int) thatA[i]) & 0xFF); - if (cmp != 0) { - return cmp; - } - } - - return 0; - } - - /* *** Type conversion *** */ - - /** - * Returns the canonical string representation of this ethernet address. - * Canonical means that all characters are lower-case and string length - * is always 17 characters (ie. leading zeroes are not omitted). - * - * @return Canonical string representation of this ethernet address. - */ - public String toString() - { - /* Let's not cache the output here (unlike with UUID), assuming - * this won't be called as often: - */ - StringBuffer b = new StringBuffer(17); - byte[] addr = mAddress; - - for (int i = 0; i < 6; ++i) { - if (i > 0) { - b.append(":"); - } - int hex = addr[i] & 0xFF; - b.append(kHexChars.charAt(hex >> 4)); - b.append(kHexChars.charAt(hex & 0x0f)); - } - return b.toString(); - } - - /** - * Returns 6 byte byte array that contains the binary representation - * of this ethernet address; byte 0 is the most significant byte - * (and so forth) - * - * @return 6 byte byte array that contains the binary representation - */ - public byte[] asByteArray() - { - byte[] result = new byte[6]; - - toByteArray(result); - - return result; - } - - /** - * Synonym to 'asByteArray()' - * - * @return 6 byte byte array that contains the binary representation - */ - public byte[] toByteArray() { return asByteArray(); } - - public void toByteArray(byte[] array) { toByteArray(array, 0); } - - public void toByteArray(byte[] array, int pos) - { - for (int i = 0; i < 6; ++i) { - array[pos+i] = mAddress[i]; - } - } - - public long toLong() - { - /* Damn Java's having signed bytes sucks... they are NEVER what - * anyone needs; and sign extension work-arounds are slow. - */ - byte[] addr = mAddress; - int hi = (((int) addr[0]) & 0xFF) << 8 - | (((int) addr[1]) & 0xFF); - int lo = ((int) addr[2]) & 0xFF; - for (int i = 3; i < 6; ++i) { - lo = (lo << 8) | (((int) addr[i]) & 0xFF); - } - - return ((long) hi) << 32 | (((long) lo) & 0xFFFFFFFFL); - } - - /** - * Constructs a new EthernetAddress given the byte array that contains - * binary representation of the address. - * - * Note that calling this method returns the same result as would - * using the matching constructor. - * - * @param addr Binary representation of the ethernet address - * - * @throws NumberFormatException if addr is invalid (less or more than - * 6 bytes in array) - */ - public static EthernetAddress valueOf(byte[] addr) - throws NumberFormatException - { - return new EthernetAddress(addr); - } - - /** - * Constructs a new EthernetAddress given the byte array that contains - * binary representation of the address. - * - * Note that calling this method returns the same result as would - * using the matching constructor. - * - * @param addr Binary representation of the ethernet address - * - * @throws NumberFormatException if addr is invalid (less or more than - * 6 ints in array) - */ - public static EthernetAddress valueOf(int[] addr) - throws NumberFormatException - { - byte[] bAddr = new byte[addr.length]; - - for (int i = 0; i < addr.length; ++i) { - bAddr[i] = (byte) addr[i]; - } - return new EthernetAddress(bAddr); - } - - /** - * Constructs a new EthernetAddress given a string representation of - * the ethernet address. - * - * Note that calling this method returns the same result as would - * using the matching constructor. - * - * @param addrStr String representation of the ethernet address - * - * @throws NumberFormatException if addr representation is invalid - */ - public static EthernetAddress valueOf(String addrStr) - throws NumberFormatException - { - return new EthernetAddress(addrStr); - } - - /** - * Constructs a new EthernetAddress given the long int value (64-bit) - * representation of the ethernet address (of which 48 LSB contain - * the definition) - * - * Note that calling this method returns the same result as would - * using the matching constructor. - * - * @param addr Long int representation of the ethernet address - */ - public static EthernetAddress valueOf(long addr) - { - return new EthernetAddress(addr); - } - - public static void main(String[] args) - { - System.out.println("EthernetAddress.main, test:"); - System.out.println("---------------------------"); - - int len; - long rnd = 0; - if (args == null || args.length == 0) { - System.out.println("[no address passed, using a random address]"); - len = 1; - rnd = System.currentTimeMillis() - ^ (long) (Math.random() * (double) 0x100000000L); - args = new String[] { new EthernetAddress(rnd).toString() }; - } - - for (int i = 0; i < args.length; ++i) { - String s = args[i]; - System.out.println("Address '"+s+"':"); - try { - EthernetAddress a = EthernetAddress.valueOf(s); - System.err.println(" Ok, comes out as '"+a.toString()+"'"); - - // EthernetAddress <-> long - System.err.print(" Converting to long, result = "); - long l = a.toLong(); - System.err.println(""+Long.toHexString(l)); - System.err.print(" Creating address from long, are equal: "); - EthernetAddress b = EthernetAddress.valueOf(l); - if (b.equals(a)) { - System.err.println("yes (OK)"); - } else { - System.err.println("no (FAIL)"); - break; - } - - // EthernetAddress <-> byte[] - System.err.println(" Converting to byte array."); - byte[] ba = a.asByteArray(); - System.err.print(" Creating address from byte[], are equal: "); - b = EthernetAddress.valueOf(ba); - if (b.equals(a)) { - System.err.println("yes (OK)"); - } else { - System.err.println("no (FAIL)"); - break; - } - } catch (NumberFormatException e) { - System.out.println(" Fail: "+e.toString()); - } - } - System.out.println("---------------------------"); - System.out.println("Done."); - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/ext/FileBasedTimestampSynchronizer.java jug-3.1.5/src/java/org/safehaus/uuid/ext/FileBasedTimestampSynchronizer.java --- jug-2.0.0/src/java/org/safehaus/uuid/ext/FileBasedTimestampSynchronizer.java 2005-08-10 03:42:06.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/ext/FileBasedTimestampSynchronizer.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid.ext; - -import org.safehaus.uuid.Logger; -import org.safehaus.uuid.TimestampSynchronizer; - -import java.io.*; - -/** - * Implementation of {@link TimestampSynchronizer}, which uses file system - * as the storage and locking mechanism. - *

- * Synchronization is achieved by obtaining an exclusive file locks on two - * specified lock files, and by using the files to store first "safe" timestamp - * value that the generator can use; alternating between one to use to ensure - * one of them always contains a valid timestamp. Latter is needed to guard - * against system clock moving backwards after UUID generator restart. - *

- * Note: this class will only work on JDK 1.4 and above, since it requires - * NIO package to do proper file locking (as well as new opening mode for - * {@link RandomAccessFile}). - *

- * Also note that it is assumed that the caller has taken care to synchronize - * access to method to be single-threaded. As such, none of the methods - * is explicitly synchronized here. - */ -public final class FileBasedTimestampSynchronizer - extends TimestampSynchronizer -{ - // // // Constants: - - /** - * The default update interval is 10 seconds, meaning that the - * synchronizer "reserves" next 10 secods for generation. This - * also means that the lock files need to be accessed at most - * once every ten second. - */ - final static long DEFAULT_UPDATE_INTERVAL = 10L * 1000L; - - final static String FILENAME1 = "uuid1.lck"; - - final static String FILENAME2 = "uuid2.lck"; - - // // // Configuration: - - long mInterval = DEFAULT_UPDATE_INTERVAL; - - final LockedFile mLocked1, mLocked2; - - // // // State: - - /** - * Flag used to indicate which of timestamp files has the most - * recently succesfully updated timestamp value. True means that - * mFile1 is more recent; false that mFile2 - * is. - */ - boolean mFirstActive = false; - - /** - * Constructor that uses default values for names of files to use - * (files will get created in the current working directory), as - * well as for the update frequency value (10 seconds). - */ - public FileBasedTimestampSynchronizer() - throws IOException - { - this(new File(FILENAME1), new File(FILENAME2)); - } - - public FileBasedTimestampSynchronizer(File f1, File f2) - throws IOException - { - this(f1, f2, DEFAULT_UPDATE_INTERVAL); - } - - public FileBasedTimestampSynchronizer(File f1, File f2, long interval) - throws IOException - { - mInterval = interval; - mLocked1 = new LockedFile(f1); - - boolean ok = false; - try { - mLocked2 = new LockedFile(f2); - ok = true; - } finally { - if (!ok) { - mLocked1.deactivate(); - } - } - - // But let's leave reading up to initialization - } - - /* - ////////////////////////////////////////////////////////////// - // Configuration - ////////////////////////////////////////////////////////////// - */ - - public void setUpdateInterval(long interval) - { - if (interval < 1L) { - throw new IllegalArgumentException("Illegal value ("+interval+"); has to be a positive integer value"); - } - mInterval = interval; - } - - /* - ////////////////////////////////////////////////////////////// - // Implementation of the API - ////////////////////////////////////////////////////////////// - */ - - /** - * This method is to be called only once by - * {@link org.safehaus.uuid.UUIDTimer}. It - * should fetch the persisted timestamp value, which indicates - * first timestamp value that is guaranteed NOT to have used by - * a previous incarnation. If it can not determine such value, it - * is to return 0L as a marker. - * - * @return First timestamp value that was NOT locked by lock files; - * 0L to indicate that no information was read. - */ - protected long initialize() - throws IOException - { - long ts1 = mLocked1.readStamp(); - long ts2 = mLocked2.readStamp(); - long result; - - if (ts1 > ts2) { - mFirstActive = true; - result = ts1; - } else { - mFirstActive = false; - result = ts2; - } - - /* Hmmh. If we didn't get a time stamp (-> 0), or if written time is - * ahead of current time, let's log something: - */ - if (result <= 0L) { - Logger.logWarning("Could not determine safe timer starting point: assuming current system time is acceptable"); - } else { - long now = System.currentTimeMillis(); - long diff = now - result; - - /* It's more suspicious if old time was ahead... although with - * longer iteration values, it can be ahead without errors. So - * let's base check on current iteration value: - */ - if ((now + mInterval) < result) { - Logger.logWarning("Safe timestamp read is "+(result - now)+" milliseconds in future, and is greater than the inteval ("+mInterval+")"); - } - - /* Hmmh. Is there any way a suspiciously old timestamp could be - * harmful? It can obviously be useless but... - */ - } - - return result; - } - - public void deactivate() - throws IOException - { - doDeactivate(mLocked1, mLocked2); - } - - /** - * @return Timestamp value that the caller can NOT use. That is, all - * timestamp values prior to (less than) this value can be used - * ok, but this value and ones after can only be used by first - * calling update. - */ - public long update(long now) - throws IOException - { - long nextAllowed = now + mInterval; - - /* We have to make sure to (over)write the one that is NOT - * actively used, to ensure that we always have fully persisted - * timestamp value, even if the write process gets interruped - * half-way through. - */ - - if (mFirstActive) { - mLocked2.writeStamp(nextAllowed); - } else { - mLocked1.writeStamp(nextAllowed); - } - - mFirstActive = !mFirstActive; - - return nextAllowed; - } - - /* - ////////////////////////////////////////////////////////////// - // Internal methods - ////////////////////////////////////////////////////////////// - */ - - protected static void doDeactivate(LockedFile lf1, LockedFile lf2) - { - if (lf1 != null) { - lf1.deactivate(); - } - if (lf2 != null) { - lf2.deactivate(); - } - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/ext/JavaUtilLogger.java jug-3.1.5/src/java/org/safehaus/uuid/ext/JavaUtilLogger.java --- jug-2.0.0/src/java/org/safehaus/uuid/ext/JavaUtilLogger.java 2005-09-25 19:16:19.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/ext/JavaUtilLogger.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid.ext; - -import java.io.*; - -import java.util.logging.Logger; - -//import org.safehaus.uuid.Logger; - -/** - * Simple wrapper that allows easy connecting of JUG logging into JDK 1.4+ - * logging implementation (aka "java.util.logging" aka "JUL". - *

- * Note: using this class requires JDK 1.4 or above. - */ -public class JavaUtilLogger - extends org.safehaus.uuid.Logger -{ - private java.util.logging.Logger mPeer; - - private JavaUtilLogger(java.util.logging.Logger peer) - { - mPeer = peer; - } - - /** - * Static method to call to make JUG use to proxy all of its logging - * through the specified j.u.l Logger instance. - *

- * Method will create a simple wrapper, and call - * {@link org.safehaus.uuid.Logger#setLogger} with the wrapper as - * the argument. This will then re-direct logging from the previously - * defined Logger (which initially is the simple JUG logger) to the - * new wrapper, which routes logging messages to the log4j peer Logger - * instance. - */ - public static void connectToJavaUtilLogging(java.util.logging.Logger peer) - { - JavaUtilLogger logger = new JavaUtilLogger(peer); - // This is static method of the base class... - setLogger(logger); - } - - /** - * Static method to call to make JUG use a log4j proxy all of its logging - * through a j.u.l Logger constructed to correspond with - * org.safehaus.uuid.Logger class (this generally determines - * j.u.l category output etc settings). - *

- * Method will create a simple wrapper, and call - * {@link org.safehaus.uuid.Logger#setLogger} with the wrapper as - * the argument. This will then re-direct logging from the previously - * defined Logger (which initially is the simple JUG logger) to the - * new wrapper, which routes logging messages to the j.u.l peer Logger - * instance. - */ - public static void connectToJavaUtilLogging() - { - connectToJavaUtilLogging(java.util.logging.Logger.getLogger(org.safehaus.uuid.Logger.class.getName())); - } - - /* - ///////////////////////////////////////////////////////////// - // Overridable implementation/instance methods from - // Logger base class - ///////////////////////////////////////////////////////////// - */ - - // // // Config - - // This is ok; let's just use base class functionality: - //protected void doSetLogLevel(int ll); - - /** - * Note: this method is meaningless with log4j, since it has more - * advanced output mapping and filtering mechanisms. As such, it's - * a no-op - */ - protected void doSetOutput(PrintStream str) - { - // Could also throw an Error.. but for now, let's log instead... - mPeer.warning("doSetOutput(PrintStream) called on "+getClass()+" instance, ignoring."); - } - - /** - * Note: this method is meaningless with log4j, since it has more - * advanced output mapping and filtering mechanisms. As such, it's - * a no-op - */ - protected void doSetOutput(Writer w) - { - mPeer.warning("doSetOutput(Writer) called on "+getClass()+" instance, ignoring."); - } - - // // // Logging methods - - protected void doLogInfo(String msg) - { - if (mLogLevel <= LOG_INFO_AND_ABOVE) { - mPeer.info(msg); - } - } - - protected void doLogWarning(String msg) - { - if (mLogLevel <= LOG_WARNING_AND_ABOVE) { - mPeer.warning(msg); - } - } - - protected void doLogError(String msg) - { - /* Hmmh. JUL doesn't have error... and SEVERE is bit drastic. But, - * well, let's use that for ERRORs for now. - */ - if (mLogLevel <= LOG_ERROR_AND_ABOVE) { - mPeer.severe(msg); - } - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/ext/LockedFile.java jug-3.1.5/src/java/org/safehaus/uuid/ext/LockedFile.java --- jug-2.0.0/src/java/org/safehaus/uuid/ext/LockedFile.java 2005-08-09 05:29:47.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/ext/LockedFile.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,292 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid.ext; - -import java.io.*; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; - -import org.safehaus.uuid.Logger; - -/** - * Utility class used by {@link FileBasedTimestampSynchronizer} to do - * actual file access and locking. - *

- * Class stores simple timestamp values based on system time accessed - * using System.currentTimeMillis(). A single timestamp - * is stored into a file using {@link RandomAccessFile} in fully - * synchronized mode. Value is written in ISO-Latin (ISO-8859-1) - * encoding (superset of Ascii, 1 byte per char) as 16-digit hexadecimal - * number, surrounded by brackets. As such, file produced should - * always have exact size of 18 bytes. For extra robustness, slight - * variations in number of digits are accepeted, as are white space - * chars before and after bracketed value. - */ -class LockedFile -{ - /** - * Expected file length comes from hex-timestamp (16 digits), - * preamble "[0x",(3 chars) and trailer "]\r\n" (2 chars, linefeed - * to help debugging -- in some environments, missing trailing linefeed - * causes problems: also, 2-char linefeed to be compatible with all - * standard linefeeds on MacOS, Unix and Windows). - */ - final static int DEFAULT_LENGTH = 22; - - final static long READ_ERROR = 0L; - - // // // Configuration: - - final File mFile; - - // // // File state - - RandomAccessFile mRAFile; - - FileChannel mChannel; - - FileLock mLock; - - ByteBuffer mWriteBuffer = null; - - /** - * Flag set if the original file (created before this instance was - * created) had size other than default size and needs to be - * truncated - */ - boolean mWeirdSize; - - /** - * Marker used to ensure that the timestamps stored are monotonously - * increasing. Shouldn't really be needed, since caller should take - * care of it, but let's be bit paranoid here. - */ - long mLastTimestamp = 0L; - - LockedFile(File f) - throws IOException - { - mFile = f; - - RandomAccessFile raf = null; - FileChannel channel = null; - FileLock lock = null; - boolean ok = false; - - try { // let's just use a single block to share cleanup code - raf = new RandomAccessFile(f, "rwd"); - - // Then lock them, if possible; if not, let's err out - channel = raf.getChannel(); - if (channel == null) { - throw new IOException("Failed to access channel for '"+f+"'"); - } - lock = channel.tryLock(); - if (lock == null) { - throw new IOException("Failed to lock '"+f+"' (another JVM running UUIDGenerator?)"); - } - ok = true; - } finally { - if (!ok) { - doDeactivate(f, raf, lock); - } - } - - mRAFile = raf; - mChannel = channel; - mLock = lock; - } - - public void deactivate() - { - RandomAccessFile raf = mRAFile; - mRAFile = null; - FileLock lock = mLock; - mLock = null; - doDeactivate(mFile, raf, lock); - } - - public long readStamp() - { - int size; - - try { - size = (int) mChannel.size(); - } catch (IOException ioe) { - doLogError("Failed to read file size: "+ioe); - return READ_ERROR; - } - - mWeirdSize = (size != DEFAULT_LENGTH); - - // Let's check specifically empty files though - if (size == 0) { - doLogWarning("Missing or empty file, can not read timestamp value"); - return READ_ERROR; - } - - // Let's also allow some slack... but just a bit - if (size > 100) { - size = 100; - } - byte[] data = new byte[size]; - try { - mRAFile.readFully(data); - } catch (IOException ie) { - doLogError("Failed to read "+size+" bytes: "+ie); - return READ_ERROR; - } - - /* Ok, got data. Now, we could just directly parse the bytes (since - * it is single-byte encoding)... but for convenience, let's create - * the String (this is only called once per JVM session) - */ - char[] cdata = new char[size]; - for (int i = 0; i < size; ++i) { - cdata[i] = (char) (data[i] & 0xFF); - } - String dataStr = new String(cdata); - // And let's trim leading (and trailing, who cares) - dataStr = dataStr.trim(); - - long result = -1; - String err = null; - - if (!dataStr.startsWith("[0") - || dataStr.length() < 3 - || Character.toLowerCase(dataStr.charAt(2)) != 'x') { - err = "does not start with '[0x' prefix"; - } else { - int ix = dataStr.indexOf(']', 3); - if (ix <= 0) { - err = "does not end with ']' marker"; - } else { - String hex = dataStr.substring(3, ix); - if (hex.length() > 16) { - err = "length of the (hex) timestamp too long; expected 16, had "+hex.length()+" ('"+hex+"')"; - } else { - try { - result = Long.parseLong(hex, 16); - } catch (NumberFormatException nex) { - err = "does not contain a valid hex timestamp; got '" - +hex+"' (parse error: "+nex+")"; - } - } - } - } - - // Unsuccesful? - if (result < 0L) { - doLogError("Malformed timestamp file contents: "+err); - return READ_ERROR; - } - - mLastTimestamp = result; - return result; - } - - final static String HEX_DIGITS = "0123456789abcdef"; - - public void writeStamp(long stamp) - throws IOException - { - // Let's do sanity check first: - if (stamp <= mLastTimestamp) { - /* same stamp is not dangerous, but pointless... so warning, - * not an error: - */ - if (stamp == mLastTimestamp) { - doLogWarning("Trying to re-write existing timestamp ("+stamp+")"); - return; - } - throw new IOException(""+getFileDesc()+" trying to overwrite existing value ("+mLastTimestamp+") with an earlier timestamp ("+stamp+")"); - } - -//System.err.println("!!!! Syncing ["+mFile+"] with "+stamp+" !!!"); - - // Need to initialize the buffer? - if (mWriteBuffer == null) { - mWriteBuffer = ByteBuffer.allocate(DEFAULT_LENGTH); - mWriteBuffer.put(0, (byte) '['); - mWriteBuffer.put(1, (byte) '0'); - mWriteBuffer.put(2, (byte) 'x'); - mWriteBuffer.put(19, (byte) ']'); - mWriteBuffer.put(20, (byte) '\r'); - mWriteBuffer.put(21, (byte) '\n'); - } - - // Converting to hex is simple - for (int i = 18; i >= 3; --i) { - int val = (((int) stamp) & 0x0F); - mWriteBuffer.put(i, (byte) HEX_DIGITS.charAt(val)); - stamp = (stamp >> 4); - } - // and off we go: - mWriteBuffer.position(0); // to make sure we always write it all - mChannel.write(mWriteBuffer, 0L); - if (mWeirdSize) { - mRAFile.setLength(DEFAULT_LENGTH); - mWeirdSize = false; - } - - // This is probably not needed (as the random access file is supposedly synced)... but let's be safe: - mChannel.force(false); - - // And that's it! - } - - /* - ////////////////////////////////////////////////////////////// - // Internal methods - ////////////////////////////////////////////////////////////// - */ - - protected void doLogWarning(String msg) - { - Logger.logWarning("(file '"+getFileDesc()+"') "+msg); - } - - protected void doLogError(String msg) - { - Logger.logError("(file '"+getFileDesc()+"') "+msg); - } - - protected String getFileDesc() { - return mFile.toString(); - } - - protected static void doDeactivate(File f, RandomAccessFile raf, - FileLock lock) - { - if (lock != null) { - try { - lock.release(); - } catch (Throwable t) { - Logger.logError("Failed to release lock (for file '"+f+"'): "+t); - } - } - if (raf != null) { - try { - raf.close(); - } catch (Throwable t) { - Logger.logError("Failed to close file '"+f+"':"+t); - } - } - } -} - - diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/ext/Log4jLogger.java jug-3.1.5/src/java/org/safehaus/uuid/ext/Log4jLogger.java --- jug-2.0.0/src/java/org/safehaus/uuid/ext/Log4jLogger.java 2005-09-25 19:16:30.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/ext/Log4jLogger.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid.ext; - -import java.io.*; - -import org.apache.log4j.Logger; - -//import org.safehaus.uuid.Logger; - -/** - * Simple wrapper that allows easy connecting of JUG logging into log4j - * logging subsystem. - *

- * Note: using this class implies all the dependencies that the log4j - * subsystem in use requires (JDK 1.2 or above, in general) - */ -public class Log4jLogger - extends org.safehaus.uuid.Logger -{ - private org.apache.log4j.Logger mPeer; - - private Log4jLogger(org.apache.log4j.Logger peer) - { - mPeer = peer; - } - - /** - * Static method to call to make JUG use to proxy all of its logging - * through the specified log4j Logger instance. - *

- * Method will create a simple wrapper, and call - * {@link org.safehaus.uuid.Logger#setLogger} with the wrapper as - * the argument. This will then re-direct logging from the previously - * defined Logger (which initially is the simple JUG logger) to the - * new wrapper, which routes logging messages to the log4j peer Logger - * instance. - */ - public static void connectToLog4j(org.apache.log4j.Logger peer) - { - Log4jLogger logger = new Log4jLogger(peer); - // This is static method of the base class... - setLogger(logger); - } - - /** - * Static method to call to make JUG use a log4j proxy all of its logging - * through a log4j Logger constructed to correspond with - * org.safehaus.uuid.Logger class (this generally determines - * log4j category output etc settings). - *

- * Method will create a simple wrapper, and call - * {@link org.safehaus.uuid.Logger#setLogger} with the wrapper as - * the argument. This will then re-direct logging from the previously - * defined Logger (which initially is the simple JUG logger) to the - * new wrapper, which routes logging messages to the log4j peer Logger - * instance. - */ - public static void connectToLog4j() - { - connectToLog4j(org.apache.log4j.Logger.getLogger(org.safehaus.uuid.Logger.class)); - } - - /* - ///////////////////////////////////////////////////////////// - // Overridable implementation/instance methods from - // Logger base class - ///////////////////////////////////////////////////////////// - */ - - // // // Config - - // This is ok; let's just use base class functionality: - //protected void doSetLogLevel(int ll); - - /** - * Note: this method is meaningless with log4j, since it has more - * advanced output mapping and filtering mechanisms. As such, it's - * a no-op - */ - protected void doSetOutput(PrintStream str) - { - // Could also throw an Error.. but for now, let's log instead... - mPeer.warn("doSetOutput(PrintStream) called on "+getClass()+" instance, ignoring."); - } - - /** - * Note: this method is meaningless with log4j, since it has more - * advanced output mapping and filtering mechanisms. As such, it's - * a no-op - */ - protected void doSetOutput(Writer w) - { - mPeer.warn("doSetOutput(Writer) called on "+getClass()+" instance, ignoring."); - } - - // // // Logging methods - - protected void doLogInfo(String msg) - { - if (mLogLevel <= LOG_INFO_AND_ABOVE) { - mPeer.info(msg); - } - } - - protected void doLogWarning(String msg) - { - if (mLogLevel <= LOG_WARNING_AND_ABOVE) { - mPeer.warn(msg); - } - } - - protected void doLogError(String msg) - { - if (mLogLevel <= LOG_ERROR_AND_ABOVE) { - mPeer.error(msg); - } - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/ext/package.html jug-3.1.5/src/java/org/safehaus/uuid/ext/package.html --- jug-2.0.0/src/java/org/safehaus/uuid/ext/package.html 2005-08-10 03:54:46.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/ext/package.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ - -Package that contains optional Jug classes; classes that either: -

    -
  • Depend on optional external packages; like log4j or java.util.logging - -based Logger adapters. -
  • -
  • Depend on JDK versions later than 1.1; for example file based timestamp -synchronizer depends on NIO, and thus JDK 1.4+. -
  • -
-

- - diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/Jug.java jug-3.1.5/src/java/org/safehaus/uuid/Jug.java --- jug-2.0.0/src/java/org/safehaus/uuid/Jug.java 2005-08-02 05:15:32.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/Jug.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,370 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.*; -import java.security.*; -import java.util.*; - -/** - * Class that implements command-line interface for accessing functionality - * implemented by {@link UUIDGenerator}. - */ -public class Jug -{ - private final static HashMap mTypes = new HashMap(); - static { - mTypes.put("time-based", "t"); - mTypes.put("random-based", "r"); - mTypes.put("name-based", "n"); - mTypes.put("tag-uri-no-timestamp", "u"); - mTypes.put("tag-uri-with-timestamp", "U"); - } - - private final static HashMap mOptions = new HashMap(); - static { - mOptions.put("count", "c"); - mOptions.put("ethernet-address", "e"); - mOptions.put("help", "h"); - mOptions.put("namespace", "s"); - mOptions.put("name", "n"); - mOptions.put("performance", "p"); - mOptions.put("verbose", "v"); - } - - static void printUsage() - { - String clsName = Jug.class.getName(); - System.err.println("Usage: java "+clsName+" [options] type"); - System.err.println("Where options are:"); - System.err.println(" --count / -c : will generate UUIDs (default: 1"); - System.err.println(" --ethernet-address / -e : defines the ethernet address"); - System.err.println(" (in xx:xx:xx:xx:xx:xx notation, usually obtained using 'ifconfig' etc)"); - System.err.println(" to use with time-based UUID generation"); - System.err.println(" --help / -h: lists the usage (ie. what you see now)"); - System.err.println(" --name / -n: specifies"); - System.err.println(" o name for name-based UUID generation"); - System.err.println(" o 'information' part of tag-URI for tag-URI UUID generation"); - System.err.println(" --namespace / -s: specifies"); - System.err.println(" o the namespace (DNS or URL) for name-based UUID generation"); - System.err.println(" o 'authority' part of tag-URI for tag-URI UUID generation;"); - System.err.println(" (fully-qualified domain name, email address)"); - System.err.println(" --performance / -p: measure time it takes to generate UUID(s)."); - System.err.println(" [note that UUIDs are not printed out unless 'verbose' is also specified]"); - System.err.println(" --verbose / -v: lists additional information about UUID generation\n (by default only UUIDs are printed out (to make it usable in scripts)"); - System.err.println("And type is one of:"); - System.err.println(" time-based / t: generate UUID based on current time and optional\n location information (defined with -e option)"); - System.err.println(" random-based / r: generate UUID based on the default secure random number generator"); - System.err.println(" name-based / n: generate UUID based on the na the default secure random number generator"); - } - - private static void printMap(Map m, PrintStream out, boolean option) - { - Iterator it = m.keySet().iterator(); - int count = 0, len = m.size(); - - while (it.hasNext()) { - String key = (String) it.next(); - String value = (String) m.get(key); - - if (++count > 1) { - if (count < len) { - out.print(", "); - } else { - out.print(" and "); - } - } - if (option) { - out.print("--"); - } - out.print(key); - out.print(" ("); - if (option) { - out.print("-"); - } - out.print(value); - out.print(")"); - } - } - - public static void main(String[] args) - { - if (args.length == 0) { - printUsage(); - return; - } - - int count = args.length; - String type = args[count-1]; - boolean verbose = false; - int genCount = 1; - String name = null, nameSpace = null; - EthernetAddress addr = null; - boolean performance = false; - - --count; - - // Type we recognize? - String tmp = (String) mTypes.get(type); - if (tmp == null) { - if (!mTypes.containsValue(type)) { - System.err.println("Unrecognized UUID generation type '"+ - type+"'; currently available ones are:"); - printMap(mTypes, System.err, false); - System.err.println(); - System.exit(1); - } - } else { - // Long names get translated to shorter ones: - type = tmp; - } - - for (int i = 0; i < count; ++i) { - String opt = args[i]; - - if (opt.length() == 0 || opt.charAt(0) != '-') { - System.err.println("Unrecognized option '"+opt+"' (missing leading hyphen?), exiting."); - System.exit(1); - } - - char option = (char)0; - if (opt.startsWith("--")) { - String o = (String) mOptions.get(opt.substring(2)); - // Let's translate longer names to simple names: - if (o != null) { - option = o.charAt(0); - } - } else { - if (mOptions.containsValue(opt.substring(1))) { - option = opt.charAt(1); - } - } - - if (option == (char) 0) { - System.err.println("Unrecognized option '"+opt+"'; exiting."); - System.err.print("[options currently available are: "); - printMap(mOptions, System.err, true); - System.err.println("]"); - System.exit(1); - } - - // K. Now we have one-letter options to handle: - try { - String next; - switch (option) { - case 'c': - // Need a number now: - next = args[++i]; - try { - genCount = Integer.parseInt(next); - } catch (NumberFormatException nex) { - System.err.println("Invalid number argument for option '"+opt+"', exiting."); - System.exit(1); - } - if (genCount < 1) { - System.err.println("Invalid number argument for option '"+opt+"'; negative numbers not allowed, ignoring (defaults to 1)."); - } - break; - case 'e': - // Need the ethernet address: - next = args[++i]; - try { - addr = EthernetAddress.valueOf(next); - } catch (NumberFormatException nex) { - System.err.println("Invalid ethernet address for option '"+opt+"', error: "+nex.toString()); - System.exit(1); - } - break; - case 'h': - printUsage(); - return; - case 'n': - // Need the name - name = args[++i]; - break; - case 'p': // performance: - performance = true; - break; - case 's': - // Need the namespace id - nameSpace = args[++i]; - break; - case 'v': - verbose = true; - break; - } - } catch (IndexOutOfBoundsException ie) { - // We get here when an arg is missing... - System.err.println("Missing argument for option '"+opt+"', exiting."); - System.exit(1); - } - } // for (int i = 0....) - - /* Ok, args look ok so far. Now to the generation; some args/options - * can't be validated without knowing the type: - */ - boolean timestamp = false; - char typeC = type.charAt(0); - UUID nsUUID = null; - TagURI nsTagURI = null; - - UUIDGenerator uuidGenerator = UUIDGenerator.getInstance(); - boolean usesRnd = false; - - switch (typeC) { - case 't': // time-based - usesRnd = true; - // No address specified? Need a dummy one... - if (addr == null) { - if (verbose) { - System.out.print("(no address specified, generating dummy address: "); - } - addr = uuidGenerator.getDummyAddress(); - if (verbose) { - System.out.print(addr.toString()); - System.out.println(")"); - } - } - break; - case 'r': // random-based - usesRnd = true; - if (verbose) { - Random r = uuidGenerator.getRandomNumberGenerator(); - if (r instanceof SecureRandom) { - SecureRandom sr = (SecureRandom) r; - System.out.print("(using the default random generator, info = '"+sr.getProvider().getInfo()+"')"); - } else { - System.out.print("(using the default random generator, class: "+r.getClass().toString()+"."); - } - } - break; - case 'U': // tagURI-based, use timestamp - timestamp = true; - // falldown to next - case 'n': // name-based - // falldown to next - case 'u': // tagURI-based, no timestamp - if (name == null) { - System.err.println("--name-space (-s) - argument missing when using method that requires it, exiting."); - System.exit(1); - } - if (name == null) { - System.err.println("--name (-n) - argument missing when using method that requires it, exiting."); - System.exit(1); - } - if (typeC == 'n') { - String orig = nameSpace; - nameSpace = nameSpace.toLowerCase(); - if (nameSpace.equals("url")) { - nameSpace = UUID.NAMESPACE_URL; - } else if (nameSpace.equals("dns")) { - nameSpace = UUID.NAMESPACE_DNS; - } else { - System.err.println("Unrecognized namespace '"+orig - +"'; only DNS and URL allowed for name-based generation."); - System.exit(1); - } - - try { - nsUUID = new UUID(nameSpace); - } catch (NumberFormatException nex) { - System.err.println("Internal error: "+nex.toString()); - System.err.println("Exiting."); - System.exit(1); - } - } else if (!timestamp) { - nsTagURI = new TagURI(nameSpace, name, null); - if (verbose) { - System.out.println("(Using tagURI '"+nsTagURI.toString()+"')"); - } - } - - if (verbose) { - MessageDigest md = uuidGenerator.getHashAlgorithm(); - System.out.println("(Using the default hash algorithm, type = '" - +md.getAlgorithm()+"', provider info - '" - +md.getProvider().getInfo()+"')"); - } - break; - } - - // And then let's rock: - if (verbose) { - System.out.println(); - } - - /* When measuring performance, make sure that the random number - * generator is initialized prior to measurements... - */ - long now = 0L; - - if (performance) { - // No need to pre-initialize for name-based schemes? - if (usesRnd) { - if (verbose) { - System.out.println("(initializing random number generator before UUID generation so that performance measurements are not skewed due to one-time init costs)"); - } - Random r = uuidGenerator.getRandomNumberGenerator(); - byte[] tmpB = new byte[1]; - r.nextBytes(tmpB); - if (verbose) { - System.out.println("(random number generator initialized ok)"); - } - } - now = System.currentTimeMillis(); - } - - for (int i = 0; i < genCount; ++i) { - UUID uuid = null; - switch (typeC) { - case 't': // time-based - uuid = uuidGenerator.generateTimeBasedUUID(addr); - break; - case 'r': // random-based - uuid = uuidGenerator.generateRandomBasedUUID(); - break; - case 'n': // name-based - uuid = uuidGenerator.generateNameBasedUUID(nsUUID, name); - break; - case 'u': // tagURI-based, no timestamp - case 'U': // tagURI-based, use timestamp - if (timestamp) { - nsTagURI = new TagURI(nameSpace, name, Calendar.getInstance()); - if (verbose) { - System.out.println("(Using tagURI '"+nsTagURI.toString()+"')"); - } - } - uuid = uuidGenerator.generateTagURIBasedUUID(nsTagURI); - break; - } - if (verbose) { - System.out.print("UUID: "); - } - if (!performance || verbose) { - System.out.println(uuid.toString()); - } - } // for (int i = 0; ...) - - if (verbose) { - System.out.println("Done."); - } - if (performance) { - now = System.currentTimeMillis() - now; - long avg = (now * 10 + (genCount / 2)) / genCount; - System.out.println("Performance: took "+now+" milliseconds to generate (and print out) "+genCount+" UUIDs; average being "+(avg / 10)+"."+(avg%10)+" msec."); - } - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/Logger.java jug-3.1.5/src/java/org/safehaus/uuid/Logger.java --- jug-2.0.0/src/java/org/safehaus/uuid/Logger.java 2005-09-25 18:36:27.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/Logger.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,291 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.*; - -/** - * This is the simple logging interface used by JUG package. It is meant - * to provide a minimal but sufficient functionality for JUG to report - * problems (warnings, errors), in a way that it can be sufficiently - * customized (redirected, suppressed; even redefined), without forcing - * overhead of a real - * full-featured logging sub-system (like log4j or java.util.logging). - * By being customizable, it is still possible to connect JUG logging into - * such a real logging framework (log4j, java.util.logging) when being - * used in a system that already uses such a framework. - *

- * To keep things as light-weight as possible, we won't bother defining - * separate interface or abstract class -- this class defines both API - * and the default implementation. It can thus be extended to override - * functionality to provide thigs like bridging to "real" logging systems. - * For simple configuration (suppress all, redirect to another stream) - * default implementation should be sufficient, however. - *

- * Note: package org.safehaus.uuid.ext does contain - * simple wrappers to connect JUG logging to log4j and java.util.logging: - * - * @see org.safehaus.uuid.ext.Log4jLogger - * @see org.safehaus.uuid.ext.JavaUtilLogger - */ -public class Logger -{ - /* - ////////////////////////////////////////////////// - // Constants - ////////////////////////////////////////////////// - */ - - public final static int LOG_ALL = 0; - public final static int LOG_INFO_AND_ABOVE = 1; - public final static int LOG_WARNING_AND_ABOVE = 2; - public final static int LOG_ERROR_AND_ABOVE = 3; - public final static int LOG_NOTHING = 4; - - /* - ////////////////////////////////////////////////// - // Static objects - ////////////////////////////////////////////////// - */ - - /** - * By default we'll use this default implementation; however, - * it can be easily changed. - */ - private static Logger sInstance = new Logger(); - - /* - ////////////////////////////////////////////////// - // Default impl. configuration - ////////////////////////////////////////////////// - */ - - /** - * Threshold to use for outputting varius log statements. - *

- * Default is to low only warnings and errors - */ - protected int mLogLevel = LOG_ALL; - - /** - * Output object to use, if defined; initialized to - * System.err. - */ - protected PrintStream mOutput1 = System.err; - - /** - * Override output used to explicitly specify where to pass diagnostic - * output, instead of System.err. Used if mOutput1 - * is null; - */ - protected PrintWriter mOutput2 = null; - - /* - ///////////////////////////////////////////////////////////// - // Life-cycle - ///////////////////////////////////////////////////////////// - */ - - protected Logger() { - } - - /** - * Method that can be used to completely re-define the logging - * functionality JUG uses. When called, JUG will start using the - * new instance; if instance passed is null, will basically suppress - * all logging. - * - * @param inst Logger instance to use for all logging JUG does; can be - * null, but if so, essentially disables all logging. - */ - public synchronized static void setLogger(Logger inst) - { - sInstance = inst; - } - - /* - ///////////////////////////////////////////////////////////// - // Actual simple logging API - // (static dispatchers to instance methods) - ///////////////////////////////////////////////////////////// - */ - - // // // Configuration - - /** - * Method to set the minimum level of messages that will get logged - * using currently specific logger instace. For example, if - * {@link #LOG_WARNING_AND_ABOVE} is passed as the argument, warnings - * and errors will be logged, but informational (INFO) messages will - * not. - *

- * Note: exact functionality invoked depends on the logger instance: - * sub-classes of this class may need to do mapping to some other - * logging sub-system (log4j and JUL logging, for example, use their - * own severity levels that while generally reasonably easy to map, - * are nonetheless not one-to-one which the simple logger). - */ - public static void setLogLevel(int level) - { - Logger l = sInstance; - if (l != null) { - l.doSetLogLevel(level); - } - } - - /** - * Method that will re-direct output of the logger using the specified - * {@link PrintStream}. Null is allowed, and signifies that all the - * output should be suppressed. - *

- * Note: exact functionality invoked depends on the logger instance. - */ - public static void setOutput(PrintStream str) - { - Logger l = sInstance; - if (l != null) { - l.doSetOutput(str); - } - } - - /** - * Method that will re-direct output of the logger using the specified - * {@link Writer}. Null is allowed, and signifies that all the - * output should be suppressed. - */ - public static void setOutput(Writer w) - { - Logger l = sInstance; - if (l != null) { - l.doSetOutput(w); - } - } - - // // // Logging methods - - public static void logInfo(String msg) - { - Logger l = sInstance; - if (l != null) { - l.doLogInfo(msg); - } - } - - public static void logWarning(String msg) - { - Logger l = sInstance; - if (l != null) { - l.doLogWarning(msg); - } - } - - public static void logError(String msg) - { - Logger l = sInstance; - if (l != null) { - l.doLogError(msg); - } - } - - /* - ///////////////////////////////////////////////////////////// - // Overridable implementation/instance methods - ///////////////////////////////////////////////////////////// - */ - - // // // Config - - protected void doSetLogLevel(int ll) - { - /* No need to sync for atomic value that's not used - * for synced or critical things - */ - mLogLevel = ll; - } - - protected void doSetOutput(PrintStream str) - { - synchronized (this) { - mOutput1 = str; - mOutput2 = null; - } - } - - protected void doSetOutput(Writer w) - { - synchronized (this) { - mOutput1 = null; - mOutput2 = (w instanceof PrintWriter) ? - (PrintWriter) w : new PrintWriter(w); - } - } - - // // // Logging methods - - protected void doLogInfo(String msg) - { - if (mLogLevel <= LOG_INFO_AND_ABOVE && isEnabled()) { - synchronized (this) { - doWrite("INFO: "+msg); - } - } - } - - protected void doLogWarning(String msg) - { - if (mLogLevel <= LOG_WARNING_AND_ABOVE && isEnabled()) { - synchronized (this) { - doWrite("WARNING: "+msg); - } - } - } - - protected void doLogError(String msg) - { - if (mLogLevel <= LOG_ERROR_AND_ABOVE && isEnabled()) { - synchronized (this) { - doWrite("ERROR: "+msg); - } - } - } - - /* - ///////////////////////////////////////////////////////////// - // Internal methods - ///////////////////////////////////////////////////////////// - */ - - protected void doWrite(String msg) - { - if (mOutput1 != null) { - mOutput1.println(msg); - } else if (mOutput2 != null) { - mOutput2.println(msg); - } - } - - /** - * Internal method used to quickly check if the Logger's output - * is suppressed or not. - *

- * Note: not synchronized since it's read-only method that's return - * value can not be used for reliable syncing. - */ - protected boolean isEnabled() { - return (mOutput1 != null) || (mOutput2 != null); - } -} - diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/NativeInterfaces.java jug-3.1.5/src/java/org/safehaus/uuid/NativeInterfaces.java --- jug-2.0.0/src/java/org/safehaus/uuid/NativeInterfaces.java 2005-08-17 04:23:37.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/NativeInterfaces.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002-2004 Tatu Saloranta, tatu.saloranta@iki.fi - * - * Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.*; -import java.security.*; -import java.util.*; - -/** - * Proxy class that uses JNI-based functionality to obtain information - * about local interfaces. - *

- * Note that there are two different places where platform-dependant - * native code libraries can be located under: - *

    - *
  • System-dependant standard library location (in unix systems - * often something like /lib or /usr/lib). This is not the default; - * if you want to enable this loading, you need to call - * {@link #setUseStdLibDir} before accessing any access method in - * this class. - *
  • Application dependant directory; often located in same directory - * as app, or one of sub-directories. This is default setting; default - * sub-directory (under current directory when starting app that uses - * JUG) is specified as {@link #sDefaultLibSubdir} - *
- */ - -public class NativeInterfaces -{ - protected final static String sDefaultLibSubdir = "jug-native"; - - /** - * Path to dir that contains native lib code. If not specified, - * {@link #sDefaultLibSubdir} is used. - */ - private static File sLibDir = null; - - /** - * Whether native code is to be loaded from system-dependant standard - * library location or not. Default is false, meaning that standard - * location is NOT used. - */ - private static boolean sUseStdLibDir = false; - - /// Whether native library has already been loaded - private static boolean mNativeLoaded = false; - - /** - * Method that allows overriding of default library directory, to - * allow loading of native interface access code from specific - * application dependant location. - */ - public synchronized static void setLibDir(File f) - { - sLibDir = f; - } - - public synchronized static void setUseStdLibDir(boolean b) - { - sUseStdLibDir = b; - } - - protected synchronized static void checkLoad() - { - if (!mNativeLoaded) { - String os = System.getProperty("os.name").trim().toLowerCase(); - String arch = System.getProperty("os.arch").trim().toLowerCase(); - - String realOS = null, realArch = null; - - /* Let's try to figure canonical OS name, just in case some - * JVMs use funny values (unlikely) - */ - if (os.indexOf("windows") >= 0) { - realOS = "win"; - } else if (os.indexOf("linux") >= 0) { - realOS = "linux"; - } else if (os.indexOf("solaris") >= 0 - || os.indexOf("sunos") >= 0) { - realOS = "solaris"; - } else if (os.indexOf("mac os x") >= 0 - || os.indexOf("macosx") >= 0) { - realOS = "macosx"; - } else if (os.indexOf("bsd") >= 0) { - if (os.indexOf("freebsd") >= 0) { - realOS = "freebsd"; - } else if (os.indexOf("netbsd") >= 0) { - realOS = "netbsd"; - } else if (os.indexOf("openbsd") >= 0) { - realOS = "openbsd"; - } else { // default - realOS = "bsd"; - } - } else if (os.indexOf("aix") >= 0) { - realOS = "aix"; - } else if (os.indexOf("hp ux") >= 0) { - realOS = "hpux"; - } else { - throw new Error("No native ethernet access library for OS '"+os+"'."); - } - - /* And ditto for arch value... here it's more likely weird - * values exist? - */ - if (arch.indexOf("x86") >= 0 || arch.indexOf("sparc") >= 0 - || arch.indexOf("ppc") >= 0) { - realArch = arch; - - // Apparently 'i386' means x86 architecture in JVM lingo? - } else if (arch.indexOf("86") >= 0 || arch.indexOf("amd") >= 0) { - realArch = "x86"; - } else { - throw new Error("No native ethernet access library for hardware platform with value '"+arch+"'."); - } - - /* Still not really guaranteed to work; not all combinations - * of os + arch are either valid, or have matching library - * (notably, linux+sparc and solaris+x86 are missing?) - */ - - String libName = realOS + "_" + realArch + "_" + "EtherAddr"; - - if (sUseStdLibDir) { - loadStdLib(libName); - } else { - loadAppLib(libName); - } - - mNativeLoaded = true; - } - } - - private static void loadStdLib(String libName) - { - try { - System.loadLibrary(libName); - } catch (SecurityException sex) { - throw new Error("Trying to load library '"+libName+"': error; "+sex.toString()); - } catch (UnsatisfiedLinkError uex) { - throw new Error("Trying to load library '"+libName+"': error; "+uex.toString()); - } - } - - private static void loadAppLib(String libName) - { - String realLibName = System.mapLibraryName(libName); - String prefix = "Tried to load library '"+libName - +"' (filename assumed to be '"+realLibName+"')"; - - try { - File f; - - if (sLibDir == null) { - f = new File(sDefaultLibSubdir); - f = new File(f, realLibName); - } else { - f = new File(sLibDir, realLibName); - } - // Let's first check if such a file exists... - try { - f = f.getCanonicalFile(); - } catch (IOException ie) { - throw new Error(prefix+": checking existence of '"+f.getAbsolutePath()+"': "+ie.toString()); - } - System.load(f.getAbsolutePath()); - // Uncomment for debugging: - //System.err.println("DEBUG: "+prefix+": Ok."); - } catch (SecurityException sex) { - throw new Error(prefix+": error; "+sex.toString()); - } catch (UnsatisfiedLinkError unsatisfiedex) { - throw new Error(prefix+": error; "+unsatisfiedex.toString()); - } - } - - public static org.safehaus.uuid.EthernetAddress getPrimaryInterface() - { - checkLoad(); - - try { - com.ccg.net.ethernet.EthernetAddress ea = - com.ccg.net.ethernet.EthernetAddress.getPrimaryAdapter(); - if (ea != null) { - return new org.safehaus.uuid.EthernetAddress(ea.getBytes()); - } - } catch (UnsatisfiedLinkError ue) { - /* Should never happen as checkLoad() should have taken - * care of the problems - */ - throw new Error(ue.toString()); - } - - return null; - } - - public static org.safehaus.uuid.EthernetAddress[] getAllInterfaces() - { - org.safehaus.uuid.EthernetAddress[] eas = null; - - checkLoad(); - - try { - Collection c = com.ccg.net.ethernet.EthernetAddress.getAllAdapters(); - eas = new org.safehaus.uuid.EthernetAddress[c.size()]; - Iterator it = c.iterator(); - - for (int i = 0; it.hasNext(); ++i) { - com.ccg.net.ethernet.EthernetAddress ea = - (com.ccg.net.ethernet.EthernetAddress) it.next(); - eas[i] = new org.safehaus.uuid.EthernetAddress(ea.getBytes()); - } - } catch (UnsatisfiedLinkError ue) { - /* Should never happen as checkLoad() should have taken - * care of the problems - */ - throw new Error(ue.toString()); - } - - return eas; - } - - /** - * Test driver to test if native ethernet adapter/interface access - * works ok. Tries to get the primary interface and output it; prints - * out error message if access fails. - */ - public static void main(String[] args) - { - if (args.length > 0 && args[0].equalsIgnoreCase("lib")) { - System.out.println("Trying to access primary ethernet interface using system-dependant library loading (use 'app' argument for other test)"); - setUseStdLibDir(true); - } else { - System.out.println("Trying to access primary ethernet interface using system independent code loading (use 'lib' argument for other test)"); - setUseStdLibDir(false); - } - - System.out.println("Trying to access primary ethernet interface:"); - try { - org.safehaus.uuid.EthernetAddress pea = getPrimaryInterface(); - - System.out.println("Ok, the interface MAC-address is: " - +pea.toString()); - } catch (Throwable t) { - System.out.println("Failed, error given: "+t.toString()); - } - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/package.html jug-3.1.5/src/java/org/safehaus/uuid/package.html --- jug-2.0.0/src/java/org/safehaus/uuid/package.html 2005-08-17 04:31:45.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/package.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ - -Package that contains core (non-optional) Jug classes. These classes -should be usable on JDK 1.1 and up, and have no external dependencies -(with the exception of {@link org.safehaus.uuid.NativeInterfaces} -that depends on JNI modules during runtime). - - diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/TagURI.java jug-3.1.5/src/java/org/safehaus/uuid/TagURI.java --- jug-2.0.0/src/java/org/safehaus/uuid/TagURI.java 2005-07-21 05:25:49.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/TagURI.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.util.*; - -/** - * A class that allows creation of tagURI instances. - * - * TagURIs are specified in IETF draft ; - * available for example at: - * - * http://sunsite.cnlab-switch.ch/ftp/mirror/internet-drafts/draft-kindberg-tag-uri-01.txt - */ -public class TagURI -{ - private final String mDesc; - - /** - * Constructor for creating tagURI instances. - * - * Typical string representations of tagURIs may look like: - *
    - *
  • tag:hp1.hp.com,2001:tst.1234567890 - *
  • tag:fred@flintstone.biz,2001-07-02:rock.123 - *
- * (see tagURI draft for more examples and full explanation of the - * basic concepts) - * - * @param authority Authority that created tag URI; usually either a - * fully-qualified domain name ("www.w3c.org") or an email address - * ("tatu.saloranta@iki.fi"). - * @param identifier A locally unique identifier; often file path or - * URL path component (like, "tst.1234567890", "/home/tatu/index.html") - * @param date Date to add as part of the tag URI, if any; null is used - * used to indicate that no datestamp should be added. - * - */ - public TagURI(String authority, String identifier, Calendar date) - { - StringBuffer b = new StringBuffer(); - b.append("tag:"); - b.append(authority); - if (date != null) { - b.append(','); - b.append(date.get(Calendar.YEAR)); - // Month is optional if it's "january" and day is "1st": - int month = date.get(Calendar.MONTH) - Calendar.JANUARY + 1; - int day = date.get(Calendar.DAY_OF_MONTH); - if (month != 1 || day != 1) { - b.append('-'); - b.append(month); - } - if (day != 1) { - b.append('-'); - b.append(day); - } - } - b.append(':'); - b.append(identifier); - - mDesc = b.toString(); - } - - public String toString() { return mDesc; } - - public boolean equals(Object o) - { - if (o instanceof TagURI) { - return mDesc.equals(((TagURI) o).toString()); - } - return false; - } - - /** - * A simple test harness is added to make (automated) testing of the - * class easier. - */ - public static void main(String[] args) - { - System.out.println("TagURI.main()"); - System.out.println("--------------------"); - System.out.println(); - - String[] auths = { "www.w3c.org", "www.google.com", "www.fi", - "tatu.saloranta@iki.fi" - }; - String[] ids = { "1234", "/home/billg/public_html/index.html", - "6ba7b810-9dad-11d1-80b4-00c04fd430c8", - "foobar" - }; - - Calendar c = null; - String auth = null; - for (int i = 0; i < 4; ++i) { - // Let's just change the date & URL a bit: - switch (i) { - case 2: - c.add(Calendar.MONTH, 1); - break; - case 3: - c.add(Calendar.DAY_OF_MONTH, -7); - break; - } - for (int j = 0; j < 4; ++j) { - TagURI t = new TagURI(auths[i], ids[j], c); - System.out.println("tagURI: "+t); - } - if (c == null) { - c = Calendar.getInstance(); - } - } - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/TimestampSynchronizer.java jug-3.1.5/src/java/org/safehaus/uuid/TimestampSynchronizer.java --- jug-2.0.0/src/java/org/safehaus/uuid/TimestampSynchronizer.java 2005-08-06 06:09:53.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/TimestampSynchronizer.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.IOException; - -/** - * This is the API for utility classes optionally used by {@link UUIDTimer} to - * ensure that timestamp values used for generating time/location-based UUIDs - * are monotonically increasing, as well as that only one such generator - * is ever used on a single system, even in presence of multiple JVMs. - *

- * The default implementation used by JUG is - * {@link org.safehaus.uuid.ext.FileBasedTimestampSynchronizer}. - */ -public abstract class TimestampSynchronizer -{ - protected TimestampSynchronizer() { } - - /** - * Initialization method is will be called on an instance by - * {@link UUIDTimer} right after it's been configured with one. - * At this point the implementation instance should have been properly - * configured, and should be able to determine the first legal timestamp - * value (return value). Method should also initialize any locking that - * it does (if any), such as locking files it needs. - *

- * Return value thus indicates the lowest initial time value that can - * be used by the caller that can not have been used by previous - * incarnations of the UUID generator (assuming instance was able to - * find properly persisted data to figure that out). - * However, caller also needs to make sure that it will - * call {@link #update} when it actually needs the time stamp for the - * first time, - * since this method can not allocate timestamps beyond this initial - * value at this point. - * - * @return First (and last) legal timestamp to use; 0L if it - * can not - * determine it and caller can use whatever value (current timestamp) - * it has access to. - */ - protected abstract long initialize() - throws IOException; - - /** - * Method {@link UUIDTimer} will call if this synchronizer object is - * being replaced by another synchronizer (or removed, that is, no - * more synchronization is to be done). It will not be called if JVM - * terminates. - */ - protected abstract void deactivate() - throws IOException; - - /** - * Method called by {@link UUIDTimer} to indicate that it has generated - * a timestamp value that is beyond last legal timestamp value. - * The method should only return once it has "locked" specified timestamp - * value (and possible additional ones). - * - * @param now Timestamp value caller wants to use, and that the - * synchronizer is asked to protect. - * - * @return First timestamp value that can NOT be used by the caller; - * has to be higher than the input timestamp value - */ - protected abstract long update(long now) - throws IOException; -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/UUIDGenerator.java jug-3.1.5/src/java/org/safehaus/uuid/UUIDGenerator.java --- jug-2.0.0/src/java/org/safehaus/uuid/UUIDGenerator.java 2005-08-10 03:41:33.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/UUIDGenerator.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,597 +0,0 @@ - -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.*; -import java.security.NoSuchAlgorithmException; -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.util.*; - -/** - * UUIDGenerator is the class that contains factory methods for - * generating UUIDs using one of the three specified 'standard' - * UUID generation methods: - * (see draft-leach-uuids-guids-01.txt for details) - *

    - *
  • Time-based generation generates UUID using spatial and - * temporal uniqueness. Spatial uniqueness is derived from - * ethernet address (MAC, 802.1); temporal from system clock. - * See the details from the explanation of - * {@link #generateTimeBasedUUID} function. - *
  • Name-based method uses MD5 hash (or, optionally any user-specified - * digest method) of the string formed from - * a name space and name. - *
  • Random method uses Java2 API's SecureRandom to produce - * cryptographically secure UUIDs. - *
  • Tag URI - method uses a variation of name-based method; instead of - * using a name space UUID and name, a hash (MD5 by default) is calculated - * from URI-tag-prefix, 2 obligatory strings (URL, path) and one - * optional string (current date). The resulting UUID is still considered - * to be 'name-based UUID' as the specification does not have additional - * UUID type ids available. - * Note that this is a non-standard method and not strictly UUID-'standard' - * compliant. - *
- * - * Some comments about performance: - *
    - *
  • For non-performance critical generation, all methods with default - * arguments (default random number generator, default hash algorithm) - * should do just fine. - *
  • When optimizing performance, it's better to use explicit random - * number generator and/or hash algorithm; this way global instance - * sharing need not be synchronized - *
  • Which of the 3 methods is fastest? It depends, and the best way - * is to just measure performance, discarding the first UUID generated - * with the methods. With time-based method, main overhead comes from - * synchronization, with name-based (MD5-)hashing, and with random-based - * the speed of random-number generator. Additionally, all methods may - * incur some overhead when using the shared global random nunber - * generator or hash algorithm. - *
  • When generating the first UUID with random-/time-based methods, - * there may be noticeable delay, as the random number generator is - * initialized. This can be avoided by either pre-initialising the - * random number generator passed (with random-based method), or by - * generating a dummy UUID on a separate thread, when starting a - * program needs to generate UUIDs at a later point. - * - *
- */ -public final class UUIDGenerator -{ - private final static UUIDGenerator sSingleton = new UUIDGenerator(); - - /** - * Random-generator, used by various UUID-generation methods: - */ - private Random mRnd = null; - - // Ethernet address for time-based UUIDs: - - private final Object mDummyAddressLock = new Object(); - private EthernetAddress mDummyAddress = null; - private final Object mTimerLock = new Object(); - private UUIDTimer mTimer = null; - - /** - * MD5 hasher for name-based digests: - */ - private MessageDigest mHasher = null; - - /* - ///////////////////////////////////////////////////// - // Life-cycle - ///////////////////////////////////////////////////// - */ - - /** - * Constructor is private to enforce singleton access. - */ - private UUIDGenerator() { } - - /** - * Method used for accessing the singleton generator instance. - */ - public static UUIDGenerator getInstance() - { - return sSingleton; - } - - /** - * Method that can (and should) be called once right after getting - * the instance, to ensure that system time stamp values used are - * valid (with respect to values used earlier by JUG instances), and - * to use file-lock based synchronization mechanism to prevent multiple - * JVMs from running conflicting instances of JUG (first one to be - * started wins on contention). It can also be called to stop - * synchronization by calling it with argument null, although such - * usage is strongly discouraged (ie. it's a good idea to either never - * use synchronization, or always; but not to mix modes). - *

- * Caller needs to instantiate an instance of - * {@link TimestampSynchronizer}; currently the only standard - * implementation is - * {@link org.safehaus.uuid.ext.FileBasedTimestampSynchronizer} (which - * is JDK 1.4+). - *

- * Note: since the generator instance is a singleton, calling this - * method will always cause all generation to be synchronized using - * the specified method. - * - * @param sync Synchronizer instance to use for synchronization. - */ - - public void synchronizeExternally(TimestampSynchronizer sync) - throws IOException - { - synchronized (mTimerLock) { - if (mTimer == null) { - mTimer = new UUIDTimer(getRandomNumberGenerator()); - } - mTimer.setSynchronizer(sync); - } - } - - /* - ///////////////////////////////////////////////////// - // Configuration - ///////////////////////////////////////////////////// - */ - - /** - * Method that returns a randomly generated dummy ethernet address. - * To prevent collision with real addresses, the returned address has - * the broadcast bit set, ie. it doesn't represent address of any existing - * NIC. - * - * Note that this dummy address will be shared for the lifetime of - * this UUIDGenerator, ie. only one is ever generated independent of - * how many times this methods is called. - * - * @return Randomly generated dummy ethernet broadcast address. - */ - public EthernetAddress getDummyAddress() - { - synchronized (mDummyAddressLock) { - if (mDummyAddress == null) { - Random rnd = getRandomNumberGenerator(); - byte[] dummy = new byte[6]; - rnd.nextBytes(dummy); - /* Need to set the broadcast bit to indicate it's not a real - * address. - */ - /* 08-Feb-2004, TSa: Note: it's the least bit, not highest; - * thanks to Ralf S. Engelschall for fix: - */ - dummy[0] |= (byte) 0x01; - try { - mDummyAddress = new EthernetAddress(dummy); - } catch (NumberFormatException nex) { - /* Let's just let this cause a null-pointer exception - * later on... - */ - } - } - } - - return mDummyAddress; - } - - /** - * Method for getting the shared random number generator used for - * generating the UUIDs. This way the initialization cost is only - * taken once; access need not be synchronized (or in cases where - * it has to, SecureRandom takes care of it); it might even be good - * for getting really 'random' stuff to get shared access... - */ - public Random getRandomNumberGenerator() - { - /* Could be synchronized, but since side effects are trivial - * (ie. possibility of generating more than one SecureRandom, - * of which all but one are dumped) let's not add synchronization - * overhead: - */ - if (mRnd == null) { - mRnd = new SecureRandom(); - } - return mRnd; - } - - /** - * Method that can be called to specify alternative random - * number generator to use. This is usually done to use - * implementation that is faster than - * {@link SecureRandom} that is used by default. - *

- * Note that to avoid first-time initialization penalty - * of using {@link SecureRandom}, this method has to be called - * before generating the first random-number based UUID. - */ - public void setRandomNumberGenerator(Random r) - { - mRnd = r; - } - - /* Method for getting the shared message digest (hash) algorithm. - * Whether to use the shared one or not depends; using shared instance - * adds synchronization overhead (access has to be sync'ed), but - * using multiple separate digests wastes memory. - */ - public MessageDigest getHashAlgorithm() - { - /* Similar to the shared random number generator, it's not necessary - * to synchronize initialization. However, use of the hash instance - * HAS to be synchronized by the caller to prevent problems with - * multiple threads updating digest etc. - */ - if (mHasher == null) { - try { - mHasher = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException nex) { - throw new Error("Couldn't instantiate an MD5 MessageDigest instance: "+nex.toString()); - } - } - return mHasher; - } - - /* - ///////////////////////////////////////////////////// - // UUID generation methods - ///////////////////////////////////////////////////// - */ - - /** - * Method for generating (pseudo-)random based UUIDs, using the - * default (shared) SecureRandom object. - * - * Note that the first time - * SecureRandom object is used, there is noticeable delay between - * calling the method and getting the reply. This is because SecureRandom - * has to initialize itself to reasonably random state. Thus, if you - * want to lessen delay, it may be be a good idea to either get the - * first random UUID asynchronously from a separate thread, or to - * use the other generateRandomBasedUUID passing a previously initialized - * SecureRandom instance. - * - * @return UUID generated using (pseudo-)random based method - */ - public UUID generateRandomBasedUUID() - { - return generateRandomBasedUUID(getRandomNumberGenerator()); - } - - /** - * Method for generating (pseudo-)random based UUIDs, using the - * specified SecureRandom object. To prevent/avoid delay JDK's - * default SecureRandom object causes when first random number - * is generated, it may be a good idea to initialize the SecureRandom - * instance (on a separate thread for example) when app starts. - * - * @param randomGenerator Random number generator to use for getting the - * random number from which UUID will be composed. - * - * @return UUID generated using (pseudo-)random based method - */ - public UUID generateRandomBasedUUID(Random randomGenerator) - { - byte[] rnd = new byte[16]; - - randomGenerator.nextBytes(rnd); - - return new UUID(UUID.TYPE_RANDOM_BASED, rnd); - } - - /** - * Method for generating time based UUIDs. Note that this version - * doesn't use any existing Hardware address (because none is available - * for some reason); instead it uses randomly generated dummy broadcast - * address. - *

- * Note that since the dummy address is only to be created once and - * shared from there on, there is some synchronization overhead. - * - * @return UUID generated using time based method - */ - public UUID generateTimeBasedUUID() - { - return generateTimeBasedUUID(getDummyAddress()); - } - - /** - * Method for generating time based UUIDs. - * - * @param addr Hardware address (802.1) to use for generating - * spatially unique part of UUID. If system has more than one NIC, - * any address is usable. If no NIC is available (or its address - * not accessible; often the case with java apps), a randomly - * generated broadcast address is acceptable. If so, use the - * alternative method that takes no arguments. - * - * @return UUID generated using time based method - */ - public UUID generateTimeBasedUUID(EthernetAddress addr) - { - byte[] contents = new byte[16]; - - addr.toByteArray(contents, 10); - - synchronized (mTimerLock) { - if (mTimer == null) { - mTimer = new UUIDTimer(getRandomNumberGenerator()); - } - - mTimer.getTimestamp(contents); - } - - return new UUID(UUID.TYPE_TIME_BASED, contents); - } - - /** - * Method for generating name-based UUIDs, using the standard - * name-based generation method described in the UUID specs, - * and the caller supplied hashing method. - * - * Note that this method is not synchronized, so caller has to make - * sure the digest object will not be accessed from other threads. - * - * Note that if you call this method directly (instead of calling - * the version with one less argument), you have to make sure that - * access to 'hash' is synchronized; either by only generating UUIDs - * from one single thread, or by using explicit sync'ing. - * - * @param nameSpaceUUID UUID of the namespace, as defined by the - * spec. UUID has 4 pre-defined "standard" name space strings - * that can be passed to UUID constructor (see example below). - * Note that this argument is optional; if no namespace is needed - * (for example when name includes namespace prefix), null may be - * passed. - * @param name Name to base the UUID on; for example, - * IP-name ("www.w3c.org") of the system for UUID.NAMESPACE_DNS, - * URL ("http://www.w3c.org/index.html") for UUID.NAMESPACE_URL - * and so on. - * @param digest Instance of MessageDigest to use for hashing the name - * value. hash.reset() will be called before calculating the has - * value, to make sure digest state is not random and UUID will - * not be randomised. - * - * @return UUID generated using name-based method based on the - * arguments given. - * - * Example: - * - * UUID uuid = gen.generateNameBasedUUID( - * new UUID(UUID.NAMESPACE_DNS, "www.w3c.org")); - * - */ - public UUID generateNameBasedUUID(UUID nameSpaceUUID, String name, - MessageDigest digest) - { - digest.reset(); - if (nameSpaceUUID != null) { - digest.update(nameSpaceUUID.asByteArray()); - } - digest.update(name.getBytes()); - return new UUID(UUID.TYPE_NAME_BASED, digest.digest()); - } - - /** - * Method similar to the previous one; the difference being that a - * shared MD5 digest instance will be used. This also means that there is - * some synchronization overhead as MD5-instances are not thread-safe - * per se. - */ - public UUID generateNameBasedUUID(UUID nameSpaceUUID, String name) - { - MessageDigest hasher = getHashAlgorithm(); - synchronized (hasher) { - return generateNameBasedUUID(nameSpaceUUID, name, getHashAlgorithm()); - } - } - - /** - * Method for generating UUIDs using tag URIs. A hash is calculated from - * the given tag URI (default being MD5 hash). The resulting UUIDs - * are reproducible, ie. given the same tag URI, same UUID will always - * result, much like with the default name-based generation method. - * - * Note that this a non-standard way of generating UUIDs; it will create - * UUIDs that appear to be name-based (and which are, but not using the - * method specified in UUID specs). - * - * @param name tag URI to base UUID on. - */ - public UUID generateTagURIBasedUUID(TagURI name) - { - return generateNameBasedUUID(null, name.toString()); - } - - /** - * Method for generating UUIDs using tag URIs. A hash is calculated from - * the given tag URI using the specified hashing algorith,. - * The resulting UUIDs are reproducible, ie. given the same tag URI and - * hash algorithm, same UUID will always result, much like with the - * default name-based generation method. - * - * Note that this a non-standard way of generating UUIDs; it will create - * UUIDs that appear to be name-based (and which are, but not using the - * method specified in UUID specs). - * - * @param name tag URI to base UUID on. - * @param hasher Hashing algorithm to use. Note that the caller has to - * make sure that it's thread-safe to use 'hasher', either by never - * calling this method from multiple threads, or by explicitly sync'ing - * the calls. - */ - public UUID generateTagURIBasedUUID(TagURI name, MessageDigest hasher) - { - return generateNameBasedUUID(null, name.toString(), hasher); - } - - /* - ///////////////////////////////////////////////////// - // Other methods - ///////////////////////////////////////////////////// - */ - - /** - * A simple test harness is added to make (automated) testing of the - * class easier. For real testing, JUnit based unit tests should - * be run. - */ - public static void main(String[] args) - { - UUIDGenerator g = UUIDGenerator.getInstance(); - UUID nsUUID = new UUID(UUID.NAMESPACE_URL); - - System.out.println("UUIDGenerator.main()"); - System.out.println(); - - /* Let's test equality testing and ordering by using TreeSet; - * since all UUIDs should be unique set should contain them all, - * and in the specified order. - */ - final int ROUNDS = 4; - final int UUID_COUNT = ROUNDS * 3; - Set uuids = new TreeSet(); - List timebased = new ArrayList(ROUNDS); - - /* First we'll create the UUIDs and do conversion tests: - */ - for (int i = 0; i < ROUNDS; ++i) { - System.out.print("Random UUID: "); - UUID u = g.generateRandomBasedUUID(); - uuids.add(u); - doTest(u, System.out, UUID.TYPE_RANDOM_BASED); - - System.out.print("Time-based UUID: "); - u = g.generateTimeBasedUUID(); - uuids.add(u); - timebased.add(u); - doTest(u, System.out, UUID.TYPE_TIME_BASED); - - String name = "test-round-"+i; - System.out.print("Named-based UUID: (namespace URL, name '" - +name+"')"); - u = g.generateNameBasedUUID(nsUUID, name); - uuids.add(u); - doTest(u, System.out, UUID.TYPE_NAME_BASED); - } - - /* And then we'll see if comparision & sorting work as - * expected: - */ - int count = uuids.size(); - System.out.print("Created "+UUID_COUNT+" uuids; ordered treeset contains "+count); - System.out.println((count == UUID_COUNT) ? " [OK]" : " [FAIL]"); - System.out.println("Checking ordering:"); - - // First, major ordering by type: - Iterator it = uuids.iterator(); - int prevType = -1; - System.out.print("Overall ordering by type: "); - while (it.hasNext()) { - System.out.print("."); - UUID uuid = (UUID) it.next(); - int currType = uuid.getType(); - if (currType < prevType) { - break; - } - prevType = currType; - } - System.out.println(it.hasNext() ? "FAIL" : "OK"); - - // And then ordering of time-based UUIDs: - it = uuids.iterator(); - int lastIndex = -1; - System.out.print("Time-based UUID ordering on creation time: "); - while (it.hasNext()) { - UUID uuid = (UUID) it.next(); - int index = timebased.indexOf(uuid); - if (index >= 0) { - System.out.print("["); - System.out.print(index); - System.out.print("]"); - if (index <= lastIndex) { - break; - } - } - } - System.out.println(it.hasNext() ? "FAIL" : "OK"); - - /* Then we'll see if both shared and explicit null UUIDs are - * recognized as null UUIDs: - */ - doTestNull(); - } - - private final static void doTest(UUID uuid, PrintStream out, int type) - { - System.out.print(uuid.toString()); - System.out.print(" [type: "+uuid.getType()); - System.out.print(", expected "+type); - System.out.print(type == uuid.getType() ? ": OK" : ": FAIL"); - System.out.println("]"); - - // Conversion test, UUID <-> string - System.out.print("... conversion UUID<->String: "); - try { - UUID uuid2 = UUID.valueOf(uuid.toString()); - System.out.println(uuid2.toString()); - System.out.print(" -> "); - System.out.println(uuid.equals(uuid2) ? "OK" : "FAIL"); - } catch (NumberFormatException nex) { - System.out.println("[FAIL: "+nex.toString()+"]"); - } - - // Conversion test, UUID <-> byte array - System.out.print("... conversion UUID<->byte array: "); - { - UUID uuid3 = UUID.valueOf(uuid.asByteArray()); - System.out.println(uuid3.toString()); - System.out.print(" -> "); - System.out.println(uuid.equals(uuid3) ? "OK" : "FAIL"); - } - - System.out.print("... considered null? "); - boolean isNull = uuid.isNullUUID(); - System.out.print(isNull); - System.out.print(" (shouldn't be) -> "); - System.out.println(isNull ? "FAIL" : "OK"); - } - - private final static void doTestNull() - { - UUID sharedNull = UUID.getNullUUID(); - - System.out.println("Testing null UUID checks:"); - - System.out.print("Testing shared null uuid; considered null: "); - boolean ok = sharedNull.isNullUUID(); - System.out.print(ok); - System.out.print("; expected true -> "); - System.out.println(ok ? "OK" : "FAIL"); - - UUID localNull = new UUID(new byte[16]); // java runtime clears the array - - System.out.print("Testing explicit null uuid; considered null: "); - ok = localNull.isNullUUID(); - System.out.print(ok); - System.out.print("; expected true -> "); - System.out.println(ok ? "OK" : "FAIL"); - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/UUID.java jug-3.1.5/src/java/org/safehaus/uuid/UUID.java --- jug-2.0.0/src/java/org/safehaus/uuid/UUID.java 2005-08-02 05:28:42.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/UUID.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,572 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.Serializable; - -/** - * UUID represents Universally Unique Identifiers (aka Global UID in - * Windows world). UUIDs are usually generated via UUIDGenerator (or in - * case of 'Null UUID', 16 zero bytes, via static method getNullUUID()), - * or received from external systems. - * - * By default class caches the string presentations of UUIDs so that - * description is only created the first time it's needed. For memory - * stingy applications this caching can be turned off (note though - * that if uuid.toString() is never called, desc is never calculated - * so only loss is the space allocated for the desc pointer... which - * can of course be commented out to save memory). - * - * Similarly, hash code is calculated when it's needed for the first - * time, and from thereon that value is just returned. This means - * that using UUIDs as keys should be reasonably efficient. - * - * UUIDs can be compared for equality, serialized, cloned and even sorted. - * Equality is a simple bit-wise comparison. Ordering (for sorting) is done by - * first ordering based on type (in the order of numeric values of - * types), secondarily by time stamp (only for time-based time stamps), - * and finally by straight numeric byte-by-byte comparison (from - * most to least significant bytes). - */ - -public class UUID - implements Serializable, Cloneable, Comparable -{ - private final static String kHexChars = "0123456789abcdefABCDEF"; - - public final static byte INDEX_CLOCK_HI = 6; - public final static byte INDEX_CLOCK_MID = 4; - public final static byte INDEX_CLOCK_LO = 0; - - public final static byte INDEX_TYPE = 6; - // Clock seq. & variant are multiplexed... - public final static byte INDEX_CLOCK_SEQUENCE = 8; - public final static byte INDEX_VARIATION = 8; - - public final static byte TYPE_NULL = 0; - public final static byte TYPE_TIME_BASED = 1; - public final static byte TYPE_DCE = 2; // Not used - public final static byte TYPE_NAME_BASED = 3; - public final static byte TYPE_RANDOM_BASED = 4; - - /* 'Standard' namespaces defined (suggested) by UUID specs: - */ - public final static String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; - public final static String NAMESPACE_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; - public final static String NAMESPACE_OID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"; - public final static String NAMESPACE_X500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"; - - /* By default let's cache desc, can be turned off. For hash code - * there's no point in turning it off (since the int is already - * part of the instance memory allocation); if you want to save - * those 4 bytes (or possibly bit more if alignment is bad) just - * comment out hash caching. - */ - private static boolean sDescCaching = true; - - /** - * The shared null UUID. Would be nice to do lazy instantiation, but - * if the instance really has to be a singleton, that would mean - * class-level locking (synchronized getNullUUID()), which would - * be some overhead... So let's just bite the bullet the first time - * assuming creation of the null UUID (plus wasted space if it's - * not needed) can be ignored. - */ - private final static UUID sNullUUID = new UUID(); - - private final byte[] mId = new byte[16]; - // Both string presentation and hash value may be cached... - private transient String mDesc = null; - private transient int mHashCode = 0; - - /* *** Object creation: *** */ - - /** - * Default constructor creates a NIL UUID, one that contains all - * zeroes - * - * Note that the clearing of array is actually unnecessary as - * JVMs are required to clear up the allocated arrays by default. - */ - public UUID() - { - /* - for (int i = 0; i < 16; ++i) { - mId[i] = (byte)0; - } - */ - } - - /** - * Constructor for cases where you already have the 16-byte binary - * representation of the UUID (for example if you save UUIDs binary - * takes less than half of space string representation takes). - * - * @param data array that contains the binary representation of UUID - */ - public UUID(byte[] data) - { - /* Could call the other constructor... and/or use System.arraycopy. - * However, it's likely that those would make this slower to use, - * and initialization is really simple as is in any case. - */ - for (int i = 0; i < 16; ++i) { - mId[i] = data[i]; - } - } - - /** - * Constructor for cases where you already have the binary - * representation of the UUID (for example if you save UUIDs binary - * takes less than half of space string representation takes) in - * a byte array - * - * @param data array that contains the binary representation of UUID - * @param start byte offset where UUID starts - */ - public UUID(byte[] data, int start) - { - for (int i = 0; i < 16; ++i) { - mId[i] = data[start + i]; - } - } - - /** - * Protected constructor used by UUIDGenerator - * - * @param type UUID type - * @param data 16 byte UUID contents - */ - UUID(int type, byte[] data) - { - for (int i = 0; i < 16; ++i) { - mId[i] = data[i]; - } - // Type is multiplexed with time_hi: - mId[INDEX_TYPE] &= (byte) 0x0F; - mId[INDEX_TYPE] |= (byte) (type << 4); - // Variant masks first two bits of the clock_seq_hi: - mId[INDEX_VARIATION] &= (byte) 0x3F; - mId[INDEX_VARIATION] |= (byte) 0x80; - } - - /** - * Constructor for creating UUIDs from the canonical string - * representation - * - * Note that implementation is optimized for speed, not necessarily - * code clarity... Also, since what we get might not be 100% canonical - * (see below), let's not yet populate mDesc here. - * - * @param id String that contains the canonical representation of - * the UUID to build; 36-char string (see UUID specs for details). - * Hex-chars may be in upper-case too; UUID class will always output - * them in lowercase. - */ - public UUID(String id) - throws NumberFormatException - { - if (id == null) { - throw new NullPointerException(); - } - if (id.length() != 36) { - throw new NumberFormatException("UUID has to be represented by the standard 36-char representation"); - } - - for (int i = 0, j = 0; i < 36; ++j) { - // Need to bypass hyphens: - switch (i) { - case 8: - case 13: - case 18: - case 23: - if (id.charAt(i) != '-') { - throw new NumberFormatException("UUID has to be represented by the standard 36-char representation"); - } - ++i; - } - int index; - char c = id.charAt(i); - - if (c >= '0' && c <= '9') { - mId[j] = (byte) ((c - '0') << 4); - } else if (c >= 'a' && c <= 'f') { - mId[j] = (byte) ((c - 'a' + 10) << 4); - } else if (c >= 'A' && c <= 'F') { - mId[j] = (byte) ((c - 'A' + 10) << 4); - } else { - throw new NumberFormatException("Non-hex character '"+c+"'"); - } - - c = id.charAt(++i); - - if (c >= '0' && c <= '9') { - mId[j] |= (byte) (c - '0'); - } else if (c >= 'a' && c <= 'f') { - mId[j] |= (byte) (c - 'a' + 10); - } else if (c >= 'A' && c <= 'F') { - mId[j] |= (byte) (c - 'A' + 10); - } else { - throw new NumberFormatException("Non-hex character '"+c+"'"); - } - ++i; - } - } - - /** - * Default cloning behaviour (bitwise copy) is just fine... - * - * Could clear out cached string presentation, but there's - * probably no point in doing that. - */ - public Object clone() - { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - // shouldn't happen - return null; - } - } - - /* *** Configuration: *** */ - public static void setDescCaching(boolean state) - { - sDescCaching = state; - } - - /* *** Accessors: *** */ - - /** - * Accessor for getting the shared null UUID - * - * @return the shared null UUID - */ - public static UUID getNullUUID() - { - return sNullUUID; - } - - public boolean isNullUUID() - { - // Assuming null uuid is usually used for nulls: - if (this == sNullUUID) { - return true; - } - // Could also check hash code; null uuid has -1 as hash? - byte[] data = mId; - int i = mId.length; - byte zero = (byte) 0; - while (--i >= 0) { - if (data[i] != zero) { - return false; - } - } - - return true; - } - - /** - * Returns the UUID type code - * - * @return UUID type - */ - public int getType() - { - return (mId[INDEX_TYPE] & 0xFF) >> 4; - } - - /** - * Returns the UUID as a 16-byte byte array - * - * @return 16-byte byte array that contains UUID bytes in the network - * byte order - */ - public byte[] asByteArray() - { - byte[] result = new byte[16]; - toByteArray(result); - return result; - } - - /** - * Fills in the 16 bytes (from index pos) of the specified byte array - * with the UUID contents. - * - * @param dst Byte array to fill - * @param pos Offset in the array - */ - public void toByteArray(byte[] dst, int pos) - { - byte[] src = mId; - for (int i = 0; i < 16; ++i) { - dst[pos+i] = src[i]; - } - } - - public void toByteArray(byte[] dst) { toByteArray(dst, 0); } - - /** - * 'Synonym' for 'asByteArray' - */ - public byte[] toByteArray() { return asByteArray(); } - - /* *** Standard methods from Object overridden: *** */ - - /** - * Could use just the default hash code, but we can probably create - * a better identity hash (ie. same contents generate same hash) - * manually, without sacrificing speed too much. Although multiplications - * with modulos would generate better hashing, let's use just shifts, - * and do 2 bytes at a time. - *

- * Of course, assuming UUIDs are randomized enough, even simpler - * approach might be good enough? - *

- * Is this a good hash? ... one of these days I better read more about - * basic hashing techniques I swear! - */ - private final static int[] kShifts = { - 3, 7, 17, 21, 29, 4, 9 - }; - - public int hashCode() - { - if (mHashCode == 0) { - // Let's handle first and last byte separately: - int result = mId[0] & 0xFF; - - result |= (result << 16); - result |= (result << 8); - - for (int i = 1; i < 15; i += 2) { - int curr = (mId[i] & 0xFF) << 8 | (mId[i+1] & 0xFF); - int shift = kShifts[i >> 1]; - - if (shift > 16) { - result ^= (curr << shift) | (curr >>> (32 - shift)); - } else { - result ^= (curr << shift); - } - } - - // and then the last byte: - int last = mId[15] & 0xFF; - result ^= (last << 3); - result ^= (last << 13); - - result ^= (last << 27); - // Let's not accept hash 0 as it indicates 'not hashed yet': - if (result == 0) { - mHashCode = -1; - } else { - mHashCode = result; - } - } - return mHashCode; - } - - public String toString() - { - /* Could be synchronized, but there isn't much harm in just taking - * our chances (ie. in the worst case we'll form the string more - * than once... but result is the same) - */ - - if (mDesc == null) { - StringBuffer b = new StringBuffer(36); - - for (int i = 0; i < 16; ++i) { - // Need to bypass hyphens: - switch (i) { - case 4: - case 6: - case 8: - case 10: - b.append('-'); - } - int hex = mId[i] & 0xFF; - b.append(kHexChars.charAt(hex >> 4)); - b.append(kHexChars.charAt(hex & 0x0f)); - } - if (!sDescCaching) { - return b.toString(); - } - mDesc = b.toString(); - } - return mDesc; - } - - /* *** Comparison methods: *** */ - - private final static int[] sTimeCompare = new int[] { - INDEX_CLOCK_HI, INDEX_CLOCK_HI + 1, - INDEX_CLOCK_MID, INDEX_CLOCK_MID + 1, - INDEX_CLOCK_LO, INDEX_CLOCK_LO + 1, - INDEX_CLOCK_LO + 2, INDEX_CLOCK_LO + 3, - }; - - /** - * Let's also make UUIDs sortable. This will mostly/only be useful with - * time-based UUIDs; they will sorted by time of creation. The order - * will be strictly correct with UUIDs produced over one JVM's lifetime; - * that is, if more than one JVMs create UUIDs and/or system is rebooted - * the order may not be 100% accurate between UUIDs created under - * different JVMs. - * - * For all UUIDs, type is first compared, and UUIDs of different types - * are sorted together (ie. null UUID is before all other UUIDs, then - * time-based UUIDs etc). If types are the same, time-based UUIDs' - * time stamps (including additional clock counter) are compared, so - * UUIDs created first are ordered first. For all other types (and for - * time-based UUIDs with same time stamp, which should only occur - * when comparing a UUID with itself, or with UUIDs created on - * different JVMs or external systems) binary comparison is done - * over all 16 bytes. - * - * @param o Object to compare this UUID to; should be a UUID - * - * @return -1 if this UUID should be ordered before the one passed, - * 1 if after, and 0 if they are the same - * - * @throws ClassCastException if o is not a UUID. - */ - public int compareTo(Object o) - { - UUID other = (UUID) o; - - int thisType = getType(); - int thatType = other.getType(); - - /* Let's first order by type: - */ - if (thisType > thatType) { - return 1; - } else if (thisType < thatType) { - return -1; - } - - /* And for time-based UUIDs let's compare time stamps first, - * then the rest... For all other types, we'll just do straight - * byte-by-byte comparison. - */ - byte[] thisId = mId; - byte[] thatId = other.mId; - int i = 0; - if (thisType == TYPE_TIME_BASED) { - for (; i < 8; ++i) { - int index = sTimeCompare[i]; - int cmp = (((int) thisId[index]) & 0xFF) - - (((int) thatId[index]) & 0xFF); - if (cmp != 0) { - return cmp; - } - } - // Let's fall down to full comparison otherwise - } - - for (; i < 16; ++i) { - int cmp = (((int) thisId[i]) & 0xFF) - (((int) thatId[i]) & 0xFF); - if (cmp != 0) { - return cmp; - } - } - - return 0; - } - - /** - * Checking equality of UUIDs is easy; just compare the 128-bit - * number. - */ - public boolean equals(Object o) - { - if (!(o instanceof UUID)) { - return false; - } - byte[] otherId = ((UUID) o).mId; - byte[] thisId = mId; - for (int i = 0; i < 16; ++i) { - if (otherId[i] != thisId[i]) { - return false; - } - } - return true; - } - - /** - * Constructs a new UUID instance given the canonical string - * representation of an UUID. - * - * Note that calling this method returns the same result as would - * using the matching (1 string arg) constructor. - * - * @param id Canonical string representation used for constructing - * an UUID instance - * - * @throws NumberFormatException if 'id' is invalid UUID - */ - public static UUID valueOf(String id) - throws NumberFormatException - { - return new UUID(id); - } - - /** - * Constructs a new UUID instance given a byte array that contains - * the (16 byte) binary representation. - * - * Note that calling this method returns the same result as would - * using the matching constructor - * - * @param src Byte array that contains the UUID definition - * @param start Offset in the array where the UUID starts - */ - public static UUID valueOf(byte[] src, int start) - { - return new UUID(src, start); - } - - /** - * Constructs a new UUID instance given a byte array that contains - * the (16 byte) binary representation. - * - * Note that calling this method returns the same result as would - * using the matching constructor - * - * @param src Byte array that contains the UUID definition - */ - public static UUID valueOf(byte[] src) - { - return new UUID(src); - } - - private void copyFrom(UUID src) - { - byte[] srcB = src.mId; - byte[] dstB = mId; - - for (int i = 0; i < 16; ++i) { - dstB[i] = srcB[i]; - } - - mDesc = sDescCaching ? src.mDesc : null; - } - - public static void main(String[] args) - { - } -} diff -Nru jug-2.0.0/src/java/org/safehaus/uuid/UUIDTimer.java jug-3.1.5/src/java/org/safehaus/uuid/UUIDTimer.java --- jug-2.0.0/src/java/org/safehaus/uuid/UUIDTimer.java 2005-08-08 05:44:49.000000000 +0000 +++ jug-3.1.5/src/java/org/safehaus/uuid/UUIDTimer.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,363 +0,0 @@ -/* JUG Java Uuid Generator - * - * Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi - * - * 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 org.safehaus.uuid; - -import java.io.*; -import java.util.*; - -/** - * UUIDTimer produces the time stamps required for time-based UUIDs. - * It works as outlined in the UUID specification, with following - * implementation: - *

    - *
  • Java classes can only product time stamps with maximum resolution - * of one millisecond (at least before JDK 1.5). - * To compensate, an additional counter is used, - * so that more than one UUID can be generated between java clock - * updates. Counter may be used to generate up to 10000 UUIDs for - * each distrinct java clock value. - *
  • Due to even lower clock resolution on some platforms (older - * Windows versions use 55 msec resolution), timestamp value can - * also advanced ahead of physical value within limits (by default, - * up 100 millisecond ahead of reported), iff necessary (ie. 10000 - * instances created before clock time advances). - *
  • As an additional precaution, counter is initialized not to 0 - * but to a random 8-bit number, and each time clock changes, lowest - * 8-bits of counter are preserved. The purpose it to make likelyhood - * of multi-JVM multi-instance generators to collide, without significantly - * reducing max. UUID generation speed. Note though that using more than - * one generator (from separate JVMs) is strongly discouraged, so - * hopefully this enhancement isn't needed. - * This 8-bit offset has to be reduced from total max. UUID count to - * preserve ordering property of UUIDs (ie. one can see which UUID - * was generated first for given UUID generator); the resulting - * 9500 UUIDs isn't much different from the optimal choice. - *
  • Finally, as of version 2.0 and onwards, optional external timestamp - * synchronization can be done. This is done similar to the way UUID - * specification suggests; except that since there is no way to - * lock the whole system, file-based locking is used. This works - * between multiple JVMs and Jug instances. - *
- *

- *Some additional assumptions about calculating the timestamp: - *

    - *
  • System.currentTimeMillis() is assumed to give time offset in UTC, - * or at least close enough thing to get correct timestamps. The - * alternate route would have to go through calendar object, use - * TimeZone offset to get to UTC, and then modify. Using currentTimeMillis - * should be much faster to allow rapid UUID creation. - *
  • Similarly, the constant used for time offset between 1.1.1970 and - * start of Gregorian calendar is assumed to be correct (which seems - * to be the case when testing with Java calendars). - *
- *

- * Note about synchronization: this class is assumed to always be called - * from a synchronized context (caller locks on either this object, or - * a similar timer lock), and so has no method synchronization. - */ -public class UUIDTimer -{ - // // // Constants - - /** - * Since System.longTimeMillis() returns time from january 1st 1970, - * and UUIDs need time from the beginning of gregorian calendar - * (15-oct-1582), need to apply the offset: - */ - private final static long kClockOffset = 0x01b21dd213814000L; - /** - * Also, instead of getting time in units of 100nsecs, we get something - * with max resolution of 1 msec... and need the multiplier as well - */ - private final static long kClockMultiplier = 10000; - private final static long kClockMultiplierL = 10000L; - - /** - * Let's allow "virtual" system time to advance at most 100 milliseconds - * beyond actual physical system time, before adding delays. - */ - private final static long kMaxClockAdvance = 100L; - - // // // Configuration - - private final Random mRnd; - - // // // Clock state: - - /** - * Additional state information used to protect against anomalous - * cases (clock time going backwards, node id getting mixed up). - * Third byte is actually used for seeding counter on counter - * overflow. - */ - private final byte[] mClockSequence = new byte[3]; - - /** - * Last physical timestamp value System.currentTimeMillis() - * returned: used to catch (and report) cases where system clock - * goes backwards. Is also used to limit "drifting", that is, amount - * timestamps used can differ from the system time value. This value - * is not guaranteed to be monotonically increasing. - */ - private long mLastSystemTimestamp = 0L; - - /** - * Timestamp value last used for generating a UUID (along with - * {@link #mClockCounter}. Usually the same as - * {@link #mLastSystemTimestamp}, but not always (system clock - * moved backwards). Note that this value is guaranteed to be - * monotonically increasing; that is, at given absolute time points - * t1 and t2 (where t2 is after t1), t1 <= t2 will always hold true. - */ - private long mLastUsedTimestamp = 0L; - - /** - * First timestamp that can NOT be used without synchronizing - * using synchronization object ({@link #mSync}). Only used when - * external timestamp synchronization (and persistence) is used, - * ie. when {@link #mSync} is not null. - */ - private long mFirstUnsafeTimestamp = Long.MAX_VALUE; - - /** - * Counter used to compensate inadequate resolution of JDK system - * timer. - */ - private int mClockCounter = 0; - - /** - * Object used to reliably ensure that no multiple JVMs - * generate UUIDs, and also that the time stamp value used for - * generating time-based UUIDs is monotonically increasing - * even if system clock moves backwards over a reboot (usually - * due to some system level problem). - *

- * See {@link TimestampSynchronizer} for details. - */ - private TimestampSynchronizer mSync = null; - - UUIDTimer(Random rnd) - { - mRnd = rnd; - initCounters(rnd); - mLastSystemTimestamp = 0L; - // This may get overwritten by the synchronizer - mLastUsedTimestamp = 0L; - } - - private void initCounters(Random rnd) - { - /* Let's generate the clock sequence field now; as with counter, - * this reduces likelihood of collisions (as explained in UUID specs) - */ - rnd.nextBytes(mClockSequence); - /* Ok, let's also initialize the counter... - * Counter is used to make it slightly less likely that - * two instances of UUIDGenerator (from separate JVMs as no more - * than one can be created in one JVM) would produce colliding - * time-based UUIDs. The practice of using multiple generators, - * is strongly discouraged, of course, but just in case... - */ - mClockCounter = mClockSequence[2] & 0xFF; - } - - public void getTimestamp(byte[] uuidData) - { - // First the clock sequence: - uuidData[UUID.INDEX_CLOCK_SEQUENCE] = mClockSequence[0]; - uuidData[UUID.INDEX_CLOCK_SEQUENCE+1] = mClockSequence[1]; - - long systime = System.currentTimeMillis(); - - /* Let's first verify that the system time is not going backwards; - * independent of whether we can use it: - */ - if (systime < mLastSystemTimestamp) { - Logger.logWarning("System time going backwards! (got value "+systime+", last "+mLastSystemTimestamp); - // Let's write it down, still - mLastSystemTimestamp = systime; - } - - /* But even without it going backwards, it may be less than the - * last one used (when generating UUIDs fast with coarse clock - * resolution; or if clock has gone backwards over reboot etc). - */ - if (systime <= mLastUsedTimestamp) { - /* Can we just use the last time stamp (ok if the counter - * hasn't hit max yet) - */ - if (mClockCounter < kClockMultiplier) { // yup, still have room - systime = mLastUsedTimestamp; - } else { // nope, have to roll over to next value and maybe wait - long actDiff = mLastUsedTimestamp - systime; - long origTime = systime; - systime = mLastUsedTimestamp + 1L; - - Logger.logWarning("Timestamp over-run: need to reinitialize random sequence"); - - /* Clock counter is now at exactly the multiplier; no use - * just anding its value. So, we better get some random - * numbers instead... - */ - initCounters(mRnd); - - /* But do we also need to slow down? (to try to keep virtual - * time close to physical time; ie. either catch up when - * system clock has been moved backwards, or when coarse - * clock resolution has forced us to advance virtual timer - * too far) - */ - if (actDiff >= kMaxClockAdvance) { - slowDown(origTime, actDiff); - } - } - } else { - /* Clock has advanced normally; just need to make sure counter is - * reset to a low value (need not be 0; good to leave a small - * residual to further decrease collisions) - */ - mClockCounter &= 0xFF; - } - - mLastUsedTimestamp = systime; - - /* Ok, we have consistent clock (virtual or physical) value that - * we can and should use. - * But do we need to check external syncing now? - */ - if (mSync != null && systime >= mFirstUnsafeTimestamp) { - try { - mFirstUnsafeTimestamp = mSync.update(systime); - } catch (IOException ioe) { - throw new RuntimeException("Failed to synchronize timestamp: "+ioe); - } - } - - /* Now, let's translate the timestamp to one UUID needs, 100ns - * unit offset from the beginning of Gregorian calendar... - */ - systime *= kClockMultiplierL; - systime += kClockOffset; - - // Plus add the clock counter: - systime += mClockCounter; - // and then increase - ++mClockCounter; - - /* Time fields are nicely split across the UUID, so can't just - * linearly dump the stamp: - */ - int clockHi = (int) (systime >>> 32); - int clockLo = (int) systime; - - uuidData[UUID.INDEX_CLOCK_HI] = (byte) (clockHi >>> 24); - uuidData[UUID.INDEX_CLOCK_HI+1] = (byte) (clockHi >>> 16); - uuidData[UUID.INDEX_CLOCK_MID] = (byte) (clockHi >>> 8); - uuidData[UUID.INDEX_CLOCK_MID+1] = (byte) clockHi; - - uuidData[UUID.INDEX_CLOCK_LO] = (byte) (clockLo >>> 24); - uuidData[UUID.INDEX_CLOCK_LO+1] = (byte) (clockLo >>> 16); - uuidData[UUID.INDEX_CLOCK_LO+2] = (byte) (clockLo >>> 8); - uuidData[UUID.INDEX_CLOCK_LO+3] = (byte) clockLo; - } - - public void setSynchronizer(TimestampSynchronizer sync) - throws IOException - { - TimestampSynchronizer old = mSync; - - if (old != null) { - try { - old.deactivate(); - } catch (IOException ioe) { - Logger.logError("Failed to deactivate the old synchronizer: "+ioe); - } - } - - mSync = sync; - - /* Ok, now; synchronizer can tell us what is the first timestamp - * value that definitely was NOT used by the previous incarnation. - * This can serve as the last used time stamp, assuming it is not - * less than value we are using now. - */ - if (sync != null) { - long lastSaved = sync.initialize(); - if (lastSaved > mLastUsedTimestamp) { - mLastUsedTimestamp = lastSaved; - } - } - - /* Also, we need to make sure there are now no safe values (since - * synchronizer is not yet requested to allocate any): - */ - mFirstUnsafeTimestamp = 0L; // ie. will always trigger sync.update() - } - - /* - /////////////////////////////////////////////////////////// - // Private methods - /////////////////////////////////////////////////////////// - */ - - private final static int MAX_WAIT_COUNT = 50; - - /** - * Simple utility method to use to wait for couple of milliseconds, - * to let system clock hopefully advance closer to the virtual - * timestamps used. Delay is kept to just a millisecond or two, - * to prevent excessive blocking; but that should be enough to - * eventually synchronize physical clock with virtual clock values - * used for UUIDs. - * - * @param msecs Number of milliseconds to wait for from current - * time point - */ - private final static void slowDown(long startTime, long actDiff) - { - /* First, let's determine how long we'd like to wait. - * This is based on how far ahead are we as of now. - */ - long ratio = actDiff / kMaxClockAdvance; - long delay; - - if (ratio < 2L) { // 200 msecs or less - delay = 1L; - } else if (ratio < 10L) { // 1 second or less - delay = 2L; - } else if (ratio < 600L) { // 1 minute or less - delay = 3L; - } else { - delay = 5L; - } - Logger.logWarning("Need to wait for "+delay+" milliseconds; virtual clock advanced too far in the future"); - long waitUntil = startTime + delay; - int counter = 0; - do { - try { - Thread.sleep(delay); - } catch (InterruptedException ie) { } - delay = 1L; - /* This is just a sanity check: don't want an "infinite" - * loop if clock happened to be moved backwards by, say, - * an hour... - */ - if (++counter > MAX_WAIT_COUNT) { - break; - } - } while (System.currentTimeMillis() < waitUntil); - } -} diff -Nru jug-2.0.0/src/java/test/FileSyncTest.java jug-3.1.5/src/java/test/FileSyncTest.java --- jug-2.0.0/src/java/test/FileSyncTest.java 2005-08-09 05:29:47.000000000 +0000 +++ jug-3.1.5/src/java/test/FileSyncTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -package test; - -import org.safehaus.uuid.*; -import org.safehaus.uuid.ext.*; - -/** - * Simple manual utility test class for manually checking whether file-based - * synchronization seems to be working or not. - */ -public class FileSyncTest -{ - public static void main(String[] args) - throws Exception - { - UUIDGenerator gen = UUIDGenerator.getInstance(); - FileBasedTimestampSynchronizer sync = - new FileBasedTimestampSynchronizer(); - // Let's stress-test it... - sync.setUpdateInterval(2000L); - gen.synchronizeExternally(sync); - - int counter = 1; - while (true) { - UUID uuid = gen.generateTimeBasedUUID(); - // Default one is for convenient output - System.out.println("#"+counter+" -> "+uuid); - - /* This allows lexical sorting by uuid... (not very useful, - * since 'real' UUID ordering is not lexical) - */ - //System.out.println(""+uuid+" (#"+counter+")"); - - // And this can be used to ensure there are no dups: - //System.out.println(""+uuid); - ++counter; - - try { - Thread.sleep(120L); - } catch (InterruptedException ie) { } - } - } -} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/EthernetAddress.java jug-3.1.5/src/main/java/com/fasterxml/uuid/EthernetAddress.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/EthernetAddress.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/EthernetAddress.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,497 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.Serializable; +import java.net.NetworkInterface; +import java.security.SecureRandom; +import java.util.Enumeration; +import java.util.Random; + +/** + * EthernetAddress encapsulates the 6-byte MAC address defined in + * IEEE 802.1 standard. + */ +public class EthernetAddress + implements Serializable, Cloneable, Comparable +{ + private static final long serialVersionUID = 1L; + + private final static char[] HEX_CHARS = "0123456789abcdefABCDEF".toCharArray(); + + /** + * We may need a random number generator, for creating dummy ethernet + * address if no real interface is found. + */ + protected static Random _rnd; + + /** + * 48-bit MAC address, stored in 6 lowest-significant bytes (in + * big endian notation) + */ + protected final long _address; + + /** + * Lazily-constructed String serialization + */ + private volatile String _asString; + + /* + /********************************************************************** + /* Instance construction + /********************************************************************** + */ + + /** + * String constructor; given a 'standard' ethernet MAC address string + * (like '00:C0:F0:3D:5B:7C'), constructs an EthernetAddress instance. + * + * Note that string is case-insensitive, and also that leading zeroes + * may be omitted. Thus '00:C0:F0:3D:5B:7C' and '0:c0:f0:3d:5b:7c' are + * equivalent, and a 'null' address could be passed as ':::::' as well + * as '00:00:00:00:00:00' (or any other intermediate combination). + * + * @param addrStr String representation of the ethernet address + */ + public EthernetAddress(String addrStr) + throws NumberFormatException + { + int len = addrStr.length(); + long addr = 0L; + + /* Ugh. Although the most logical format would be the 17-char one + * (12 hex digits separated by colons), apparently leading zeroes + * can be omitted. Thus... Can't just check string length. :-/ + */ + for (int i = 0, j = 0; j < 6; ++j) { + if (i >= len) { + // Is valid if this would have been the last byte: + if (j == 5) { + addr <<= 8; + break; + } + throw new NumberFormatException("Incomplete ethernet address (missing one or more digits"); + } + + char c = addrStr.charAt(i); + ++i; + int value; + + // The whole number may be omitted (if it was zero): + if (c == ':') { + value = 0; + } else { + // No, got at least one digit? + if (c >= '0' && c <= '9') { + value = (c - '0'); + } else if (c >= 'a' && c <= 'f') { + value = (c - 'a' + 10); + } else if (c >= 'A' && c <= 'F') { + value = (c - 'A' + 10); + } else { + throw new NumberFormatException("Non-hex character '"+c+"'"); + } + + // How about another one? + if (i < len) { + c = addrStr.charAt(i); + ++i; + if (c != ':') { + value = (value << 4); + if (c >= '0' && c <= '9') { + value |= (c - '0'); + } else if (c >= 'a' && c <= 'f') { + value |= (c - 'a' + 10); + } else if (c >= 'A' && c <= 'F') { + value |= (c - 'A' + 10); + } else { + throw new NumberFormatException("Non-hex character '"+c+"'"); + } + } + } + } + + addr = (addr << 8) | value; + + if (c != ':') { + if (i < len) { + if (addrStr.charAt(i) != ':') { + throw new NumberFormatException("Expected ':', got ('"+ addrStr.charAt(i)+"')"); + } + ++i; + } else if (j < 5) { + throw new NumberFormatException("Incomplete ethernet address (missing one or more digits"); + } + } + } + _address = addr; + } + + /** + * Binary constructor that constructs an instance given the 6 byte + * (48-bit) address. Useful if an address is saved in binary format + * (for saving space for example). + */ + public EthernetAddress(byte [] addr) + throws NumberFormatException + { + if (addr.length != 6) { + throw new NumberFormatException("Ethernet address has to consist of 6 bytes"); + } + long l = addr[0] & 0xFF; + for (int i = 1; i < 6; ++i) { + l = (l << 8) | (addr[i] & 0xFF); + } + _address = l; + } + + /** + * Another binary constructor; constructs an instance from the given + * long argument; the lowest 6 bytes contain the address. + * + * @param addr long that contains the MAC address in 6 least significant + * bytes. + */ + public EthernetAddress(long addr) { + _address = addr; + } + + /** + * Default cloning behaviour (bitwise copy) is just fine... + */ + public Object clone() + { + return new EthernetAddress(_address); + } + + /** + * Constructs a new EthernetAddress given the byte array that contains + * binary representation of the address. + * + * Note that calling this method returns the same result as would + * using the matching constructor. + * + * @param addr Binary representation of the ethernet address + * + * @throws NumberFormatException if addr is invalid (less or more than + * 6 bytes in array) + */ + public static EthernetAddress valueOf(byte[] addr) + throws NumberFormatException + { + return new EthernetAddress(addr); + } + + /** + * Constructs a new EthernetAddress given the byte array that contains + * binary representation of the address. + * + * Note that calling this method returns the same result as would + * using the matching constructor. + * + * @param addr Binary representation of the ethernet address + * + * @throws NumberFormatException if addr is invalid (less or more than + * 6 ints in array) + */ + public static EthernetAddress valueOf(int[] addr) + throws NumberFormatException + { + byte[] bAddr = new byte[addr.length]; + + for (int i = 0; i < addr.length; ++i) { + bAddr[i] = (byte) addr[i]; + } + return new EthernetAddress(bAddr); + } + + /** + * Constructs a new EthernetAddress given a string representation of + * the ethernet address. + * + * Note that calling this method returns the same result as would + * using the matching constructor. + * + * @param addrStr String representation of the ethernet address + * + * @throws NumberFormatException if addr representation is invalid + */ + public static EthernetAddress valueOf(String addrStr) + throws NumberFormatException + { + return new EthernetAddress(addrStr); + } + + /** + * Constructs a new EthernetAddress given the long int value (64-bit) + * representation of the ethernet address (of which 48 LSB contain + * the definition) + * + * Note that calling this method returns the same result as would + * using the matching constructor. + * + * @param addr Long int representation of the ethernet address + */ + public static EthernetAddress valueOf(long addr) + { + return new EthernetAddress(addr); + } + + /** + * Factory method that locates a network interface that has + * a suitable mac address (ethernet cards, and things that + * emulate one), and return that address. If there are multiple + * applicable interfaces, one of them is returned; which one + * is returned is not specified. + * Method is meant for accessing an address needed to construct + * generator for time+location based UUID generation method. + * + * @return Ethernet address of one of interfaces system has; + * not including local or loopback addresses; if one exists, + * null if no such interfaces are found. + */ + public static EthernetAddress fromInterface() + { + try { + Enumeration en = NetworkInterface.getNetworkInterfaces(); + while (en.hasMoreElements()) { + NetworkInterface nint = en.nextElement(); + if (!nint.isLoopback()) { + byte[] data = nint.getHardwareAddress(); + if (data != null && data.length == 6) { + return new EthernetAddress(data); + } + } + } + } catch (java.net.SocketException e) { + // fine, let's take is as signal of not having any interfaces + } + return null; + } + + /** + * Factory method that can be used to construct a random multicast + * address; to be used in cases where there is no "real" ethernet + * address to use. Address to generate should be a multicase address + * to avoid accidental collision with real manufacturer-assigned + * MAC addresses. + *

+ * Internally a {@link SecureRandom} instance is used for generating + * random number to base address on. + */ + public static EthernetAddress constructMulticastAddress() + { + return constructMulticastAddress(_randomNumberGenerator()); + } + + /** + * Factory method that can be used to construct a random multicast + * address; to be used in cases where there is no "real" ethernet + * address to use. Address to generate should be a multicase address + * to avoid accidental collision with real manufacturer-assigned + * MAC addresses. + *

+ * Address is created using specified random number generator. + */ + public static EthernetAddress constructMulticastAddress(Random rnd) + { + byte[] dummy = new byte[6]; + synchronized (rnd) { + rnd.nextBytes(dummy); + } + /* Need to set the broadcast bit to indicate it's not a real + * address. + */ + /* 20-May-2010, tatu: Actually, we could use both second least-sig-bit + * ("locally administered") or the LSB (multicast), as neither is + * ever set for 'real' addresses. + * Since UUID specs recommends latter, use that. + */ + dummy[0] |= (byte) 0x01; + return new EthernetAddress(dummy); + } + + /* + /********************************************************************** + /* Conversions to raw types + /********************************************************************** + */ + + /** + * Returns 6 byte byte array that contains the binary representation + * of this ethernet address; byte 0 is the most significant byte + * (and so forth) + * + * @return 6 byte byte array that contains the binary representation + */ + public byte[] asByteArray() + { + byte[] result = new byte[6]; + toByteArray(result); + return result; + } + + /** + * Synonym to 'asByteArray()' + * + * @return 6 byte byte array that contains the binary representation + */ + public byte[] toByteArray() { return asByteArray(); } + + public void toByteArray(byte[] array) { + if (array.length < 6) { + throw new IllegalArgumentException("Too small array, need to have space for 6 bytes"); + } + toByteArray(array, 0); + } + + public void toByteArray(byte[] array, int pos) + { + if (pos < 0 || (pos + 6) > array.length) { + throw new IllegalArgumentException("Illegal offset ("+pos+"), need room for 6 bytes"); + } + int i = (int) (_address >> 32); + array[pos++] = (byte) (i >> 8); + array[pos++] = (byte) i; + i = (int) _address; + array[pos++] = (byte) (i >> 24); + array[pos++] = (byte) (i >> 16); + array[pos++] = (byte) (i >> 8); + array[pos] = (byte) i; + } + + public long toLong() { + return _address; + } + + /* + /********************************************************************** + /* Accessors + /********************************************************************** + */ + + /** + * Method that can be used to check if this address refers + * to a multicast address. + * Such addresses are never assigned to individual network + * cards. + */ + public boolean isMulticastAddress() { + return (((int) (_address >> 40)) & 0x01) != 0; + } + + /** + * Method that can be used to check if this address refers + * to a "locally administered address" + * (see [http://en.wikipedia.org/wiki/MAC_address] for details). + * Such addresses are not assigned to individual network + * cards. + */ + public boolean isLocallyAdministeredAddress() { + return (((int) (_address >> 40)) & 0x02) != 0; + } + + /* + /********************************************************************** + /* Standard methods + /********************************************************************** + */ + + @Override + public boolean equals(Object o) + { + if (o == this) return true; + if (o == null) return false; + if (o.getClass() != getClass()) return false; + return ((EthernetAddress) o)._address == _address; + } + + /** + * Method that compares this EthernetAddress to one passed in as + * argument. Comparison is done simply by comparing individual + * address bytes in the order. + * + * @return negative number if this EthernetAddress should be sorted before the + * parameter address if they are equal, os positive non-zero number if this address + * should be sorted after parameter + */ + public int compareTo(EthernetAddress other) + { + long l = _address - other._address; + if (l < 0L) return -1; + return (l == 0L) ? 0 : 1; + } + + /** + * Returns the canonical string representation of this ethernet address. + * Canonical means that all characters are lower-case and string length + * is always 17 characters (ie. leading zeroes are not omitted). + * + * @return Canonical string representation of this ethernet address. + */ + @Override + public String toString() + { + String str = _asString; + if (str != null) { + return str; + } + + /* Let's not cache the output here (unlike with UUID), assuming + * this won't be called as often: + */ + StringBuilder b = new StringBuilder(17); + int i1 = (int) (_address >> 32); + int i2 = (int) _address; + + _appendHex(b, i1 >> 8); + b.append(':'); + _appendHex(b, i1); + b.append(':'); + _appendHex(b, i2 >> 24); + b.append(':'); + _appendHex(b, i2 >> 16); + b.append(':'); + _appendHex(b, i2 >> 8); + b.append(':'); + _appendHex(b, i2); + _asString = str = b.toString(); + return str; + } + + /* + /********************************************************************** + /* Internal methods + /********************************************************************** + */ + + /** + * Helper method for accessing configured random number generator + */ + protected synchronized static Random _randomNumberGenerator() + { + if (_rnd == null) { + _rnd = new SecureRandom(); + } + return _rnd; + } + + private final void _appendHex(StringBuilder sb, int hex) + { + sb.append(HEX_CHARS[(hex >> 4) & 0xF]); + sb.append(HEX_CHARS[(hex & 0x0f)]); + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/FileBasedTimestampSynchronizer.java jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/FileBasedTimestampSynchronizer.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/FileBasedTimestampSynchronizer.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/FileBasedTimestampSynchronizer.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,230 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.ext; + +import com.fasterxml.uuid.Logger; +import com.fasterxml.uuid.TimestampSynchronizer; + +import java.io.*; + +/** + * Implementation of {@link TimestampSynchronizer}, which uses file system + * as the storage and locking mechanism. + *

+ * Synchronization is achieved by obtaining an exclusive file locks on two + * specified lock files, and by using the files to store first "safe" timestamp + * value that the generator can use; alternating between one to use to ensure + * one of them always contains a valid timestamp. Latter is needed to guard + * against system clock moving backwards after UUID generator restart. + *

+ * Note: this class will only work on JDK 1.4 and above, since it requires + * NIO package to do proper file locking (as well as new opening mode for + * {@link RandomAccessFile}). + *

+ * Also note that it is assumed that the caller has taken care to synchronize + * access to method to be single-threaded. As such, none of the methods + * is explicitly synchronized here. + */ +public final class FileBasedTimestampSynchronizer + extends TimestampSynchronizer +{ + // // // Constants: + + /** + * The default update interval is 10 seconds, meaning that the + * synchronizer "reserves" next 10 seconds for generation. This + * also means that the lock files need to be accessed at most + * once every ten second. + */ + final static long DEFAULT_UPDATE_INTERVAL = 10L * 1000L; + + protected final static String DEFAULT_LOCK_FILE_NAME1 = "uuid1.lck"; + + protected final static String DEFAULT_LOCK_FILE_NAME2 = "uuid2.lck"; + + // // // Configuration: + + protected long mInterval = DEFAULT_UPDATE_INTERVAL; + + protected final LockedFile mLocked1, mLocked2; + + // // // State: + + /** + * Flag used to indicate which of timestamp files has the most + * recently succesfully updated timestamp value. True means that + * mFile1 is more recent; false that mFile2 + * is. + */ + boolean mFirstActive = false; + + /** + * Constructor that uses default values for names of files to use + * (files will get created in the current working directory), as + * well as for the update frequency value (10 seconds). + */ + public FileBasedTimestampSynchronizer() + throws IOException + { + this(new File(DEFAULT_LOCK_FILE_NAME1), new File(DEFAULT_LOCK_FILE_NAME2)); + } + + public FileBasedTimestampSynchronizer(File lockFile1, File lockFile2) + throws IOException + { + this(lockFile1, lockFile2, DEFAULT_UPDATE_INTERVAL); + } + + public FileBasedTimestampSynchronizer(File lockFile1, File lockFile2, long interval) + throws IOException + { + mInterval = interval; + mLocked1 = new LockedFile(lockFile1); + + boolean ok = false; + try { + mLocked2 = new LockedFile(lockFile2); + ok = true; + } finally { + if (!ok) { + mLocked1.deactivate(); + } + } + + // But let's leave reading up to initialization + } + + /* + ////////////////////////////////////////////////////////////// + // Configuration + ////////////////////////////////////////////////////////////// + */ + + public void setUpdateInterval(long interval) + { + if (interval < 1L) { + throw new IllegalArgumentException("Illegal value ("+interval+"); has to be a positive integer value"); + } + mInterval = interval; + } + + /* + ////////////////////////////////////////////////////////////// + // Implementation of the API + ////////////////////////////////////////////////////////////// + */ + + /** + * This method is to be called only once by + * {@link com.fasterxml.uuid.UUIDTimer}. It + * should fetch the persisted timestamp value, which indicates + * first timestamp value that is guaranteed NOT to have used by + * a previous incarnation. If it can not determine such value, it + * is to return 0L as a marker. + * + * @return First timestamp value that was NOT locked by lock files; + * 0L to indicate that no information was read. + */ + protected long initialize() + throws IOException + { + long ts1 = mLocked1.readStamp(); + long ts2 = mLocked2.readStamp(); + long result; + + if (ts1 > ts2) { + mFirstActive = true; + result = ts1; + } else { + mFirstActive = false; + result = ts2; + } + + /* Hmmh. If we didn't get a time stamp (-> 0), or if written time is + * ahead of current time, let's log something: + */ + if (result <= 0L) { + Logger.logWarning("Could not determine safe timer starting point: assuming current system time is acceptable"); + } else { + long now = System.currentTimeMillis(); + //long diff = now - result; + + /* It's more suspicious if old time was ahead... although with + * longer iteration values, it can be ahead without errors. So + * let's base check on current iteration value: + */ + if ((now + mInterval) < result) { + Logger.logWarning("Safe timestamp read is "+(result - now)+" milliseconds in future, and is greater than the inteval ("+mInterval+")"); + } + + /* Hmmh. Is there any way a suspiciously old timestamp could be + * harmful? It can obviously be useless but... + */ + } + + return result; + } + + public void deactivate() + throws IOException + { + doDeactivate(mLocked1, mLocked2); + } + + /** + * @return Timestamp value that the caller can NOT use. That is, all + * timestamp values prior to (less than) this value can be used + * ok, but this value and ones after can only be used by first + * calling update. + */ + public long update(long now) + throws IOException + { + long nextAllowed = now + mInterval; + + /* We have to make sure to (over)write the one that is NOT + * actively used, to ensure that we always have fully persisted + * timestamp value, even if the write process gets interruped + * half-way through. + */ + + if (mFirstActive) { + mLocked2.writeStamp(nextAllowed); + } else { + mLocked1.writeStamp(nextAllowed); + } + + mFirstActive = !mFirstActive; + + return nextAllowed; + } + + /* + ////////////////////////////////////////////////////////////// + // Internal methods + ////////////////////////////////////////////////////////////// + */ + + protected static void doDeactivate(LockedFile lf1, LockedFile lf2) + { + if (lf1 != null) { + lf1.deactivate(); + } + if (lf2 != null) { + lf2.deactivate(); + } + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/JavaUtilLogger.java jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/JavaUtilLogger.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/JavaUtilLogger.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/JavaUtilLogger.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,132 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.ext; + +import java.io.*; + +//import com.fasterxml.uuid.Logger; + +/** + * Simple wrapper that allows easy connecting of JUG logging into JDK 1.4+ + * logging implementation (aka "java.util.logging" aka "JUL". + *

+ * Note: using this class requires JDK 1.4 or above. + */ +public class JavaUtilLogger + extends com.fasterxml.uuid.Logger +{ + private java.util.logging.Logger mPeer; + + private JavaUtilLogger(java.util.logging.Logger peer) + { + mPeer = peer; + } + + /** + * Static method to call to make JUG use to proxy all of its logging + * through the specified j.u.l Logger instance. + *

+ * Method will create a simple wrapper, and call + * {@link com.fasterxml.uuid.Logger#setLogger} with the wrapper as + * the argument. This will then re-direct logging from the previously + * defined Logger (which initially is the simple JUG logger) to the + * new wrapper, which routes logging messages to the log4j peer Logger + * instance. + */ + public static void connectToJavaUtilLogging(java.util.logging.Logger peer) + { + JavaUtilLogger logger = new JavaUtilLogger(peer); + // This is static method of the base class... + setLogger(logger); + } + + /** + * Static method to call to make JUG use a log4j proxy all of its logging + * through a j.u.l Logger constructed to correspond with + * com.fasterxml.uuid.Logger class (this generally determines + * j.u.l category output etc settings). + *

+ * Method will create a simple wrapper, and call + * {@link com.fasterxml.uuid.Logger#setLogger} with the wrapper as + * the argument. This will then re-direct logging from the previously + * defined Logger (which initially is the simple JUG logger) to the + * new wrapper, which routes logging messages to the j.u.l peer Logger + * instance. + */ + public static void connectToJavaUtilLogging() + { + connectToJavaUtilLogging(java.util.logging.Logger.getLogger(com.fasterxml.uuid.Logger.class.getName())); + } + + /* + ///////////////////////////////////////////////////////////// + // Overridable implementation/instance methods from + // Logger base class + ///////////////////////////////////////////////////////////// + */ + + // // // Config + + // This is ok; let's just use base class functionality: + //protected void doSetLogLevel(int ll); + + /** + * Note: this method is meaningless with log4j, since it has more + * advanced output mapping and filtering mechanisms. As such, it's + * a no-op + */ + protected void doSetOutput(PrintStream str) + { + // Could also throw an Error.. but for now, let's log instead... + mPeer.warning("doSetOutput(PrintStream) called on "+getClass()+" instance, ignoring."); + } + + /** + * Note: this method is meaningless with log4j, since it has more + * advanced output mapping and filtering mechanisms. As such, it's + * a no-op + */ + protected void doSetOutput(Writer w) + { + mPeer.warning("doSetOutput(Writer) called on "+getClass()+" instance, ignoring."); + } + + // // // Logging methods + + protected void doLogInfo(String msg) + { + if (_logLevel <= LOG_INFO_AND_ABOVE) { + mPeer.info(msg); + } + } + + protected void doLogWarning(String msg) + { + if (_logLevel <= LOG_WARNING_AND_ABOVE) { + mPeer.warning(msg); + } + } + + protected void doLogError(String msg) + { + /* Hmmh. JUL doesn't have error... and SEVERE is bit drastic. But, + * well, let's use that for ERRORs for now. + */ + if (_logLevel <= LOG_ERROR_AND_ABOVE) { + mPeer.severe(msg); + } + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/LockedFile.java jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/LockedFile.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/LockedFile.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/LockedFile.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,292 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.ext; + +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; + +import com.fasterxml.uuid.Logger; + +/** + * Utility class used by {@link FileBasedTimestampSynchronizer} to do + * actual file access and locking. + *

+ * Class stores simple timestamp values based on system time accessed + * using System.currentTimeMillis(). A single timestamp + * is stored into a file using {@link RandomAccessFile} in fully + * synchronized mode. Value is written in ISO-Latin (ISO-8859-1) + * encoding (superset of Ascii, 1 byte per char) as 16-digit hexadecimal + * number, surrounded by brackets. As such, file produced should + * always have exact size of 18 bytes. For extra robustness, slight + * variations in number of digits are accepeted, as are white space + * chars before and after bracketed value. + */ +class LockedFile +{ + /** + * Expected file length comes from hex-timestamp (16 digits), + * preamble "[0x",(3 chars) and trailer "]\r\n" (2 chars, linefeed + * to help debugging -- in some environments, missing trailing linefeed + * causes problems: also, 2-char linefeed to be compatible with all + * standard linefeeds on MacOS, Unix and Windows). + */ + final static int DEFAULT_LENGTH = 22; + + final static long READ_ERROR = 0L; + + // // // Configuration: + + final File mFile; + + // // // File state + + RandomAccessFile mRAFile; + + FileChannel mChannel; + + FileLock mLock; + + ByteBuffer mWriteBuffer = null; + + /** + * Flag set if the original file (created before this instance was + * created) had size other than default size and needs to be + * truncated + */ + boolean mWeirdSize; + + /** + * Marker used to ensure that the timestamps stored are monotonously + * increasing. Shouldn't really be needed, since caller should take + * care of it, but let's be bit paranoid here. + */ + long mLastTimestamp = 0L; + + LockedFile(File f) + throws IOException + { + mFile = f; + + RandomAccessFile raf = null; + FileChannel channel = null; + FileLock lock = null; + boolean ok = false; + + try { // let's just use a single block to share cleanup code + raf = new RandomAccessFile(f, "rwd"); + + // Then lock them, if possible; if not, let's err out + channel = raf.getChannel(); + if (channel == null) { + throw new IOException("Failed to access channel for '"+f+"'"); + } + lock = channel.tryLock(); + if (lock == null) { + throw new IOException("Failed to lock '"+f+"' (another JVM running UUIDGenerator?)"); + } + ok = true; + } finally { + if (!ok) { + doDeactivate(f, raf, lock); + } + } + + mRAFile = raf; + mChannel = channel; + mLock = lock; + } + + public void deactivate() + { + RandomAccessFile raf = mRAFile; + mRAFile = null; + FileLock lock = mLock; + mLock = null; + doDeactivate(mFile, raf, lock); + } + + public long readStamp() + { + int size; + + try { + size = (int) mChannel.size(); + } catch (IOException ioe) { + doLogError("Failed to read file size: "+ioe); + return READ_ERROR; + } + + mWeirdSize = (size != DEFAULT_LENGTH); + + // Let's check specifically empty files though + if (size == 0) { + doLogWarning("Missing or empty file, can not read timestamp value"); + return READ_ERROR; + } + + // Let's also allow some slack... but just a bit + if (size > 100) { + size = 100; + } + byte[] data = new byte[size]; + try { + mRAFile.readFully(data); + } catch (IOException ie) { + doLogError("Failed to read "+size+" bytes: "+ie); + return READ_ERROR; + } + + /* Ok, got data. Now, we could just directly parse the bytes (since + * it is single-byte encoding)... but for convenience, let's create + * the String (this is only called once per JVM session) + */ + char[] cdata = new char[size]; + for (int i = 0; i < size; ++i) { + cdata[i] = (char) (data[i] & 0xFF); + } + String dataStr = new String(cdata); + // And let's trim leading (and trailing, who cares) + dataStr = dataStr.trim(); + + long result = -1; + String err = null; + + if (!dataStr.startsWith("[0") + || dataStr.length() < 3 + || Character.toLowerCase(dataStr.charAt(2)) != 'x') { + err = "does not start with '[0x' prefix"; + } else { + int ix = dataStr.indexOf(']', 3); + if (ix <= 0) { + err = "does not end with ']' marker"; + } else { + String hex = dataStr.substring(3, ix); + if (hex.length() > 16) { + err = "length of the (hex) timestamp too long; expected 16, had "+hex.length()+" ('"+hex+"')"; + } else { + try { + result = Long.parseLong(hex, 16); + } catch (NumberFormatException nex) { + err = "does not contain a valid hex timestamp; got '" + +hex+"' (parse error: "+nex+")"; + } + } + } + } + + // Unsuccesful? + if (result < 0L) { + doLogError("Malformed timestamp file contents: "+err); + return READ_ERROR; + } + + mLastTimestamp = result; + return result; + } + + final static String HEX_DIGITS = "0123456789abcdef"; + + public void writeStamp(long stamp) + throws IOException + { + // Let's do sanity check first: + if (stamp <= mLastTimestamp) { + /* same stamp is not dangerous, but pointless... so warning, + * not an error: + */ + if (stamp == mLastTimestamp) { + doLogWarning("Trying to re-write existing timestamp ("+stamp+")"); + return; + } + throw new IOException(""+getFileDesc()+" trying to overwrite existing value ("+mLastTimestamp+") with an earlier timestamp ("+stamp+")"); + } + +//System.err.println("!!!! Syncing ["+mFile+"] with "+stamp+" !!!"); + + // Need to initialize the buffer? + if (mWriteBuffer == null) { + mWriteBuffer = ByteBuffer.allocate(DEFAULT_LENGTH); + mWriteBuffer.put(0, (byte) '['); + mWriteBuffer.put(1, (byte) '0'); + mWriteBuffer.put(2, (byte) 'x'); + mWriteBuffer.put(19, (byte) ']'); + mWriteBuffer.put(20, (byte) '\r'); + mWriteBuffer.put(21, (byte) '\n'); + } + + // Converting to hex is simple + for (int i = 18; i >= 3; --i) { + int val = (((int) stamp) & 0x0F); + mWriteBuffer.put(i, (byte) HEX_DIGITS.charAt(val)); + stamp = (stamp >> 4); + } + // and off we go: + mWriteBuffer.position(0); // to make sure we always write it all + mChannel.write(mWriteBuffer, 0L); + if (mWeirdSize) { + mRAFile.setLength(DEFAULT_LENGTH); + mWeirdSize = false; + } + + // This is probably not needed (as the random access file is supposedly synced)... but let's be safe: + mChannel.force(false); + + // And that's it! + } + + /* + ////////////////////////////////////////////////////////////// + // Internal methods + ////////////////////////////////////////////////////////////// + */ + + protected void doLogWarning(String msg) + { + Logger.logWarning("(file '"+getFileDesc()+"') "+msg); + } + + protected void doLogError(String msg) + { + Logger.logError("(file '"+getFileDesc()+"') "+msg); + } + + protected String getFileDesc() { + return mFile.toString(); + } + + protected static void doDeactivate(File f, RandomAccessFile raf, + FileLock lock) + { + if (lock != null) { + try { + lock.release(); + } catch (Throwable t) { + Logger.logError("Failed to release lock (for file '"+f+"'): "+t); + } + } + if (raf != null) { + try { + raf.close(); + } catch (Throwable t) { + Logger.logError("Failed to close file '"+f+"':"+t); + } + } + } +} + + diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/Log4jLogger.java jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/Log4jLogger.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/Log4jLogger.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/Log4jLogger.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,130 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.ext; + +import java.io.*; + +//import com.fasterxml.uuid.Logger; + +/** + * Simple wrapper that allows easy connecting of JUG logging into log4j + * logging subsystem. + *

+ * Note: using this class implies all the dependencies that the log4j + * subsystem in use requires (JDK 1.2 or above, in general) + */ +public class Log4jLogger + extends com.fasterxml.uuid.Logger +{ + private org.apache.log4j.Logger mPeer; + + private Log4jLogger(org.apache.log4j.Logger peer) + { + mPeer = peer; + } + + /** + * Static method to call to make JUG use to proxy all of its logging + * through the specified log4j Logger instance. + *

+ * Method will create a simple wrapper, and call + * {@link com.fasterxml.uuid.Logger#setLogger} with the wrapper as + * the argument. This will then re-direct logging from the previously + * defined Logger (which initially is the simple JUG logger) to the + * new wrapper, which routes logging messages to the log4j peer Logger + * instance. + */ + public static void connectToLog4j(org.apache.log4j.Logger peer) + { + Log4jLogger logger = new Log4jLogger(peer); + // This is static method of the base class... + setLogger(logger); + } + + /** + * Static method to call to make JUG use a log4j proxy all of its logging + * through a log4j Logger constructed to correspond with + * com.fasterxml.uuid.Logger class (this generally determines + * log4j category output etc settings). + *

+ * Method will create a simple wrapper, and call + * {@link com.fasterxml.uuid.Logger#setLogger} with the wrapper as + * the argument. This will then re-direct logging from the previously + * defined Logger (which initially is the simple JUG logger) to the + * new wrapper, which routes logging messages to the log4j peer Logger + * instance. + */ + public static void connectToLog4j() + { + connectToLog4j(org.apache.log4j.Logger.getLogger(com.fasterxml.uuid.Logger.class)); + } + + /* + ///////////////////////////////////////////////////////////// + // Overridable implementation/instance methods from + // Logger base class + ///////////////////////////////////////////////////////////// + */ + + // // // Config + + // This is ok; let's just use base class functionality: + //protected void doSetLogLevel(int ll); + + /** + * Note: this method is meaningless with log4j, since it has more + * advanced output mapping and filtering mechanisms. As such, it's + * a no-op + */ + protected void doSetOutput(PrintStream str) + { + // Could also throw an Error.. but for now, let's log instead... + mPeer.warn("doSetOutput(PrintStream) called on "+getClass()+" instance, ignoring."); + } + + /** + * Note: this method is meaningless with log4j, since it has more + * advanced output mapping and filtering mechanisms. As such, it's + * a no-op + */ + protected void doSetOutput(Writer w) + { + mPeer.warn("doSetOutput(Writer) called on "+getClass()+" instance, ignoring."); + } + + // // // Logging methods + + protected void doLogInfo(String msg) + { + if (_logLevel <= LOG_INFO_AND_ABOVE) { + mPeer.info(msg); + } + } + + protected void doLogWarning(String msg) + { + if (_logLevel <= LOG_WARNING_AND_ABOVE) { + mPeer.warn(msg); + } + } + + protected void doLogError(String msg) + { + if (_logLevel <= LOG_ERROR_AND_ABOVE) { + mPeer.error(msg); + } + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/package.html jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/package.html --- jug-2.0.0/src/main/java/com/fasterxml/uuid/ext/package.html 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/ext/package.html 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,11 @@ + +Package that contains optional Java UUID Generator classes; classes that: +

    +
  • Depend on optional external packages; like log4j or java.util.logging - +based Logger adapters (java.util.logging itself was added in JDK 1.4) +
  • +
+

+Otherwise base JDK version requirement for these classes is 1.4. +

+ diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/Generators.java jug-3.1.5/src/main/java/com/fasterxml/uuid/Generators.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/Generators.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/Generators.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,198 @@ +/* JUG Java UUID Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.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; + + // // 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) { + try { + digester = MessageDigest.getInstance("SHA-1"); + type = UUIDType.NAME_BASED_SHA1; + } catch (NoSuchAlgorithmException nex) { + throw new IllegalArgumentException("Couldn't instantiate SHA-1 MessageDigest instance: "+nex.toString()); + } + } + return new NameBasedGenerator(namespace, digester, type); + } + + // // Time+location-based generation + + /** + * Factory method for constructing UUID generator that generates UUID using + * variant 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 + * variant 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 + * variant 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 + * variant 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); + } + + /* + /********************************************************************** + /* 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; + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/GeneratorImplBase.java jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/GeneratorImplBase.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/GeneratorImplBase.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/GeneratorImplBase.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,8 @@ +package com.fasterxml.uuid.impl; + +/** + * Shared base class for various UUID generator implementations. + */ +public class GeneratorImplBase +{ +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/NameBasedGenerator.java jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/NameBasedGenerator.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/NameBasedGenerator.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/NameBasedGenerator.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,139 @@ +package com.fasterxml.uuid.impl; + +import java.nio.charset.Charset; +import java.security.MessageDigest; +import java.util.UUID; + +import com.fasterxml.uuid.Logger; +import com.fasterxml.uuid.StringArgGenerator; +import com.fasterxml.uuid.UUIDType; + +/** + * Implementation of UUID generator that uses one of name-based generation methods + * (variants 3 (MD5) and 5 (SHA1)). + *

+ * As all JUG provided implementations, this generator is fully thread-safe; access + * to digester is synchronized as necessary. + * + * @since 3.0 + */ +public class NameBasedGenerator extends StringArgGenerator +{ + public final static Charset _utf8; + static { + _utf8 = Charset.forName("UTF-8"); + } + + /** + * Namespace used when name is a DNS name. + */ + public final static UUID NAMESPACE_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8"); + + /** + * Namespace used when name is a URL. + */ + public final static UUID NAMESPACE_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); + /** + * Namespace used when name is an OID. + */ + public final static UUID NAMESPACE_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); + /** + * Namespace used when name is an X500 identifier + */ + public final static UUID NAMESPACE_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"); + + /* + /********************************************************************** + /* Configuration + /********************************************************************** + */ + + /** + * Namespace to use as prefix. + */ + protected final UUID _namespace; + + /** + * Message digesster to use for hash calculation + */ + protected final MessageDigest _digester; + + protected final UUIDType _type; + + /* + /********************************************************************** + /* Construction + /********************************************************************** + */ + + /** + * @param namespace of the namespace, as defined by the + * spec. UUID has 4 pre-defined "standard" name space strings + * that can be passed to UUID constructor (see example below). + * Note that this argument is optional; if no namespace is needed + * (for example when name includes namespace prefix), null may be passed. + * @param digester Hashing algorithm to use. + + */ + public NameBasedGenerator(UUID namespace, MessageDigest digester, UUIDType type) + { + _namespace = namespace; + // And default digester SHA-1 + if (digester == null) { + + } + if (type == null) { + String typeStr = digester.getAlgorithm(); + if (typeStr.startsWith("MD5")) { + type = UUIDType.NAME_BASED_MD5; + } else if (typeStr.startsWith("SHA")) { + type = UUIDType.NAME_BASED_SHA1; + } else { + // Hmmh... error out? Let's default to SHA-1, but log a warning + type = UUIDType.NAME_BASED_SHA1; + Logger.logWarning("Could not determine type of Digester from '"+typeStr+"'; assuming 'SHA-1' type"); + } + } + _digester = digester; + _type = type; + } + + /* + /********************************************************************** + /* Access to config + /********************************************************************** + */ + + @Override + public UUIDType getType() { return _type; } + + public UUID getNamespace() { return _namespace; } + + /* + /********************************************************************** + /* UUID generation + /********************************************************************** + */ + + @Override + public UUID generate(String name) + { + // !!! TODO: 14-Oct-2010, tatu: can repurpose faster UTF-8 encoding from Jackson + return generate(name.getBytes(_utf8)); + } + + @Override + public UUID generate(byte[] nameBytes) + { + byte[] digest; + synchronized (_digester) { + _digester.reset(); + if (_namespace != null) { + _digester.update(UUIDUtil.asByteArray(_namespace)); + } + _digester.update(nameBytes); + digest = _digester.digest(); + } + return UUIDUtil.constructUUID(_type, digest); + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/RandomBasedGenerator.java jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/RandomBasedGenerator.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/RandomBasedGenerator.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/RandomBasedGenerator.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,137 @@ +package com.fasterxml.uuid.impl; + +import java.security.SecureRandom; +import java.util.Random; +import java.util.UUID; + +import com.fasterxml.uuid.NoArgGenerator; +import com.fasterxml.uuid.UUIDType; + +/** + * Implementation of UUID generator that uses generation method 4. + *

+ * Note on random number generation when using {@link SecureRandom} for random number + * generation: the first time {@link SecureRandom} object is used, there is noticeable delay between + * calling the method and getting the reply. This is because SecureRandom + * has to initialize itself to reasonably random state. Thus, if you + * want to lessen delay, it may be be a good idea to either get the + * first random UUID asynchronously from a separate thread, or to + * use the other generateRandomBasedUUID passing a previously initialized + * SecureRandom instance. + * + * @since 3.0 + */ +public class RandomBasedGenerator extends NoArgGenerator +{ + /** + * Default shared random number generator, used if no random number generator + * is explicitly specified for instance + */ + protected static Random _sharedRandom = null; + + /** + * Random number generator that this generator uses. + */ + protected final Random _random; + + /** + * Looks like {@link SecureRandom} implementation is more efficient + * using single call access (compared to basic {@link java.util.Random}), + * so let's use that knowledge to our benefit. + */ + protected final boolean _secureRandom; + + /** + * @param rnd Random number generator to use for generating UUIDs; if null, + * shared default generator is used. Note that it is strongly recommend to + * use a good (pseudo) random number generator; for example, JDK's + * {@link SecureRandom}. + */ + public RandomBasedGenerator(Random rnd) + { + if (rnd == null) { + rnd = LazyRandom.sharedSecureRandom(); + _secureRandom = true; + } else { + _secureRandom = (rnd instanceof SecureRandom); + } + _random = rnd; + } + + /* + /********************************************************************** + /* Access to config + /********************************************************************** + */ + + @Override + public UUIDType getType() { return UUIDType.RANDOM_BASED; } + + /* + /********************************************************************** + /* UUID generation + /********************************************************************** + */ + + @Override + public UUID generate() + { + /* 14-Oct-2010, tatu: Surprisingly, variant for reading byte array is + * tad faster for SecureRandom... so let's use that then + */ + long r1, r2; + + if (_secureRandom) { + final byte[] buffer = new byte[16]; + _random.nextBytes(buffer); + r1 = _toLong(buffer, 0); + r2 = _toLong(buffer, 1); + } else { + r1 = _random.nextLong(); + r2 = _random.nextLong(); + } + return UUIDUtil.constructUUID(UUIDType.RANDOM_BASED, r1, r2); + } + + /* + /********************************************************************** + /* Internal methods + /********************************************************************** + */ + + private final static long _toLong(byte[] buffer, int offset) + { + long l1 = _toInt(buffer, offset); + long l2 = _toInt(buffer, offset+4); + long l = (l1 << 32) + ((l2 << 32) >>> 32); + return l; + } + + private final static long _toInt(byte[] buffer, int offset) + { + return (buffer[offset] << 24) + + ((buffer[++offset] & 0xFF) << 16) + + ((buffer[++offset] & 0xFF) << 8) + + (buffer[++offset] & 0xFF); + } + + /* + /********************************************************************** + /* Helper classes + /********************************************************************** + */ + + /** + * Trivial helper class that uses class loading as synchronization + * mechanism for lazy instantation of the shared secure random + * instance. + */ + private final static class LazyRandom + { + private final static SecureRandom shared = new SecureRandom(); + + public static SecureRandom sharedSecureRandom() { + return shared; + } + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/TimeBasedGenerator.java jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/TimeBasedGenerator.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/TimeBasedGenerator.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/TimeBasedGenerator.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,112 @@ +package com.fasterxml.uuid.impl; + +import java.util.UUID; + +import com.fasterxml.uuid.*; + +/** + * Implementation of UUID generator that uses time/location based generation + * method (variant 1). + *

+ * As all JUG provided implementations, this generator is fully thread-safe. + * Additionally it can also be made externally synchronized with other + * instances (even ones running on other JVMs); to do this, + * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer} + * (or equivalent). + * + * @since 3.0 + */ +public class TimeBasedGenerator extends NoArgGenerator +{ + /* + /********************************************************************** + /* Configuration + /********************************************************************** + */ + + protected final EthernetAddress _ethernetAddress; + + /** + * Object used for synchronizing access to timestamps, to guarantee + * that timestamps produced by this generator are unique and monotonically increasings. + * Some implementations offer even stronger guarantees, for example that + * same guarantee holds between instances running on different JVMs (or + * with native code). + */ + protected final UUIDTimer _timer; + + /** + * Base values for the second long (last 8 bytes) of UUID to construct + */ + protected final long _uuidL2; + + /* + /********************************************************************** + /* Construction + /********************************************************************** + */ + + /** + * @param ethAddr Hardware address (802.1) to use for generating + * spatially unique part of UUID. If system has more than one NIC, + */ + + public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer) + { + byte[] uuidBytes = new byte[16]; + if (ethAddr == null) { + ethAddr = EthernetAddress.constructMulticastAddress(); + } + // initialize baseline with MAC address info + _ethernetAddress = ethAddr; + _ethernetAddress.toByteArray(uuidBytes, 10); + // and add clock sequence + int clockSeq = timer.getClockSequence(); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq; + long l2 = UUIDUtil.gatherLong(uuidBytes, 8); + _uuidL2 = UUIDUtil.initUUIDSecondLong(l2); + _timer = timer; + } + + /* + /********************************************************************** + /* Access to config + /********************************************************************** + */ + + @Override + public UUIDType getType() { return UUIDType.TIME_BASED; } + + public EthernetAddress getEthernetAddress() { return _ethernetAddress; } + + /* + /********************************************************************** + /* UUID generation + /********************************************************************** + */ + + /* As timer is not synchronized (nor _uuidBytes), need to sync; but most + * importantly, synchronize on timer which may also be shared between + * multiple instances + */ + @Override + public UUID generate() + { + final long rawTimestamp = _timer.getTimestamp(); + // Time field components are kind of shuffled, need to slice: + int clockHi = (int) (rawTimestamp >>> 32); + int clockLo = (int) rawTimestamp; + // and dice + int midhi = (clockHi << 16) | (clockHi >>> 16); + // need to squeeze in type (4 MSBs in byte 6, clock hi) + midhi &= ~0xF000; // remove high nibble of 6th byte + midhi |= 0x1000; // type 1 + long midhiL = (long) midhi; + midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension + // and reconstruct + long l1 = (((long) clockLo) << 32) | midhiL; + // last detail: must force 2 MSB to be '10' + return new UUID(l1, _uuidL2); + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/UUIDUtil.java jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/UUIDUtil.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/impl/UUIDUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/impl/UUIDUtil.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,308 @@ +package com.fasterxml.uuid.impl; + +import java.util.UUID; + +import com.fasterxml.uuid.UUIDType; + +public class UUIDUtil +{ + public final static int BYTE_OFFSET_CLOCK_LO = 0; + public final static int BYTE_OFFSET_CLOCK_MID = 4; + public final static int BYTE_OFFSET_CLOCK_HI = 6; + + // note: clock-hi and type occupy same byte (different bits) + public final static int BYTE_OFFSET_TYPE = 6; + + // similarly, clock sequence and variant are multiplexed + public final static int BYTE_OFFSET_CLOCK_SEQUENCE = 8; + public final static int BYTE_OFFSET_VARIATION = 8; + + /* + /********************************************************************** + /* Construction (can instantiate, although usually not necessary) + /********************************************************************** + */ + + // note: left public just for convenience; all functionality available + // via static methods + public UUIDUtil() { } + + /* + /********************************************************************** + /* Factory methods + /********************************************************************** + */ + + /** + * Factory method for creating UUIDs from the canonical string + * representation. + * + * @param id String that contains the canonical representation of + * the UUID to build; 36-char string (see UUID specs for details). + * Hex-chars may be in upper-case too; UUID class will always output + * them in lowercase. + */ + public static UUID uuid(String id) + { + if (id == null) { + throw new NullPointerException(); + } + if (id.length() != 36) { + throw new NumberFormatException("UUID has to be represented by the standard 36-char representation"); + } + + long lo, hi; + lo = hi = 0; + + for (int i = 0, j = 0; i < 36; ++j) { + + // Need to bypass hyphens: + switch (i) { + case 8: + case 13: + case 18: + case 23: + if (id.charAt(i) != '-') { + throw new NumberFormatException("UUID has to be represented by the standard 36-char representation"); + } + ++i; + } + int curr; + char c = id.charAt(i); + + if (c >= '0' && c <= '9') { + curr = (c - '0'); + } else if (c >= 'a' && c <= 'f') { + curr = (c - 'a' + 10); + } else if (c >= 'A' && c <= 'F') { + curr = (c - 'A' + 10); + } else { + throw new NumberFormatException("Non-hex character at #"+i+": '"+c + +"' (value 0x"+Integer.toHexString(c)+")"); + } + curr = (curr << 4); + + c = id.charAt(++i); + + if (c >= '0' && c <= '9') { + curr |= (c - '0'); + } else if (c >= 'a' && c <= 'f') { + curr |= (c - 'a' + 10); + } else if (c >= 'A' && c <= 'F') { + curr |= (c - 'A' + 10); + } else { + throw new NumberFormatException("Non-hex character at #"+i+": '"+c + +"' (value 0x"+Integer.toHexString(c)+")"); + } + if (j < 8) { + hi = (hi << 8) | curr; + } else { + lo = (lo << 8) | curr; + } + ++i; + } + return new UUID(hi, lo); + } + + /** + * Factory method for constructing {@link java.util.UUID} instance from given + * 16 bytes. + * NOTE: since absolutely no validation is done for contents, this method should + * only be used if contents are known to be valid. + */ + public static UUID uuid(byte[] bytes) + { + _checkUUIDByteArray(bytes, 0); + long l1 = gatherLong(bytes, 0); + long l2 = gatherLong(bytes, 8); + return new UUID(l1, l2); + } + + /** + * Factory method for constructing {@link java.util.UUID} instance from given + * 16 bytes. + * NOTE: since absolutely no validation is done for contents, this method should + * only be used if contents are known to be valid. + * + * @param bytes Array that contains sequence of 16 bytes that contain a valid UUID + * @param offset Offset of the first of 16 bytes + */ + public static UUID uuid(byte[] bytes, int offset) + { + _checkUUIDByteArray(bytes, offset); + return new UUID(gatherLong(bytes, offset), gatherLong(bytes, offset+8)); + } + + /** + * Helper method for constructing UUID instances with appropriate type + */ + public static UUID constructUUID(UUIDType type, byte[] uuidBytes) + { + // first, ensure type is ok + int b = uuidBytes[BYTE_OFFSET_TYPE] & 0xF; // clear out high nibble + b |= type.raw() << 4; + uuidBytes[BYTE_OFFSET_TYPE] = (byte) b; + // second, ensure variant is properly set too + b = uuidBytes[UUIDUtil.BYTE_OFFSET_VARIATION] & 0x3F; // remove 2 MSB + b |= 0x80; // set as '10' + uuidBytes[BYTE_OFFSET_VARIATION] = (byte) b; + return uuid(uuidBytes); + } + + public static UUID constructUUID(UUIDType type, long l1, long l2) + { + // first, ensure type is ok + l1 &= ~0xF000L; // remove high nibble of 6th byte + l1 |= (long) (type.raw() << 12); + // second, ensure variant is properly set too (8th byte; most-sig byte of second long) + l2 = ((l2 << 2) >>> 2); // remove 2 MSB + l2 |= (2L << 62); // set 2 MSB to '10' + return new UUID(l1, l2); + } + + public static long initUUIDFirstLong(long l1, UUIDType type) + { + return initUUIDFirstLong(l1, type.raw()); + } + + public static long initUUIDFirstLong(long l1, int rawType) + { + l1 &= ~0xF000L; // remove high nibble of 6th byte + l1 |= (long) (rawType << 12); + return l1; + } + + public static long initUUIDSecondLong(long l2) + { + l2 = ((l2 << 2) >>> 2); // remove 2 MSB + l2 |= (2L << 62); // set 2 MSB to '10' + return l2; + } + + /* + /*********************************************************************** + /* Type introspection + /*********************************************************************** + */ + + /** + * Method for determining which type of UUID given UUID is. + * Returns null if type can not be determined. + * + * @param uuid UUID to check + * + * @return Null if UUID is null or type can not be determined (== invalid UUID); + * otherwise type + */ + public static UUIDType typeOf(UUID uuid) + { + if (uuid == null) { + return null; + } + // Ok: so 4 MSB of byte at offset 6... + long l = uuid.getMostSignificantBits(); + int typeNibble = (((int) l) >> 12) & 0xF; + switch (typeNibble) { + case 0: + // possibly null? + if (l == 0L && uuid.getLeastSignificantBits() == l) { + return UUIDType.UNKNOWN; + } + break; + case 1: + return UUIDType.TIME_BASED; + case 2: + return UUIDType.DCE; + case 3: + return UUIDType.NAME_BASED_MD5; + case 4: + return UUIDType.RANDOM_BASED; + case 5: + return UUIDType.NAME_BASED_SHA1; + } + // not recognized: return null + return null; + } + + /* + /*********************************************************************** + /* Conversions to other types + /*********************************************************************** + */ + + public static byte[] asByteArray(UUID uuid) + { + long hi = uuid.getMostSignificantBits(); + long lo = uuid.getLeastSignificantBits(); + byte[] result = new byte[16]; + _appendInt((int) (hi >> 32), result, 0); + _appendInt((int) hi, result, 4); + _appendInt((int) (lo >> 32), result, 8); + _appendInt((int) lo, result, 12); + return result; + } + + public static void toByteArray(UUID uuid, byte[] buffer) { + toByteArray(uuid, buffer, 0); + } + + public static void toByteArray(UUID uuid, byte[] buffer, int offset) + { + _checkUUIDByteArray(buffer, offset); + long hi = uuid.getMostSignificantBits(); + long lo = uuid.getLeastSignificantBits(); + _appendInt((int) (hi >> 32), buffer, offset); + _appendInt((int) hi, buffer, offset+4); + _appendInt((int) (lo >> 32), buffer, offset+8); + _appendInt((int) lo, buffer, offset+12); + } + + /* + /******************************************************************************** + /* Package helper methods + /******************************************************************************** + */ + + //private final static long MASK_LOW_INT = 0x0FFFFFFFF; + + protected final static long gatherLong(byte[] buffer, int offset) + { + long hi = ((long) _gatherInt(buffer, offset)) << 32; + //long lo = ((long) _gatherInt(buffer, offset+4)) & MASK_LOW_INT; + long lo = (((long) _gatherInt(buffer, offset+4)) << 32) >>> 32; + return hi | lo; + } + + /* + /******************************************************************************** + /* Internal helper methods + /******************************************************************************** + */ + + private final static void _appendInt(int value, byte[] buffer, int offset) + { + buffer[offset++] = (byte) (value >> 24); + buffer[offset++] = (byte) (value >> 16); + buffer[offset++] = (byte) (value >> 8); + buffer[offset] = (byte) value; + } + + private final static int _gatherInt(byte[] buffer, int offset) + { + return (buffer[offset] << 24) | ((buffer[offset+1] & 0xFF) << 16) + | ((buffer[offset+2] & 0xFF) << 8) | (buffer[offset+3] & 0xFF); + } + + private final static void _checkUUIDByteArray(byte[] bytes, int offset) + { + if (bytes == null) { + throw new IllegalArgumentException("Invalid byte[] passed: can not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("Invalid offset ("+offset+") passed: can not be negative"); + } + if ((offset + 16) > bytes.length) { + throw new IllegalArgumentException("Invalid offset ("+offset+") passed: not enough room in byte array (need 16 bytes)"); + } + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/Jug.java jug-3.1.5/src/main/java/com/fasterxml/uuid/Jug.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/Jug.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/Jug.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,321 @@ +/* JUG Java UUID Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.*; +import java.util.*; + +import com.fasterxml.uuid.impl.NameBasedGenerator; + +/** + * Simple command-line interface to UUID generation functionality. + */ +public class Jug +{ + protected final static HashMap TYPES = new HashMap(); + static { + TYPES.put("time-based", "t"); + TYPES.put("random-based", "r"); + TYPES.put("name-based", "n"); + } + + protected final static HashMap OPTIONS = new HashMap(); + static { + OPTIONS.put("count", "c"); + OPTIONS.put("ethernet-address", "e"); + OPTIONS.put("help", "h"); + OPTIONS.put("namespace", "s"); + OPTIONS.put("name", "n"); + OPTIONS.put("performance", "p"); + OPTIONS.put("verbose", "v"); + } + + protected static void printUsage() + { + String clsName = Jug.class.getName(); + System.err.println("Usage: java "+clsName+" [options] type"); + System.err.println("Where options are:"); + System.err.println(" --count / -c : will generate UUIDs (default: 1)"); + System.err.println(" --ethernet-address / -e : defines the ethernet address"); + System.err.println(" (in xx:xx:xx:xx:xx:xx notation, usually obtained using 'ifconfig' etc)"); + System.err.println(" to use with time-based UUID generation"); + System.err.println(" --help / -h: lists the usage (ie. what you see now)"); + System.err.println(" --name / -n: specifies"); + System.err.println(" o name for name-based UUID generation"); + System.err.println(" o 'information' part of tag-URI for tag-URI UUID generation"); + System.err.println(" --namespace / -s: specifies"); + System.err.println(" o the namespace (DNS or URL) for name-based UUID generation"); + System.err.println(" o 'authority' part of tag-URI for tag-URI UUID generation;"); + System.err.println(" (fully-qualified domain name, email address)"); + System.err.println(" --performance / -p: measure time it takes to generate UUID(s)."); + System.err.println(" [note that UUIDs are not printed out unless 'verbose' is also specified]"); + System.err.println(" --verbose / -v: lists additional information about UUID generation\n (by default only UUIDs are printed out (to make it usable in scripts)"); + System.err.println("And type is one of:"); + System.err.println(" time-based / t: generate UUID based on current time and optional\n location information (defined with -e option)"); + System.err.println(" random-based / r: generate UUID based on the default secure random number generator"); + System.err.println(" name-based / n: generate UUID based on the na the default secure random number generator"); + } + + private static void printMap(Map m, PrintStream out, boolean option) + { + int i = 0; + int len = m.size(); + for (Map.Entry en : m.entrySet()) { + if (++i > 1) { + if (i < len) { + out.print(", "); + } else { + out.print(" and "); + } + } + if (option) { + out.print("--"); + } + out.print(en.getKey()); + out.print(" ("); + if (option) { + out.print("-"); + } + out.print(en.getValue()); + out.print(")"); + } + } + + public static void main(String[] args) + { + if (args.length == 0) { + printUsage(); + return; + } + + int count = args.length; + String type = args[count-1]; + boolean verbose = false; + int genCount = 1; + String name = null; + String nameSpace = null; + EthernetAddress addr = null; + boolean performance = false; + + --count; + + // Type we recognize? + String tmp = (String) TYPES.get(type); + if (tmp == null) { + if (!TYPES.containsValue(type)) { + System.err.println("Unrecognized UUID generation type '"+ + type+"'; currently available ones are:"); + printMap(TYPES, System.err, false); + System.err.println(); + System.exit(1); + } + } else { + // Long names get translated to shorter ones: + type = tmp; + } + + + NoArgGenerator noArgGenerator = null; // random- or time-based + StringArgGenerator nameArgGenerator = null; // name-based + + for (int i = 0; i < count; ++i) { + String opt = args[i]; + + if (opt.length() == 0 || opt.charAt(0) != '-') { + System.err.println("Unrecognized option '"+opt+"' (missing leading hyphen?), exiting."); + System.exit(1); + } + + char option = (char)0; + if (opt.startsWith("--")) { + String o = (String) OPTIONS.get(opt.substring(2)); + // Let's translate longer names to simple names: + if (o != null) { + option = o.charAt(0); + } + } else { + if (OPTIONS.containsValue(opt.substring(1))) { + option = opt.charAt(1); + } + } + + if (option == (char) 0) { + System.err.println("Unrecognized option '"+opt+"'; exiting."); + System.err.print("[options currently available are: "); + printMap(OPTIONS, System.err, true); + System.err.println("]"); + System.exit(1); + } + + // K. Now we have one-letter options to handle: + try { + String next; + switch (option) { + case 'c': + // Need a number now: + next = args[++i]; + try { + genCount = Integer.parseInt(next); + } catch (NumberFormatException nex) { + System.err.println("Invalid number argument for option '"+opt+"', exiting."); + System.exit(1); + } + if (genCount < 1) { + System.err.println("Invalid number argument for option '"+opt+"'; negative numbers not allowed, ignoring (defaults to 1)."); + } + break; + case 'e': + // Need the ethernet address: + next = args[++i]; + try { + addr = EthernetAddress.valueOf(next); + } catch (NumberFormatException nex) { + System.err.println("Invalid ethernet address for option '"+opt+"', error: "+nex.toString()); + System.exit(1); + } + break; + case 'h': + printUsage(); + return; + case 'n': + // Need the name + name = args[++i]; + break; + case 'p': // performance: + performance = true; + break; + case 's': + // Need the namespace id + nameSpace = args[++i]; + break; + case 'v': + verbose = true; + break; + } + } catch (IndexOutOfBoundsException ie) { + // We get here when an arg is missing... + System.err.println("Missing argument for option '"+opt+"', exiting."); + System.exit(1); + } + } // for (int i = 0....) + + /* Ok, args look ok so far. Now to the generation; some args/options + * can't be validated without knowing the type: + */ + char typeC = type.charAt(0); + UUID nsUUID = null; + + boolean usesRnd = false; + + switch (typeC) { + case 't': // time-based + usesRnd = true; + // No address specified? Need a dummy one... + if (addr == null) { + if (verbose) { + System.out.print("(no address specified, generating dummy address: "); + } + addr = EthernetAddress.constructMulticastAddress(new java.util.Random(System.currentTimeMillis())); + if (verbose) { + System.out.print(addr.toString()); + System.out.println(")"); + } + } + noArgGenerator = Generators.timeBasedGenerator(addr); + break; + case 'r': // random-based + usesRnd = true; + { + SecureRandom r = new SecureRandom(); + if (verbose) { + System.out.print("(using secure random generator, info = '"+r.getProvider().getInfo()+"')"); + } + noArgGenerator = Generators.randomBasedGenerator(r); + } + break; + case 'n': // name-based + if (name == null) { + System.err.println("--name-space (-s) - argument missing when using method that requires it, exiting."); + System.exit(1); + } + if (name == null) { + System.err.println("--name (-n) - argument missing when using method that requires it, exiting."); + System.exit(1); + } + if (typeC == 'n') { + String orig = nameSpace; + nameSpace = nameSpace.toLowerCase(); + if (nameSpace.equals("url")) { + nsUUID = NameBasedGenerator.NAMESPACE_URL; + } else if (nameSpace.equals("dns")) { + nsUUID = NameBasedGenerator.NAMESPACE_DNS; + } else { + System.err.println("Unrecognized namespace '"+orig + +"'; only DNS and URL allowed for name-based generation."); + System.exit(1); + } + } + nameArgGenerator = Generators.nameBasedGenerator(nsUUID); + break; + } + + // And then let's rock: + if (verbose) { + System.out.println(); + } + + /* When measuring performance, make sure that the random number + * generator is initialized prior to measurements... + */ + long now = 0L; + + if (performance) { + // No need to pre-initialize for name-based schemes? + if (usesRnd) { + if (verbose) { + System.out.println("(initializing random number generator before UUID generation so that performance measurements are not skewed due to one-time init costs)"); + } + // should initialize by just calling it + noArgGenerator.generate(); + if (verbose) { + System.out.println("(random number generator initialized ok)"); + } + } + now = System.currentTimeMillis(); + } + + for (int i = 0; i < genCount; ++i) { + UUID uuid = (nameArgGenerator == null) ? + noArgGenerator.generate() : nameArgGenerator.generate(name); + if (verbose) { + System.out.print("UUID: "); + } + if (!performance || verbose) { + System.out.println(uuid.toString()); + } + } // for (int i = 0; ...) + + if (verbose) { + System.out.println("Done."); + } + if (performance) { + now = System.currentTimeMillis() - now; + long avg = (now * 10 + (genCount / 2)) / genCount; + System.out.println("Performance: took "+now+" milliseconds to generate (and print out) "+genCount+" UUIDs; average being "+(avg / 10)+"."+(avg%10)+" msec."); + } + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/Logger.java jug-3.1.5/src/main/java/com/fasterxml/uuid/Logger.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/Logger.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/Logger.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,290 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.*; + +/** + * This is the simple logging interface used by JUG package. It is meant + * to provide a minimal but sufficient functionality for JUG to report + * problems (warnings, errors), in a way that it can be sufficiently + * customized (redirected, suppressed; even redefined), without forcing + * overhead of a real + * full-featured logging sub-system (like log4j or java.util.logging). + * By being customizable, it is still possible to connect JUG logging into + * real logging framework (log4j, java.util.logging) used by application + * or system that uses JUG. + *

+ * To keep things as light-weight as possible, we won't bother defining + * separate interface or abstract class -- this class defines both API + * and the default implementation. It can thus be extended to override + * functionality to provide things like bridging to "real" logging systems. + * For simple configuration (suppress all, redirect to another stream) + * default implementation should be sufficient, however. + *

+ * Note: package com.fasterxml.uuid.ext does contain + * simple wrappers to connect JUG logging to log4j and java.util.logging: + * + * @see com.fasterxml.uuid.ext.Log4jLogger + * @see com.fasterxml.uuid.ext.JavaUtilLogger + */ +public class Logger +{ + /* + ////////////////////////////////////////////////// + // Constants + ////////////////////////////////////////////////// + */ + + public final static int LOG_ALL = 0; + public final static int LOG_INFO_AND_ABOVE = 1; + public final static int LOG_WARNING_AND_ABOVE = 2; + public final static int LOG_ERROR_AND_ABOVE = 3; + public final static int LOG_NOTHING = 4; + + /* + /********************************************************************** + /* Static objects + /********************************************************************** + */ + + /** + * By default we'll use this default implementation; however, + * it can be easily changed. + */ + private static Logger instance = new Logger(); + + /* + /********************************************************************** + /* Default impl. configuration + /********************************************************************** + */ + + /** + * Threshold to use for outputting varius log statements. + *

+ * Default is to low only warnings and errors + */ + protected int _logLevel = LOG_ALL; + + /** + * Output object to use, if defined; initialized to + * System.err. + */ + protected PrintStream _output1 = System.err; + + /** + * Override output used to explicitly specify where to pass diagnostic + * output, instead of System.err. Used if _output1 + * is null; + */ + protected PrintWriter _output2 = null; + + /* + /********************************************************************** + /* Life-cycle + /********************************************************************** + */ + + protected Logger() { } + + /** + * Method that can be used to completely re-define the logging + * functionality JUG uses. When called, JUG will start using the + * new instance; if instance passed is null, will basically suppress + * all logging. + * + * @param inst Logger instance to use for all logging JUG does; can be + * null, but if so, essentially disables all logging. + */ + public synchronized static void setLogger(Logger inst) + { + instance = inst; + } + + /* + /********************************************************************** + /* Actual simple logging API + /* (static dispatchers to instance methods) + /********************************************************************** + */ + + // // // Configuration + + /** + * Method to set the minimum level of messages that will get logged + * using currently specific logger instace. For example, if + * {@link #LOG_WARNING_AND_ABOVE} is passed as the argument, warnings + * and errors will be logged, but informational (INFO) messages will + * not. + *

+ * Note: exact functionality invoked depends on the logger instance: + * sub-classes of this class may need to do mapping to some other + * logging sub-system (log4j and JUL logging, for example, use their + * own severity levels that while generally reasonably easy to map, + * are nonetheless not one-to-one which the simple logger). + */ + public static void setLogLevel(int level) + { + Logger l = instance; + if (l != null) { + l.doSetLogLevel(level); + } + } + + /** + * Method that will re-direct output of the logger using the specified + * {@link PrintStream}. Null is allowed, and signifies that all the + * output should be suppressed. + *

+ * Note: exact functionality invoked depends on the logger instance. + */ + public static void setOutput(PrintStream str) + { + Logger l = instance; + if (l != null) { + l.doSetOutput(str); + } + } + + /** + * Method that will re-direct output of the logger using the specified + * {@link Writer}. Null is allowed, and signifies that all the + * output should be suppressed. + */ + public static void setOutput(Writer w) + { + Logger l = instance; + if (l != null) { + l.doSetOutput(w); + } + } + + // // // Logging methods + + public static void logInfo(String msg) + { + Logger l = instance; + if (l != null) { + l.doLogInfo(msg); + } + } + + public static void logWarning(String msg) + { + Logger l = instance; + if (l != null) { + l.doLogWarning(msg); + } + } + + public static void logError(String msg) + { + Logger l = instance; + if (l != null) { + l.doLogError(msg); + } + } + + /* + /********************************************************************** + /* Overridable implementation/instance methods + /********************************************************************** + */ + + // // // Config + + protected void doSetLogLevel(int ll) + { + /* No need to sync for atomic value that's not used + * for synced or critical things + */ + _logLevel = ll; + } + + protected void doSetOutput(PrintStream str) + { + synchronized (this) { + _output1 = str; + _output2 = null; + } + } + + protected void doSetOutput(Writer w) + { + synchronized (this) { + _output1 = null; + _output2 = (w instanceof PrintWriter) ? + (PrintWriter) w : new PrintWriter(w); + } + } + + // // // Logging methods + + protected void doLogInfo(String msg) + { + if (_logLevel <= LOG_INFO_AND_ABOVE && isEnabled()) { + synchronized (this) { + doWrite("INFO: "+msg); + } + } + } + + protected void doLogWarning(String msg) + { + if (_logLevel <= LOG_WARNING_AND_ABOVE && isEnabled()) { + synchronized (this) { + doWrite("WARNING: "+msg); + } + } + } + + protected void doLogError(String msg) + { + if (_logLevel <= LOG_ERROR_AND_ABOVE && isEnabled()) { + synchronized (this) { + doWrite("ERROR: "+msg); + } + } + } + + /* + /********************************************************************** + /* Internal methods + /********************************************************************** + */ + + protected void doWrite(String msg) + { + if (_output1 != null) { + _output1.println(msg); + } else if (_output2 != null) { + _output2.println(msg); + } + } + + /** + * Internal method used to quickly check if the Logger's output + * is suppressed or not. + *

+ * Note: not synchronized since it's read-only method that's return + * value can not be used for reliable syncing. + */ + protected boolean isEnabled() { + return (_output1 != null) || (_output2 != null); + } +} + diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/NoArgGenerator.java jug-3.1.5/src/main/java/com/fasterxml/uuid/NoArgGenerator.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/NoArgGenerator.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/NoArgGenerator.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,14 @@ +package com.fasterxml.uuid; + +import java.util.UUID; + +/** + * Intermediate base class for UUID generators that do not take arguments for individual + * calls. This includes random and time-based variants, but not name-based ones. + * + * @since 3.0 + */ +public abstract class NoArgGenerator extends UUIDGenerator +{ + public abstract UUID generate(); +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/package.html jug-3.1.5/src/main/java/com/fasterxml/uuid/package.html --- jug-2.0.0/src/main/java/com/fasterxml/uuid/package.html 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/package.html 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,14 @@ + +Package that contains core (non-optional) Java UUID Generator API classes. +Implementation classes can be found from under {@link com.fasterxml.uuid.impl}. +These classes should be usable on JDK 1.4 and up, and have no external dependencies; +except that any functionality that uses Ethernet-address discovery requires JDK 1.6. +

+The primary point is {@link com.fasterxml.uuid.Generators}, used to construct actual +generators, based on method to use and some optional arguments. +

+

+Note: earlier JUG versions (up to 2.0) supported older JDKs (1.1); 1.4 is now needed +since {@link java.util.UUID} is used as a core abstraction. +

+ diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/StringArgGenerator.java jug-3.1.5/src/main/java/com/fasterxml/uuid/StringArgGenerator.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/StringArgGenerator.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/StringArgGenerator.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,26 @@ +package com.fasterxml.uuid; + +import java.util.UUID; + +/** + * Intermediate base class for UUID generators that take one String argument for individual + * calls. This includes name-based generators, but not random and time-based generators. + * + * @since 3.0 + */ +public abstract class StringArgGenerator extends UUIDGenerator +{ + /** + * Method for generating name-based UUIDs using specified name (serialized to + * bytes using UTF-8 encoding) + */ + public abstract UUID generate(String name); + + /** + * Method for generating name-based UUIDs using specified byte-serialization + * of name. + * + * @since 3.1 + */ + public abstract UUID generate(byte[] nameBytes); +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/TimestampSynchronizer.java jug-3.1.5/src/main/java/com/fasterxml/uuid/TimestampSynchronizer.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/TimestampSynchronizer.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/TimestampSynchronizer.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,82 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.IOException; + +/** + * This is the API for utility classes optionally used by {@link UUIDTimer} to + * ensure that timestamp values used for generating time/location-based UUIDs + * are monotonically increasing, as well as that only one such generator + * is ever used on a single system, even in presence of multiple JVMs. + *

+ * The default implementation used by JUG is + * {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}. + */ +public abstract class TimestampSynchronizer +{ + protected TimestampSynchronizer() { } + + /** + * Initialization method is will be called on an instance by + * {@link UUIDTimer} right after it's been configured with one. + * At this point the implementation instance should have been properly + * configured, and should be able to determine the first legal timestamp + * value (return value). Method should also initialize any locking that + * it does (if any), such as locking files it needs. + *

+ * Return value thus indicates the lowest initial time value that can + * be used by the caller that can not have been used by previous + * incarnations of the UUID generator (assuming instance was able to + * find properly persisted data to figure that out). + * However, caller also needs to make sure that it will + * call {@link #update} when it actually needs the time stamp for the + * first time, + * since this method can not allocate timestamps beyond this initial + * value at this point. + * + * @return First (and last) legal timestamp to use; 0L if it + * can not + * determine it and caller can use whatever value (current timestamp) + * it has access to. + */ + protected abstract long initialize() + throws IOException; + + /** + * Method {@link UUIDTimer} will call if this synchronizer object is + * being replaced by another synchronizer (or removed, that is, no + * more synchronization is to be done). It will not be called if JVM + * terminates. + */ + protected abstract void deactivate() + throws IOException; + + /** + * Method called by {@link UUIDTimer} to indicate that it has generated + * a timestamp value that is beyond last legal timestamp value. + * The method should only return once it has "locked" specified timestamp + * value (and possible additional ones). + * + * @param now Timestamp value caller wants to use, and that the + * synchronizer is asked to protect. + * + * @return First timestamp value that can NOT be used by the caller; + * has to be higher than the input timestamp value + */ + protected abstract long update(long now) + throws IOException; +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDComparator.java jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDComparator.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDComparator.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDComparator.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,77 @@ +package com.fasterxml.uuid; + +import java.util.Comparator; +import java.util.UUID; + +/** + * Default {@link java.util.UUID} comparator is not very useful, since + * it just does blind byte-by-byte comparison which does not work well + * for time+location - based UUIDs. Additionally it also uses signed + * comparisons for longs which can lead to unexpected behavior + * This comparator does implement proper lexical ordering: starting with + * type (different types are collated + * separately), followed by time and location (for time/location based), + * and simple lexical (byte-by-byte) ordering for name/hash and random + * variants. + * + * @author tatu + */ +public class UUIDComparator implements Comparator +{ + @Override + public int compare(UUID u1, UUID u2) + { + return staticCompare(u1, u2); + } + + /** + * Static helper method that can be used instead of instantiating comparator + * (used by unit tests, can be used by code too) + */ + public static int staticCompare(UUID u1, UUID u2) + { + // First: major sorting by types + int type = u1.version(); + int diff = type - u2.version(); + if (diff != 0) { + return diff; + } + // Second: for time-based variant, order by time stamp: + if (type == UUIDType.TIME_BASED.raw()) { + diff = compareULongs(u1.timestamp(), u2.timestamp()); + if (diff == 0) { + // or if that won't work, by other bits lexically + diff = compareULongs(u1.getLeastSignificantBits(), u2.getLeastSignificantBits()); + } + } else { + // note: java.util.UUIDs compares with sign extension, IMO that's wrong, so: + diff = compareULongs(u1.getMostSignificantBits(), + u2.getMostSignificantBits()); + if (diff == 0) { + diff = compareULongs(u1.getLeastSignificantBits(), + u2.getLeastSignificantBits()); + } + } + return diff; + } + + protected final static int compareULongs(long l1, long l2) { + int diff = compareUInts((int) (l1 >> 32), (int) (l2 >> 32)); + if (diff == 0) { + diff = compareUInts((int) l1, (int) l2); + } + return diff; + } + + protected final static int compareUInts(int i1, int i2) + { + /* bit messier due to java's insistence on signed values: if both + * have same sign, normal comparison (by subtraction) works fine; + * but if signs don't agree need to resolve differently + */ + if (i1 < 0) { + return (i2 < 0) ? (i1 - i2) : 1; + } + return (i2 < 0) ? -1 : (i1 - i2); + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDGenerator.java jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDGenerator.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDGenerator.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDGenerator.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,49 @@ +/* JUG Java UUID Generator + * + * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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; + +/** + * Minimal "tag" base class from which all generator implementations + * derive. Actual generation methods are not included since different + * generators take different number of arguments. + * + * @since 3.0 + */ +public abstract class UUIDGenerator +{ + /* + /********************************************************** + /* Life-cycle + /********************************************************** + */ + + /** + * Constructor is private to enforce singleton access. + */ + protected UUIDGenerator() { } + + /* + /********************************************************** + /* Shared (minimal) API + /********************************************************** + */ + + /** + * Accessor for determining type of UUIDs (variant) that this + * generator instance will produce. + */ + public abstract UUIDType getType(); +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDTimer.java jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDTimer.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDTimer.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDTimer.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,379 @@ +/* JUG Java Uuid Generator + * + * Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi + * + * 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.util.*; + +import com.fasterxml.uuid.impl.UUIDUtil; + +/** + * UUIDTimer produces the time stamps required for time-based UUIDs. + * It works as outlined in the UUID specification, with following + * implementation: + *

    + *
  • Java classes can only product time stamps with maximum resolution + * of one millisecond (at least before JDK 1.5). + * To compensate, an additional counter is used, + * so that more than one UUID can be generated between java clock + * updates. Counter may be used to generate up to 10000 UUIDs for + * each distinct java clock value. + *
  • Due to even lower clock resolution on some platforms (older + * Windows versions use 55 msec resolution), timestamp value can + * also advanced ahead of physical value within limits (by default, + * up 100 millisecond ahead of reported), if necessary (ie. 10000 + * instances created before clock time advances). + *
  • As an additional precaution, counter is initialized not to 0 + * but to a random 8-bit number, and each time clock changes, lowest + * 8-bits of counter are preserved. The purpose it to make likelyhood + * of multi-JVM multi-instance generators to collide, without significantly + * reducing max. UUID generation speed. Note though that using more than + * one generator (from separate JVMs) is strongly discouraged, so + * hopefully this enhancement isn't needed. + * This 8-bit offset has to be reduced from total max. UUID count to + * preserve ordering property of UUIDs (ie. one can see which UUID + * was generated first for given UUID generator); the resulting + * 9500 UUIDs isn't much different from the optimal choice. + *
  • Finally, as of version 2.0 and onwards, optional external timestamp + * synchronization can be done. This is done similar to the way UUID + * specification suggests; except that since there is no way to + * lock the whole system, file-based locking is used. This works + * between multiple JVMs and Jug instances. + *
+ *

+ *Some additional assumptions about calculating the timestamp: + *

    + *
  • System.currentTimeMillis() is assumed to give time offset in UTC, + * or at least close enough thing to get correct timestamps. The + * alternate route would have to go through calendar object, use + * TimeZone offset to get to UTC, and then modify. Using currentTimeMillis + * should be much faster to allow rapid UUID creation. + *
  • Similarly, the constant used for time offset between 1.1.1970 and + * start of Gregorian calendar is assumed to be correct (which seems + * to be the case when testing with Java calendars). + *
+ *

+ * Note about synchronization: main synchronization point (as of version + * 3.1.1 and above) is {@link #getTimestamp}, so caller need not + * synchronize access explicitly. + */ +public class UUIDTimer +{ + // // // Constants + + /** + * Since System.longTimeMillis() returns time from january 1st 1970, + * and UUIDs need time from the beginning of gregorian calendar + * (15-oct-1582), need to apply the offset: + */ + private final static long kClockOffset = 0x01b21dd213814000L; + /** + * Also, instead of getting time in units of 100nsecs, we get something + * with max resolution of 1 msec... and need the multiplier as well + */ + private final static int kClockMultiplier = 10000; + + private final static long kClockMultiplierL = 10000L; + + /** + * Let's allow "virtual" system time to advance at most 100 milliseconds + * beyond actual physical system time, before adding delays. + */ + private final static long kMaxClockAdvance = 100L; + + // // // Configuration + + /** + * Object used to reliably ensure that no multiple JVMs + * generate UUIDs, and also that the time stamp value used for + * generating time-based UUIDs is monotonically increasing + * even if system clock moves backwards over a reboot (usually + * due to some system level problem). + *

+ * See {@link TimestampSynchronizer} for details. + */ + protected final TimestampSynchronizer _syncer; + + /** + * Random number generator used to generate additional information + * to further reduce probability of collisions. + */ + protected final Random _random; + + // // // Clock state: + + /** + * Additional state information used to protect against anomalous + * cases (clock time going backwards, node id getting mixed up). + * Third byte is actually used for seeding counter on counter + * overflow. + * Note that only lowermost 16 bits are actually used as sequence + */ + private int _clockSequence; + + /** + * Last physical timestamp value System.currentTimeMillis() + * returned: used to catch (and report) cases where system clock + * goes backwards. Is also used to limit "drifting", that is, amount + * timestamps used can differ from the system time value. This value + * is not guaranteed to be monotonically increasing. + */ + private long _lastSystemTimestamp = 0L; + + /** + * Timestamp value last used for generating a UUID (along with + * {@link #_clockCounter}. Usually the same as + * {@link #_lastSystemTimestamp}, but not always (system clock + * moved backwards). Note that this value is guaranteed to be + * monotonically increasing; that is, at given absolute time points + * t1 and t2 (where t2 is after t1), t1 <= t2 will always hold true. + */ + private long _lastUsedTimestamp = 0L; + + /** + * First timestamp that can NOT be used without synchronizing + * using synchronization object ({@link #_syncer}). Only used when + * external timestamp synchronization (and persistence) is used, + * ie. when {@link #_syncer} is not null. + */ + private long _firstUnsafeTimestamp = Long.MAX_VALUE; + + /** + * Counter used to compensate inadequate resolution of JDK system + * timer. + */ + private int _clockCounter = 0; + + public UUIDTimer(Random rnd, TimestampSynchronizer sync) throws IOException + { + _random = rnd; + _syncer = sync; + initCounters(rnd); + _lastSystemTimestamp = 0L; + // This may get overwritten by the synchronizer + _lastUsedTimestamp = 0L; + + /* Ok, now; synchronizer can tell us what is the first timestamp + * value that definitely was NOT used by the previous incarnation. + * This can serve as the last used time stamp, assuming it is not + * less than value we are using now. + */ + if (sync != null) { + long lastSaved = sync.initialize(); + if (lastSaved > _lastUsedTimestamp) { + _lastUsedTimestamp = lastSaved; + } + } + + /* Also, we need to make sure there are now no safe values (since + * synchronizer is not yet requested to allocate any): + */ + _firstUnsafeTimestamp = 0L; // ie. will always trigger sync.update() + } + + private void initCounters(Random rnd) + { + /* Let's generate the clock sequence field now; as with counter, + * this reduces likelihood of collisions (as explained in UUID specs) + */ + _clockSequence = rnd.nextInt(); + /* Ok, let's also initialize the counter... + * Counter is used to make it slightly less likely that + * two instances of UUIDGenerator (from separate JVMs as no more + * than one can be created in one JVM) would produce colliding + * time-based UUIDs. The practice of using multiple generators, + * is strongly discouraged, of course, but just in case... + */ + _clockCounter = (_clockSequence >> 16) & 0xFF; + } + + public int getClockSequence() { + return (_clockSequence & 0xFFFF); + } + + /** + * Method that constructs unique timestamp suitable for use for + * constructing UUIDs. Default implementation is fully synchronized; + * sub-classes may choose to implemented alternate strategies + * + * @return 64-bit timestamp to use for constructing UUID + */ + public synchronized long getTimestamp() + { + long systime = System.currentTimeMillis(); + /* Let's first verify that the system time is not going backwards; + * independent of whether we can use it: + */ + if (systime < _lastSystemTimestamp) { + Logger.logWarning("System time going backwards! (got value "+systime+", last "+_lastSystemTimestamp); + // Let's write it down, still + _lastSystemTimestamp = systime; + } + + /* But even without it going backwards, it may be less than the + * last one used (when generating UUIDs fast with coarse clock + * resolution; or if clock has gone backwards over reboot etc). + */ + if (systime <= _lastUsedTimestamp) { + /* Can we just use the last time stamp (ok if the counter + * hasn't hit max yet) + */ + if (_clockCounter < kClockMultiplier) { // yup, still have room + systime = _lastUsedTimestamp; + } else { // nope, have to roll over to next value and maybe wait + long actDiff = _lastUsedTimestamp - systime; + long origTime = systime; + systime = _lastUsedTimestamp + 1L; + + Logger.logWarning("Timestamp over-run: need to reinitialize random sequence"); + + /* Clock counter is now at exactly the multiplier; no use + * just anding its value. So, we better get some random + * numbers instead... + */ + initCounters(_random); + + /* But do we also need to slow down? (to try to keep virtual + * time close to physical time; i.e. either catch up when + * system clock has been moved backwards, or when coarse + * clock resolution has forced us to advance virtual timer + * too far) + */ + if (actDiff >= kMaxClockAdvance) { + slowDown(origTime, actDiff); + } + } + } else { + /* Clock has advanced normally; just need to make sure counter is + * reset to a low value (need not be 0; good to leave a small + * residual to further decrease collisions) + */ + _clockCounter &= 0xFF; + } + + _lastUsedTimestamp = systime; + + /* Ok, we have consistent clock (virtual or physical) value that + * we can and should use. + * But do we need to check external syncing now? + */ + if (_syncer != null && systime >= _firstUnsafeTimestamp) { + try { + _firstUnsafeTimestamp = _syncer.update(systime); + } catch (IOException ioe) { + throw new RuntimeException("Failed to synchronize timestamp: "+ioe); + } + } + + /* Now, let's translate the timestamp to one UUID needs, 100ns + * unit offset from the beginning of Gregorian calendar... + */ + systime *= kClockMultiplierL; + systime += kClockOffset; + + // Plus add the clock counter: + systime += _clockCounter; + // and then increase + ++_clockCounter; + return systime; + } + + /* + /********************************************************************** + /* Test-support methods + /********************************************************************** + */ + + /* Method for accessing timestamp to use for creating UUIDs. + * Used ONLY by unit tests, hence protected. + */ + protected final void getAndSetTimestamp(byte[] uuidBytes) + { + long timestamp = getTimestamp(); + + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) _clockSequence; + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) (_clockSequence >> 8); + + // Time fields aren't nicely split across the UUID, so can't just + // linearly dump the stamp: + int clockHi = (int) (timestamp >>> 32); + int clockLo = (int) timestamp; + + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_HI] = (byte) (clockHi >>> 24); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_HI+1] = (byte) (clockHi >>> 16); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_MID] = (byte) (clockHi >>> 8); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_MID+1] = (byte) clockHi; + + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_LO] = (byte) (clockLo >>> 24); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_LO+1] = (byte) (clockLo >>> 16); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_LO+2] = (byte) (clockLo >>> 8); + uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_LO+3] = (byte) clockLo; + } + + /* + /********************************************************************** + /* Private methods + /********************************************************************** + */ + + private final static int MAX_WAIT_COUNT = 50; + + /** + * Simple utility method to use to wait for couple of milliseconds, + * to let system clock hopefully advance closer to the virtual + * timestamps used. Delay is kept to just a millisecond or two, + * to prevent excessive blocking; but that should be enough to + * eventually synchronize physical clock with virtual clock values + * used for UUIDs. + * + * @param msecs Number of milliseconds to wait for from current + * time point + */ + protected static void slowDown(long startTime, long actDiff) + { + /* First, let's determine how long we'd like to wait. + * This is based on how far ahead are we as of now. + */ + long ratio = actDiff / kMaxClockAdvance; + long delay; + + if (ratio < 2L) { // 200 msecs or less + delay = 1L; + } else if (ratio < 10L) { // 1 second or less + delay = 2L; + } else if (ratio < 600L) { // 1 minute or less + delay = 3L; + } else { + delay = 5L; + } + Logger.logWarning("Need to wait for "+delay+" milliseconds; virtual clock advanced too far in the future"); + long waitUntil = startTime + delay; + int counter = 0; + do { + try { + Thread.sleep(delay); + } catch (InterruptedException ie) { } + delay = 1L; + /* This is just a sanity check: don't want an "infinite" + * loop if clock happened to be moved backwards by, say, + * an hour... + */ + if (++counter > MAX_WAIT_COUNT) { + break; + } + } while (System.currentTimeMillis() < waitUntil); + } +} diff -Nru jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDType.java jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDType.java --- jug-2.0.0/src/main/java/com/fasterxml/uuid/UUIDType.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/com/fasterxml/uuid/UUIDType.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,29 @@ +package com.fasterxml.uuid; + +/** + * Enumeration of different flavors of UUIDs: 5 specified by specs + * (RFC-4122) + * and one + * virtual entry ("UNKNOWN") to represent invalid one that consists of + * all zero bites + */ +public enum UUIDType { + TIME_BASED(1), + DCE(2), + NAME_BASED_MD5(3), + RANDOM_BASED(4), + NAME_BASED_SHA1(5), + UNKNOWN(0) + ; + + private final int _raw; + + private UUIDType(int raw) { + _raw = raw; + } + + /** + * Returns "raw" type constants, embedded within UUID bytes. + */ + public int raw() { return _raw; } +} diff -Nru jug-2.0.0/src/main/java/perf/MeasurePerformance.java jug-3.1.5/src/main/java/perf/MeasurePerformance.java --- jug-2.0.0/src/main/java/perf/MeasurePerformance.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/perf/MeasurePerformance.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,183 @@ +package perf; + +import java.util.UUID; + +import com.fasterxml.uuid.*; +import com.fasterxml.uuid.impl.RandomBasedGenerator; +import com.fasterxml.uuid.impl.TimeBasedGenerator; + +/** + * Simple micro-benchmark for evaluating performance of various UUID generation + * techniques, including JDK's method as well as JUG's variants. + *

+ * Notes: for name-based variant we will pass plain Strings, assuming this is the + * most common use case; even though it is possible to also pass raw byte arrays. + * JDK and Jug implementations have similar performance so this only changes + * relative speeds of name- vs time-based variants. + * + * @since 3.1 + */ +public class MeasurePerformance +{ + // Let's generate quarter million UUIDs per test + + private static final int ROUNDS = 250; + private static final int COUNT = 1000; + + // also: let's just use a single name for name-based, to avoid extra overhead: + final String NAME = "http://www.cowtowncoder.com/blog/blog.html"; + final byte[] NAME_BYTES; + + public MeasurePerformance() throws java.io.IOException + { + NAME_BYTES = NAME.getBytes("UTF-8"); + } + + public void test() throws Exception + { + int i = 0; + + final Object[] uuids = new Object[COUNT]; + + // can either use bogus address; or local one, no difference perf-wise + EthernetAddress nic = EthernetAddress.fromInterface(); + + // Whether to include namespace? Depends on whether we compare with JDK (which does not) +// UUID namespaceForNamed = NAMESPACE; + UUID namespaceForNamed = null; + + final RandomBasedGenerator secureRandomGen = Generators.randomBasedGenerator(); + final RandomBasedGenerator utilRandomGen = Generators.randomBasedGenerator(new java.util.Random(123)); + final TimeBasedGenerator timeGenPlain = Generators.timeBasedGenerator(nic); + final TimeBasedGenerator timeGenSynced = Generators.timeBasedGenerator(nic, + new com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer()); + final StringArgGenerator nameGen = Generators.nameBasedGenerator(namespaceForNamed); + + while (true) { + try { Thread.sleep(100L); } catch (InterruptedException ie) { } + int round = (i++ % 7); + + long curr = System.currentTimeMillis(); + String msg; + boolean lf = (round == 0); + + switch (round) { + + case 0: + msg = "JDK, random"; + testJDK(uuids, ROUNDS); + break; + + case 1: + msg = "JDK, name"; + testJDKNames(uuids, ROUNDS); + break; + + case 2: + msg = "Jug, time-based (non-sync)"; + testTimeBased(uuids, ROUNDS, timeGenPlain); + break; + + case 3: + msg = "Jug, time-based (SYNC)"; + testTimeBased(uuids, ROUNDS, timeGenSynced); + break; + + case 4: + msg = "Jug, SecureRandom"; + testRandom(uuids, ROUNDS, secureRandomGen); + break; + + case 5: + msg = "Jug, java.util.Random"; + testRandom(uuids, ROUNDS, utilRandomGen); + break; + + + case 6: + msg = "Jug, name-based"; + testNameBased(uuids, ROUNDS, nameGen); + break; + + /* + case 7: + msg = "http://johannburkard.de/software/uuid/"; + testUUID32(uuids, ROUNDS); + break; + */ + + default: + throw new Error("Internal error"); + } + + curr = System.currentTimeMillis() - curr; + if (lf) { + System.out.println(); + } + System.out.println("Test '"+msg+"' -> "+curr+" msecs; last UUID: "+uuids[COUNT-1]); + } + } + + // Test implementation from http://johannburkard.de/software/uuid/ + /* + private final void testUUID32(Object[] uuids, int rounds) + { + while (--rounds >= 0) { + for (int i = 0, len = uuids.length; i < len; ++i) { + uuids[i] = new com.eaio.uuid.UUID(); + } + } + } + */ + + private final void testJDK(Object[] uuids, int rounds) + { + while (--rounds >= 0) { + for (int i = 0, len = uuids.length; i < len; ++i) { + uuids[i] = UUID.randomUUID(); + } + } + } + + private final void testJDKNames(Object[] uuids, int rounds) throws java.io.IOException + { + while (--rounds >= 0) { + for (int i = 0, len = uuids.length; i < len; ++i) { + final byte[] nameBytes = NAME.getBytes("UTF-8"); + uuids[i] = UUID.nameUUIDFromBytes(nameBytes); + } + } + } + + private final void testRandom(Object[] uuids, int rounds, RandomBasedGenerator uuidGen) + { + while (--rounds >= 0) { + for (int i = 0, len = uuids.length; i < len; ++i) { + uuids[i] = uuidGen.generate(); + } + } + } + + private final void testTimeBased(Object[] uuids, int rounds, TimeBasedGenerator uuidGen) + { + while (--rounds >= 0) { + for (int i = 0, len = uuids.length; i < len; ++i) { + uuids[i] = uuidGen.generate(); + } + } + } + + private final void testNameBased(Object[] uuids, int rounds, StringArgGenerator uuidGen) + { + while (--rounds >= 0) { + for (int i = 0, len = uuids.length; i < len; ++i) { + uuids[i] = uuidGen.generate(NAME); + } + } + } + + public static void main(String[] args) throws Exception + { + new MeasurePerformance().test(); + } +} diff -Nru jug-2.0.0/src/main/java/test/FileSyncTest.java jug-3.1.5/src/main/java/test/FileSyncTest.java --- jug-2.0.0/src/main/java/test/FileSyncTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/java/test/FileSyncTest.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,46 @@ +package test; + +import java.util.UUID; + +import com.fasterxml.uuid.*; +import com.fasterxml.uuid.ext.*; +import com.fasterxml.uuid.impl.TimeBasedGenerator; + +/** + * Simple manual utility test class for manually checking whether file-based + * synchronization seems to be working or not. + */ +public class FileSyncTest +{ + public static void main(String[] args) + throws Exception + { + FileBasedTimestampSynchronizer sync = new FileBasedTimestampSynchronizer(); + // Let's stress-test it... + sync.setUpdateInterval(2000L); + + // must have a NIC for this to work, should be ok: + EthernetAddress eth = EthernetAddress.fromInterface(); + TimeBasedGenerator gen = Generators.timeBasedGenerator(eth, sync); + + int counter = 1; + while (true) { + UUID uuid = gen.generate(); + // Default one is for convenient output + System.out.println("#"+counter+" -> "+uuid); + + /* This allows lexical sorting by uuid... (not very useful, + * since 'real' UUID ordering is not lexical) + */ + System.out.println(""+uuid+" (#"+counter+")"); + + // And this can be used to ensure there are no dups: + System.out.println(""+uuid); + ++counter; + + try { + Thread.sleep(120L); + } catch (InterruptedException ie) { } + } + } +} diff -Nru jug-2.0.0/src/main/resources/META-INF/LICENSE jug-3.1.5/src/main/resources/META-INF/LICENSE --- jug-2.0.0/src/main/resources/META-INF/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/resources/META-INF/LICENSE 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,7 @@ +This copy of Java UUID Generator (JUG) library is licensed under Apache (Software) License, +version 2.0 ("the License"). +See the License for details about distribution rights, and the specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff -Nru jug-2.0.0/src/main/resources/META-INF/NOTICE jug-3.1.5/src/main/resources/META-INF/NOTICE --- jug-2.0.0/src/main/resources/META-INF/NOTICE 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/main/resources/META-INF/NOTICE 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,7 @@ +Java UUID generator library has been written by Tatu Saloranta (tatu.saloranta@iki.fi) + +Other developers who have contributed code are: + +* Eric Bie contributed extensive unit test suite which has helped ensure high implementation + quality + diff -Nru jug-2.0.0/src/test/java/com/fasterxml/uuid/EthernetAddressTest.java jug-3.1.5/src/test/java/com/fasterxml/uuid/EthernetAddressTest.java --- jug-2.0.0/src/test/java/com/fasterxml/uuid/EthernetAddressTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/test/java/com/fasterxml/uuid/EthernetAddressTest.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,1491 @@ +/* JUG Java Uuid Generator + * EthernetAddressTest.java + * Created on July 16, 2003, 11:17 PM + * + * Copyright (c) 2003 Eric Bie + * + * 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 junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + +import java.util.Arrays; +import java.util.Random; + +import com.fasterxml.uuid.EthernetAddress; + +/** + * JUnit Test class for the com.fasterxml.uuid.EthernetAddress class. + * + * @author Eric Bie + * @author Tatu Saloranta (changes for version 3.0) + */ +public class EthernetAddressTest extends TestCase +{ + // constant defining the length of a valid ethernet address byte array + private static final int ETHERNET_ADDRESS_ARRAY_LENGTH = 6; + + // some strings for failure case tests + private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_1 = + "01f23:45:67:89:ab"; + private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_2 = + "01:23f45:67:89:ab"; + private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_3 = + "01:23:45f67:89:ab"; + private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_4 = + "01:23:45:67f89:ab"; + private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_5 = + "01:23:45:67:89fab"; + private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_6 = + "01f23f45f67f89fab"; + private static final String NON_HEX_ETHERNET_ADDRESS_STRING = + "NON-HEX0-FORSURE0"; + private static final String RANDOM_PROPER_LENGTH_STRING = + "Same LengthString"; + + // some valid strings for the various dropped digit cases + private static final String FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = + "00:23:45:67:89:ab"; + private static final String FIRST_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = + "0:23:45:67:89:ab"; + private static final String FIRST_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = + ":23:45:67:89:ab"; + private static final String SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = + "01:00:45:67:89:ab"; + private static final String SECOND_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = + "01:0:45:67:89:ab"; + private static final String SECOND_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = + "01::45:67:89:ab"; + private static final String THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = + "01:23:00:67:89:ab"; + private static final String THIRD_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = + "01:23:0:67:89:ab"; + private static final String THIRD_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = + "01:23::67:89:ab"; + private static final String FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:00:89:ab"; + private static final String FOURTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:0:89:ab"; + private static final String FOURTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45::89:ab"; + private static final String FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:67:00:ab"; + private static final String FIFTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:67:0:ab"; + private static final String FIFTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:67::ab"; + private static final String SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:67:89:00"; + private static final String SIXTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:67:89:0"; + private static final String SIXTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = + "01:23:45:67:89:"; + private static final String MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = + "01:03:00:07:00:00"; + private static final String MIXED_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = + "1:3:0:7:0:0"; + private static final String MIXED_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = + "1:3::7::"; + + // here are some sets of good ethernet addresses in various forms + private static final String NULL_ETHERNET_ADDRESS_STRING = + "00:00:00:00:00:00"; + private static final long NULL_ETHERNET_ADDRESS_LONG = 0x0000000000000000L; + private static final byte[] NULL_ETHERNET_ADDRESS_BYTE_ARRAY = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; + //private static final int[] NULL_ETHERNET_ADDRESS_INT_ARRAY = new int[ETHERNET_ADDRESS_ARRAY_LENGTH]; + private static final EthernetAddress NULL_ETHERNET_ADDRESS = + new EthernetAddress(0L); + + private static final String VALID_ETHERNET_ADDRESS_STRING = + "87:f5:93:06:d3:0c"; + private static final String MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING = + "87:f5:93:06:D3:0c"; + private static final String UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING = + "87:F5:93:06:D3:0C"; + private static final String LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING = + VALID_ETHERNET_ADDRESS_STRING; + private static final long VALID_ETHERNET_ADDRESS_LONG = + 0x000087f59306d30cL; + private static final byte[] VALID_ETHERNET_ADDRESS_BYTE_ARRAY = + { + (byte)0x87, (byte)0xf5, (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c + }; + private static final int[] VALID_ETHERNET_ADDRESS_INT_ARRAY = + { + 0x87, 0xf5, 0x93, 0x06, 0xd3, 0x0c + }; + + private static final byte[] ANOTHER_VALID_ETHERNET_ADDRESS_BYTE_ARRAY = + { + (byte)0x4c, (byte)0xde, (byte)0xfb, (byte)0xba, (byte)0x5a, (byte)0x1c + }; + /* + private static final EthernetAddress VALID_ETHERNET_ADDRESS = new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); + private static final String ANOTHER_VALID_ETHERNET_ADDRESS_STRING = "4c:de:fb:ba:5a:1c"; + private static final long ANOTHER_VALID_ETHERNET_ADDRESS_LONG = 0x00004cdefbba5a1cL; + private static final int[] ANOTHER_VALID_ETHERNET_ADDRESS_INT_ARRAY = + { + 0x4c, 0xde, 0xfb, 0xba, 0x5a, 0x1c + }; + */ + //private static final EthernetAddress ANOTHER_VALID_ETHERNET_ADDRESS = new EthernetAddress(ANOTHER_VALID_ETHERNET_ADDRESS_LONG); + + // some ethernet addresses for the ordering tests + private static final EthernetAddress MAC0_ETHERNET_ADDRESS = + new EthernetAddress(0x0000015ae2e61893L); + private static final EthernetAddress MAC1_ETHERNET_ADDRESS = + new EthernetAddress(0x00001f0f1b0e8e6eL); + private static final EthernetAddress MAC2_ETHERNET_ADDRESS = + new EthernetAddress(0x000022d8afb0b888L); + private static final EthernetAddress MAC3_ETHERNET_ADDRESS = + new EthernetAddress(0x00004cfdc9a5e86aL); + private static final EthernetAddress MAC4_ETHERNET_ADDRESS = + new EthernetAddress(0x000091038ffa38eeL); + private static final EthernetAddress MAC5_ETHERNET_ADDRESS = + new EthernetAddress(0x00009857e4f202a3L); + private static final EthernetAddress MAC6_ETHERNET_ADDRESS = + new EthernetAddress(0x0000a8c0600ccc69L); + private static final EthernetAddress MAC7_ETHERNET_ADDRESS = + new EthernetAddress(0x0000a9a18860d8fcL); + private static final EthernetAddress MAC8_ETHERNET_ADDRESS = + new EthernetAddress(0x0000c8b30f0b395aL); + private static final EthernetAddress MAC9_ETHERNET_ADDRESS = + new EthernetAddress(0x0000cf74d8ef49b8L); + + + public EthernetAddressTest(java.lang.String testName) + { + super(testName); + } + + public static Test suite() + { + TestSuite suite = new TestSuite(EthernetAddressTest.class); + return suite; + } + + public static void main(String[] args) + { + TestRunner.run(suite()); + } + + /************************************************************************** + * Begin Constructor tests + *************************************************************************/ + /** + * Test of EthernetAddress(byte[]) constructor, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testByteArrayEthernetAddressConstructor() + { + // lets test some error cases + // first, passing null + try + { + /*EthernetAddress ethernet_address =*/ + new EthernetAddress((byte[])null); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too small + try + { + /*EthernetAddress ethernet_address =*/ + new EthernetAddress( + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too big + try { + /*EthernetAddress ethernet_address =*/ + new EthernetAddress( + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + 1]); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (NumberFormatException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // let's test that creating a EthernetAddress from an zero'd array + // gives us a null EthernetAddress (definition of null EthernetAddress) + EthernetAddress ethernet_address = + new EthernetAddress(new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]); + assertEquals( + "EthernetAddress(byte[]) did not create expected EthernetAddress", + NULL_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + + // let's test creating an array from a good byte array + ethernet_address = + new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertEquals( + "EthernetAddress(byte[]) did not create expected EthernetAddress", + VALID_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + } + + /** + * Test of EthernetAddress(long) constructor, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testLongEthernetAddressConstructor() + { + // let's test that creating a EthernetAddress from an zero long + // gives us a null EthernetAddress (definition of null EthernetAddress) + EthernetAddress ethernet_address = + new EthernetAddress(0x0000000000000000L); + assertEquals( + "EthernetAddress(long) did not create expected EthernetAddress", + NULL_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + + // let's test creating an array from a good long + ethernet_address = new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); + assertEquals( + "EthernetAddress(long) did not create expected EthernetAddress", + VALID_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + } + + /** + * Test of EthernetAddress(String) constructor, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testStringEthernetAddressConstructor() + { + // test a null string case + try + { + /*EthernetAddress ethernet_address =*/ + new EthernetAddress((String)null); + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // test some failure cases for the string constructor + badStringEthernetAddressConstructorHelper( + IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_1); + badStringEthernetAddressConstructorHelper( + IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_2); + badStringEthernetAddressConstructorHelper( + IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_3); + badStringEthernetAddressConstructorHelper( + IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_4); + badStringEthernetAddressConstructorHelper( + IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_5); + badStringEthernetAddressConstructorHelper( + IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_6); + badStringEthernetAddressConstructorHelper( + NON_HEX_ETHERNET_ADDRESS_STRING); + badStringEthernetAddressConstructorHelper( + RANDOM_PROPER_LENGTH_STRING); + + // some valid strings for the various dropped digit cases + goodStringEthernetAddressConstructorHelper( + FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FIRST_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FIRST_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + SECOND_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + SECOND_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + THIRD_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + THIRD_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FOURTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FOURTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FIFTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + FIFTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + SIXTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + SIXTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + MIXED_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + MIXED_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + + // test the other good cases + goodStringEthernetAddressConstructorHelper( + NULL_ETHERNET_ADDRESS_STRING, + NULL_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING, + UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING, + LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING); + goodStringEthernetAddressConstructorHelper( + MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING, + MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); + } + + /************************************************************************** + * End Constructor tests + *************************************************************************/ + /** + * Test of asByteArray method, of class com.fasterxml.uuid.EthernetAddress. + */ + public void testAsByteArray() + { + // we'll test making a couple EthernetAddresses and then check that + // asByteArray returns the same value in long form as used to create it + + // first we'll test the null EthernetAddress + EthernetAddress ethernet_address = new EthernetAddress(0L); + assertEquals("Expected length of returned array wrong", + ETHERNET_ADDRESS_ARRAY_LENGTH, + ethernet_address.asByteArray().length); + assertEthernetAddressArraysAreEqual( + NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address.asByteArray(), 0); + + // now test a non-null EthernetAddress + ethernet_address = new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); + assertEquals("Expected length of returned array wrong", + ETHERNET_ADDRESS_ARRAY_LENGTH, + ethernet_address.asByteArray().length); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address.asByteArray(), 0); + + // let's make sure that changing the returned array doesn't mess with + // the wrapped EthernetAddress's internals + byte[] ethernet_address_byte_array = ethernet_address.asByteArray(); + // we'll just stir it up a bit and then check that the original + // EthernetAddress was not changed in the process. + // The easiest stir is to sort it ;) + Arrays.sort(ethernet_address_byte_array); + assertEthernetAddressArraysAreNotEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address_byte_array, 0); + assertEthernetAddressArraysAreNotEqual( + ethernet_address.asByteArray(), 0, + ethernet_address_byte_array, 0); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address.asByteArray(), 0); + } + + /** + * Test of clone method, of class com.fasterxml.uuid.EthernetAddress. + */ + public void testClone() + { + // as lifted from the JDK Object JavaDoc for clone: + // x.clone() Creates and returns a copy of x. + // The precise meaning of "copy" may depend on + // the class of the object. The general intent + // is that, for any object x, the expression: + // x.clone() != x + // will be true, and that the expression: + // x.clone().getClass() == x.getClass() + // will be true, but these are not absolute requirements. + // While it is typically the case that: + // x.clone().equals(x) + // will be true, this is not an absolute requirement. + // For EthernetAddress, this test will check that all the above + // ARE true in the case of EthernetAddress clone() because it is + // the desired behavior. + EthernetAddress x = new EthernetAddress(VALID_ETHERNET_ADDRESS_STRING); + assertTrue("x.clone() != x did not return true", + x.clone() != x); + assertTrue("x.clone().getClass() == x.getClass() did not return true", + x.clone().getClass() == x.getClass()); + assertTrue("x.clone().equals(x) did not return true", + x.clone().equals(x)); + } + + /** + * Test of compareTo method, of class com.fasterxml.uuid.EthernetAddress. + */ + public void testCompareTo() + { + // first, let's make sure calling compareTo with null + // throws the appropriate NullPointerException + try + { + // the 'null EthernetAddress' will be fine + NULL_ETHERNET_ADDRESS.compareTo(null); + fail("Expected exception not thrown"); + } + catch (NullPointerException ex) + { + // good, we caught the expected exception, so we passed + } + catch (Exception ex) + { + fail("Caught an unexpected exception: " + ex); + } + + // now we'll test some simple base cases + // 2 null EthernetAddresses always compare to 0 + assertEthernetAddressEqualOrderHelper(NULL_ETHERNET_ADDRESS, + new EthernetAddress(0L)); + + // 2 of the same value EthernetAddresses are always 0 + assertEthernetAddressEqualOrderHelper(MAC0_ETHERNET_ADDRESS, + new EthernetAddress(MAC0_ETHERNET_ADDRESS.toLong())); + + // the 'null EthernetAddress' always comes first in the ordering + assertEthernetAddressGreaterOrderHelper(MAC0_ETHERNET_ADDRESS, + NULL_ETHERNET_ADDRESS); + + // EthernetAddresses will always sort + // with the 'numerically' greater MAC addresses coming later + assertEthernetAddressGreaterOrderHelper(MAC4_ETHERNET_ADDRESS, + MAC0_ETHERNET_ADDRESS); + assertEthernetAddressGreaterOrderHelper(MAC9_ETHERNET_ADDRESS, + MAC4_ETHERNET_ADDRESS); + assertEthernetAddressGreaterOrderHelper(MAC9_ETHERNET_ADDRESS, + MAC0_ETHERNET_ADDRESS); + + // now we will test a bigger case of the compareTo functionality + // of the EthernetAddress class + // easiest way to do this is to create an array of EthernetAddresses + // and sort it then test that this array is in the expected order + + // before sort, the array contains (in psudo-random order) + // 15 EthernetAddresses of this distribution: + // 1 - null EthernetAddress + // 2 - mac0 + // 1 - mac1 + // 1 - mac2 + // 2 - mac3 + // 2 - mac4 + // 2 - mac5 + // 1 - mac6 + // 1 - mac7 + // 1 - mac8 + // 1 - mac9 + EthernetAddress ethernet_address_array[] = new EthernetAddress[15]; + ethernet_address_array[0] = MAC4_ETHERNET_ADDRESS; + ethernet_address_array[1] = MAC6_ETHERNET_ADDRESS; + ethernet_address_array[2] = MAC0_ETHERNET_ADDRESS; + ethernet_address_array[3] = MAC5_ETHERNET_ADDRESS; + ethernet_address_array[4] = MAC3_ETHERNET_ADDRESS; + ethernet_address_array[5] = MAC5_ETHERNET_ADDRESS; + ethernet_address_array[6] = MAC0_ETHERNET_ADDRESS; + ethernet_address_array[7] = NULL_ETHERNET_ADDRESS; + ethernet_address_array[8] = MAC8_ETHERNET_ADDRESS; + ethernet_address_array[9] = MAC3_ETHERNET_ADDRESS; + ethernet_address_array[10] = MAC4_ETHERNET_ADDRESS; + ethernet_address_array[11] = MAC7_ETHERNET_ADDRESS; + ethernet_address_array[12] = MAC1_ETHERNET_ADDRESS; + ethernet_address_array[13] = MAC9_ETHERNET_ADDRESS; + ethernet_address_array[14] = MAC2_ETHERNET_ADDRESS; + + Arrays.sort(ethernet_address_array); + // now we should be able to see that the array is in order + assertEthernetAddressesMatchHelper( + NULL_ETHERNET_ADDRESS, ethernet_address_array[0]); + assertEthernetAddressesMatchHelper( + MAC0_ETHERNET_ADDRESS, ethernet_address_array[1]); + assertEthernetAddressesMatchHelper( + MAC0_ETHERNET_ADDRESS, ethernet_address_array[2]); + assertEthernetAddressesMatchHelper( + MAC1_ETHERNET_ADDRESS, ethernet_address_array[3]); + assertEthernetAddressesMatchHelper( + MAC2_ETHERNET_ADDRESS, ethernet_address_array[4]); + assertEthernetAddressesMatchHelper( + MAC3_ETHERNET_ADDRESS, ethernet_address_array[5]); + assertEthernetAddressesMatchHelper( + MAC3_ETHERNET_ADDRESS, ethernet_address_array[6]); + assertEthernetAddressesMatchHelper( + MAC4_ETHERNET_ADDRESS, ethernet_address_array[7]); + assertEthernetAddressesMatchHelper( + MAC4_ETHERNET_ADDRESS, ethernet_address_array[8]); + assertEthernetAddressesMatchHelper( + MAC5_ETHERNET_ADDRESS, ethernet_address_array[9]); + assertEthernetAddressesMatchHelper( + MAC5_ETHERNET_ADDRESS, ethernet_address_array[10]); + assertEthernetAddressesMatchHelper( + MAC6_ETHERNET_ADDRESS, ethernet_address_array[11]); + assertEthernetAddressesMatchHelper( + MAC7_ETHERNET_ADDRESS, ethernet_address_array[12]); + assertEthernetAddressesMatchHelper( + MAC8_ETHERNET_ADDRESS, ethernet_address_array[13]); + assertEthernetAddressesMatchHelper( + MAC9_ETHERNET_ADDRESS, ethernet_address_array[14]); + } + + /** + * Test of equals method, of class com.fasterxml.uuid.EthernetAddress. + */ + public void testEquals() + { + // test passing null to equals returns false + // (as specified in the JDK docs for Object) + EthernetAddress x = + new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertFalse("equals(null) didn't return false", + x.equals((Object)null)); + + // test passing an object which is not a EthernetAddress returns false + assertFalse("x.equals(non_EthernetAddress_object) didn't return false", + x.equals(new Object())); + + // test a case where two EthernetAddresss are definitly not equal + EthernetAddress w = + new EthernetAddress(ANOTHER_VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertFalse("x == w didn't return false", + x == w); + assertFalse("x.equals(w) didn't return false", + x.equals(w)); + + // test refelexivity + assertTrue("x.equals(x) didn't return true", + x.equals(x)); + + // test symmetry + EthernetAddress y = + new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertFalse("x == y didn't return false", + x == y); + assertTrue("y.equals(x) didn't return true", + y.equals(x)); + assertTrue("x.equals(y) didn't return true", + x.equals(y)); + + // now we'll test transitivity + EthernetAddress z = + new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertFalse("x == y didn't return false", + x == y); + assertFalse("x == y didn't return false", + y == z); + assertFalse("x == y didn't return false", + x == z); + assertTrue("x.equals(y) didn't return true", + x.equals(y)); + assertTrue("y.equals(z) didn't return true", + y.equals(z)); + assertTrue("x.equals(z) didn't return true", + x.equals(z)); + + // test consistancy (this test is just calling equals multiple times) + assertFalse("x == y didn't return false", + x == y); + assertTrue("x.equals(y) didn't return true", + x.equals(y)); + assertTrue("x.equals(y) didn't return true", + x.equals(y)); + assertTrue("x.equals(y) didn't return true", + x.equals(y)); + } + + /** + * Test of toByteArray method, of class com.fasterxml.uuid.EthernetAddress. + */ + public void testToByteArray() + { + // we'll test making a couple EthernetAddresses and then check that the + // toByteArray returns the same value in byte form as used to create it + + // first we'll test the null EthernetAddress + EthernetAddress ethernet_address = new EthernetAddress(0L); + assertEquals("Expected length of returned array wrong", + ETHERNET_ADDRESS_ARRAY_LENGTH, + ethernet_address.toByteArray().length); + assertEthernetAddressArraysAreEqual( + NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address.toByteArray(), 0); + + // now test a non-null EthernetAddress + ethernet_address = new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); + assertEquals("Expected length of returned array wrong", + ETHERNET_ADDRESS_ARRAY_LENGTH, + ethernet_address.toByteArray().length); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address.toByteArray(), 0); + + // let's make sure that changing the returned array doesn't mess with + // the wrapped EthernetAddress's internals + byte[] ethernet_address_byte_array = ethernet_address.toByteArray(); + // we'll just stir it up a bit and then check that the original + // EthernetAddress was not changed in the process. + // The easiest stir is to sort it ;) + Arrays.sort(ethernet_address_byte_array); + assertEthernetAddressArraysAreNotEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address_byte_array, 0); + assertEthernetAddressArraysAreNotEqual( + ethernet_address.toByteArray(), 0, + ethernet_address_byte_array, 0); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + ethernet_address.toByteArray(), 0); + } + + /** + * Test of toByteArray(byte[]) method, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testToByteArrayDest() + { + // constant for use in this test + final int EXTRA_DATA_LENGTH = 9; + + // lets test some error cases + // first, passing null + try + { + EthernetAddress ethernet_address = new EthernetAddress(0L); + ethernet_address.toByteArray((byte[])null); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too small + try { + EthernetAddress ethernet_address = new EthernetAddress(0L); + byte[] ethernet_address_byte_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]; + ethernet_address.toByteArray(ethernet_address_byte_array); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // we'll test making a couple EthernetAddresses and then check that + // toByteArray returns the same value in byte form as used to create it + + // here we'll test the null EthernetAddress + EthernetAddress ethernet_address = new EthernetAddress(0L); + byte[] test_array = new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array); + assertEthernetAddressArraysAreEqual( + NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + + // now test a non-null EthernetAddress + ethernet_address = new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + + // now test a null EthernetAddress case with extra data in the array + ethernet_address = new EthernetAddress(0L); + test_array = new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array); + assertEthernetAddressArraysAreEqual(NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) + { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); + } + + // now test a good EthernetAddress case with extra data in the array + ethernet_address = + new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); + test_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) + { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); + } + } + + /** + * Test of toByteArray(byte[], int) method, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testToByteArrayDestOffset() + { + // constant value for use in this test + final int EXTRA_DATA_LENGTH = 9; + + // lets test some error cases + // first, passing null and 0 + try + { + EthernetAddress ethernet_address = new EthernetAddress(0L); + ethernet_address.toByteArray((byte[])null, 0); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too small + try + { + EthernetAddress ethernet_address = new EthernetAddress(0L); + byte[] ethernet_address_byte_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]; + ethernet_address.toByteArray(ethernet_address_byte_array, 0); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // now an index that is negative + try { + EthernetAddress ethernet_address = new EthernetAddress(0L); + byte[] ethernet_address_byte_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; + ethernet_address.toByteArray(ethernet_address_byte_array, -1); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // now an index that is too big + try + { + EthernetAddress ethernet_address = new EthernetAddress(0L); + byte[] ethernet_address_byte_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; + ethernet_address.toByteArray( + ethernet_address_byte_array, ETHERNET_ADDRESS_ARRAY_LENGTH); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // now an index that is in the array, + // but without enough bytes to read ETHERNET_ADDRESS_ARRAY_LENGTH + try { + EthernetAddress ethernet_address = new EthernetAddress(0L); + byte[] ethernet_address_byte_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; + ethernet_address.toByteArray(ethernet_address_byte_array, 1); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // we'll test making a couple EthernetAddresss and then check + // that toByteArray + // returns the same value in byte form as used to create it + + // here we'll test the null EthernetAddress at offset 0 + EthernetAddress ethernet_address = new EthernetAddress(0L); + byte[] test_array = new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array, 0); + assertEthernetAddressArraysAreEqual( + NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + + // now test a non-null EthernetAddress + ethernet_address = + new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + + // now test a null EthernetAddress case with extra data in the array + ethernet_address = new EthernetAddress(0L); + test_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array, 0); + assertEthernetAddressArraysAreEqual( + NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); + } + + // now test a null EthernetAddress case with extra data in the array + ethernet_address = new EthernetAddress(0L); + test_array = new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array, EXTRA_DATA_LENGTH/2); + assertEthernetAddressArraysAreEqual( + NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + test_array, EXTRA_DATA_LENGTH/2); + for (int i = 0; i < EXTRA_DATA_LENGTH/2; i++) + { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i]); + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH + + EXTRA_DATA_LENGTH/2]); + } + + // now test a good EthernetAddress case with extra data in the array + ethernet_address = + new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); + test_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array, 0); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) + { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); + } + + // now test a good EthernetAddress case with extra data in the array + ethernet_address = + new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); + test_array = + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + ethernet_address.toByteArray(test_array, EXTRA_DATA_LENGTH/2); + assertEthernetAddressArraysAreEqual( + VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, + test_array, EXTRA_DATA_LENGTH/2); + for (int i = 0; i < EXTRA_DATA_LENGTH/2; i++) + { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i]); + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH + + EXTRA_DATA_LENGTH/2]); + } + } + + /** + * Test of toLong method, of class com.fasterxml.uuid.EthernetAddress. + */ + public void testToLong() + { + // test making a couple EthernetAddresss and then check that the toLong + // gives back the same value in long form that was used to create it + + // test the null EthernetAddress + EthernetAddress ethernet_address = new EthernetAddress(0L); + assertEquals("null EthernetAddress long and toLong did not match", + NULL_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + + // test a non-null EthernetAddress + ethernet_address = + new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertEquals("EthernetAddress long and toLong results did not match", + VALID_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + } + + /** + * Test of toString method, of class com.fasterxml.uuid.EthernetAddress. + */ + public void testToString() + { + // test making a few EthernetAddresss and check that the toString + // gives back the same value in string form that was used to create it + + // test the null EthernetAddress + EthernetAddress ethernet_address = new EthernetAddress(0L); + assertEquals("null EthernetAddress string and toString did not match", + NULL_ETHERNET_ADDRESS_STRING.toLowerCase(), + ethernet_address.toString().toLowerCase()); + + // test a non-null EthernetAddress + ethernet_address = + new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertEquals( + "EthernetAddress string and toString results did not match", + MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING.toLowerCase(), + ethernet_address.toString().toLowerCase()); + + // EthernetAddress implementation returns strings all lowercase. + // Although relying on this behavior in code is not recommended, + // here is a unit test which will break if this assumption + // becomes bad. This will act as an early warning to anyone + // who relies on this particular behavior. + ethernet_address = + new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertFalse("mixed case EthernetAddress string and toString " + + "matched (expected toString to be all lower case)", + MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING.equals( + ethernet_address.toString())); + assertEquals("mixed case string toLowerCase and " + + "toString results did not match (expected toString to " + + "be all lower case)", + MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING.toLowerCase(), + ethernet_address.toString()); + } + + /** + * Test of valueOf(byte[]) method, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testValueOfByteArray() + { + // lets test some error cases + // first, passing null + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf((byte[])null); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too small + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf( + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too big + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf( + new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + 1]); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // test that creating a EthernetAddress from an zero'd array + // gives us a null EthernetAddress (definition of null EthernetAddress) + EthernetAddress ethernet_address = + EthernetAddress.valueOf(new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]); + assertEquals( + "EthernetAddress.valueOf did not create expected EthernetAddress", + NULL_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + + // let's test creating an array from a good byte array + ethernet_address = + EthernetAddress.valueOf(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); + assertEquals( + "EthernetAddress.valueOf did not create expected EthernetAddress", + VALID_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + } + + /** + * Test of valueOf(int[]) method, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testValueOfIntArray() + { + // lets test some error cases + // first, passing null + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf((int[])null); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too small + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf( + new int[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too big + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf( + new int[ETHERNET_ADDRESS_ARRAY_LENGTH + 1]); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // let's test that creating a EthernetAddress from an zero'd array + // gives a null EthernetAddress (definition of a null EthernetAddress) + EthernetAddress ethernet_address = + EthernetAddress.valueOf(new int[ETHERNET_ADDRESS_ARRAY_LENGTH]); + assertEquals( + "EthernetAddress.valueOf did not create expected EthernetAddress", + NULL_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + + // let's test creating an array from a good int array + ethernet_address = + EthernetAddress.valueOf(VALID_ETHERNET_ADDRESS_INT_ARRAY); + assertEquals( + "EthernetAddress.valueOf did not create expected EthernetAddress", + VALID_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + } + + /** + * Test of valueOf(long) method, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testValueOfLong() + { + // let's test that creating a EthernetAddress from an zero long + // gives a null EthernetAddress (definition of a null EthernetAddress) + EthernetAddress ethernet_address = + EthernetAddress.valueOf(0x0000000000000000L); + assertEquals( + "EthernetAddress.valueOf did not create expected EthernetAddress", + NULL_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + + // let's test creating an array from a good long + ethernet_address = + EthernetAddress.valueOf(VALID_ETHERNET_ADDRESS_LONG); + assertEquals( + "EthernetAddress.valueOf did not create expected EthernetAddress", + VALID_ETHERNET_ADDRESS_LONG, + ethernet_address.toLong()); + } + + /** + * Test of valueOf(String) method, + * of class com.fasterxml.uuid.EthernetAddress. + */ + public void testValueOfString() + { + // test a null string case + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf((String)null); + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // test some failure cases for the string constructor + badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_1); + badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_2); + badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_3); + badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_4); + badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_5); + badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_6); + badStringValueOfHelper(NON_HEX_ETHERNET_ADDRESS_STRING); + badStringValueOfHelper(RANDOM_PROPER_LENGTH_STRING); + + // some valid strings for the various dropped digit cases + goodStringValueOfHelper(FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FIRST_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FIRST_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(SECOND_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(SECOND_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(THIRD_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(THIRD_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FOURTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FOURTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FIFTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(FIFTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(SIXTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(SIXTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, + MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(MIXED_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, + MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(MIXED_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, + MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); + + // test the other good cases + goodStringValueOfHelper(NULL_ETHERNET_ADDRESS_STRING, + NULL_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING, + UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING, + LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING); + goodStringValueOfHelper(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING, + MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); + } + + /** + * Ok; this test is bit non-kosher, as it assumes existence of a valid + * interface + * + * @since 3.0 + */ + public void testFromInterface() throws Exception + { + EthernetAddress addr = EthernetAddress.fromInterface(); + assertNotNull(addr); + assertNotNull(addr.toString()); + } + + public void testBogus() throws Exception + { + // First, two using pseudo-random; verify they are different + Random r = new Random(123); + EthernetAddress a1 = EthernetAddress.constructMulticastAddress(r); + assertNotNull(a1); + assertEquals(a1, a1); + assertTrue(a1.isMulticastAddress()); + EthernetAddress a2 = EthernetAddress.constructMulticastAddress(r); + assertNotNull(a2); + assertTrue(a2.isMulticastAddress()); + assertEquals(a2, a2); + assertFalse(a1.equals(a2)); + + // and then default, which uses SecureRandom + EthernetAddress a3 = EthernetAddress.constructMulticastAddress(); + assertNotNull(a3); + assertNotNull(a3.toString()); + } + + /************************************************************************** + * Begin private helper functions for use in tests + *************************************************************************/ + private void badStringEthernetAddressConstructorHelper( + String ethernetAddressString) + { + try + { + /*EthernetAddress ethernet_address =*/ + new EthernetAddress(ethernetAddressString); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + } + + private void goodStringEthernetAddressConstructorHelper( + String ethernetAddressString, + String expectedEthernetAddressString) + { + EthernetAddress ethernet_address = null; + try + { + ethernet_address = new EthernetAddress(ethernetAddressString); + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + assertEquals("EthernetAddresses were not equal", + expectedEthernetAddressString.toLowerCase(), + ethernet_address.toString().toLowerCase()); + } + + private void badStringValueOfHelper(String ethernetAddressString) + { + try + { + /*EthernetAddress ethernet_address =*/ + EthernetAddress.valueOf(ethernetAddressString); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + } + + private void goodStringValueOfHelper(String ethernetAddressString, + String expectedEthernetAddressString) + { + EthernetAddress ethernet_address = null; + try + { + ethernet_address = EthernetAddress.valueOf(ethernetAddressString); + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + assertEquals("EthernetAddresses were not equal", + expectedEthernetAddressString.toLowerCase(), + ethernet_address.toString().toLowerCase()); + } + + private void assertEthernetAddressesMatchHelper(EthernetAddress expected, + EthernetAddress actual) + { + assertEquals("EthernetAddresses in long form did not match", + expected.toLong(), + actual.toLong()); + assertEquals("EthernetAddress equals did not match", + expected, + actual); + } + + private void assertEthernetAddressEqualOrderHelper( + EthernetAddress ethernetAddress1, + EthernetAddress ethernetAddress2) + { + assertTrue(ethernetAddress1 + " did not test as equal to " + + ethernetAddress2, + 0 == ethernetAddress1.compareTo(ethernetAddress2)); + assertTrue(ethernetAddress2 + " did not test as equal to " + + ethernetAddress1, + 0 == ethernetAddress2.compareTo(ethernetAddress1)); + } + + private void assertEthernetAddressGreaterOrderHelper( + EthernetAddress ethernetAddress1, + EthernetAddress ethernetAddress2) + { + assertTrue(ethernetAddress1 + " did not test as larger then " + + ethernetAddress2, + 0 < ethernetAddress1.compareTo(ethernetAddress2)); + assertTrue(ethernetAddress2 + " did not test as smaller then " + + ethernetAddress1, + 0 > ethernetAddress2.compareTo(ethernetAddress1)); + } + + private void assertEthernetAddressArraysAreEqual(byte[] array1, + int array1_start, + byte[] array2, + int array2_start) + { + assertTrue("Array1 start offset is invalid", + 0 <= array1_start); + assertTrue("Array2 start offset is invalid", + 0 <= array2_start); + assertTrue("Array1 is not long enough for the given start offset", + array1.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array1_start); + assertTrue("Array2 is not long enough for the given start offset", + array2.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array2_start); + for (int i = 0; i < ETHERNET_ADDRESS_ARRAY_LENGTH; i++) + { + assertEquals("Array1 and Array2 did not match (index #"+i+")", + array1[i + array1_start], + array2[i + array2_start]); + } + } + + private void assertEthernetAddressArraysAreNotEqual(byte[] array1, + int array1_start, + byte[] array2, + int array2_start) + { + assertTrue("Array1 start offset is invalid", + 0 <= array1_start); + assertTrue("Array2 start offset is invalid", + 0 <= array2_start); + assertTrue("Array1 is not long enough for the given start offset", + array1.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array1_start); + assertTrue("Array2 is not long enough for the given start offset", + array2.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array2_start); + for (int i = 0; i < ETHERNET_ADDRESS_ARRAY_LENGTH; i++) + { + // as soon as we find a non-matching byte, + // we know we're not equal, so return + if (array1[i + array1_start] != array2[i + array2_start]) + { + return; + } + } + fail("Array1 and Array2 matched"); + } +} diff -Nru jug-2.0.0/src/test/java/com/fasterxml/uuid/SimpleGenerationTest.java jug-3.1.5/src/test/java/com/fasterxml/uuid/SimpleGenerationTest.java --- jug-2.0.0/src/test/java/com/fasterxml/uuid/SimpleGenerationTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/test/java/com/fasterxml/uuid/SimpleGenerationTest.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,18 @@ +package com.fasterxml.uuid; + +import java.util.UUID; + +import junit.framework.TestCase; + +public class SimpleGenerationTest extends TestCase +{ + public void testIssue5() throws Exception + { + UUID uuid = Generators.randomBasedGenerator().generate(); + assertNotNull(uuid); + + // but second time's the charm... + uuid = Generators.randomBasedGenerator().generate(); + assertNotNull(uuid); + } +} diff -Nru jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDComparatorTest.java jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDComparatorTest.java --- jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDComparatorTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDComparatorTest.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,103 @@ +/* JUG Java UUID Generator + * + * Copyright (c) 2010 Tatu Saloranta + * + * 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.util.UUID; + +import junit.framework.TestCase; + +public class UUIDComparatorTest + extends TestCase +{ + public void testIntComp() + { + assertEquals(0, UUIDComparator.compareUInts(123, 123)); + assertEquals(0, UUIDComparator.compareUInts(-9999, -9999)); + assertEquals(0, UUIDComparator.compareUInts(0, 0)); + assertEquals(0, UUIDComparator.compareUInts(Integer.MIN_VALUE, Integer.MIN_VALUE)); + assertEquals(0, UUIDComparator.compareUInts(Integer.MAX_VALUE, Integer.MAX_VALUE)); + + assertTrue(UUIDComparator.compareUInts(0, 5) < 0); + assertTrue(UUIDComparator.compareUInts(5, 0) > 0); + + assertTrue(UUIDComparator.compareUInts(4, 0xFFFFFFFE) < 0); + assertTrue(UUIDComparator.compareUInts(0xFFFFFFFE, 129) > 0); + + assertTrue(UUIDComparator.compareUInts(0xFFFFFFFC, 0xFFFFFFFE) < 0); + assertTrue(UUIDComparator.compareUInts(0xFFFFFFFE, 0xFFFFFFFC) > 0); + assertTrue(UUIDComparator.compareUInts(0xFFFFFF17, 0xFFFFFF00) > 0); + assertTrue(UUIDComparator.compareUInts(0xFFFFFF00, 0xFFFFFF17) < 0); + } + + public void testLongComp() + { + assertEquals(0, UUIDComparator.compareULongs(123L, 123L)); + assertEquals(0, UUIDComparator.compareULongs(-9999L, -9999L)); + assertEquals(0, UUIDComparator.compareULongs(0L, 0L)); + assertEquals(0, UUIDComparator.compareULongs(Long.MIN_VALUE, Long.MIN_VALUE)); + assertEquals(0, UUIDComparator.compareULongs(Long.MAX_VALUE, Long.MAX_VALUE)); + + assertTrue(UUIDComparator.compareULongs(0L, 5L) < 0); + assertTrue(UUIDComparator.compareULongs(5L, 0L) > 0); + + // Ok, repeat int values first + assertTrue(UUIDComparator.compareULongs(4L, 0xFFFFFFFEL) < 0); + assertTrue(UUIDComparator.compareULongs(0xFFFFFFFEL, 129L) > 0); + assertTrue(UUIDComparator.compareULongs(0xFFFFFFFCL, 0xFFFFFFFEL) < 0); + assertTrue(UUIDComparator.compareULongs(0xFFFFFF17L, 0xFFFFFF00L) > 0); + + assertTrue(UUIDComparator.compareULongs(1L, 0xffffffffFFFFFFFEL) < 0); + assertTrue(UUIDComparator.compareULongs(0xffffffffFFFFFFFEL, 13L) > 0); + assertTrue(UUIDComparator.compareULongs(0xffffffffFFFFFFFCL, 0xffffffffFFFFFFFEL) < 0); + assertTrue(UUIDComparator.compareULongs(0xffffffffFFFFFFFEL, 0xffffffffFFFFFFFCL) > 0); + assertTrue(UUIDComparator.compareULongs(0xffffffffFFFFFF17L, 0xffffffffFFFFFF00L) > 0); + assertTrue(UUIDComparator.compareULongs(0xffffffffFFFFFF00L, 0xffffffffFFFFFF17L) < 0); + } + + /* + * [Issue#13] + */ + public void testSorting() + { + String[] src = new String[] { + "7ef7c38a-bb6e-11e3-9e8f-000000000000", + "7f905a0b-bb6e-11e3-9e8f-000000000000", + "8028f08c-bb6e-11e3-9e8f-000000000000", + "80c1870d-bb6e-11e3-9e8f-000000000000" + }; + + /* 03-Apr-2014, tatu: NOTE: JDK's UUID.compareTo() is broken, and it can + * NOT be used. Which is why we have "UUIDComparator" that does work. + */ + final UUIDComparator comp = new UUIDComparator(); + for (int i = 0; i < src.length-1; ++i) { + + UUID u1 = UUID.fromString(src[i]); + UUID u2 = UUID.fromString(src[i+1]); + + assertEquals(0, comp.compare(u1, u1)); + assertEquals(0, comp.compare(u2, u2)); + + int x = comp.compare(u1, u2); + if (x >= 0) { + fail("Entry #"+i+" should have value < 0, had "+x); + } + int y = comp.compare(u2, u1); + if (y <= 0) { + fail("Entry #"+i+" should have value > 0, had "+y); + } + } + } +} diff -Nru jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDGeneratorTest.java jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDGeneratorTest.java --- jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDGeneratorTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDGeneratorTest.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,571 @@ +/* JUG Java Uuid Generator + * UUIDGeneratorTest.java + * Created on July 16, 2003, 11:17 PM + * + * Copyright (c) 2003 Eric Bie + * + * 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.security.MessageDigest; +import java.util.*; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + + +import com.fasterxml.uuid.EthernetAddress; +import com.fasterxml.uuid.Generators; +import com.fasterxml.uuid.UUIDType; +import com.fasterxml.uuid.impl.UUIDUtil; +import com.fasterxml.uuid.impl.NameBasedGenerator; +import com.fasterxml.uuid.impl.RandomBasedGenerator; +import com.fasterxml.uuid.impl.TimeBasedGenerator; + +/** + * JUnit Test class for the com.fasterxml.uuid.UUIDGenerator class. + * + * @author Eric Bie + */ +public class UUIDGeneratorTest extends TestCase +{ + // size of the arrays to create for tests using arrays of values + private static final int SIZE_OF_TEST_ARRAY = 10000; + + public UUIDGeneratorTest(java.lang.String testName) + { + super(testName); + } + + public static Test suite() + { + TestSuite suite = new TestSuite(UUIDGeneratorTest.class); + return suite; + } + + public static void main(String[] args) + { + TestRunner.run(suite()); + } + + /** + * Test of getDummyAddress method, + * of class com.fasterxml.uuid.UUIDGenerator. + */ + public void testGetDummyAddress() + { + // this test will attempt to check for reasonable behavior of the + // getDummyAddress method + + // for the random UUID generator, we will generate a bunch of + // dummy ethernet addresses + // NOTE: although creating a bunch of dummy ethernet addresses + // is not the normal mode of operation, we'return testing for + // generally good behavior, so we'll create a bunch to make sure the + // general patterns are observed + EthernetAddress ethernet_address_array[] = + new EthernetAddress[SIZE_OF_TEST_ARRAY]; + + // now create the array of uuids + Random rnd = new Random(123L); + for (int i = 0; i < ethernet_address_array.length; i++) { + ethernet_address_array[i] = EthernetAddress.constructMulticastAddress(rnd); + } + + EthernetAddress null_ethernet_address = new EthernetAddress(0L); + for (int i = 0; i < ethernet_address_array.length; i++) + { + byte[] ethernet_address = ethernet_address_array[i].asByteArray(); + // check that none of the EthernetAddresses are null + assertFalse("dummy EthernetAddress was null", + Arrays.equals(null_ethernet_address.asByteArray(), + ethernet_address)); + + // check that the "broadcast" bit is set in the created address + /* 08-Feb-2004, TSa: Fixed as per fix to actual code; apparently + * broadcast bit is LSB, not MSB. + */ + assertEquals("dummy EthernetAddress was not broadcast", + 0x01, + (ethernet_address[0] & 0x01)); + } + } + + /** + * Test of generateRandomBasedUUID method, + * of class com.fasterxml.uuid.UUIDGenerator. + */ + public void testGenerateRandomBasedUUID() + { + // this test will attempt to check for reasonable behavior of the + // generateRandomBasedUUID method + + // we need a instance to use + RandomBasedGenerator uuid_gen = Generators.randomBasedGenerator(); + + // for the random UUID generator, we will generate a bunch of + // random UUIDs + UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) + { + uuid_array[i] = uuid_gen.generate(); + } + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + + // check that all the uuids were correct variant and version (type-4) + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.RANDOM_BASED); + + // check that all uuids were unique + // NOTE: technically, this test 'could' fail, but statistically + // speaking it should be extremely unlikely unless the implementation + // of (Secure)Random is bad + checkUUIDArrayForUniqueness(uuid_array); + } + + /** + * Test of generateTimeBasedUUID() method, + * of class com.fasterxml.uuid.UUIDGenerator. + */ + public void testGenerateTimeBasedUUID() + { + // this test will attempt to check for reasonable behavior of the + // generateTimeBasedUUID method + + // we need a instance to use + TimeBasedGenerator uuid_gen = Generators.timeBasedGenerator(); + + // first check that given a number of calls to generateTimeBasedUUID, + // all returned UUIDs order after the last returned UUID + // we'll check this by generating the UUIDs into one array and sorting + // then in another and checking the order of the two match + // change the number in the array statement if you want more or less + // UUIDs to be generated and tested + UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; + + // before we generate all the uuids, lets get the start time + long start_time = System.currentTimeMillis(); + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) + { + uuid_array[i] = uuid_gen.generate(); + } + + // now capture the end time + long end_time = System.currentTimeMillis(); + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + + // check that all the uuids were correct variant and version (type-1) + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.TIME_BASED); + + // check that all the uuids were generated with correct order + checkUUIDArrayForCorrectOrdering(uuid_array); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + + // check that all uuids have timestamps between the start and end time + checkUUIDArrayForCorrectCreationTime(uuid_array, start_time, end_time); + } + + /** + * Test of generateTimeBasedUUID(EthernetAddress) method, + * of class com.fasterxml.uuid.UUIDGenerator. + */ + public void testGenerateTimeBasedUUIDWithEthernetAddress() + { + // this test will attempt to check for reasonable behavior of the + // generateTimeBasedUUID(EthernetAddress) method + EthernetAddress ethernet_address = + new EthernetAddress("87:F5:93:06:D3:0C"); + + // we need a instance to use + TimeBasedGenerator uuid_gen = Generators.timeBasedGenerator(ethernet_address); + + // check that given a number of calls to generateTimeBasedUUID, + // all returned UUIDs order after the last returned UUID + // we'll check this by generating the UUIDs into one array and sorting + // then in another and checking the order of the two match + // change the number in the array statement if you want more or less + // UUIDs to be generated and tested + UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; + + // before we generate all the uuids, lets get the start time + long start_time = System.currentTimeMillis(); + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) { + uuid_array[i] = uuid_gen.generate(); + } + + // now capture the end time + long end_time = System.currentTimeMillis(); + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + + // check that all the uuids were correct variant and version (type-1) + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.TIME_BASED); + + // check that all the uuids were generated with correct order + checkUUIDArrayForCorrectOrdering(uuid_array); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + + // check that all uuids have timestamps between the start and end time + checkUUIDArrayForCorrectCreationTime(uuid_array, start_time, end_time); + + // check that all UUIDs have the correct ethernet address in the UUID + checkUUIDArrayForCorrectEthernetAddress(uuid_array, ethernet_address); + } + + /** + * Test of generateNameBasedUUID(UUID, String) + * method, of class com.fasterxml.uuid.UUIDGenerator. + */ + public void testGenerateNameBasedUUIDNameSpaceAndName() + { + // this test will attempt to check for reasonable behavior of the + // generateNameBasedUUID method + + // we need a instance to use + NameBasedGenerator uuid_gen = Generators.nameBasedGenerator(NameBasedGenerator.NAMESPACE_URL); + + UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) { + uuid_array[i] = uuid_gen.generate("test name" + i); + } + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + + // check that all the uuids were correct variant and version + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.NAME_BASED_SHA1); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) { + uuid_array[i] = uuid_gen.generate("test name" + i); + } + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + + // check that all the uuids were correct variant and version + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.NAME_BASED_SHA1); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + + // now, lets make sure generating two sets of name based uuid with the + // same args always gives the same result + uuid_array = new UUID[SIZE_OF_TEST_ARRAY]; + + uuid_gen = Generators.nameBasedGenerator(NameBasedGenerator.NAMESPACE_URL); + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) { + uuid_array[i] = uuid_gen.generate("test name" + i); + } + + UUID uuid_array2[] = new UUID[SIZE_OF_TEST_ARRAY]; + uuid_gen = Generators.nameBasedGenerator(NameBasedGenerator.NAMESPACE_URL); + + // now create the array of uuids + for (int i = 0; i < uuid_array2.length; i++) { + uuid_array2[i] = uuid_gen.generate("test name" + i); + } + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + checkUUIDArrayForNonNullUUIDs(uuid_array2); + + // check that all the uuids were correct variant and version + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.NAME_BASED_SHA1); + checkUUIDArrayForCorrectVariantAndVersion(uuid_array2, UUIDType.NAME_BASED_SHA1); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + checkUUIDArrayForUniqueness(uuid_array2); + + // check that both arrays are equal to one another + assertTrue("expected both arrays to be equal, they were not!", + Arrays.equals(uuid_array, uuid_array2)); + } + + /** + * Test of generateNameBasedUUID(UUID, String, MessageDigest) + * method, of class com.fasterxml.uuid.UUIDGenerator. + */ + public void testGenerateNameBasedUUIDNameSpaceNameAndMessageDigest() + { + MessageDigest MESSAGE_DIGEST = null; + try + { + MESSAGE_DIGEST = MessageDigest.getInstance("MD5"); + } catch (Exception ex) { + fail("exception caught getting test digest : " + ex); + } + + // this test will attempt to check for reasonable behavior of the + // generateNameBasedUUID method + + NameBasedGenerator uuid_gen = Generators.nameBasedGenerator(NameBasedGenerator.NAMESPACE_URL, MESSAGE_DIGEST); + UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) + { + uuid_array[i] = uuid_gen.generate("test name"+i); + } + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + + // check that all the uuids were correct variant and version + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.NAME_BASED_MD5); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) + { + uuid_array[i] = uuid_gen.generate("test name" + i); + } + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + + // check that all the uuids were correct variant and version + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.NAME_BASED_MD5); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + + // now, lets make sure generating two sets of name based uuid with the + // same args always gives the same result + uuid_array = new UUID[SIZE_OF_TEST_ARRAY]; + + // now create the array of uuids + for (int i = 0; i < uuid_array.length; i++) { + uuid_array[i] = uuid_gen.generate("test name" + i); + } + + UUID uuid_array2[] = new UUID[SIZE_OF_TEST_ARRAY]; + + // now create the array of uuids + for (int i = 0; i < uuid_array2.length; i++) { + uuid_array2[i] = uuid_gen.generate("test name" + i); + } + + // check that none of the UUIDs are null + checkUUIDArrayForNonNullUUIDs(uuid_array); + checkUUIDArrayForNonNullUUIDs(uuid_array2); + + // check that all the uuids were correct variant and version + checkUUIDArrayForCorrectVariantAndVersion(uuid_array, UUIDType.NAME_BASED_MD5); + checkUUIDArrayForCorrectVariantAndVersion(uuid_array2, UUIDType.NAME_BASED_MD5); + + // check that all uuids were unique + checkUUIDArrayForUniqueness(uuid_array); + checkUUIDArrayForUniqueness(uuid_array2); + + // check that both arrays are equal to one another + assertTrue("expected both arrays to be equal, they were not!", + Arrays.equals(uuid_array, uuid_array2)); + } + + /************************************************************************** + * Begin Private Helper Methods for use in tests + *************************************************************************/ + private class ReverseOrderUUIDComparator implements Comparator + { + // this Comparator class has a compare which orders reverse of the + // compareTo methond in UUID (so we can be sure our arrays below are + // 'not ordered in sorted order' before we sort them. + public int compare(UUID uuid1, UUID uuid2) + { + return -uuid1.compareTo(uuid2); + } + + // we are only implementing equals because it's needed, super should do + public boolean equals(Object o) + { + return super.equals(o); + } + } + + private void checkUUIDArrayForCorrectOrdering(UUID[] uuidArray) + { + // now we'll clone the array and reverse it + UUID uuid_sorted_array[] = (UUID[])uuidArray.clone(); + assertEquals("Cloned array length did not match", + uuidArray.length, + uuid_sorted_array.length); + + ReverseOrderUUIDComparator rev_order_uuid_comp = + new ReverseOrderUUIDComparator(); + Arrays.sort(uuid_sorted_array, rev_order_uuid_comp); + + // let's check that the array is actually reversed + for (int i = 0; i < uuid_sorted_array.length; i++) + { + assertTrue( + "Reverse order check on uuid arrays failed on element " + i, + uuidArray[i].equals( + uuid_sorted_array[uuid_sorted_array.length - (1 + i)])); + } + + // now let's sort the reversed array and check that it + // sorted to the same order as the original + Arrays.sort(uuid_sorted_array); + for (int i = 0; i < uuid_sorted_array.length; i++) + { + assertTrue( + "Same order check on uuid arrays failed on element " + i, + uuidArray[i].equals(uuid_sorted_array[i])); + } + } + + private void checkUUIDArrayForUniqueness(UUID[] uuidArray) + { + // here we'll assert that all elements in the list are not equal to + // each other (aka, there should be no duplicates) we'll do this by + // inserting all elements into a HashSet and making sure none of them + //were already present (add will return false if it was already there) + HashSet hash_set = new HashSet(); + for (int i = 0; i < uuidArray.length; i++) + { + assertTrue("Uniqueness test failed on insert into HashSet: index "+i+", value "+uuidArray[i], + hash_set.add(uuidArray[i])); + assertFalse("Paranoia Uniqueness test failed (second insert)", + hash_set.add(uuidArray[i])); + } + } + + private void checkUUIDArrayForCorrectVariantAndVersion(UUID[] uuidArray, + UUIDType expectedType) + { + // let's check that all the UUIDs are valid type-X UUIDs with the + // correct variant according to the specification. + for (int i = 0; i < uuidArray.length; i++) { + UUIDType actual = UUIDUtil.typeOf(uuidArray[i]); + if (actual != expectedType) { + fail("Expected version (type) did not match for UUID '"+uuidArray[i]+"' "+i+" (of "+uuidArray.length+"); expected " + +expectedType+", got "+actual); + } + // now. let's double check the variant and type from the array + byte[] temp_uuid = UUIDUtil.asByteArray(uuidArray[i]); + + // extract type from the UUID and check for correct type + int type = (temp_uuid[UUIDUtil.BYTE_OFFSET_TYPE] & 0xFF) >> 4; + assertEquals("Expected type did not match", + expectedType.raw(), + type); + // extract variant from the UUID and check for correct variant + int variant = (temp_uuid[UUIDUtil.BYTE_OFFSET_VARIATION] & 0xFF) >> 6; + assertEquals("Expected variant did not match", + 2, + variant); + } + } + + private void checkUUIDArrayForCorrectCreationTime(UUID[] uuidArray, long startTime, long endTime) + { + // we need to convert from 100-nanosecond units (as used in UUIDs) + // to millisecond units as used in UTC based time + final long MILLI_CONVERSION_FACTOR = 10000L; + // Since System.currentTimeMillis() returns time epoc time + // (from 1-Jan-1970), and UUIDs use time from the beginning of + // Gregorian calendar (15-Oct-1582) we have a offset for correction + final long GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET = + 122192928000000000L; + + assertTrue("start time was not before the end time", startTime < endTime); + + // let's check that all uuids in the array have a timestamp which lands + // between the start and end time + for (int i = 0; i < uuidArray.length; i++){ + byte[] temp_uuid = UUIDUtil.asByteArray(uuidArray[i]); + + // first we'll collect the UUID time stamp which is + // the number of 100-nanosecond intervals since + // 00:00:00.00 15 October 1582 + long uuid_time = 0L; + uuid_time |= ((temp_uuid[3] & 0xF0L) << 0); + uuid_time |= ((temp_uuid[2] & 0xFFL) << 8); + uuid_time |= ((temp_uuid[1] & 0xFFL) << 16); + uuid_time |= ((temp_uuid[0] & 0xFFL) << 24); + uuid_time |= ((temp_uuid[5] & 0xFFL) << 32); + uuid_time |= ((temp_uuid[4] & 0xFFL) << 40); + uuid_time |= ((temp_uuid[7] & 0xFFL) << 48); + uuid_time |= ((temp_uuid[6] & 0x0FL) << 56); + + // first we'll remove the gregorian offset + uuid_time -= GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET; + + // and convert to milliseconds as the system clock is in millis + uuid_time /= MILLI_CONVERSION_FACTOR; + + // now check that the times are correct + assertTrue( + "Start time: " + startTime + + " was not before UUID timestamp: " + uuid_time, + startTime <= uuid_time); + assertTrue( + "UUID timestamp: " + uuid_time + + " was not before the start time: " + endTime, + uuid_time <= endTime); + } + } + + private void checkUUIDArrayForCorrectEthernetAddress(UUID[] uuidArray, + EthernetAddress ethernetAddress) + { + for (int i = 0; i < uuidArray.length; i++) + { + byte[] uuid_ethernet_address = new byte[6]; + System.arraycopy(UUIDUtil.asByteArray(uuidArray[i]), 10, uuid_ethernet_address, 0, 6); + byte[] ethernet_address = ethernetAddress.asByteArray(); + + assertTrue( + "UUID ethernet address did not equal passed ethernetAddress", + Arrays.equals(ethernet_address, uuid_ethernet_address)); + } + } + + private void checkUUIDArrayForNonNullUUIDs(UUID[] uuidArray) + { + for (int i = 0; i < uuidArray.length; i++) { + if (UUIDUtil.typeOf(uuidArray[i]) == UUIDType.UNKNOWN) { + fail("Entry #"+i+" was UNKNOWN UUID, shouldn't be"); + } + } + } + /************************************************************************** + * End Private Helper Methods for use in tests + *************************************************************************/ +} diff -Nru jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDTest.java jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDTest.java --- jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDTest.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,1116 @@ +/* JUG Java Uuid Generator + * UUIDTest.java + * Created on July 16, 2003, 11:17 PM + * + * Copyright (c) 2003 Eric Bie + * + * 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 junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + +import java.util.Arrays; +import java.util.UUID; + +import com.fasterxml.uuid.UUIDType; +import com.fasterxml.uuid.impl.UUIDUtil; + +/** + * This class tests UUID for correct functionality. + * + * @author Eric Bie + */ +public class UUIDTest extends TestCase +{ + final static UUID nullUUID = new UUID(0L, 0L); + + public UUIDTest(java.lang.String testName) + { + super(testName); + } + + public static Test suite() + { + TestSuite suite = new TestSuite(UUIDTest.class); + return suite; + } + + public static void main(String[] args) + { + TestRunner.run(suite()); + } + + /************************************************************************** + * Begin constructor tests + *************************************************************************/ + /** + * Test of UUID() constructor, of class com.fasterxml.uuid.UUID. + */ + public void testDefaultUUIDConstructor() + { + // this test technically relies on the toString() and toByteArray() + // methods of the UUID class working properly. + // If it fails, that is fine... the test only needs to indicate + // proper working behavior or that it needs to be fixed. + UUID uuid = nullUUID; + assertEquals("Default constructor did not create expected null UUID", + NULL_UUID_STRING, + uuid.toString()); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + } + + /** + * Test of UUID(byte[]) constructor, of class com.fasterxml.uuid.UUID. + */ + public void testByteArrayUUIDConstructor() + { + // passing array that is too small + try + { + /*UUID uuid =*/ UUIDUtil.uuid(new byte[UUID_BYTE_ARRAY_LENGTH - 1]); + fail("Expected exception not caught"); + } + catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // test that creating a uuid from an zero'd array + // gives us a null UUID (definition of a null UUID) + UUID uuid = UUIDUtil.uuid(new byte[UUID_BYTE_ARRAY_LENGTH]); + assertEquals("constructor did not create expected null UUID", + NULL_UUID_STRING, + uuid.toString()); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + + // test creating an array from a good byte array + uuid = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertEquals("constructor did not create expected UUID", + MIXED_CASE_VALID_UUID_STRING.toLowerCase(), + uuid.toString().toLowerCase()); + + // test creating an array from a good byte array with extra data on end + uuid = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END); + assertEquals("constructor did not create expected UUID", + MIXED_CASE_VALID_UUID_STRING.toLowerCase(), + uuid.toString().toLowerCase()); + } + + /** + * Test of UUID(String) constructor, of class com.fasterxml.uuid.UUID. + */ + public void testStringUUIDConstructor() + { + // test a null string case + try + { + /*UUID uuid =*/ UUIDUtil.uuid((String)null); + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // test some failure cases for the string constructor + badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_1); + badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_2); + badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_3); + badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_4); + badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_5); + badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_6); + badStringUUIDConstructorHelper(NON_HEX_UUID_STRING); + badStringUUIDConstructorHelper(RANDOM_PROPER_LENGTH_STRING); + + // test some good cases + goodStringUUIDConstructorHelper(NULL_UUID_STRING); + goodStringUUIDConstructorHelper(UPPER_CASE_VALID_UUID_STRING); + goodStringUUIDConstructorHelper(LOWER_CASE_VALID_UUID_STRING); + goodStringUUIDConstructorHelper(MIXED_CASE_VALID_UUID_STRING); + } + /************************************************************************** + * End constructor tests + *************************************************************************/ + + /** + * Test of asByteArray method, of class com.fasterxml.uuid.UUID. + */ + public void testAsByteArray() + { + // we'll test making a couple UUIDs and then check that the asByteArray + // gives back the same value in byte form that we used to create it + + // first we'll test the null uuid + UUID uuid = nullUUID; + assertEquals("Expected length of returned array wrong", + UUID_BYTE_ARRAY_LENGTH, + UUIDUtil.asByteArray(uuid).length); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + + // now test a non-null uuid + uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + assertEquals("Expected length of returned array wrong", + UUID_BYTE_ARRAY_LENGTH, + UUIDUtil.asByteArray(uuid).length); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + + // let's make sure that changing the returned array doesn't mess with + // the wrapped UUID's internals + uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + assertEquals("Expected length of returned array wrong", + UUID_BYTE_ARRAY_LENGTH, + UUIDUtil.asByteArray(uuid).length); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + + byte[] test_byte_array = UUIDUtil.asByteArray(uuid); + // now stir it up a bit and then check that the original UUID was + // not changed in the process. The easiest stir is to sort it ;) + Arrays.sort(test_byte_array); + assertFalse("Expected array was equal other array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, test_byte_array)); + assertFalse("Expected array was equal other array", + Arrays.equals(UUIDUtil.asByteArray(uuid), test_byte_array)); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + } + + /** + * Test of compareTo method, of class com.fasterxml.uuid.UUID. + */ + public void testCompareTo() + { + // first, let's make sure calling compareTo with null + // throws the appropriate NullPointerException + try { + NULL_UUID.compareTo(null); + fail("Expected exception not thrown"); + } catch (NullPointerException ex) { + // good, we caught the expected exception, so we passed + } catch (Exception ex) { + fail("Caught an unexpected exception: " + ex); + } + + // now we'll test some simple base cases + // 2 null uuids always compare to 0 + assertUUIDEqualOrderHelper(NULL_UUID, nullUUID); + + // 2 of the same value UUIDs are always 0 + assertUUIDEqualOrderHelper(TIME3_MAC1_UUID, UUIDUtil.uuid(TIME3_MAC1_UUID.toString())); + + // the 'null UUID' always comes first in the ordering + assertUUIDGreaterOrderHelper(TIME3_MAC1_UUID, NULL_UUID); + + // a UUID with a greater time is always comes after a lower time uuid + // given the same MAC address + assertUUIDGreaterOrderHelper(TIME3_MAC1_UUID, TIME1_MAC1_UUID); + + // a UUID with a greater time and a different MAC will always sort + // with the greater time coming later + assertUUIDGreaterOrderHelper(TIME3_MAC1_UUID, TIME1_MAC2_UUID); + + // a UUID with the same time stamp and different MAC will always sort + // with the 'numerically' greater MAC coming later + assertUUIDGreaterOrderHelper(TIME1_MAC2_UUID, TIME1_MAC1_UUID); + + // now we will test a bigger case of the compareTo functionality + // of the UUID class + // easiest way to do this is to create an array of UUIDs and sort it + // then test that this array is in the expected order + + // first we'll try a MAC address homogeneous sort + // before sort, the array contains (in psudo-random order) + // 10 UUIDs of this distribution: + // 2 - null uuid + // 2 - time1_mac1 + // 1 - time2_mac1 + // 2 - time3_mac1 + // 2 - time4_mac1 + // 1 - time5_mac1 + UUID test_uuid_array[] = new UUID[10]; + test_uuid_array[0] = TIME3_MAC1_UUID; + test_uuid_array[1] = TIME4_MAC1_UUID; + test_uuid_array[2] = TIME1_MAC1_UUID; + test_uuid_array[3] = NULL_UUID; + test_uuid_array[4] = TIME3_MAC1_UUID; + test_uuid_array[5] = TIME5_MAC1_UUID; + test_uuid_array[6] = TIME2_MAC1_UUID; + test_uuid_array[7] = TIME1_MAC1_UUID; + test_uuid_array[8] = NULL_UUID; + test_uuid_array[9] = TIME4_MAC1_UUID; + + Arrays.sort(test_uuid_array, new UUIDComparator()); + // now we should be able to see that the array is in order + assertUUIDsMatchHelper(NULL_UUID, test_uuid_array[0]); + assertUUIDsMatchHelper(NULL_UUID, test_uuid_array[1]); + assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[2]); + assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[3]); + assertUUIDsMatchHelper(TIME2_MAC1_UUID, test_uuid_array[4]); + assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[5]); + assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[6]); + assertUUIDsMatchHelper(TIME4_MAC1_UUID, test_uuid_array[7]); + assertUUIDsMatchHelper(TIME4_MAC1_UUID, test_uuid_array[8]); + assertUUIDsMatchHelper(TIME5_MAC1_UUID, test_uuid_array[9]); + + // allow array to be GC'd (and make sure we don't somehow use the wrong + // array below) + test_uuid_array = null; + + // now lets try a MAC address heterogeneous case + // before sort, the array contains (in psudo-random order) + // 15 UUIDs of this distribution: + // 1 - null uuid + // 2 - time1_mac1 + // 1 - time1_mac2 + // 1 - time2_mac1 + // 2 - time2_mac2 + // 2 - time3_mac1 + // 2 - time3_mac2 + // 1 - time4_mac1 + // 1 - time4_mac2 + // 1 - time5_mac1 + // 1 - time5_mac2 + test_uuid_array = new UUID[15]; + test_uuid_array[0] = TIME3_MAC1_UUID; + test_uuid_array[1] = TIME4_MAC1_UUID; + test_uuid_array[2] = TIME1_MAC1_UUID; + test_uuid_array[3] = TIME3_MAC2_UUID; + test_uuid_array[4] = TIME2_MAC2_UUID; + test_uuid_array[5] = TIME3_MAC2_UUID; + test_uuid_array[6] = TIME1_MAC1_UUID; + test_uuid_array[7] = NULL_UUID; + test_uuid_array[8] = TIME5_MAC1_UUID; + test_uuid_array[9] = TIME2_MAC2_UUID; + test_uuid_array[10] = TIME3_MAC1_UUID; + test_uuid_array[11] = TIME4_MAC2_UUID; + test_uuid_array[12] = TIME1_MAC2_UUID; + test_uuid_array[13] = TIME5_MAC2_UUID; + test_uuid_array[14] = TIME2_MAC1_UUID; + + Arrays.sort(test_uuid_array, new UUIDComparator()); + // now we should be able to see that the array is in order + assertUUIDsMatchHelper(NULL_UUID, test_uuid_array[0]); + assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[1]); + assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[2]); + assertUUIDsMatchHelper(TIME1_MAC2_UUID, test_uuid_array[3]); + assertUUIDsMatchHelper(TIME2_MAC1_UUID, test_uuid_array[4]); + assertUUIDsMatchHelper(TIME2_MAC2_UUID, test_uuid_array[5]); + assertUUIDsMatchHelper(TIME2_MAC2_UUID, test_uuid_array[6]); + assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[7]); + assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[8]); + assertUUIDsMatchHelper(TIME3_MAC2_UUID, test_uuid_array[9]); + assertUUIDsMatchHelper(TIME3_MAC2_UUID, test_uuid_array[10]); + assertUUIDsMatchHelper(TIME4_MAC1_UUID, test_uuid_array[11]); + assertUUIDsMatchHelper(TIME4_MAC2_UUID, test_uuid_array[12]); + assertUUIDsMatchHelper(TIME5_MAC1_UUID, test_uuid_array[13]); + assertUUIDsMatchHelper(TIME5_MAC2_UUID, test_uuid_array[14]); + } + + /** + * Test of equals method, of class com.fasterxml.uuid.UUID. + */ + public void testEquals() + { + // test passing null to equals returns false + // (as specified in the JDK docs for Object) + UUID x = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertFalse("equals(null) didn't return false", x.equals((Object)null)); + + // test that passing an object which is not a UUID returns false + assertFalse("x.equals(non_UUID_object) didn't return false", x.equals(new Object())); + + // test a case where two UUIDs are definitly not equal + UUID w = UUIDUtil.uuid(ANOTHER_VALID_UUID_BYTE_ARRAY); + assertFalse("x.equals(w) didn't return false", x.equals(w)); + + // test refelexivity + assertTrue("x.equals(x) didn't return true", x.equals(x)); + + // test symmetry + UUID y = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertTrue("y.equals(x) didn't return true", y.equals(x)); + assertTrue("x.equals(y) didn't return true", x.equals(y)); + + // now we'll test transitivity + UUID z = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertTrue("x.equals(y) didn't return true", x.equals(y)); + assertTrue("y.equals(z) didn't return true", y.equals(z)); + assertTrue("x.equals(z) didn't return true", x.equals(z)); + + // test consistancy (this test is just calling equals multiple times) + assertTrue("x.equals(y) didn't return true", x.equals(y)); + assertTrue("x.equals(y) didn't return true", x.equals(y)); + assertTrue("x.equals(y) didn't return true", x.equals(y)); + } + + /** + * Test of getNullUUID method, of class com.fasterxml.uuid.UUID. + */ + public void testGetNullUUID() + { + UUID uuid = nullUUID; + assertEquals("getNullUUID did not create expected null UUID", + NULL_UUID_STRING, + uuid.toString()); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + + // also, validate that getNullUUID is getting the same null each time + UUID uuid2 = nullUUID; + assertEquals("getNullUUID did not create expected null UUID", + NULL_UUID_STRING, + uuid2.toString()); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid2))); + assertTrue("two returned null UUIDs were not the sam object instance", + uuid == uuid2); + } + + /** + * Test of getType method, of class com.fasterxml.uuid.UUID. + */ + public void testGetType() + { + // here we will test that UUID's constructed with the right type + // have the correct type returned from getType + + // test creating a null UUID + UUID uuid = nullUUID; + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + assertEquals("Expected type was not returned", + UUIDUtil.typeOf(nullUUID), + UUIDUtil.typeOf(uuid)); + + // test Random UUID in this case + uuid = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + assertEquals("Expected type was not returned", + UUIDType.RANDOM_BASED, + UUIDUtil.typeOf(uuid)); + + // test time based UUID in this case + uuid = UUIDUtil.uuid(UUIDUtil.asByteArray(TIME1_MAC1_UUID)); + assertEquals("constructor did not create expected UUID", + TIME1_MAC1_UUID.toString().toLowerCase(), + uuid.toString().toLowerCase()); + assertEquals("Expected type was not returned", + UUIDType.TIME_BASED, + UUIDUtil.typeOf(uuid)); + + // test name based UUID in this case + uuid = UUIDUtil.uuid(NAME_BASED_UUID_STRING); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NAME_BASED_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + assertEquals("Expected type was not returned", + UUIDType.NAME_BASED_MD5, + UUIDUtil.typeOf(uuid)); + + // test DCE based UUID in this case + uuid = UUIDUtil.uuid(DCE_BASED_UUID_BYTE_ARRAY); + assertTrue("Expected array did not equal actual array", + Arrays.equals(DCE_BASED_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + assertEquals("Expected type was not returned", + UUIDType.DCE, + UUIDUtil.typeOf(uuid)); + } + + /** + * Test of hashCode method, of class com.fasterxml.uuid.UUID. + */ + public void testHashCode() + { + // as lifted from the JDK Object JavaDocs: + // Whenever it is invoked on the same object more than once + // during an execution of a Java application, the hashCode + // method must consistently return the same integer, provided + // no information used in equals comparisons on the object is + // modified. This integer need not remain consistent from one + // execution of an application to another execution of the + // same application + UUID x = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertTrue("x.equals(x) didn't return true", + x.equals(x)); + assertEquals("x.hashCode() didn't equal x.hashCode()", + x.hashCode(), + x.hashCode()); + assertEquals("x.hashCode() didn't equal x.hashCode()", + x.hashCode(), + x.hashCode()); + + // as lifted from the JDK Object JavaDocs: + // If two objects are equal according to the equals(Object) method, + // then calling the hashCode method on each of the two objects + // must produce the same integer result + UUID y = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertFalse("x == y didn't return false", + x == y); + assertTrue("x.equals(y) didn't return true", + x.equals(y)); + assertEquals("x.hashCode() didn't equal y.hashCode()", + x.hashCode(), + y.hashCode()); + + // it is not REQUIRED that hashCode return different ints for different + // objects where x.equals(z) is not true. + // So, there is no test for that here + } + + /** + * Test of isNullUUID method, of class com.fasterxml.uuid.UUID. + */ + public void testIsNullUUID() + { + // this test will test isNullUUID using the five main ways you could + // create a null UUID and test a case where it should NOT be true + + // test using default constructor + UUID uuid = nullUUID; + assertIsNullUUID(uuid); + + // test by string creation using null uuid represented in string form + uuid = UUIDUtil.uuid(NULL_UUID_STRING); + assertIsNullUUID(uuid); + + // test by byte[] creation using null uuid represented in byte[] form + uuid = UUIDUtil.uuid(NULL_UUID_BYTE_ARRAY); + assertIsNullUUID(uuid); + + // test by byte[] creation using null uuid represented in byte[] form + // starting at an offset + byte[] null_uuid_array = new byte[20]; + Arrays.fill(null_uuid_array, 0, 3, (byte)'x'); + uuid = UUIDUtil.uuid(null_uuid_array, 4); + assertIsNullUUID(uuid); + + // test a not null case + uuid = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertFalse(0L == uuid.getMostSignificantBits()); + assertFalse(0L == uuid.getLeastSignificantBits()); + } + + private void assertIsNullUUID(UUID uuid) { + assertEquals(0L, uuid.getMostSignificantBits()); + assertEquals(0L, uuid.getLeastSignificantBits()); + } + + /** + * Test of toByteArray() method, of class com.fasterxml.uuid.UUID. + */ + public void testToByteArray() + { + // we'll test making a couple UUIDs and then check that the toByteArray + // gives back the same value in byte form that we used to create it + + // first we'll test the null uuid + UUID uuid = nullUUID; + assertEquals("Expected length of returned array wrong", + UUID_BYTE_ARRAY_LENGTH, + UUIDUtil.asByteArray(uuid).length); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + + // now test a non-null uuid + uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + assertEquals("Expected length of returned array wrong", + UUID_BYTE_ARRAY_LENGTH, + UUIDUtil.asByteArray(uuid).length); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + + // let's make sure that changing the returned array doesn't mess with + // the wrapped UUID's internals + uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + assertEquals("Expected length of returned array wrong", + UUID_BYTE_ARRAY_LENGTH, + UUIDUtil.asByteArray(uuid).length); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + byte[] test_byte_array = UUIDUtil.asByteArray(uuid); + // now stir it up a bit and then check that the original UUID was + // not changed in the process. The easiest stir is to sort it ;) + Arrays.sort(test_byte_array); + assertFalse("Expected array was equal other array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, test_byte_array)); + assertFalse("Expected array was equal other array", + Arrays.equals(UUIDUtil.asByteArray(uuid), test_byte_array)); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, UUIDUtil.asByteArray(uuid))); + } + + /** + * Test of toByteArray(byte[]) method, of class com.fasterxml.uuid.UUID. + */ + public void testToByteArrayDest() + { + // constant for use in this test + final int EXTRA_DATA_LENGTH = 9; + + // lets test some error cases + // first, passing null + try + { + UUID test_uuid = nullUUID; + UUIDUtil.toByteArray(test_uuid, (byte[])null); + + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (IllegalArgumentException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // now an array that is too small + try + { + UUID test_uuid = nullUUID; + byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH - 1]; + UUIDUtil.toByteArray(test_uuid, uuid_array); + + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (IllegalArgumentException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + // we'll test making a couple UUIDs and then check that the toByteArray + // gives back the same value in byte form that we used to create it + + // here we'll test the null uuid + UUID test_uuid = nullUUID; + byte[] test_array = new byte[UUID_BYTE_ARRAY_LENGTH]; + UUIDUtil.toByteArray(test_uuid, test_array); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, test_array)); + + // now test a non-null uuid + test_uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + UUIDUtil.toByteArray(test_uuid, test_array); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, test_array)); + + // now test a null uuid case with extra data in the array + test_uuid = nullUUID; + test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + UUIDUtil.toByteArray(test_uuid, test_array); + for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) + { + assertEquals("Expected array values did not match", + NULL_UUID_BYTE_ARRAY[i], + test_array[i]); + } + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) + { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + UUID_BYTE_ARRAY_LENGTH]); + } + + // now test a good uuid case with extra data in the array + test_uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + UUIDUtil.toByteArray(test_uuid, test_array); + for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) + { + assertEquals("Expected array values did not match", + VALID_UUID_BYTE_ARRAY[i], + test_array[i]); + } + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) + { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + UUID_BYTE_ARRAY_LENGTH]); + } + } + + /** + * Test of toByteArray(byte[], int) method, + * of class com.fasterxml.uuid.UUID. + */ + public void testToByteArrayDestOffset() + { + // constant value for use in this test + final int EXTRA_DATA_LENGTH = 9; + + // now an array that is too small + try + { + UUID test_uuid = nullUUID; + byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH - 1]; + UUIDUtil.toByteArray(test_uuid, uuid_array, 0); + + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // now an index that is negative + try { + UUID test_uuid = nullUUID; + byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH]; + UUIDUtil.toByteArray(test_uuid, uuid_array, -1); + + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // now an index that is too big + try { + UUID test_uuid = nullUUID; + byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH]; + UUIDUtil.toByteArray(test_uuid, uuid_array, UUID_BYTE_ARRAY_LENGTH); + + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // now an index that is in the array, + // but without enough bytes to read UUID_BYTE_ARRAY_LENGTH + try { + UUID test_uuid = nullUUID; + byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH]; + UUIDUtil.toByteArray(test_uuid, uuid_array, 1); + + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } catch (IllegalArgumentException ex) { + // this is the success case so do nothing + } catch (Exception ex) { + fail("Caught unexpected exception: " + ex); + } + + // we'll test making a couple UUIDs and then check that the toByteArray + // gives back the same value in byte form that we used to create it + + // here we'll test the null uuid at offset 0 + UUID test_uuid = nullUUID; + byte[] test_array = new byte[UUID_BYTE_ARRAY_LENGTH]; + UUIDUtil.toByteArray(test_uuid, test_array, 0); + assertTrue("Expected array did not equal actual array", + Arrays.equals(NULL_UUID_BYTE_ARRAY, test_array)); + + // now test a non-null uuid + test_uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + UUIDUtil.toByteArray(test_uuid, test_array); + assertTrue("Expected array did not equal actual array", + Arrays.equals(VALID_UUID_BYTE_ARRAY, test_array)); + + // now test a null uuid case with extra data in the array + test_uuid = nullUUID; + test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + UUIDUtil.toByteArray(test_uuid, test_array, 0); + for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) { + assertEquals("Expected array values did not match", + NULL_UUID_BYTE_ARRAY[i], + test_array[i]); + } + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + UUID_BYTE_ARRAY_LENGTH]); + } + + // now test a null uuid case with extra data in the array + test_uuid = nullUUID; + test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + UUIDUtil.toByteArray(test_uuid, test_array, EXTRA_DATA_LENGTH/2); + // first check the data (in the middle of the array) + for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) { + assertEquals("Expected array values did not match (offset "+i+")", + NULL_UUID_BYTE_ARRAY[i], + test_array[i + EXTRA_DATA_LENGTH/2]); + } + // and now check that the surrounding bytes were not changed + for (int i = 0; i < EXTRA_DATA_LENGTH/2; ++i) { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i]); + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH/2]); + } + + // now test a good uuid case with extra data in the array + test_uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + UUIDUtil.toByteArray(test_uuid, test_array, 0); + for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) { + assertEquals("Expected array values did not match", + VALID_UUID_BYTE_ARRAY[i], + test_array[i]); + } + for (int i = 0; i < EXTRA_DATA_LENGTH; i++) { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + UUID_BYTE_ARRAY_LENGTH]); + } + + // now test a good uuid case with extra data in the array + // to make sure we aren't blowing the bounds of the buffer + test_uuid = UUIDUtil.uuid(MIXED_CASE_VALID_UUID_STRING); + test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + UUIDUtil.toByteArray(test_uuid, test_array, EXTRA_DATA_LENGTH/2); + // first check the data (in the middle of the array) + for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) { + assertEquals("Expected array values did not match", + VALID_UUID_BYTE_ARRAY[i], + test_array[i + EXTRA_DATA_LENGTH/2]); + } + // and now check that the surrounding bytes were not changed + for (int i = 0; i < EXTRA_DATA_LENGTH/2; ++i) { + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i]); + assertEquals("Expected array fill value changed", + (byte)'x', + test_array[i + UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH/2]); + } + } + + /** + * Test of toString method, of class com.fasterxml.uuid.UUID. + */ + public void testToString() + { + // test making a couple UUIDs and then check that the toString + // gives back the same value in string form that was used to create it + + // test the null uuid + UUID uuid = nullUUID; + assertEquals("null uuid string and toString did not match", + NULL_UUID_STRING.toLowerCase(), + uuid.toString().toLowerCase()); + + // test a non-null uuid + uuid = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertEquals("uuid string and toString results did not match", + MIXED_CASE_VALID_UUID_STRING.toLowerCase(), + uuid.toString().toLowerCase()); + + // The current UUID implementation returns strings all lowercase. + // Although relying on this behavior in code is not recommended, + // here is a unit test which will break if this assumption + // becomes bad. This will act as an early warning to anyone + // who relies on this particular behavior. + uuid = UUIDUtil.uuid(VALID_UUID_BYTE_ARRAY); + assertFalse("mixed case uuid string and toString " + + "matched (expected toString to be all lower case)", + MIXED_CASE_VALID_UUID_STRING.equals(uuid.toString())); + assertEquals("mixed case string toLowerCase and " + + "toString results did not match (expected toString to " + + "be all lower case)", + MIXED_CASE_VALID_UUID_STRING.toLowerCase(), + uuid.toString()); + } + + /** + * Test of valueOf(String) method, of class com.fasterxml.uuid.UUID. + */ + public void testValueOfString() + { + // test some failure cases for the string constructor + badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_1); + badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_2); + badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_3); + badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_4); + badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_5); + badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_6); + badStringValueOfHelper(NON_HEX_UUID_STRING); + badStringValueOfHelper(RANDOM_PROPER_LENGTH_STRING); + + // test the good cases + goodStringValueOfHelper(NULL_UUID_STRING); + goodStringValueOfHelper(UPPER_CASE_VALID_UUID_STRING); + goodStringValueOfHelper(LOWER_CASE_VALID_UUID_STRING); + goodStringValueOfHelper(MIXED_CASE_VALID_UUID_STRING); + } + + /************************************************************************** + * Begin private helper functions for use in tests + *************************************************************************/ + private void badStringUUIDConstructorHelper(String uuidString) + { + try + { + /*UUID uuid =*/ UUIDUtil.uuid(uuidString); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + } + + private void goodStringUUIDConstructorHelper(String uuidString) + { + UUID temp_uuid = null; + try + { + temp_uuid = UUIDUtil.uuid(uuidString); + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + assertEquals("uuid strings were not equal", + uuidString.toLowerCase(), + temp_uuid.toString().toLowerCase()); + } + + private void badStringValueOfHelper(String uuidString) + { + try + { + /*UUID uuid =*/ UUIDUtil.uuid(uuidString); + // if we reached here we failed because we didn't get an exception + fail("Expected exception not caught"); + } + catch (NumberFormatException ex) + { + // this is the success case so do nothing + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + } + + private void goodStringValueOfHelper(String uuidString) + { + UUID temp_uuid = null; + try + { + temp_uuid = UUIDUtil.uuid(uuidString); + } + catch (Exception ex) + { + fail("Caught unexpected exception: " + ex); + } + + assertEquals("UUID strings were not equal", + uuidString.toLowerCase(), + temp_uuid.toString().toLowerCase()); + } + + private void assertUUIDsMatchHelper(UUID expected, UUID actual) + { + // technically, toString will always return lowercase uuid strings, + // but just to be paranoid, we will always do toLowerCase in this test + assertEquals("UUID strings did not match", + expected.toString().toLowerCase(), + actual.toString().toLowerCase()); + + assertEquals("UUID equals did not match", + expected, + actual); + } + + private void assertUUIDEqualOrderHelper(UUID uuid1, UUID uuid2) + { + assertTrue(uuid1 + " did not test as equal to " + uuid2, + 0 == UUIDComparator.staticCompare(uuid1, uuid2)); + assertTrue(uuid2 + " did not test as equal to " + uuid1, + 0 == UUIDComparator.staticCompare(uuid2, uuid1)); + } + + private void assertUUIDGreaterOrderHelper(UUID uuid1, UUID uuid2) + { + int diff = UUIDComparator.staticCompare(uuid1, uuid2); + assertTrue(uuid1 + " did not test as larger than " + uuid2+", diff: "+diff, diff > 0); + diff = UUIDComparator.staticCompare(uuid2, uuid1); + assertTrue(uuid2 + " did not test as smaller than " + uuid1+", diff: "+diff, diff < 0); + } + /************************************************************************** + * End private helper functions for use in tests + *************************************************************************/ + + /************************************************************************** + * Begin private constants for use in tests above + *************************************************************************/ + private static final int UUID_BYTE_ARRAY_LENGTH = 16; + + // some strings for failure case tests + private static final String IMPROPER_NUM_DASHES_UUID_STRING_1 = + "01234567089AB-CDEF-0123-456789ABCDEF"; + private static final String IMPROPER_NUM_DASHES_UUID_STRING_2 = + "01234567-89AB0CDEF-0123-456789ABCDEF"; + private static final String IMPROPER_NUM_DASHES_UUID_STRING_3 = + "01234567-89AB-CDEF00123-456789ABCDEF"; + private static final String IMPROPER_NUM_DASHES_UUID_STRING_4 = + "01234567-89AB-CDEF-01230456789ABCDEF"; + private static final String IMPROPER_NUM_DASHES_UUID_STRING_5 = + "01234567089AB0CDEF001230456789ABCDEF"; + private static final String IMPROPER_NUM_DASHES_UUID_STRING_6 = + "0123-4567-89AB-CDEF-0123-456789ABCDE"; + private static final String NON_HEX_UUID_STRING = + "01THISIS-ANON-HEX0-UUID-FORSURE01234"; + private static final String RANDOM_PROPER_LENGTH_STRING = + "String Of The Same Length as a UUID!"; + + // some strings and matching byte arrays for the success case tests + private static final String NULL_UUID_STRING = + "00000000-0000-0000-0000-000000000000"; + private static final byte[] NULL_UUID_BYTE_ARRAY = + new byte[UUID_BYTE_ARRAY_LENGTH]; + + private static final String UPPER_CASE_VALID_UUID_STRING = + "4D687664-3A1E-4F30-ACC1-87F59306D30C"; + private static final String MIXED_CASE_VALID_UUID_STRING = + "4d687664-3A1e-4F30-aCc1-87F59306d30C"; + private static final String LOWER_CASE_VALID_UUID_STRING = + "4d687664-3a1e-4f30-acc1-87f59306d30c"; + private static final byte[] VALID_UUID_BYTE_ARRAY = + { + (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, + (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, + (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, + (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c + }; + /* + private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_START = + { + 'e', 'x', 't', 'r', 'a', ' ', 'j', 'u', 'n', 'k', + (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, + (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, + (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, + (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c + }; + */ + private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END = + { + (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, + (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, + (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, + (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c, + 'o', 'n', ' ', 't', 'h', 'e', ' ', 'e', 'n', 'd', + ' ', 'a', 's', ' ', 'w', 'e', 'l', 'l' + }; + /* + private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_BOTH = + { + 'e', 'x', 't', 'r', 'a', ' ', 'j', 'u', 'n', 'k', + (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, + (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, + (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, + (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c, + 'o', 'n', ' ', 't', 'h', 'e', ' ', 'e', 'n', 'd', + ' ', 'a', 's', ' ', 'w', 'e', 'l', 'l' + }; + */ + //private static final String ANOTHER_VALID_UUID_STRING = "4aba2d17-08c9-4376-92fe-4cdefbba5a1c"; + private static final byte[] ANOTHER_VALID_UUID_BYTE_ARRAY = + { + (byte)0x4a, (byte)0xba, (byte)0x2d, (byte)0x17, + (byte)0x08, (byte)0xc9, (byte)0x43, (byte)0x76, + (byte)0x92, (byte)0xfe, (byte)0x4c, (byte)0xde, + (byte)0xfb, (byte)0xba, (byte)0x5a, (byte)0x1c + }; + + // valid namespace based UUID string + private static final String NAME_BASED_UUID_STRING = + "71ee9b64-39d3-386c-bce3-c70549ca8829"; + private static final byte[] NAME_BASED_UUID_BYTE_ARRAY = + { + (byte)0x71, (byte)0xee, (byte)0x9b, (byte)0x64, + (byte)0x39, (byte)0xd3, (byte)0x38, (byte)0x6c, + (byte)0xbc, (byte)0xe3, (byte)0xc7, (byte)0x05, + (byte)0x49, (byte)0xca, (byte)0x88, (byte)0x29 + }; + + // dummy DCE based UUID string since I have no real examples to use + //private static final String DCE_BASED_UUID_STRING = "01234567-0123-2000-8000-0123456789ab"; + private static final byte[] DCE_BASED_UUID_BYTE_ARRAY = + { + (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, + (byte)0x01, (byte)0x23, (byte)0x20, (byte)0x00, + (byte)0x80, (byte)0x00, (byte)0x01, (byte)0x23, + (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xab + }; + + // some strings for the "ordered" uuid test cases + // notice that these uuid cases vary in the time portion and for each + // "exact time" there is a case for two different MAC addresses + // to insure the ordering test between different MAC addresses + private static final UUID NULL_UUID = nullUUID; + private static final UUID TIME1_MAC1_UUID = + UUIDUtil.uuid("ebb8e8fe-b1b1-11d7-8adb-00b0d078fa18"); + private static final UUID TIME1_MAC2_UUID = + UUIDUtil.uuid("ebb8e8fe-b1b1-11d7-8adb-baa07db6d227"); + private static final UUID TIME2_MAC1_UUID = + UUIDUtil.uuid("ec3ffdda-b1b1-11d7-8adb-00b0d078fa18"); + private static final UUID TIME2_MAC2_UUID = + UUIDUtil.uuid("ec3ffdda-b1b1-11d7-8adb-baa07db6d227"); + private static final UUID TIME3_MAC1_UUID = + UUIDUtil.uuid("eca4c616-b1b1-11d7-8adb-00b0d078fa18"); + private static final UUID TIME3_MAC2_UUID = + UUIDUtil.uuid("eca4c616-b1b1-11d7-8adb-baa07db6d227"); + private static final UUID TIME4_MAC1_UUID = + UUIDUtil.uuid("ed17de08-b1b1-11d7-8adb-00b0d078fa18"); + private static final UUID TIME4_MAC2_UUID = + UUIDUtil.uuid("ed17de08-b1b1-11d7-8adb-baa07db6d227"); + private static final UUID TIME5_MAC1_UUID = + UUIDUtil.uuid("ed94244a-b1b1-11d7-8adb-00b0d078fa18"); + private static final UUID TIME5_MAC2_UUID = + UUIDUtil.uuid("ed94244a-b1b1-11d7-8adb-baa07db6d227"); + /************************************************************************** + * End private constants for use in tests above + *************************************************************************/ +} diff -Nru jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDTimerTest.java jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDTimerTest.java --- jug-2.0.0/src/test/java/com/fasterxml/uuid/UUIDTimerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ jug-3.1.5/src/test/java/com/fasterxml/uuid/UUIDTimerTest.java 2018-02-21 02:29:25.000000000 +0000 @@ -0,0 +1,368 @@ +/* JUG Java Uuid Generator + * UUIDTimerTest.java + * Created on July 28, 2003, 10:09 PM + * + * Copyright (c) 2003 Eric Bie + * + * 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.IOException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + +import com.fasterxml.uuid.UUIDTimer; + +/** + * JUnit Test class for the com.fasterxml.uuid.UUIDTimer class. + * + * @author Eric Bie + */ +public class UUIDTimerTest extends TestCase +{ + // constants for use in the tests + private static final int UUID_TIMER_ARRAY_LENGTH = 10; + private static final int SIZE_OF_TEST_ARRAY = 10000; + + public UUIDTimerTest(java.lang.String testName) + { + super(testName); + } + + public static Test suite() + { + TestSuite suite = new TestSuite(UUIDTimerTest.class); + return suite; + } + + public static void main(String[] args) + { + TestRunner.run(suite()); + } + + /************************************************************************** + * Begin constructor tests + *************************************************************************/ + /** + * Test of UUIDTimer(SecureRandom) constructor, + * of class com.fasterxml.uuid.UUIDTimer. + */ + public void testSecureRandomUUIDTimerConstructor() throws IOException + { + // try passing a null SecureRandom argument + try + { + /*UUIDTimer uuid_timer =*/ new UUIDTimer((SecureRandom)null, null); + // if we reach here we didn't catch what we should have + fail("Expected exception not caught"); + } + catch (NullPointerException ex) + { + // caught the expected exception, this is good, just go on + } + catch (Exception ex) + { + fail("Unexpected exception caught"); + } + + // now construct a valid case + SecureRandom secure_random = new SecureRandom(); + UUIDTimer uuid_timer = new UUIDTimer(secure_random, null); + + // we'll do a simple run to see that it at least produces output + byte[] test_array = new byte[UUID_TIMER_ARRAY_LENGTH]; + uuid_timer.getAndSetTimestamp(test_array); + // check that it's not all null + assertArrayNotEqual(test_array, + new byte[UUID_TIMER_ARRAY_LENGTH], + UUID_TIMER_ARRAY_LENGTH); + } + /************************************************************************** + * End constructor tests + *************************************************************************/ + + /** + * Test of getAndSetTimestamp method, of class com.fasterxml.uuid.UUIDTimer. + */ + public void testGetTimestamp() throws IOException + { + // constant for use in this test + final int EXTRA_DATA_LENGTH = 9; + + // construct a UUIDTimer + SecureRandom secure_random = new SecureRandom(); + UUIDTimer uuid_timer = new UUIDTimer(secure_random, null); + + // test an array thats too small + try + { + byte[] test_array = new byte[UUID_TIMER_ARRAY_LENGTH - 1]; + uuid_timer.getAndSetTimestamp(test_array); + // if we get here, we didn't catch the expected exception + fail("Expected exception not caught"); + } + catch (ArrayIndexOutOfBoundsException ex) + { + // caught the expected exception, this is good, just go on + } + catch (Exception ex) + { + fail("Unexpected exception caught"); + } + + // construct a valid array exactly big enough and see that it works + byte[] test_array = new byte[UUID_TIMER_ARRAY_LENGTH]; + uuid_timer.getAndSetTimestamp(test_array); + // check that it's not all null + assertArrayNotEqual(test_array, + new byte[UUID_TIMER_ARRAY_LENGTH], + UUID_TIMER_ARRAY_LENGTH); + + // construct a valid array bigger then we need + // and make sure getAndSetTimeStamp only touches the begining part + test_array = new byte[UUID_TIMER_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; + Arrays.fill(test_array, (byte)'x'); + uuid_timer.getAndSetTimestamp(test_array); + for (int i = 0; i < EXTRA_DATA_LENGTH; ++i) + { + assertEquals("test_array element was corrupted", + (byte)'x', + test_array[i + UUID_TIMER_ARRAY_LENGTH]); + } + // check that the timer portion is not all null + assertArrayNotEqual(test_array, + new byte[UUID_TIMER_ARRAY_LENGTH], + UUID_TIMER_ARRAY_LENGTH); + + // now make a bunch of timer elements and validate that they are + // are well behaved timer elements + byte[][] array_of_uuid_timer_byte_arrays = + new byte[SIZE_OF_TEST_ARRAY][UUID_TIMER_ARRAY_LENGTH]; + + // before generating all the uuid timer arrays, get the start time + long start_time = System.currentTimeMillis(); + + // now create the array of uuid timer output arrays + for (int i = 0; i < array_of_uuid_timer_byte_arrays.length; i++) + { + uuid_timer.getAndSetTimestamp(array_of_uuid_timer_byte_arrays[i]); + } + + // now capture the end time + long end_time = System.currentTimeMillis(); + + // convert the array into array of longs holding the numerical values + Long[] uuid_timer_array_of_longs = + convertArrayOfByteArraysToArrayOfLongs( + array_of_uuid_timer_byte_arrays); + + // check that none of the UUID Timer arrays are all null + checkUUIDTimerLongArrayForNonNullTimes(uuid_timer_array_of_longs); + + // check that all UUID Timers were generated with correct order + checkUUIDTimerLongArrayForCorrectOrdering(uuid_timer_array_of_longs); + + // check that all UUID Timers were unique + checkUUIDTimerLongArrayForUniqueness(uuid_timer_array_of_longs); + + // check that all timestamps are between the start and end time + checkUUIDTimerLongArrayForCorrectCreationTime( + uuid_timer_array_of_longs, start_time, end_time); + } + + /************************************************************************** + * Begin private helper functions for use in tests + *************************************************************************/ + private Long[] convertArrayOfByteArraysToArrayOfLongs( + byte[][] uuidTimerArrayOfByteArrays) + { + Long[] array_of_longs = new Long[uuidTimerArrayOfByteArrays.length]; + for (int i = 0; i < uuidTimerArrayOfByteArrays.length; i++) + { + // collect the UUID time stamp which is + // the number of 100-nanosecond intervals since + // 00:00:00.00 15 October 1582 + long uuid_timer = 0L; + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][3] & 0xFFL) << 0); + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][2] & 0xFFL) << 8); + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][1] & 0xFFL) << 16); + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][0] & 0xFFL) << 24); + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][5] & 0xFFL) << 32); + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][4] & 0xFFL) << 40); + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][7] & 0xFFL) << 48); + uuid_timer |= ((uuidTimerArrayOfByteArrays[i][6] & 0xFFL) << 56); + + array_of_longs[i] = new Long(uuid_timer); + } + + return array_of_longs; + } + + private class ReverseOrderUUIDTimerLongComparator implements Comparator + { + // this Comparator class has a compare which orders reverse of the + // compare method in UUIDTimerArrayComparator (so we can be sure our + // arrays below are 'not ordered in sorted order' + // before we sort them). + public int compare(Long uuid_timer_long1, Long uuid_timer_long2) { + return -uuid_timer_long1.compareTo(uuid_timer_long2); + } + + // we are only implementing equals because it's needed, super should do + public boolean equals(Object o) + { + return super.equals(o); + } + } + + private void checkUUIDTimerLongArrayForCorrectOrdering( + Long[] uuidTimerLongArray) + { + // now we'll clone the array and reverse it + Long[] uuid_timer_sorted_arrays = (Long[])uuidTimerLongArray.clone(); + assertEquals("Cloned array length did not match", + uuidTimerLongArray.length, + uuid_timer_sorted_arrays.length); + + ReverseOrderUUIDTimerLongComparator rev_order_uuid_timer_comp = + new ReverseOrderUUIDTimerLongComparator(); + Arrays.sort(uuid_timer_sorted_arrays, rev_order_uuid_timer_comp); + + // let's check that the array is actually reversed + int sorted_arrays_length = uuid_timer_sorted_arrays.length; + for (int i = 0; i < sorted_arrays_length; i++) + { + assertTrue( + "Reverse order check on uuid timer arrays failed" + + " on element " + i + ": " + + uuidTimerLongArray[i].longValue() + " does not equal " + + uuid_timer_sorted_arrays[ + sorted_arrays_length - (1 + i)].longValue(), + uuidTimerLongArray[i].equals( + uuid_timer_sorted_arrays[sorted_arrays_length - (1 + i)])); + } + + // now let's sort the reversed array and check that it sorted to + // the same order as the original + Arrays.sort(uuid_timer_sorted_arrays); + for (int i = 0; i < sorted_arrays_length; i++) + { + assertTrue( + "Same order check on uuid timer arrays failed on element " + + i + ": " + uuidTimerLongArray[i].longValue() + + " does not equal " + + uuid_timer_sorted_arrays[i].longValue(), + uuidTimerLongArray[i].equals(uuid_timer_sorted_arrays[i])); + } + } + + private void checkUUIDTimerLongArrayForUniqueness(Long[] uuidTimerLongArray) + { + // here we'll assert that all elements in the list are not equal to + // each other (aka, there should be no duplicates) we'll do this by + // inserting all elements into a Set and making sure none of them + // were already present (add will return false if it was already there) + Set set = new HashSet(); + for (int i = 0; i < uuidTimerLongArray.length; i++) + { + assertTrue("Uniqueness test failed on insert into HashSet", + set.add(uuidTimerLongArray[i])); + assertFalse( + "Paranoia Uniqueness test failed (second insert into HashSet)", + set.add(uuidTimerLongArray[i])); + } + } + + private void checkUUIDTimerLongArrayForCorrectCreationTime( + Long[] uuidTimerLongArray, + long startTime, + long endTime) + { + // we need to convert from 100-naonsecond units (as used in UUIDs) + // to millisecond units as used in UTC based time + final long MILLI_CONVERSION_FACTOR = 10000L; + // Since System.currentTimeMillis() returns time epoc time + // (from 1-Jan-1970), and UUIDs use time from the beginning of + // Gregorian calendar (15-Oct-1582) we have a offset for correction + final long GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET = + 122192928000000000L; + + assertTrue("Start time was not before the end time", + startTime < endTime); + + // let's check that all the uuid timer longs in the array have a + // timestamp which lands between the start and end time + for (int i = 0; i < uuidTimerLongArray.length; i++) + { + long uuid_time = uuidTimerLongArray[i].longValue(); + + // first we'll remove the gregorian offset + uuid_time -= GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET; + + // and convert to milliseconds as the system clock is in millis + uuid_time /= MILLI_CONVERSION_FACTOR; + + // now check that the times are correct + assertTrue( + "Start time: " + startTime + + " was not before UUID timestamp: " + uuid_time, + startTime <= uuid_time); + assertTrue( + "UUID timestamp: " + uuid_time + + " was not before the end time: " + endTime, + uuid_time <= endTime); + } + } + + private void checkUUIDTimerLongArrayForNonNullTimes( + Long[] uuidTimerLongArray) + { + for (int i = 0; i < uuidTimerLongArray.length; i++) + { + assertFalse("Timer Long was null", + 0 == uuidTimerLongArray[i].longValue()); + } + } + + private void assertArrayNotEqual(byte[] array1, byte[] array2, int length) + { + assertTrue("array1 was not equal or longer then length", + array1.length >= length); + assertTrue("array2 was not equal or longer then length", + array2.length >= length); + + for (int i = 0; i < length; ++i) + { + // we know the arrays aren't equal the first time we + // fine an array element that isn't equal. + // in that case just return + if (array1[i] != array2[i]) + { + return; + } + } + // if we get out of the loop, both arrays were identical, so fail + fail("All elements of Array1 were equal to all elements of Array2"); + } + /************************************************************************** + * End private helper functions for use in tests + *************************************************************************/ +} diff -Nru jug-2.0.0/src/test/org/safehaus/uuid/EthernetAddressPackageAccessTest.java jug-3.1.5/src/test/org/safehaus/uuid/EthernetAddressPackageAccessTest.java --- jug-2.0.0/src/test/org/safehaus/uuid/EthernetAddressPackageAccessTest.java 2005-07-21 05:25:47.000000000 +0000 +++ jug-3.1.5/src/test/org/safehaus/uuid/EthernetAddressPackageAccessTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -/* JUG Java Uuid Generator - * EthernetAddressPackageAccessTest.java - * Created on October 7, 2003, 10:46 PM - * - * Copyright (c) 2003 Eric Bie - * - * 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 org.safehaus.uuid; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.textui.TestRunner; - -import java.util.Arrays; - -import org.safehaus.uuid.EthernetAddress; - -/** - * JUnit Test class for checking the package access - * methods of the org.safehaus.uuid.EthernetAddress class. - * - * @author Eric Bie - */ -public class EthernetAddressPackageAccessTest extends TestCase -{ - // constant defining the length of a valid ethernet address byte array - private static final int ETHERNET_ADDRESS_ARRAY_LENGTH = 6; - - // here are some sets of good ethernet addresses in various forms - private static final String NULL_ETHERNET_ADDRESS_STRING = - "00:00:00:00:00:00"; - private static final long NULL_ETHERNET_ADDRESS_LONG = 0x0000000000000000L; - private static final byte[] NULL_ETHERNET_ADDRESS_BYTE_ARRAY = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; - private static final int[] NULL_ETHERNET_ADDRESS_INT_ARRAY = - new int[ETHERNET_ADDRESS_ARRAY_LENGTH]; - private static final EthernetAddress NULL_ETHERNET_ADDRESS = - new EthernetAddress(0L); - - public EthernetAddressPackageAccessTest(java.lang.String testName) - { - super(testName); - } - - public static Test suite() - { - TestSuite suite = - new TestSuite(EthernetAddressPackageAccessTest.class); - return suite; - } - - public static void main(String[] args) - { - TestRunner.run(suite()); - } - - /************************************************************************** - * Begin Constructor tests - *************************************************************************/ - /** - * Test of EthernetAddress() constructor, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testDefaultEthernetAddressConstructor() - { - // this test technically relies on the toString() and toLong() - // methods of the EthernetAddress class working properly. - // If it fails, that is fine... the test only needs to indicate - // proper working behavior or that it needs to be fixed. - EthernetAddress ethernet_address = new EthernetAddress(); - assertEquals( - "Default constructor did not create expected null EthernetAddress", - NULL_ETHERNET_ADDRESS_STRING, - ethernet_address.toString()); - assertEquals( - "Default constructor did not create expected null EthernetAddress", - NULL_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - } - /************************************************************************** - * End Constructor tests - *************************************************************************/ -} diff -Nru jug-2.0.0/src/test/org/safehaus/uuid/test/EthernetAddressTest.java jug-3.1.5/src/test/org/safehaus/uuid/test/EthernetAddressTest.java --- jug-2.0.0/src/test/org/safehaus/uuid/test/EthernetAddressTest.java 2005-07-21 05:25:47.000000000 +0000 +++ jug-3.1.5/src/test/org/safehaus/uuid/test/EthernetAddressTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,1514 +0,0 @@ -/* JUG Java Uuid Generator - * EthernetAddressTest.java - * Created on July 16, 2003, 11:17 PM - * - * Copyright (c) 2003 Eric Bie - * - * 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 org.safehaus.uuid.test; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.textui.TestRunner; - -import java.util.Arrays; - -import org.safehaus.uuid.EthernetAddress; - -/** - * JUnit Test class for the org.safehaus.uuid.EthernetAddress class. - * - * @author Eric Bie - */ -public class EthernetAddressTest extends TestCase -{ - // constant defining the length of a valid ethernet address byte array - private static final int ETHERNET_ADDRESS_ARRAY_LENGTH = 6; - - // some strings for failure case tests - private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_1 = - "01f23:45:67:89:ab"; - private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_2 = - "01:23f45:67:89:ab"; - private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_3 = - "01:23:45f67:89:ab"; - private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_4 = - "01:23:45:67f89:ab"; - private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_5 = - "01:23:45:67:89fab"; - private static final String IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_6 = - "01f23f45f67f89fab"; - private static final String NON_HEX_ETHERNET_ADDRESS_STRING = - "NON-HEX0-FORSURE0"; - private static final String RANDOM_PROPER_LENGTH_STRING = - "Same LengthString"; - - // some valid strings for the various dropped digit cases - private static final String FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = - "00:23:45:67:89:ab"; - private static final String FIRST_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = - "0:23:45:67:89:ab"; - private static final String FIRST_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = - ":23:45:67:89:ab"; - private static final String SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = - "01:00:45:67:89:ab"; - private static final String SECOND_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = - "01:0:45:67:89:ab"; - private static final String SECOND_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = - "01::45:67:89:ab"; - private static final String THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = - "01:23:00:67:89:ab"; - private static final String THIRD_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = - "01:23:0:67:89:ab"; - private static final String THIRD_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = - "01:23::67:89:ab"; - private static final String FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:00:89:ab"; - private static final String FOURTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:0:89:ab"; - private static final String FOURTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45::89:ab"; - private static final String FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:67:00:ab"; - private static final String FIFTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:67:0:ab"; - private static final String FIFTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:67::ab"; - private static final String SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:67:89:00"; - private static final String SIXTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:67:89:0"; - private static final String SIXTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = - "01:23:45:67:89:"; - private static final String MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING = - "01:03:00:07:00:00"; - private static final String MIXED_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING = - "1:3:0:7:0:0"; - private static final String MIXED_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING = - "1:3::7::"; - - // here are some sets of good ethernet addresses in various forms - private static final String NULL_ETHERNET_ADDRESS_STRING = - "00:00:00:00:00:00"; - private static final long NULL_ETHERNET_ADDRESS_LONG = 0x0000000000000000L; - private static final byte[] NULL_ETHERNET_ADDRESS_BYTE_ARRAY = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; - private static final int[] NULL_ETHERNET_ADDRESS_INT_ARRAY = - new int[ETHERNET_ADDRESS_ARRAY_LENGTH]; - private static final EthernetAddress NULL_ETHERNET_ADDRESS = - new EthernetAddress(0L); - - private static final String VALID_ETHERNET_ADDRESS_STRING = - "87:f5:93:06:d3:0c"; - private static final String MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING = - "87:f5:93:06:D3:0c"; - private static final String UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING = - "87:F5:93:06:D3:0C"; - private static final String LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING = - VALID_ETHERNET_ADDRESS_STRING; - private static final long VALID_ETHERNET_ADDRESS_LONG = - 0x000087f59306d30cL; - private static final byte[] VALID_ETHERNET_ADDRESS_BYTE_ARRAY = - { - (byte)0x87, (byte)0xf5, (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c - }; - private static final int[] VALID_ETHERNET_ADDRESS_INT_ARRAY = - { - 0x87, 0xf5, 0x93, 0x06, 0xd3, 0x0c - }; - private static final EthernetAddress VALID_ETHERNET_ADDRESS = - new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); - - private static final String ANOTHER_VALID_ETHERNET_ADDRESS_STRING = - "4c:de:fb:ba:5a:1c"; - private static final long ANOTHER_VALID_ETHERNET_ADDRESS_LONG = - 0x00004cdefbba5a1cL; - private static final byte[] ANOTHER_VALID_ETHERNET_ADDRESS_BYTE_ARRAY = - { - (byte)0x4c, (byte)0xde, (byte)0xfb, (byte)0xba, (byte)0x5a, (byte)0x1c - }; - private static final int[] ANOTHER_VALID_ETHERNET_ADDRESS_INT_ARRAY = - { - 0x4c, 0xde, 0xfb, 0xba, 0x5a, 0x1c - }; - private static final EthernetAddress ANOTHER_VALID_ETHERNET_ADDRESS = - new EthernetAddress(ANOTHER_VALID_ETHERNET_ADDRESS_LONG); - - // some ethernet addresses for the ordering tests - private static final EthernetAddress MAC0_ETHERNET_ADDRESS = - new EthernetAddress(0x0000015ae2e61893L); - private static final EthernetAddress MAC1_ETHERNET_ADDRESS = - new EthernetAddress(0x00001f0f1b0e8e6eL); - private static final EthernetAddress MAC2_ETHERNET_ADDRESS = - new EthernetAddress(0x000022d8afb0b888L); - private static final EthernetAddress MAC3_ETHERNET_ADDRESS = - new EthernetAddress(0x00004cfdc9a5e86aL); - private static final EthernetAddress MAC4_ETHERNET_ADDRESS = - new EthernetAddress(0x000091038ffa38eeL); - private static final EthernetAddress MAC5_ETHERNET_ADDRESS = - new EthernetAddress(0x00009857e4f202a3L); - private static final EthernetAddress MAC6_ETHERNET_ADDRESS = - new EthernetAddress(0x0000a8c0600ccc69L); - private static final EthernetAddress MAC7_ETHERNET_ADDRESS = - new EthernetAddress(0x0000a9a18860d8fcL); - private static final EthernetAddress MAC8_ETHERNET_ADDRESS = - new EthernetAddress(0x0000c8b30f0b395aL); - private static final EthernetAddress MAC9_ETHERNET_ADDRESS = - new EthernetAddress(0x0000cf74d8ef49b8L); - - - public EthernetAddressTest(java.lang.String testName) - { - super(testName); - } - - public static Test suite() - { - TestSuite suite = new TestSuite(EthernetAddressTest.class); - return suite; - } - - public static void main(String[] args) - { - TestRunner.run(suite()); - } - - /************************************************************************** - * Begin Constructor tests - *************************************************************************/ - /** - * Test of EthernetAddress(byte[]) constructor, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testByteArrayEthernetAddressConstructor() - { - // lets test some error cases - // first, passing null - try - { - EthernetAddress ethernet_address = - new EthernetAddress((byte[])null); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - EthernetAddress ethernet_address = - new EthernetAddress( - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too big - try - { - EthernetAddress ethernet_address = - new EthernetAddress( - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + 1]); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // let's test that creating a EthernetAddress from an zero'd array - // gives us a null EthernetAddress (definition of null EthernetAddress) - EthernetAddress ethernet_address = - new EthernetAddress(new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]); - assertEquals( - "EthernetAddress(byte[]) did not create expected EthernetAddress", - NULL_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - - // let's test creating an array from a good byte array - ethernet_address = - new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertEquals( - "EthernetAddress(byte[]) did not create expected EthernetAddress", - VALID_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - } - - /** - * Test of EthernetAddress(long) constructor, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testLongEthernetAddressConstructor() - { - // let's test that creating a EthernetAddress from an zero long - // gives us a null EthernetAddress (definition of null EthernetAddress) - EthernetAddress ethernet_address = - new EthernetAddress(0x0000000000000000L); - assertEquals( - "EthernetAddress(long) did not create expected EthernetAddress", - NULL_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - - // let's test creating an array from a good long - ethernet_address = new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); - assertEquals( - "EthernetAddress(long) did not create expected EthernetAddress", - VALID_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - } - - /** - * Test of EthernetAddress(String) constructor, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testStringEthernetAddressConstructor() - { - // test a null string case - try - { - EthernetAddress ethernet_address = - new EthernetAddress((String)null); - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test some failure cases for the string constructor - badStringEthernetAddressConstructorHelper( - IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_1); - badStringEthernetAddressConstructorHelper( - IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_2); - badStringEthernetAddressConstructorHelper( - IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_3); - badStringEthernetAddressConstructorHelper( - IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_4); - badStringEthernetAddressConstructorHelper( - IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_5); - badStringEthernetAddressConstructorHelper( - IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_6); - badStringEthernetAddressConstructorHelper( - NON_HEX_ETHERNET_ADDRESS_STRING); - badStringEthernetAddressConstructorHelper( - RANDOM_PROPER_LENGTH_STRING); - - // some valid strings for the various dropped digit cases - goodStringEthernetAddressConstructorHelper( - FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FIRST_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FIRST_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - SECOND_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - SECOND_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - THIRD_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - THIRD_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FOURTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FOURTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FIFTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - FIFTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - SIXTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - SIXTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - MIXED_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - MIXED_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - - // test the other good cases - goodStringEthernetAddressConstructorHelper( - NULL_ETHERNET_ADDRESS_STRING, - NULL_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING, - UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING, - LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING); - goodStringEthernetAddressConstructorHelper( - MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING, - MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); - } - - /************************************************************************** - * End Constructor tests - *************************************************************************/ - /** - * Test of asByteArray method, of class org.safehaus.uuid.EthernetAddress. - */ - public void testAsByteArray() - { - // we'll test making a couple EthernetAddresses and then check that - // asByteArray returns the same value in long form as used to create it - - // first we'll test the null EthernetAddress - EthernetAddress ethernet_address = new EthernetAddress(0L); - assertEquals("Expected length of returned array wrong", - ETHERNET_ADDRESS_ARRAY_LENGTH, - ethernet_address.asByteArray().length); - assertEthernetAddressArraysAreEqual( - NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address.asByteArray(), 0); - - // now test a non-null EthernetAddress - ethernet_address = new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); - assertEquals("Expected length of returned array wrong", - ETHERNET_ADDRESS_ARRAY_LENGTH, - ethernet_address.asByteArray().length); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address.asByteArray(), 0); - - // let's make sure that changing the returned array doesn't mess with - // the wrapped EthernetAddress's internals - byte[] ethernet_address_byte_array = ethernet_address.asByteArray(); - // we'll just stir it up a bit and then check that the original - // EthernetAddress was not changed in the process. - // The easiest stir is to sort it ;) - Arrays.sort(ethernet_address_byte_array); - assertEthernetAddressArraysAreNotEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address_byte_array, 0); - assertEthernetAddressArraysAreNotEqual( - ethernet_address.asByteArray(), 0, - ethernet_address_byte_array, 0); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address.asByteArray(), 0); - } - - /** - * Test of clone method, of class org.safehaus.uuid.EthernetAddress. - */ - public void testClone() - { - // as lifted from the JDK Object JavaDoc for clone: - // x.clone() Creates and returns a copy of x. - // The precise meaning of "copy" may depend on - // the class of the object. The general intent - // is that, for any object x, the expression: - // x.clone() != x - // will be true, and that the expression: - // x.clone().getClass() == x.getClass() - // will be true, but these are not absolute requirements. - // While it is typically the case that: - // x.clone().equals(x) - // will be true, this is not an absolute requirement. - // For EthernetAddress, this test will check that all the above - // ARE true in the case of EthernetAddress clone() because it is - // the desired behavior. - EthernetAddress x = new EthernetAddress(VALID_ETHERNET_ADDRESS_STRING); - assertTrue("x.clone() != x did not return true", - x.clone() != x); - assertTrue("x.clone().getClass() == x.getClass() did not return true", - x.clone().getClass() == x.getClass()); - assertTrue("x.clone().equals(x) did not return true", - x.clone().equals(x)); - } - - /** - * Test of compareTo method, of class org.safehaus.uuid.EthernetAddress. - */ - public void testCompareTo() - { - // first, let's make sure calling compareTo with null - // throws the appropriate NullPointerException - try - { - // the 'null EthernetAddress' will be fine - NULL_ETHERNET_ADDRESS.compareTo(null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // good, we caught the expected exception, so we passed - } - catch (Exception ex) - { - fail("Caught an unexpected exception: " + ex); - } - - // now, let's make sure giving compareTo a non-EthernetAddress class - // results in the appropriate ClassCastException - try - { - // the 'null EthernetAddress' will be fine - NULL_ETHERNET_ADDRESS.compareTo((new Integer(5))); - fail("Expected exception not thrown"); - } - catch (ClassCastException ex) - { - // good, we caught the expected exception, so we passed - } - catch (Exception ex) - { - fail("Caught an unexpected exception: " + ex); - } - - // now we'll test some simple base cases - // 2 null EthernetAddresses always compare to 0 - assertEthernetAddressEqualOrderHelper(NULL_ETHERNET_ADDRESS, - new EthernetAddress(0L)); - - // 2 of the same value EthernetAddresses are always 0 - assertEthernetAddressEqualOrderHelper(MAC0_ETHERNET_ADDRESS, - new EthernetAddress(MAC0_ETHERNET_ADDRESS.toLong())); - - // the 'null EthernetAddress' always comes first in the ordering - assertEthernetAddressGreaterOrderHelper(MAC0_ETHERNET_ADDRESS, - NULL_ETHERNET_ADDRESS); - - // EthernetAddresses will always sort - // with the 'numerically' greater MAC addresses coming later - assertEthernetAddressGreaterOrderHelper(MAC4_ETHERNET_ADDRESS, - MAC0_ETHERNET_ADDRESS); - assertEthernetAddressGreaterOrderHelper(MAC9_ETHERNET_ADDRESS, - MAC4_ETHERNET_ADDRESS); - assertEthernetAddressGreaterOrderHelper(MAC9_ETHERNET_ADDRESS, - MAC0_ETHERNET_ADDRESS); - - // now we will test a bigger case of the compareTo functionality - // of the EthernetAddress class - // easiest way to do this is to create an array of EthernetAddresses - // and sort it then test that this array is in the expected order - - // before sort, the array contains (in psudo-random order) - // 15 EthernetAddresses of this distribution: - // 1 - null EthernetAddress - // 2 - mac0 - // 1 - mac1 - // 1 - mac2 - // 2 - mac3 - // 2 - mac4 - // 2 - mac5 - // 1 - mac6 - // 1 - mac7 - // 1 - mac8 - // 1 - mac9 - EthernetAddress ethernet_address_array[] = new EthernetAddress[15]; - ethernet_address_array[0] = MAC4_ETHERNET_ADDRESS; - ethernet_address_array[1] = MAC6_ETHERNET_ADDRESS; - ethernet_address_array[2] = MAC0_ETHERNET_ADDRESS; - ethernet_address_array[3] = MAC5_ETHERNET_ADDRESS; - ethernet_address_array[4] = MAC3_ETHERNET_ADDRESS; - ethernet_address_array[5] = MAC5_ETHERNET_ADDRESS; - ethernet_address_array[6] = MAC0_ETHERNET_ADDRESS; - ethernet_address_array[7] = NULL_ETHERNET_ADDRESS; - ethernet_address_array[8] = MAC8_ETHERNET_ADDRESS; - ethernet_address_array[9] = MAC3_ETHERNET_ADDRESS; - ethernet_address_array[10] = MAC4_ETHERNET_ADDRESS; - ethernet_address_array[11] = MAC7_ETHERNET_ADDRESS; - ethernet_address_array[12] = MAC1_ETHERNET_ADDRESS; - ethernet_address_array[13] = MAC9_ETHERNET_ADDRESS; - ethernet_address_array[14] = MAC2_ETHERNET_ADDRESS; - - Arrays.sort(ethernet_address_array); - // now we should be able to see that the array is in order - assertEthernetAddressesMatchHelper( - NULL_ETHERNET_ADDRESS, ethernet_address_array[0]); - assertEthernetAddressesMatchHelper( - MAC0_ETHERNET_ADDRESS, ethernet_address_array[1]); - assertEthernetAddressesMatchHelper( - MAC0_ETHERNET_ADDRESS, ethernet_address_array[2]); - assertEthernetAddressesMatchHelper( - MAC1_ETHERNET_ADDRESS, ethernet_address_array[3]); - assertEthernetAddressesMatchHelper( - MAC2_ETHERNET_ADDRESS, ethernet_address_array[4]); - assertEthernetAddressesMatchHelper( - MAC3_ETHERNET_ADDRESS, ethernet_address_array[5]); - assertEthernetAddressesMatchHelper( - MAC3_ETHERNET_ADDRESS, ethernet_address_array[6]); - assertEthernetAddressesMatchHelper( - MAC4_ETHERNET_ADDRESS, ethernet_address_array[7]); - assertEthernetAddressesMatchHelper( - MAC4_ETHERNET_ADDRESS, ethernet_address_array[8]); - assertEthernetAddressesMatchHelper( - MAC5_ETHERNET_ADDRESS, ethernet_address_array[9]); - assertEthernetAddressesMatchHelper( - MAC5_ETHERNET_ADDRESS, ethernet_address_array[10]); - assertEthernetAddressesMatchHelper( - MAC6_ETHERNET_ADDRESS, ethernet_address_array[11]); - assertEthernetAddressesMatchHelper( - MAC7_ETHERNET_ADDRESS, ethernet_address_array[12]); - assertEthernetAddressesMatchHelper( - MAC8_ETHERNET_ADDRESS, ethernet_address_array[13]); - assertEthernetAddressesMatchHelper( - MAC9_ETHERNET_ADDRESS, ethernet_address_array[14]); - } - - /** - * Test of equals method, of class org.safehaus.uuid.EthernetAddress. - */ - public void testEquals() - { - // test passing null to equals returns false - // (as specified in the JDK docs for Object) - EthernetAddress x = - new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertFalse("equals(null) didn't return false", - x.equals((Object)null)); - - // test passing an object which is not a EthernetAddress returns false - assertFalse("x.equals(non_EthernetAddress_object) didn't return false", - x.equals(new Object())); - - // test a case where two EthernetAddresss are definitly not equal - EthernetAddress w = - new EthernetAddress(ANOTHER_VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertFalse("x == w didn't return false", - x == w); - assertFalse("x.equals(w) didn't return false", - x.equals(w)); - - // test refelexivity - assertTrue("x == x didn't return true", - x == x); - assertTrue("x.equals(x) didn't return true", - x.equals(x)); - - // test symmetry - EthernetAddress y = - new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertFalse("x == y didn't return false", - x == y); - assertTrue("y.equals(x) didn't return true", - y.equals(x)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - - // now we'll test transitivity - EthernetAddress z = - new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertFalse("x == y didn't return false", - x == y); - assertFalse("x == y didn't return false", - y == z); - assertFalse("x == y didn't return false", - x == z); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("y.equals(z) didn't return true", - y.equals(z)); - assertTrue("x.equals(z) didn't return true", - x.equals(z)); - - // test consistancy (this test is just calling equals multiple times) - assertFalse("x == y didn't return false", - x == y); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - } - - /** - * Test of toByteArray method, of class org.safehaus.uuid.EthernetAddress. - */ - public void testToByteArray() - { - // we'll test making a couple EthernetAddresses and then check that the - // toByteArray returns the same value in byte form as used to create it - - // first we'll test the null EthernetAddress - EthernetAddress ethernet_address = new EthernetAddress(0L); - assertEquals("Expected length of returned array wrong", - ETHERNET_ADDRESS_ARRAY_LENGTH, - ethernet_address.toByteArray().length); - assertEthernetAddressArraysAreEqual( - NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address.toByteArray(), 0); - - // now test a non-null EthernetAddress - ethernet_address = new EthernetAddress(VALID_ETHERNET_ADDRESS_LONG); - assertEquals("Expected length of returned array wrong", - ETHERNET_ADDRESS_ARRAY_LENGTH, - ethernet_address.toByteArray().length); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address.toByteArray(), 0); - - // let's make sure that changing the returned array doesn't mess with - // the wrapped EthernetAddress's internals - byte[] ethernet_address_byte_array = ethernet_address.toByteArray(); - // we'll just stir it up a bit and then check that the original - // EthernetAddress was not changed in the process. - // The easiest stir is to sort it ;) - Arrays.sort(ethernet_address_byte_array); - assertEthernetAddressArraysAreNotEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address_byte_array, 0); - assertEthernetAddressArraysAreNotEqual( - ethernet_address.toByteArray(), 0, - ethernet_address_byte_array, 0); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - ethernet_address.toByteArray(), 0); - } - - /** - * Test of toByteArray(byte[]) method, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testToByteArrayDest() - { - // constant for use in this test - final int EXTRA_DATA_LENGTH = 9; - - // lets test some error cases - // first, passing null - try - { - EthernetAddress ethernet_address = new EthernetAddress(0L); - ethernet_address.toByteArray((byte[])null); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - EthernetAddress ethernet_address = new EthernetAddress(0L); - byte[] ethernet_address_byte_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]; - ethernet_address.toByteArray(ethernet_address_byte_array); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // we'll test making a couple EthernetAddresses and then check that - // toByteArray returns the same value in byte form as used to create it - - // here we'll test the null EthernetAddress - EthernetAddress ethernet_address = new EthernetAddress(0L); - byte[] test_array = new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array); - assertEthernetAddressArraysAreEqual( - NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - - // now test a non-null EthernetAddress - ethernet_address = - new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - - // now test a null EthernetAddress case with extra data in the array - ethernet_address = new EthernetAddress(0L); - test_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array); - assertEthernetAddressArraysAreEqual( - NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); - } - - // now test a good EthernetAddress case with extra data in the array - ethernet_address = - new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); - test_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); - } - } - - /** - * Test of toByteArray(byte[], int) method, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testToByteArrayDestOffset() - { - // constant value for use in this test - final int EXTRA_DATA_LENGTH = 9; - - // lets test some error cases - // first, passing null and 0 - try - { - EthernetAddress ethernet_address = new EthernetAddress(0L); - ethernet_address.toByteArray((byte[])null, 0); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - EthernetAddress ethernet_address = new EthernetAddress(0L); - byte[] ethernet_address_byte_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]; - ethernet_address.toByteArray(ethernet_address_byte_array, 0); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is negative - try - { - EthernetAddress ethernet_address = new EthernetAddress(0L); - byte[] ethernet_address_byte_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; - ethernet_address.toByteArray(ethernet_address_byte_array, -1); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is too big - try - { - EthernetAddress ethernet_address = new EthernetAddress(0L); - byte[] ethernet_address_byte_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; - ethernet_address.toByteArray( - ethernet_address_byte_array, ETHERNET_ADDRESS_ARRAY_LENGTH); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is in the array, - // but without enough bytes to read ETHERNET_ADDRESS_ARRAY_LENGTH - try - { - EthernetAddress ethernet_address = new EthernetAddress(0L); - byte[] ethernet_address_byte_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; - ethernet_address.toByteArray(ethernet_address_byte_array, 1); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // we'll test making a couple EthernetAddresss and then check - // that toByteArray - // returns the same value in byte form as used to create it - - // here we'll test the null EthernetAddress at offset 0 - EthernetAddress ethernet_address = new EthernetAddress(0L); - byte[] test_array = new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array, 0); - assertEthernetAddressArraysAreEqual( - NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - - // now test a non-null EthernetAddress - ethernet_address = - new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - - // now test a null EthernetAddress case with extra data in the array - ethernet_address = new EthernetAddress(0L); - test_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array, 0); - assertEthernetAddressArraysAreEqual( - NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); - } - - // now test a null EthernetAddress case with extra data in the array - ethernet_address = new EthernetAddress(0L); - test_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array, EXTRA_DATA_LENGTH/2); - assertEthernetAddressArraysAreEqual( - NULL_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - test_array, EXTRA_DATA_LENGTH/2); - for (int i = 0; i < EXTRA_DATA_LENGTH/2; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i]); - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH + - EXTRA_DATA_LENGTH/2]); - } - - // now test a good EthernetAddress case with extra data in the array - ethernet_address = - new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); - test_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array, 0); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, test_array, 0); - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH]); - } - - // now test a good EthernetAddress case with extra data in the array - ethernet_address = - new EthernetAddress(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); - test_array = - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - ethernet_address.toByteArray(test_array, EXTRA_DATA_LENGTH/2); - assertEthernetAddressArraysAreEqual( - VALID_ETHERNET_ADDRESS_BYTE_ARRAY, 0, - test_array, EXTRA_DATA_LENGTH/2); - for (int i = 0; i < EXTRA_DATA_LENGTH/2; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i]); - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + ETHERNET_ADDRESS_ARRAY_LENGTH + - EXTRA_DATA_LENGTH/2]); - } - } - - /** - * Test of toLong method, of class org.safehaus.uuid.EthernetAddress. - */ - public void testToLong() - { - // test making a couple EthernetAddresss and then check that the toLong - // gives back the same value in long form that was used to create it - - // test the null EthernetAddress - EthernetAddress ethernet_address = new EthernetAddress(0L); - assertEquals("null EthernetAddress long and toLong did not match", - NULL_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - - // test a non-null EthernetAddress - ethernet_address = - new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertEquals("EthernetAddress long and toLong results did not match", - VALID_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - } - - /** - * Test of toString method, of class org.safehaus.uuid.EthernetAddress. - */ - public void testToString() - { - // test making a few EthernetAddresss and check that the toString - // gives back the same value in string form that was used to create it - - // test the null EthernetAddress - EthernetAddress ethernet_address = new EthernetAddress(0L); - assertEquals("null EthernetAddress string and toString did not match", - NULL_ETHERNET_ADDRESS_STRING.toLowerCase(), - ethernet_address.toString().toLowerCase()); - - // test a non-null EthernetAddress - ethernet_address = - new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertEquals( - "EthernetAddress string and toString results did not match", - MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING.toLowerCase(), - ethernet_address.toString().toLowerCase()); - - // EthernetAddress implementation returns strings all lowercase. - // Although relying on this behavior in code is not recommended, - // here is a unit test which will break if this assumption - // becomes bad. This will act as an early warning to anyone - // who relies on this particular behavior. - ethernet_address = - new EthernetAddress(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertFalse("mixed case EthernetAddress string and toString " + - "matched (expected toString to be all lower case)", - MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING.equals( - ethernet_address.toString())); - assertEquals("mixed case string toLowerCase and " + - "toString results did not match (expected toString to " + - "be all lower case)", - MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING.toLowerCase(), - ethernet_address.toString()); - } - - /** - * Test of valueOf(byte[]) method, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testValueOfByteArray() - { - // lets test some error cases - // first, passing null - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf((byte[])null); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf( - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too big - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf( - new byte[ETHERNET_ADDRESS_ARRAY_LENGTH + 1]); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test that creating a EthernetAddress from an zero'd array - // gives us a null EthernetAddress (definition of null EthernetAddress) - EthernetAddress ethernet_address = - EthernetAddress.valueOf(new byte[ETHERNET_ADDRESS_ARRAY_LENGTH]); - assertEquals( - "EthernetAddress.valueOf did not create expected EthernetAddress", - NULL_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - - // let's test creating an array from a good byte array - ethernet_address = - EthernetAddress.valueOf(VALID_ETHERNET_ADDRESS_BYTE_ARRAY); - assertEquals( - "EthernetAddress.valueOf did not create expected EthernetAddress", - VALID_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - } - - /** - * Test of valueOf(int[]) method, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testValueOfIntArray() - { - // lets test some error cases - // first, passing null - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf((int[])null); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf( - new int[ETHERNET_ADDRESS_ARRAY_LENGTH - 1]); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too big - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf( - new int[ETHERNET_ADDRESS_ARRAY_LENGTH + 1]); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // let's test that creating a EthernetAddress from an zero'd array - // gives a null EthernetAddress (definition of a null EthernetAddress) - EthernetAddress ethernet_address = - EthernetAddress.valueOf(new int[ETHERNET_ADDRESS_ARRAY_LENGTH]); - assertEquals( - "EthernetAddress.valueOf did not create expected EthernetAddress", - NULL_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - - // let's test creating an array from a good int array - ethernet_address = - EthernetAddress.valueOf(VALID_ETHERNET_ADDRESS_INT_ARRAY); - assertEquals( - "EthernetAddress.valueOf did not create expected EthernetAddress", - VALID_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - } - - /** - * Test of valueOf(long) method, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testValueOfLong() - { - // let's test that creating a EthernetAddress from an zero long - // gives a null EthernetAddress (definition of a null EthernetAddress) - EthernetAddress ethernet_address = - EthernetAddress.valueOf(0x0000000000000000L); - assertEquals( - "EthernetAddress.valueOf did not create expected EthernetAddress", - NULL_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - - // let's test creating an array from a good long - ethernet_address = - EthernetAddress.valueOf(VALID_ETHERNET_ADDRESS_LONG); - assertEquals( - "EthernetAddress.valueOf did not create expected EthernetAddress", - VALID_ETHERNET_ADDRESS_LONG, - ethernet_address.toLong()); - } - - /** - * Test of valueOf(String) method, - * of class org.safehaus.uuid.EthernetAddress. - */ - public void testValueOfString() - { - // test a null string case - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf((String)null); - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test some failure cases for the string constructor - badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_1); - badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_2); - badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_3); - badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_4); - badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_5); - badStringValueOfHelper(IMPROPER_NUM_COLONS_ETHERNET_ADDRESS_STRING_6); - badStringValueOfHelper(NON_HEX_ETHERNET_ADDRESS_STRING); - badStringValueOfHelper(RANDOM_PROPER_LENGTH_STRING); - - // some valid strings for the various dropped digit cases - goodStringValueOfHelper(FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FIRST_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FIRST_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - FIRST_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(SECOND_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(SECOND_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - SECOND_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(THIRD_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(THIRD_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - THIRD_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FOURTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FOURTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - FOURTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FIFTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(FIFTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - FIFTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(SIXTH_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(SIXTH_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - SIXTH_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING, - MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(MIXED_GROUP_ONE_NUM_ETHERNET_ADDRESS_STRING, - MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(MIXED_GROUP_NO_NUM_ETHERNET_ADDRESS_STRING, - MIXED_GROUP_ALL_NUM_ETHERNET_ADDRESS_STRING); - - // test the other good cases - goodStringValueOfHelper(NULL_ETHERNET_ADDRESS_STRING, - NULL_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING, - UPPER_CASE_VALID_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING, - LOWER_CASE_VALID_ETHERNET_ADDRESS_STRING); - goodStringValueOfHelper(MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING, - MIXED_CASE_VALID_ETHERNET_ADDRESS_STRING); - } - - /************************************************************************** - * Begin private helper functions for use in tests - *************************************************************************/ - private void badStringEthernetAddressConstructorHelper( - String ethernetAddressString) - { - try - { - EthernetAddress ethernet_address = - new EthernetAddress(ethernetAddressString); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - } - - private void goodStringEthernetAddressConstructorHelper( - String ethernetAddressString, - String expectedEthernetAddressString) - { - EthernetAddress ethernet_address = null; - try - { - ethernet_address = new EthernetAddress(ethernetAddressString); - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - assertEquals("EthernetAddresses were not equal", - expectedEthernetAddressString.toLowerCase(), - ethernet_address.toString().toLowerCase()); - } - - private void badStringValueOfHelper(String ethernetAddressString) - { - try - { - EthernetAddress ethernet_address = - EthernetAddress.valueOf(ethernetAddressString); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - } - - private void goodStringValueOfHelper(String ethernetAddressString, - String expectedEthernetAddressString) - { - EthernetAddress ethernet_address = null; - try - { - ethernet_address = EthernetAddress.valueOf(ethernetAddressString); - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - assertEquals("EthernetAddresses were not equal", - expectedEthernetAddressString.toLowerCase(), - ethernet_address.toString().toLowerCase()); - } - - private void assertEthernetAddressesMatchHelper(EthernetAddress expected, - EthernetAddress actual) - { - assertEquals("EthernetAddresses in long form did not match", - expected.toLong(), - actual.toLong()); - assertEquals("EthernetAddress equals did not match", - expected, - actual); - } - - private void assertEthernetAddressEqualOrderHelper( - EthernetAddress ethernetAddress1, - EthernetAddress ethernetAddress2) - { - assertTrue(ethernetAddress1 + " did not test as equal to " + - ethernetAddress2, - 0 == ethernetAddress1.compareTo(ethernetAddress2)); - assertTrue(ethernetAddress2 + " did not test as equal to " + - ethernetAddress1, - 0 == ethernetAddress2.compareTo(ethernetAddress1)); - } - - private void assertEthernetAddressGreaterOrderHelper( - EthernetAddress ethernetAddress1, - EthernetAddress ethernetAddress2) - { - assertTrue(ethernetAddress1 + " did not test as larger then " + - ethernetAddress2, - 0 < ethernetAddress1.compareTo(ethernetAddress2)); - assertTrue(ethernetAddress2 + " did not test as smaller then " + - ethernetAddress1, - 0 > ethernetAddress2.compareTo(ethernetAddress1)); - } - - private void assertEthernetAddressArraysAreEqual(byte[] array1, - int array1_start, - byte[] array2, - int array2_start) - { - assertTrue("Array1 start offset is invalid", - 0 <= array1_start); - assertTrue("Array2 start offset is invalid", - 0 <= array2_start); - assertTrue("Array1 is not long enough for the given start offset", - array1.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array1_start); - assertTrue("Array2 is not long enough for the given start offset", - array2.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array2_start); - for (int i = 0; i < ETHERNET_ADDRESS_ARRAY_LENGTH; i++) - { - assertEquals("Array1 and Array2 did not match", - array1[i + array1_start], - array2[i + array2_start]); - } - } - - private void assertEthernetAddressArraysAreNotEqual(byte[] array1, - int array1_start, - byte[] array2, - int array2_start) - { - assertTrue("Array1 start offset is invalid", - 0 <= array1_start); - assertTrue("Array2 start offset is invalid", - 0 <= array2_start); - assertTrue("Array1 is not long enough for the given start offset", - array1.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array1_start); - assertTrue("Array2 is not long enough for the given start offset", - array2.length >= ETHERNET_ADDRESS_ARRAY_LENGTH + array2_start); - for (int i = 0; i < ETHERNET_ADDRESS_ARRAY_LENGTH; i++) - { - // as soon as we find a non-matching byte, - // we know we're not equal, so return - if (array1[i + array1_start] != array2[i + array2_start]) - { - return; - } - } - fail("Array1 and Array2 matched"); - } - /************************************************************************** - * End private helper functions for use in tests - *************************************************************************/ -} diff -Nru jug-2.0.0/src/test/org/safehaus/uuid/test/TagURITest.java jug-3.1.5/src/test/org/safehaus/uuid/test/TagURITest.java --- jug-2.0.0/src/test/org/safehaus/uuid/test/TagURITest.java 2005-07-21 05:25:47.000000000 +0000 +++ jug-3.1.5/src/test/org/safehaus/uuid/test/TagURITest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,208 +0,0 @@ -/* JUG Java Uuid Generator - * TagURITest.java - * Created on October 8, 2003, 12:22 AM - * - * Copyright (c) 2003 Eric Bie - * - * 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 org.safehaus.uuid.test; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import java.util.Calendar; - -import org.safehaus.uuid.TagURI; - -/** - * JUnit Test class for the org.safehaus.uuid.TagURI class. - * - * @author Eric Bie - */ -public class TagURITest extends TestCase -{ - private static final String[] AUTHORITIES = - { - "www.w3c.org", - "www.google.com", - "www.fi", - "tatu.saloranta@iki.fi" - }; - - private static final String[] IDS = - { - "1234", - "/home/billg/public_html/index.html", - "6ba7b810-9dad-11d1-80b4-00c04fd430c8", - "foobar" - }; - - public TagURITest(java.lang.String testName) - { - super(testName); - } - - public static Test suite() - { - TestSuite suite = new TestSuite(TagURITest.class); - return suite; - } - - /** - * Test of toString method, of class org.safehaus.uuid.TagURI. - */ - public void testToString() - { - final Calendar CALENDAR = Calendar.getInstance(); - - // we'll test that a few expected constructed TagURI's create the - // expected strings - - // first, some tests with a null calendar - for (int i = 0; i < 4; ++i) - { - for (int j = 0; j < 4; ++j) - { - TagURI tag_uri = new TagURI(AUTHORITIES[i], IDS[j], null); - String expected = "tag:" + AUTHORITIES[i] + ":" + IDS[j]; - assertEquals( - "Expected string did not match generated toString()", - expected, - tag_uri.toString()); - } - } - - // now some cases with date - for (int i = 0; i < 4; ++i) - { - CALENDAR.set(Calendar.MONTH, Calendar.JULY); - CALENDAR.set(Calendar.DAY_OF_MONTH, 4); - - for (int j = 0; j < 4; ++j) - { - TagURI tag_uri = new TagURI(AUTHORITIES[i], IDS[j], CALENDAR); - String expected = "tag:" + AUTHORITIES[i] + "," + - CALENDAR.get(Calendar.YEAR) + "-" + - (CALENDAR.get(Calendar.MONTH) + 1) + "-" + - CALENDAR.get(Calendar.DAY_OF_MONTH) + ":" + IDS[j]; - assertEquals( - "Expected string did not match generated toString()", - expected, - tag_uri.toString()); - } - } - - // now some cases with date such that day is left out - // (first of the month) - for (int i = 0; i < 4; ++i) - { - CALENDAR.set(Calendar.MONTH, Calendar.APRIL); - CALENDAR.set(Calendar.DAY_OF_MONTH, 1); - - for (int j = 0; j < 4; ++j) - { - TagURI tag_uri = new TagURI(AUTHORITIES[i], IDS[j], CALENDAR); - String expected = "tag:" + AUTHORITIES[i] + "," + - CALENDAR.get(Calendar.YEAR) + "-" + - (CALENDAR.get(Calendar.MONTH) + 1) + ":" + IDS[j]; - assertEquals( - "Expected string did not match generated toString()", - expected, - tag_uri.toString()); - } - } - - // now some cases with date such that day and month are left out - // (jan-1) - for (int i = 0; i < 4; ++i) - { - CALENDAR.set(Calendar.MONTH, Calendar.JANUARY); - CALENDAR.set(Calendar.DAY_OF_MONTH, 1); - - for (int j = 0; j < 4; ++j) - { - TagURI tag_uri = new TagURI(AUTHORITIES[i], IDS[j], CALENDAR); - String expected = "tag:" + AUTHORITIES[i] + "," + - CALENDAR.get(Calendar.YEAR) + ":" + IDS[j]; - assertEquals( - "Expected string did not match generated toString()", - expected, - tag_uri.toString()); - } - } - } - - /** - * Test of equals method, of class org.safehaus.uuid.TagURI. - */ - public void testEquals() - { - // test passing null to equals returns false - // (as specified in the JDK docs for Object) - TagURI x = new TagURI(AUTHORITIES[1], IDS[2], null); - assertFalse("equals(null) didn't return false", - x.equals((Object)null)); - - // test that passing an object which is not a TagURI returns false - assertFalse("x.equals(non_TagURI_object) didn't return false", - x.equals(new Object())); - - // test a case where two TagURIs are definitly not equal - TagURI w = new TagURI(AUTHORITIES[2], IDS[0], Calendar.getInstance()); - assertFalse("x == w didn't return false", - x == w); - assertFalse("x.equals(w) didn't return false", - x.equals(w)); - - // test refelexivity - assertTrue("x == x didn't return true", - x == x); - assertTrue("x.equals(x) didn't return true", - x.equals(x)); - - // test symmetry - TagURI y = new TagURI(AUTHORITIES[1], IDS[2], null); - assertFalse("x == y didn't return false", - x == y); - assertTrue("y.equals(x) didn't return true", - y.equals(x)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - - // now we'll test transitivity - TagURI z = new TagURI(AUTHORITIES[1], IDS[2], null); - assertFalse("x == y didn't return false", - x == y); - assertFalse("x == y didn't return false", - y == z); - assertFalse("x == y didn't return false", - x == z); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("y.equals(z) didn't return true", - y.equals(z)); - assertTrue("x.equals(z) didn't return true", - x.equals(z)); - - // test consistancy (this test is just calling equals multiple times) - assertFalse("x == y didn't return false", - x == y); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - } -} diff -Nru jug-2.0.0/src/test/org/safehaus/uuid/test/UUIDGeneratorTest.java jug-3.1.5/src/test/org/safehaus/uuid/test/UUIDGeneratorTest.java --- jug-2.0.0/src/test/org/safehaus/uuid/test/UUIDGeneratorTest.java 2005-07-21 05:25:47.000000000 +0000 +++ jug-3.1.5/src/test/org/safehaus/uuid/test/UUIDGeneratorTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,1071 +0,0 @@ -/* JUG Java Uuid Generator - * UUIDGeneratorTest.java - * Created on July 16, 2003, 11:17 PM - * - * Copyright (c) 2003 Eric Bie - * - * 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 org.safehaus.uuid.test; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.textui.TestRunner; - -import java.security.MessageDigest; -import java.security.SecureRandom; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.Calendar; -import java.util.HashSet; -import java.util.Random; - -import org.safehaus.uuid.EthernetAddress; -import org.safehaus.uuid.TagURI; -import org.safehaus.uuid.UUID; -import org.safehaus.uuid.UUIDGenerator; - -/** - * JUnit Test class for the org.safehaus.uuid.UUIDGenerator class. - * - * @author Eric Bie - */ -public class UUIDGeneratorTest extends TestCase -{ - // size of the arrays to create for tests using arrays of values - private static final int SIZE_OF_TEST_ARRAY = 10000; - - public UUIDGeneratorTest(java.lang.String testName) - { - super(testName); - } - - public static Test suite() - { - TestSuite suite = new TestSuite(UUIDGeneratorTest.class); - return suite; - } - - public static void main(String[] args) - { - TestRunner.run(suite()); - } - - /** - * Test of getInstance method, of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGetInstance() - { - // really, there isn't a lot to test here - // we'll make sure that getInstance returns the same - // reference when called twice since it is supposed to - // be a singleton class factory - UUIDGenerator uuid_gen1 = UUIDGenerator.getInstance(); - UUIDGenerator uuid_gen2 = UUIDGenerator.getInstance(); - UUIDGenerator uuid_gen3 = UUIDGenerator.getInstance(); - - assertTrue("uuid_gen1 == uuid_gen2 was not true", - uuid_gen1 == uuid_gen2); - assertTrue("uuid_gen2 == uuid_gen3 was not true", - uuid_gen2 == uuid_gen3); - assertTrue("uuid_gen1 == uuid_gen3 was not true", - uuid_gen1 == uuid_gen3); - } - - /** - * Test of getDummyAddress method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGetDummyAddress() - { - // this test will attempt to check for reasonable behavior of the - // getDummyAddress method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // for the random UUID generator, we will generate a bunch of - // dummy ethernet addresses - // NOTE: although creating a bunch of dummy ethernet addresses - // is not the normal mode of operation, we'return testing for - // generally good behavior, so we'll create a bunch to make sure the - // general patterns are observed - EthernetAddress ethernet_address_array[] = - new EthernetAddress[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < ethernet_address_array.length; i++) - { - ethernet_address_array[i] = uuid_gen.getDummyAddress(); - } - - EthernetAddress null_ethernet_address = new EthernetAddress(0L); - for (int i = 0; i < ethernet_address_array.length; i++) - { - byte[] ethernet_address = ethernet_address_array[i].asByteArray(); - // check that none of the EthernetAddresses are null - assertFalse("dummy EthernetAddress was null", - Arrays.equals(null_ethernet_address.asByteArray(), - ethernet_address)); - - // check that the "broadcast" bit is set in the created address - /* 08-Feb-2004, TSa: Fixed as per fix to actual code; apparently - * broadcast bit is LSB, not MSB. - */ - assertEquals("dummy EthernetAddress was not broadcast", - 0x01, - (ethernet_address[0] & 0x01)); - } - } - - /** - * Test of getRandomNumberGenerator method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGetRandomNumberGenerator() - { - // really, there isn't a lot to test here - // we'll make sure that getRandomNumberGenerator returns the same - // reference when called more then once from more then one instance - // since it is supposed to be a shared generator - UUIDGenerator uuid_gen1 = UUIDGenerator.getInstance(); - UUIDGenerator uuid_gen2 = UUIDGenerator.getInstance(); - UUIDGenerator uuid_gen3 = UUIDGenerator.getInstance(); - - assertTrue("uuid_gen1 == uuid_gen2 was not true", - uuid_gen1 == uuid_gen2); - assertTrue("uuid_gen2 == uuid_gen3 was not true", - uuid_gen2 == uuid_gen3); - assertTrue("uuid_gen1 == uuid_gen3 was not true", - uuid_gen1 == uuid_gen3); - - Random secure_rand1 = uuid_gen1.getRandomNumberGenerator(); - Random secure_rand2 = uuid_gen1.getRandomNumberGenerator(); - Random secure_rand3 = uuid_gen2.getRandomNumberGenerator(); - Random secure_rand4 = uuid_gen2.getRandomNumberGenerator(); - Random secure_rand5 = uuid_gen3.getRandomNumberGenerator(); - Random secure_rand6 = uuid_gen3.getRandomNumberGenerator(); - - assertTrue("secure_rand1 == secure_rand2 was not true", - secure_rand1 == secure_rand2); - assertTrue("secure_rand2 == secure_rand3 was not true", - secure_rand2 == secure_rand3); - assertTrue("secure_rand3 == secure_rand4 was not true", - secure_rand3 == secure_rand4); - assertTrue("secure_rand4 == secure_rand5 was not true", - secure_rand4 == secure_rand5); - assertTrue("secure_rand5 == secure_rand6 was not true", - secure_rand5 == secure_rand6); - assertTrue("secure_rand6 == secure_rand1 was not true", - secure_rand6 == secure_rand1); - } - - /** - * Test of getHashAlgorithm method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGetHashAlgorithm() - { - // really, there isn't a lot to test here - // we'll make sure that getHashAlgorithm returns the same - // reference when called more then once from more then one instance - // since it is supposed to be a shared MessageDigest - UUIDGenerator uuid_gen1 = UUIDGenerator.getInstance(); - UUIDGenerator uuid_gen2 = UUIDGenerator.getInstance(); - UUIDGenerator uuid_gen3 = UUIDGenerator.getInstance(); - - assertTrue("uuid_gen1 == uuid_gen2 was not true", - uuid_gen1 == uuid_gen2); - assertTrue("uuid_gen2 == uuid_gen3 was not true", - uuid_gen2 == uuid_gen3); - assertTrue("uuid_gen1 == uuid_gen3 was not true", - uuid_gen1 == uuid_gen3); - - MessageDigest message_digest1 = uuid_gen1.getHashAlgorithm(); - MessageDigest message_digest2 = uuid_gen1.getHashAlgorithm(); - MessageDigest message_digest3 = uuid_gen2.getHashAlgorithm(); - MessageDigest message_digest4 = uuid_gen2.getHashAlgorithm(); - MessageDigest message_digest5 = uuid_gen3.getHashAlgorithm(); - MessageDigest message_digest6 = uuid_gen3.getHashAlgorithm(); - - assertTrue("message_digest1 == message_digest2 was not true", - message_digest1 == message_digest2); - assertTrue("message_digest2 == message_digest3 was not true", - message_digest2 == message_digest3); - assertTrue("message_digest3 == message_digest4 was not true", - message_digest3 == message_digest4); - assertTrue("message_digest4 == message_digest5 was not true", - message_digest4 == message_digest5); - assertTrue("message_digest5 == message_digest6 was not true", - message_digest5 == message_digest6); - assertTrue("message_digest6 == message_digest1 was not true", - message_digest6 == message_digest1); - } - - /** - * Test of generateRandomBasedUUID method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateRandomBasedUUID() - { - // this test will attempt to check for reasonable behavior of the - // generateRandomBasedUUID method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // for the random UUID generator, we will generate a bunch of - // random UUIDs - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = uuid_gen.generateRandomBasedUUID(); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version (type-4) - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_RANDOM_BASED); - - // check that all uuids were unique - // NOTE: technically, this test 'could' fail, but statistically - // speaking it should be extremely unlikely unless the implementation - // of (Secure)Random is bad - checkUUIDArrayForUniqueness(uuid_array); - } - - /** - * Test of generateRandomBasedUUID(Random) method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateRandomBasedUUIDWithRandom() - { - // this test will attempt to check for reasonable behavior of the - // generateRandomBasedUUID method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // first, check that a null passed in causes the appropriate exception - try - { - UUID uuid = uuid_gen.generateRandomBasedUUID((Random)null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - // for the random UUID generator, we will generate a bunch of - // random UUIDs using a (Secure)Random instance we generated - SecureRandom secure_random = new SecureRandom(); - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = uuid_gen.generateRandomBasedUUID(secure_random); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version (type-4) - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_RANDOM_BASED); - - // check that all uuids were unique - // NOTE: technically, this test 'could' fail, but statistically - // speaking it should be extremely unlikely unless the - // implementation of SecureRandom is bad - checkUUIDArrayForUniqueness(uuid_array); - } - - /** - * Test of generateTimeBasedUUID() method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateTimeBasedUUID() - { - // this test will attempt to check for reasonable behavior of the - // generateTimeBasedUUID method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // first check that given a number of calls to generateTimeBasedUUID, - // all returned UUIDs order after the last returned UUID - // we'll check this by generating the UUIDs into one array and sorting - // then in another and checking the order of the two match - // change the number in the array statement if you want more or less - // UUIDs to be generated and tested - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // before we generate all the uuids, lets get the start time - long start_time = System.currentTimeMillis(); - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = uuid_gen.generateTimeBasedUUID(); - } - - // now capture the end time - long end_time = System.currentTimeMillis(); - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version (type-1) - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_TIME_BASED); - - // check that all the uuids were generated with correct order - checkUUIDArrayForCorrectOrdering(uuid_array); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // check that all uuids have timestamps between the start and end time - checkUUIDArrayForCorrectCreationTime(uuid_array, start_time, end_time); - } - - /** - * Test of generateTimeBasedUUID(EthernetAddress) method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateTimeBasedUUIDWithEthernetAddress() - { - // this test will attempt to check for reasonable behavior of the - // generateTimeBasedUUID(EthernetAddress) method - EthernetAddress ethernet_address = - new EthernetAddress("87:F5:93:06:D3:0C"); - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // first, check that a null passed in causes the appropriate exception - try - { - UUID uuid = uuid_gen.generateTimeBasedUUID((EthernetAddress)null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - // check that given a number of calls to generateTimeBasedUUID, - // all returned UUIDs order after the last returned UUID - // we'll check this by generating the UUIDs into one array and sorting - // then in another and checking the order of the two match - // change the number in the array statement if you want more or less - // UUIDs to be generated and tested - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // before we generate all the uuids, lets get the start time - long start_time = System.currentTimeMillis(); - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = uuid_gen.generateTimeBasedUUID(ethernet_address); - } - - // now capture the end time - long end_time = System.currentTimeMillis(); - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version (type-1) - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_TIME_BASED); - - // check that all the uuids were generated with correct order - checkUUIDArrayForCorrectOrdering(uuid_array); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // check that all uuids have timestamps between the start and end time - checkUUIDArrayForCorrectCreationTime(uuid_array, start_time, end_time); - - // check that all UUIDs have the correct ethernet address in the UUID - checkUUIDArrayForCorrectEthernetAddress(uuid_array, ethernet_address); - } - - /** - * Test of generateNameBasedUUID(UUID, String) - * method, of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateNameBasedUUIDNameSpaceAndName() - { - final UUID NAMESPACE_UUID = new UUID(UUID.NAMESPACE_URL); - - // this test will attempt to check for reasonable behavior of the - // generateNameBasedUUID method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // first, check that a null passed in causes the appropriate exception - try - { - UUID uuid = - uuid_gen.generateNameBasedUUID(NAMESPACE_UUID, (String)null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, "test name" + i); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = - uuid_gen.generateNameBasedUUID(null, "test name" + i); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // now, lets make sure generating two sets of name based uuid with the - // same args always gives the same result - uuid_array = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, "test name" + i); - } - - UUID uuid_array2[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array2.length; i++) - { - uuid_array2[i] = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, "test name" + i); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - checkUUIDArrayForNonNullUUIDs(uuid_array2); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array2, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - checkUUIDArrayForUniqueness(uuid_array2); - - // check that both arrays are equal to one another - assertTrue("expected both arrays to be equal, they were not!", - Arrays.equals(uuid_array, uuid_array2)); - } - - /** - * Test of generateNameBasedUUID(UUID, String, MessageDigest) - * method, of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateNameBasedUUIDNameSpaceNameAndMessageDigest() - { - final UUID NAMESPACE_UUID = new UUID(UUID.NAMESPACE_URL); - MessageDigest MESSAGE_DIGEST = null; - try - { - MESSAGE_DIGEST = MessageDigest.getInstance("MD5"); - } - catch (Exception ex) - { - fail("exception caught getting test digest : " + ex); - } - - // this test will attempt to check for reasonable behavior of the - // generateNameBasedUUID method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // first, check that a null passed in causes the appropriate exception - try - { - UUID uuid = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, (String)null, MESSAGE_DIGEST); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - try - { - UUID uuid = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, "test name", (MessageDigest)null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - try - { - UUID uuid = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, (String)null, (MessageDigest)null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, "test name" + i, MESSAGE_DIGEST); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = - uuid_gen.generateNameBasedUUID( - null, "test name" + i, MESSAGE_DIGEST); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // now, lets make sure generating two sets of name based uuid with the - // same args always gives the same result - uuid_array = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - uuid_array[i] = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, "test name" + i, MESSAGE_DIGEST); - } - - UUID uuid_array2[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array2.length; i++) - { - uuid_array2[i] = - uuid_gen.generateNameBasedUUID( - NAMESPACE_UUID, "test name" + i, MESSAGE_DIGEST); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - checkUUIDArrayForNonNullUUIDs(uuid_array2); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array2, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - checkUUIDArrayForUniqueness(uuid_array2); - - // check that both arrays are equal to one another - assertTrue("expected both arrays to be equal, they were not!", - Arrays.equals(uuid_array, uuid_array2)); - } - - /** - * Test of generateTagURIBasedUUID(TagURI) method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateTagURIBasedUUID() - { - final String TEST_AUTHORITY = "www.safehaus.org"; - - // this test will attempt to check for reasonable behavior of the - // generateTagURIBasedUUID method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // first, check that a null passed in causes the appropriate exception - try - { - UUID uuid = uuid_gen.generateTagURIBasedUUID(null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - TagURI test_tag = - new TagURI(TEST_AUTHORITY, "test id" + i, - Calendar.getInstance()); - uuid_array[i] = - uuid_gen.generateTagURIBasedUUID(test_tag); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // now, lets make sure generating two sets of tag based uuid with the - // same args always gives the same result - uuid_array = new UUID[SIZE_OF_TEST_ARRAY]; - UUID uuid_array2[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - TagURI test_tag = - new TagURI(TEST_AUTHORITY, "test id" + i, - Calendar.getInstance()); - uuid_array[i] = - uuid_gen.generateTagURIBasedUUID(test_tag); - uuid_array2[i] = - uuid_gen.generateTagURIBasedUUID(test_tag); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - checkUUIDArrayForNonNullUUIDs(uuid_array2); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array2, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - checkUUIDArrayForUniqueness(uuid_array2); - - // check that both arrays are equal to one another - assertTrue("expected both arrays to be equal, they were not!", - Arrays.equals(uuid_array, uuid_array2)); - } - - /** - * Test of generateTagURIBasedUUID(TagURI, MessageDigest) method, - * of class org.safehaus.uuid.UUIDGenerator. - */ - public void testGenerateTagURIBasedUUIDWithMessageDigest() - { - final String TEST_AUTHORITY = "www.safehaus.org"; - MessageDigest MESSAGE_DIGEST = null; - try - { - MESSAGE_DIGEST = MessageDigest.getInstance("MD5"); - } - catch (Exception ex) - { - fail("exception caught getting test digest : " + ex); - } - - // this test will attempt to check for reasonable behavior of the - // generateTagURIBasedUUID method - - // we need a instance to use - UUIDGenerator uuid_gen = UUIDGenerator.getInstance(); - - // first, check that a null passed in causes the appropriate exception - try - { - UUID uuid = uuid_gen.generateTagURIBasedUUID(null, MESSAGE_DIGEST); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - try - { - TagURI test_tag = - new TagURI(TEST_AUTHORITY, "test id", Calendar.getInstance()); - UUID uuid = uuid_gen.generateTagURIBasedUUID(test_tag, null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - try - { - UUID uuid = uuid_gen.generateTagURIBasedUUID(null, null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // expected exception caught, do nothing - } - catch (Exception ex) - { - fail("unexpected exception caught: " + ex); - } - - UUID uuid_array[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - TagURI test_tag = - new TagURI(TEST_AUTHORITY, "test id" + i, - Calendar.getInstance()); - uuid_array[i] = - uuid_gen.generateTagURIBasedUUID(test_tag, MESSAGE_DIGEST); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - - // now, lets make sure generating two sets of tag based uuid with the - // same args always gives the same result - uuid_array = new UUID[SIZE_OF_TEST_ARRAY]; - UUID uuid_array2[] = new UUID[SIZE_OF_TEST_ARRAY]; - - // now create the array of uuids - for (int i = 0; i < uuid_array.length; i++) - { - TagURI test_tag = - new TagURI(TEST_AUTHORITY, "test id" + i, - Calendar.getInstance()); - uuid_array[i] = - uuid_gen.generateTagURIBasedUUID(test_tag, MESSAGE_DIGEST); - uuid_array2[i] = - uuid_gen.generateTagURIBasedUUID(test_tag, MESSAGE_DIGEST); - } - - // check that none of the UUIDs are null - checkUUIDArrayForNonNullUUIDs(uuid_array); - checkUUIDArrayForNonNullUUIDs(uuid_array2); - - // check that all the uuids were correct variant and version - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array, UUID.TYPE_NAME_BASED); - checkUUIDArrayForCorrectVariantAndVersion( - uuid_array2, UUID.TYPE_NAME_BASED); - - // check that all uuids were unique - checkUUIDArrayForUniqueness(uuid_array); - checkUUIDArrayForUniqueness(uuid_array2); - - // check that both arrays are equal to one another - assertTrue("expected both arrays to be equal, they were not!", - Arrays.equals(uuid_array, uuid_array2)); - } - - /************************************************************************** - * Begin Private Helper Methods for use in tests - *************************************************************************/ - private class ReverseOrderUUIDComparator implements Comparator - { - // this Comparator class has a compare which orders reverse of the - // compareTo methond in UUID (so we can be sure our arrays below are - // 'not ordered in sorted order' before we sort them. - public int compare(Object o1, Object o2) - { - UUID uuid1 = (UUID)o1; - UUID uuid2 = (UUID)o2; - - return -uuid1.compareTo(uuid2); - } - - // we are only implementing equals because it's needed, super should do - public boolean equals(Object o) - { - return super.equals(o); - } - } - - private void checkUUIDArrayForCorrectOrdering(UUID[] uuidArray) - { - // now we'll clone the array and reverse it - UUID uuid_sorted_array[] = (UUID[])uuidArray.clone(); - assertEquals("Cloned array length did not match", - uuidArray.length, - uuid_sorted_array.length); - - ReverseOrderUUIDComparator rev_order_uuid_comp = - new ReverseOrderUUIDComparator(); - Arrays.sort(uuid_sorted_array, rev_order_uuid_comp); - - // let's check that the array is actually reversed - for (int i = 0; i < uuid_sorted_array.length; i++) - { - assertTrue( - "Reverse order check on uuid arrays failed on element " + i, - uuidArray[i].equals( - uuid_sorted_array[uuid_sorted_array.length - (1 + i)])); - } - - // now let's sort the reversed array and check that it - // sorted to the same order as the original - Arrays.sort(uuid_sorted_array); - for (int i = 0; i < uuid_sorted_array.length; i++) - { - assertTrue( - "Same order check on uuid arrays failed on element " + i, - uuidArray[i].equals(uuid_sorted_array[i])); - } - } - - private void checkUUIDArrayForUniqueness(UUID[] uuidArray) - { - // here we'll assert that all elements in the list are not equal to - // each other (aka, there should be no duplicates) we'll do this by - // inserting all elements into a HashSet and making sure none of them - //were already present (add will return false if it was already there) - HashSet hash_set = new HashSet(); - for (int i = 0; i < uuidArray.length; i++) - { - assertTrue("Uniqueness test failed on insert into HashSet", - hash_set.add(uuidArray[i])); - assertFalse("Paranoia Uniqueness test failed (second insert)", - hash_set.add(uuidArray[i])); - } - } - - private void checkUUIDArrayForCorrectVariantAndVersion(UUID[] uuidArray, - int expectedType) - { - // let's check that all the UUIDs are valid type-1 UUIDs with the - // correct variant according to the specification. - for (int i = 0; i < uuidArray.length; i++) - { - assertEquals("Expected version (type) did not match", - expectedType, - uuidArray[i].getType()); - - // now. let's double check the variant and type from the array - byte[] temp_uuid = uuidArray[i].toByteArray(); - - // extract type from the UUID and check for correct type - int type = (temp_uuid[UUID.INDEX_TYPE] & 0xFF) >> 4; - assertEquals("Expected type did not match", - expectedType, - type); - // extract variant from the UUID and check for correct variant - int variant = (temp_uuid[UUID.INDEX_VARIATION] & 0xFF) >> 6; - assertEquals("Expected variant did not match", - 2, - variant); - } - } - - private void checkUUIDArrayForCorrectCreationTime( - UUID[] uuidArray, long startTime, long endTime) - { - // we need to convert from 100-naonsecond units (as used in UUIDs) - // to millisecond units as used in UTC based time - final long MILLI_CONVERSION_FACTOR = 10000L; - // Since System.currentTimeMillis() returns time epoc time - // (from 1-Jan-1970), and UUIDs use time from the beginning of - // Gregorian calendar (15-Oct-1582) we have a offset for correction - final long GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET = - 122192928000000000L; - - assertTrue("start time was not before the end time", - startTime < endTime); - - // let's check that all uuids in the array have a timestamp which lands - // between the start and end time - for (int i = 0; i < uuidArray.length; i++) - { - byte[] temp_uuid = uuidArray[i].toByteArray(); - - // first we'll collect the UUID time stamp which is - // the number of 100-nanosecond intervals since - // 00:00:00.00 15 October 1582 - long uuid_time = 0L; - uuid_time |= ((temp_uuid[3] & 0xF0L) << 0); - uuid_time |= ((temp_uuid[2] & 0xFFL) << 8); - uuid_time |= ((temp_uuid[1] & 0xFFL) << 16); - uuid_time |= ((temp_uuid[0] & 0xFFL) << 24); - uuid_time |= ((temp_uuid[5] & 0xFFL) << 32); - uuid_time |= ((temp_uuid[4] & 0xFFL) << 40); - uuid_time |= ((temp_uuid[7] & 0xFFL) << 48); - uuid_time |= ((temp_uuid[6] & 0x0FL) << 56); - - // first we'll remove the gregorian offset - uuid_time -= GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET; - - // and convert to milliseconds as the system clock is in millis - uuid_time /= MILLI_CONVERSION_FACTOR; - - // now check that the times are correct - assertTrue( - "Start time: " + startTime + - " was not before UUID timestamp: " + uuid_time, - startTime <= uuid_time); - assertTrue( - "UUID timestamp: " + uuid_time + - " was not before the start time: " + endTime, - uuid_time <= endTime); - } - } - - private void checkUUIDArrayForCorrectEthernetAddress(UUID[] uuidArray, - EthernetAddress ethernetAddress) - { - for (int i = 0; i < uuidArray.length; i++) - { - byte[] uuid_ethernet_address = new byte[6]; - System.arraycopy( - uuidArray[i].toByteArray(), 10, uuid_ethernet_address, 0, 6); - byte[] ethernet_address = ethernetAddress.asByteArray(); - - assertTrue( - "UUID ethernet address did not equal passed ethernetAddress", - Arrays.equals(ethernet_address, uuid_ethernet_address)); - } - } - - private void checkUUIDArrayForNonNullUUIDs(UUID[] uuidArray) - { - for (int i = 0; i < uuidArray.length; i++) - { - assertFalse("UUID was null", - uuidArray[i].isNullUUID()); - } - } - /************************************************************************** - * End Private Helper Methods for use in tests - *************************************************************************/ -} diff -Nru jug-2.0.0/src/test/org/safehaus/uuid/test/UUIDTest.java jug-3.1.5/src/test/org/safehaus/uuid/test/UUIDTest.java --- jug-2.0.0/src/test/org/safehaus/uuid/test/UUIDTest.java 2005-07-21 05:25:47.000000000 +0000 +++ jug-3.1.5/src/test/org/safehaus/uuid/test/UUIDTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,1655 +0,0 @@ -/* JUG Java Uuid Generator - * UUIDTest.java - * Created on July 16, 2003, 11:17 PM - * - * Copyright (c) 2003 Eric Bie - * - * 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 org.safehaus.uuid.test; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.textui.TestRunner; - -import java.util.Arrays; - -import org.safehaus.uuid.UUID; - - -/** - * This class tests UUID for correct functionality. - * - * The UUIDTest class is in a different sub-package to make sure - * 'public' methods are correctly accessable. - * - * @author Eric Bie - */ -public class UUIDTest extends TestCase -{ - public UUIDTest(java.lang.String testName) - { - super(testName); - } - - public static Test suite() - { - TestSuite suite = new TestSuite(UUIDTest.class); - return suite; - } - - public static void main(String[] args) - { - TestRunner.run(suite()); - } - - /************************************************************************** - * Begin constructor tests - *************************************************************************/ - /** - * Test of UUID() constructor, of class org.safehaus.uuid.UUID. - */ - public void testDefaultUUIDConstructor() - { - // this test technically relies on the toString() and toByteArray() - // methods of the UUID class working properly. - // If it fails, that is fine... the test only needs to indicate - // proper working behavior or that it needs to be fixed. - UUID uuid = new UUID(); - assertEquals("Default constructor did not create expected null UUID", - NULL_UUID_STRING, - uuid.toString()); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - } - - /** - * Test of UUID(byte[]) constructor, of class org.safehaus.uuid.UUID. - */ - public void testByteArrayUUIDConstructor() - { - // passing null - try - { - UUID uuid = new UUID((byte[])null); - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // passing array that is too small - try - { - UUID uuid = new UUID(new byte[UUID_BYTE_ARRAY_LENGTH - 1]); - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test that creating a uuid from an zero'd array - // gives us a null UUID (definition of a null UUID) - UUID uuid = new UUID(new byte[UUID_BYTE_ARRAY_LENGTH]); - assertEquals("constructor did not create expected null UUID", - NULL_UUID_STRING, - uuid.toString()); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - - // test creating an array from a good byte array - uuid = new UUID(VALID_UUID_BYTE_ARRAY); - assertEquals("constructor did not create expected UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test creating an array from a good byte array with extra data on end - uuid = new UUID(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END); - assertEquals("constructor did not create expected UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - } - - /** - * Test of UUID(byte[], int) constructor, of class org.safehaus.uuid.UUID. - */ - public void testByteArrayFromOffsetUUIDConstructor() - { - // constant for use in this test - final int EXTRA_DATA_LENGTH = 9; - - // passing null and 0 - try - { - UUID uuid = new UUID((byte[])null, 0); - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // passing an array that is too small - try - { - UUID uuid = new UUID(new byte[UUID_BYTE_ARRAY_LENGTH - 1], 0); - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // passing an index that is negative - try - { - UUID uuid = new UUID(new byte[UUID_BYTE_ARRAY_LENGTH], -1); - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // passing an index that is too big - try - { - UUID uuid = - new UUID( - new byte[UUID_BYTE_ARRAY_LENGTH], UUID_BYTE_ARRAY_LENGTH); - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // passing an index that is in the array, - // but without enough bytes to read UUID_BYTE_ARRAY_LENGTH - try - { - UUID uuid = new UUID(new byte[UUID_BYTE_ARRAY_LENGTH], 1); - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test that creating a uuid from an zero'd array - // gives us a null UUID (definition of a null UUID) - UUID uuid = new UUID(new byte[UUID_BYTE_ARRAY_LENGTH], 0); - assertEquals("constructor did not create expected null UUID", - NULL_UUID_STRING, - uuid.toString()); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - - // test that creating a uuid from an zero'd array with extra stuff - // on the front gives us a null UUID (definition of a null UUID) - byte[] null_uuid_array = - new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(null_uuid_array, 0, EXTRA_DATA_LENGTH, (byte)'x'); - uuid = new UUID(null_uuid_array, EXTRA_DATA_LENGTH); - assertEquals("constructor did not create expected null UUID", - NULL_UUID_STRING, - uuid.toString()); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - - // test creating an array from a good byte array - uuid = new UUID(VALID_UUID_BYTE_ARRAY, 0); - assertEquals("constructor did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test creating an array from a good byte array with extra data on end - uuid = new UUID(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END, 0); - assertEquals("constructor did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test creating uuid from a byte array with extra junk on start - uuid = new UUID(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_START, 10); - assertEquals("constructor did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test creating an uuid from a byte array with extra junk on both ends - uuid = new UUID(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_BOTH, 10); - assertEquals("constructor did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - } - - /** - * Test of UUID(String) constructor, of class org.safehaus.uuid.UUID. - */ - public void testStringUUIDConstructor() - { - // test a null string case - try - { - UUID uuid = new UUID((String)null); - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test some failure cases for the string constructor - badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_1); - badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_2); - badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_3); - badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_4); - badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_5); - badStringUUIDConstructorHelper(IMPROPER_NUM_DASHES_UUID_STRING_6); - badStringUUIDConstructorHelper(NON_HEX_UUID_STRING); - badStringUUIDConstructorHelper(RANDOM_PROPER_LENGTH_STRING); - - // test some good cases - goodStringUUIDConstructorHelper(NULL_UUID_STRING); - goodStringUUIDConstructorHelper(UPPER_CASE_VALID_UUID_STRING); - goodStringUUIDConstructorHelper(LOWER_CASE_VALID_UUID_STRING); - goodStringUUIDConstructorHelper(MIXED_CASE_VALID_UUID_STRING); - } - /************************************************************************** - * End constructor tests - *************************************************************************/ - - /** - * Test of asByteArray method, of class org.safehaus.uuid.UUID. - */ - public void testAsByteArray() - { - // we'll test making a couple UUIDs and then check that the asByteArray - // gives back the same value in byte form that we used to create it - - // first we'll test the null uuid - UUID uuid = new UUID(); - assertEquals("Expected length of returned array wrong", - UUID_BYTE_ARRAY_LENGTH, - uuid.asByteArray().length); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.asByteArray())); - - // now test a non-null uuid - uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - assertEquals("Expected length of returned array wrong", - UUID_BYTE_ARRAY_LENGTH, - uuid.asByteArray().length); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, uuid.asByteArray())); - - // let's make sure that changing the returned array doesn't mess with - // the wrapped UUID's internals - uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - assertEquals("Expected length of returned array wrong", - UUID_BYTE_ARRAY_LENGTH, - uuid.asByteArray().length); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, uuid.asByteArray())); - - byte[] test_uuid_array = uuid.asByteArray(); - // now stir it up a bit and then check that the original UUID was - // not changed in the process. The easiest stir is to sort it ;) - Arrays.sort(test_uuid_array); - assertFalse("Expected array was equal other array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, test_uuid_array)); - assertFalse("Expected array was equal other array", - Arrays.equals(uuid.asByteArray(), test_uuid_array)); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, uuid.asByteArray())); - } - - /** - * Test of clone method, of class org.safehaus.uuid.UUID. - */ - public void testClone() - { - // as lifted from the JDK Object JavaDoc for clone: - // x.clone() Creates and returns a copy of x. - // The precise meaning of "copy" may depend on - // the class of the object. The general intent - // is that, for any object x, the expression: - // x.clone() != x - // will be true, and that the expression: - // x.clone().getClass() == x.getClass() - // will be true, but these are not absolute requirements. - // While it is typically the case that: - // x.clone().equals(x) - // will be true, this is not an absolute requirement. - // For UUID, this test will check that all the above ARE true - // in the case of UUID clone() because it is the desired behavior. - UUID x = new UUID(VALID_UUID_BYTE_ARRAY); - assertTrue("x.clone() != x did not return true", - x.clone() != x); - assertTrue("x.clone().getClass() == x.getClass() did not return true", - x.clone().getClass() == x.getClass()); - assertTrue("x.clone().equals(x) did not return true", - x.clone().equals(x)); - } - - /** - * Test of compareTo method, of class org.safehaus.uuid.UUID. - */ - public void testCompareTo() - { - // first, let's make sure calling compareTo with null - // throws the appropriate NullPointerException - try - { - // the 'null UUID' will be fine - NULL_UUID.compareTo(null); - fail("Expected exception not thrown"); - } - catch (NullPointerException ex) - { - // good, we caught the expected exception, so we passed - } - catch (Exception ex) - { - fail("Caught an unexpected exception: " + ex); - } - - // now, let's make sure giving compareTo a non-UUID class - // results in the appropriate ClassCastException - try - { - // the 'null UUID' will be fine - NULL_UUID.compareTo((new Integer(5))); - fail("Expected exception not thrown"); - } - catch (ClassCastException ex) - { - // good, we caught the expected exception, so we passed - } - catch (Exception ex) - { - fail("Caught an unexpected exception: " + ex); - } - - // now we'll test some simple base cases - // 2 null uuids always compare to 0 - assertUUIDEqualOrderHelper(NULL_UUID, new UUID()); - - // 2 of the same value UUIDs are always 0 - assertUUIDEqualOrderHelper( - TIME3_MAC1_UUID, new UUID(TIME3_MAC1_UUID.toString())); - - // the 'null UUID' always comes first in the ordering - assertUUIDGreaterOrderHelper(TIME3_MAC1_UUID, NULL_UUID); - - // a UUID with a greater time is always comes after a lower time uuid - // given the same MAC address - assertUUIDGreaterOrderHelper(TIME3_MAC1_UUID, TIME1_MAC1_UUID); - - // a UUID with a greater time and a different MAC will always sort - // with the greater time coming later - assertUUIDGreaterOrderHelper(TIME3_MAC1_UUID, TIME1_MAC2_UUID); - - // a UUID with the same time stamp and different MAC will always sort - // with the 'numerically' greater MAC coming later - assertUUIDGreaterOrderHelper(TIME1_MAC2_UUID, TIME1_MAC1_UUID); - - // now we will test a bigger case of the compareTo functionality - // of the UUID class - // easiest way to do this is to create an array of UUIDs and sort it - // then test that this array is in the expected order - - // first we'll try a MAC address homogeneous sort - // before sort, the array contains (in psudo-random order) - // 10 UUIDs of this distribution: - // 2 - null uuid - // 2 - time1_mac1 - // 1 - time2_mac1 - // 2 - time3_mac1 - // 2 - time4_mac1 - // 1 - time5_mac1 - UUID test_uuid_array[] = new UUID[10]; - test_uuid_array[0] = TIME3_MAC1_UUID; - test_uuid_array[1] = TIME4_MAC1_UUID; - test_uuid_array[2] = TIME1_MAC1_UUID; - test_uuid_array[3] = NULL_UUID; - test_uuid_array[4] = TIME3_MAC1_UUID; - test_uuid_array[5] = TIME5_MAC1_UUID; - test_uuid_array[6] = TIME2_MAC1_UUID; - test_uuid_array[7] = TIME1_MAC1_UUID; - test_uuid_array[8] = NULL_UUID; - test_uuid_array[9] = TIME4_MAC1_UUID; - - Arrays.sort(test_uuid_array); - // now we should be able to see that the array is in order - assertUUIDsMatchHelper(NULL_UUID, test_uuid_array[0]); - assertUUIDsMatchHelper(NULL_UUID, test_uuid_array[1]); - assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[2]); - assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[3]); - assertUUIDsMatchHelper(TIME2_MAC1_UUID, test_uuid_array[4]); - assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[5]); - assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[6]); - assertUUIDsMatchHelper(TIME4_MAC1_UUID, test_uuid_array[7]); - assertUUIDsMatchHelper(TIME4_MAC1_UUID, test_uuid_array[8]); - assertUUIDsMatchHelper(TIME5_MAC1_UUID, test_uuid_array[9]); - - // allow array to be GC'd (and make sure we don't somehow use the wrong - // array below) - test_uuid_array = null; - - // now lets try a MAC address heterogeneous case - // before sort, the array contains (in psudo-random order) - // 15 UUIDs of this distribution: - // 1 - null uuid - // 2 - time1_mac1 - // 1 - time1_mac2 - // 1 - time2_mac1 - // 2 - time2_mac2 - // 2 - time3_mac1 - // 2 - time3_mac2 - // 1 - time4_mac1 - // 1 - time4_mac2 - // 1 - time5_mac1 - // 1 - time5_mac2 - test_uuid_array = new UUID[15]; - test_uuid_array[0] = TIME3_MAC1_UUID; - test_uuid_array[1] = TIME4_MAC1_UUID; - test_uuid_array[2] = TIME1_MAC1_UUID; - test_uuid_array[3] = TIME3_MAC2_UUID; - test_uuid_array[4] = TIME2_MAC2_UUID; - test_uuid_array[5] = TIME3_MAC2_UUID; - test_uuid_array[6] = TIME1_MAC1_UUID; - test_uuid_array[7] = NULL_UUID; - test_uuid_array[8] = TIME5_MAC1_UUID; - test_uuid_array[9] = TIME2_MAC2_UUID; - test_uuid_array[10] = TIME3_MAC1_UUID; - test_uuid_array[11] = TIME4_MAC2_UUID; - test_uuid_array[12] = TIME1_MAC2_UUID; - test_uuid_array[13] = TIME5_MAC2_UUID; - test_uuid_array[14] = TIME2_MAC1_UUID; - - Arrays.sort(test_uuid_array); - // now we should be able to see that the array is in order - assertUUIDsMatchHelper(NULL_UUID, test_uuid_array[0]); - assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[1]); - assertUUIDsMatchHelper(TIME1_MAC1_UUID, test_uuid_array[2]); - assertUUIDsMatchHelper(TIME1_MAC2_UUID, test_uuid_array[3]); - assertUUIDsMatchHelper(TIME2_MAC1_UUID, test_uuid_array[4]); - assertUUIDsMatchHelper(TIME2_MAC2_UUID, test_uuid_array[5]); - assertUUIDsMatchHelper(TIME2_MAC2_UUID, test_uuid_array[6]); - assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[7]); - assertUUIDsMatchHelper(TIME3_MAC1_UUID, test_uuid_array[8]); - assertUUIDsMatchHelper(TIME3_MAC2_UUID, test_uuid_array[9]); - assertUUIDsMatchHelper(TIME3_MAC2_UUID, test_uuid_array[10]); - assertUUIDsMatchHelper(TIME4_MAC1_UUID, test_uuid_array[11]); - assertUUIDsMatchHelper(TIME4_MAC2_UUID, test_uuid_array[12]); - assertUUIDsMatchHelper(TIME5_MAC1_UUID, test_uuid_array[13]); - assertUUIDsMatchHelper(TIME5_MAC2_UUID, test_uuid_array[14]); - } - - /** - * Test of equals method, of class org.safehaus.uuid.UUID. - */ - public void testEquals() - { - // test passing null to equals returns false - // (as specified in the JDK docs for Object) - UUID x = new UUID(VALID_UUID_BYTE_ARRAY); - assertFalse("equals(null) didn't return false", - x.equals((Object)null)); - - // test that passing an object which is not a UUID returns false - assertFalse("x.equals(non_UUID_object) didn't return false", - x.equals(new Object())); - - // test a case where two UUIDs are definitly not equal - UUID w = new UUID(ANOTHER_VALID_UUID_BYTE_ARRAY); - assertFalse("x == w didn't return false", - x == w); - assertFalse("x.equals(w) didn't return false", - x.equals(w)); - - // test refelexivity - assertTrue("x == x didn't return true", - x == x); - assertTrue("x.equals(x) didn't return true", - x.equals(x)); - - // test symmetry - UUID y = new UUID(VALID_UUID_BYTE_ARRAY); - assertFalse("x == y didn't return false", - x == y); - assertTrue("y.equals(x) didn't return true", - y.equals(x)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - - // now we'll test transitivity - UUID z = new UUID(VALID_UUID_BYTE_ARRAY); - assertFalse("x == y didn't return false", - x == y); - assertFalse("x == y didn't return false", - y == z); - assertFalse("x == y didn't return false", - x == z); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("y.equals(z) didn't return true", - y.equals(z)); - assertTrue("x.equals(z) didn't return true", - x.equals(z)); - - // test consistancy (this test is just calling equals multiple times) - assertFalse("x == y didn't return false", - x == y); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - } - - /** - * Test of getNullUUID method, of class org.safehaus.uuid.UUID. - */ - public void testGetNullUUID() - { - UUID uuid = UUID.getNullUUID(); - assertEquals("getNullUUID did not create expected null UUID", - NULL_UUID_STRING, - uuid.toString()); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - - // also, validate that getNullUUID is getting the same null each time - UUID uuid2 = UUID.getNullUUID(); - assertEquals("getNullUUID did not create expected null UUID", - NULL_UUID_STRING, - uuid2.toString()); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid2.toByteArray())); - assertTrue("two returned null UUIDs were not the sam object instance", - uuid == uuid2); - } - - /** - * Test of getType method, of class org.safehaus.uuid.UUID. - */ - public void testGetType() - { - // here we will test that UUID's constructed with the right type - // have the correct type returned from getType - - // test creating a null UUID - UUID uuid = new UUID(); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - assertEquals("Expected type was not returned", - UUID.TYPE_NULL, - uuid.getType()); - - // test Random UUID in this case - uuid = new UUID(VALID_UUID_BYTE_ARRAY); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, uuid.toByteArray())); - assertEquals("Expected type was not returned", - UUID.TYPE_RANDOM_BASED, - uuid.getType()); - - // test time based UUID in this case - uuid = new UUID(TIME1_MAC1_UUID.toByteArray()); - assertEquals("constructor did not create expected UUID", - TIME1_MAC1_UUID.toString().toLowerCase(), - uuid.toString().toLowerCase()); - assertEquals("Expected type was not returned", - UUID.TYPE_TIME_BASED, - uuid.getType()); - - // test name based UUID in this case - uuid = new UUID(NAME_BASED_UUID_STRING); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NAME_BASED_UUID_BYTE_ARRAY, uuid.toByteArray())); - assertEquals("Expected type was not returned", - UUID.TYPE_NAME_BASED, - uuid.getType()); - - // test DCE based UUID in this case - uuid = new UUID(DCE_BASED_UUID_BYTE_ARRAY); - assertTrue("Expected array did not equal actual array", - Arrays.equals(DCE_BASED_UUID_BYTE_ARRAY, uuid.toByteArray())); - assertEquals("Expected type was not returned", - UUID.TYPE_DCE, - uuid.getType()); - } - - /** - * Test of hashCode method, of class org.safehaus.uuid.UUID. - */ - public void testHashCode() - { - // as lifted from the JDK Object JavaDocs: - // Whenever it is invoked on the same object more than once - // during an execution of a Java application, the hashCode - // method must consistently return the same integer, provided - // no information used in equals comparisons on the object is - // modified. This integer need not remain consistent from one - // execution of an application to another execution of the - // same application - UUID x = new UUID(VALID_UUID_BYTE_ARRAY); - assertTrue("x == x didn't return true", - x == x); - assertTrue("x.equals(x) didn't return true", - x.equals(x)); - assertEquals("x.hashCode() didn't equal x.hashCode()", - x.hashCode(), - x.hashCode()); - assertEquals("x.hashCode() didn't equal x.hashCode()", - x.hashCode(), - x.hashCode()); - - // as lifted from the JDK Object JavaDocs: - // If two objects are equal according to the equals(Object) method, - // then calling the hashCode method on each of the two objects - // must produce the same integer result - UUID y = new UUID(VALID_UUID_BYTE_ARRAY); - assertFalse("x == y didn't return false", - x == y); - assertTrue("x.equals(y) didn't return true", - x.equals(y)); - assertEquals("x.hashCode() didn't equal y.hashCode()", - x.hashCode(), - y.hashCode()); - - // it is not REQUIRED that hashCode return different ints for different - // objects where x.equals(z) is not true. - // So, there is no test for that here - } - - /** - * Test of isNullUUID method, of class org.safehaus.uuid.UUID. - */ - public void testIsNullUUID() - { - // this test will test isNullUUID using the five main ways you could - // create a null UUID and test a case where it should NOT be true - UUID uuid = null; - - // test using default constructor - uuid = new UUID(); - assertTrue("isNullUUID was not true", - uuid.isNullUUID()); - - uuid = null; - - // test using static getNullUUID - uuid = UUID.getNullUUID(); - assertTrue("isNullUUID was not true", - uuid.isNullUUID()); - - uuid = null; - - // test by string creation using null uuid represented in string form - uuid = new UUID(NULL_UUID_STRING); - assertTrue("isNullUUID was not true", - uuid.isNullUUID()); - - uuid = null; - - // test by byte[] creation using null uuid represented in byte[] form - uuid = new UUID(NULL_UUID_BYTE_ARRAY); - assertTrue("isNullUUID was not true", - uuid.isNullUUID()); - - uuid = null; - - // test by byte[] creation using null uuid represented in byte[] form - // starting at an offset - byte[] null_uuid_array = new byte[20]; - Arrays.fill(null_uuid_array, 0, 3, (byte)'x'); - uuid = new UUID(null_uuid_array, 4); - assertTrue("isNullUUID was not true", - uuid.isNullUUID()); - - uuid = null; - - // test a not null case - uuid = new UUID(VALID_UUID_BYTE_ARRAY); - assertFalse("isNullUUID was true", - uuid.isNullUUID()); - } - - /** - * Test of setDescCaching method, of class org.safehaus.uuid.UUID. - */ - public void testSetDescCaching() - { - // there is no really good way to 'test' this feature other then - // to check that if a UUID is created and desc caching is set false - // then two different calls to toString give 2 strings which are != - UUID uuid = new UUID(VALID_UUID_BYTE_ARRAY); - uuid.setDescCaching(false); - - String x = uuid.toString(); - String y = uuid.toString(); - assertFalse("x == y was not false", - x == y); - assertEquals("x.equals(y) was not true", - x, - y); - - uuid.setDescCaching(true); - String a = uuid.toString(); - String b = uuid.toString(); - assertTrue("a == b was not true", - a == b); - assertEquals("a.equals(b) was not true", - a, - b); - assertFalse("y == a was not false", - y == a); - assertEquals("y.equals(a) was not true", - y, - a); - } - - /** - * Test of toByteArray() method, of class org.safehaus.uuid.UUID. - */ - public void testToByteArray() - { - // we'll test making a couple UUIDs and then check that the toByteArray - // gives back the same value in byte form that we used to create it - - // first we'll test the null uuid - UUID uuid = new UUID(); - assertEquals("Expected length of returned array wrong", - UUID_BYTE_ARRAY_LENGTH, - uuid.toByteArray().length); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - - // now test a non-null uuid - uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - assertEquals("Expected length of returned array wrong", - UUID_BYTE_ARRAY_LENGTH, - uuid.toByteArray().length); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, uuid.toByteArray())); - - // let's make sure that changing the returned array doesn't mess with - // the wrapped UUID's internals - uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - assertEquals("Expected length of returned array wrong", - UUID_BYTE_ARRAY_LENGTH, - uuid.toByteArray().length); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, uuid.toByteArray())); - byte[] test_uuid_array = uuid.toByteArray(); - // now stir it up a bit and then check that the original UUID was - // not changed in the process. The easiest stir is to sort it ;) - Arrays.sort(test_uuid_array); - assertFalse("Expected array was equal other array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, test_uuid_array)); - assertFalse("Expected array was equal other array", - Arrays.equals(uuid.toByteArray(), test_uuid_array)); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, uuid.toByteArray())); - } - - /** - * Test of toByteArray(byte[]) method, of class org.safehaus.uuid.UUID. - */ - public void testToByteArrayDest() - { - // constant for use in this test - final int EXTRA_DATA_LENGTH = 9; - - // lets test some error cases - // first, passing null - try - { - UUID test_uuid = new UUID(); - test_uuid.toByteArray((byte[])null); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - UUID test_uuid = new UUID(); - byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH - 1]; - test_uuid.toByteArray(uuid_array); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // we'll test making a couple UUIDs and then check that the toByteArray - // gives back the same value in byte form that we used to create it - - // here we'll test the null uuid - UUID test_uuid = new UUID(); - byte[] test_array = new byte[UUID_BYTE_ARRAY_LENGTH]; - test_uuid.toByteArray(test_array); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, test_array)); - - // now test a non-null uuid - test_uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - test_uuid.toByteArray(test_array); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, test_array)); - - // now test a null uuid case with extra data in the array - test_uuid = new UUID(); - test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - test_uuid.toByteArray(test_array); - for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) - { - assertEquals("Expected array values did not match", - NULL_UUID_BYTE_ARRAY[i], - test_array[i]); - } - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + UUID_BYTE_ARRAY_LENGTH]); - } - - // now test a good uuid case with extra data in the array - test_uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - test_uuid.toByteArray(test_array); - for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) - { - assertEquals("Expected array values did not match", - VALID_UUID_BYTE_ARRAY[i], - test_array[i]); - } - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + UUID_BYTE_ARRAY_LENGTH]); - } - } - - /** - * Test of toByteArray(byte[], int) method, - * of class org.safehaus.uuid.UUID. - */ - public void testToByteArrayDestOffset() - { - // constant value for use in this test - final int EXTRA_DATA_LENGTH = 9; - - // lets test some error cases - // first, passing null and 0 - try - { - UUID test_uuid = new UUID(); - test_uuid.toByteArray((byte[])null, 0); - - UUID uuid = UUID.valueOf((byte[])null, 0); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - UUID test_uuid = new UUID(); - byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH - 1]; - test_uuid.toByteArray(uuid_array, 0); - - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is negative - try - { - UUID test_uuid = new UUID(); - byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH]; - test_uuid.toByteArray(uuid_array, -1); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is too big - try - { - UUID test_uuid = new UUID(); - byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH]; - test_uuid.toByteArray(uuid_array, UUID_BYTE_ARRAY_LENGTH); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is in the array, - // but without enough bytes to read UUID_BYTE_ARRAY_LENGTH - try - { - UUID test_uuid = new UUID(); - byte[] uuid_array = new byte[UUID_BYTE_ARRAY_LENGTH]; - test_uuid.toByteArray(uuid_array, 1); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // we'll test making a couple UUIDs and then check that the toByteArray - // gives back the same value in byte form that we used to create it - - // here we'll test the null uuid at offset 0 - UUID test_uuid = new UUID(); - byte[] test_array = new byte[UUID_BYTE_ARRAY_LENGTH]; - test_uuid.toByteArray(test_array, 0); - assertTrue("Expected array did not equal actual array", - Arrays.equals(NULL_UUID_BYTE_ARRAY, test_array)); - - // now test a non-null uuid - test_uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - test_uuid.toByteArray(test_array); - assertTrue("Expected array did not equal actual array", - Arrays.equals(VALID_UUID_BYTE_ARRAY, test_array)); - - // now test a null uuid case with extra data in the array - test_uuid = new UUID(); - test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - test_uuid.toByteArray(test_array, 0); - for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) - { - assertEquals("Expected array values did not match", - NULL_UUID_BYTE_ARRAY[i], - test_array[i]); - } - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + UUID_BYTE_ARRAY_LENGTH]); - } - - // now test a null uuid case with extra data in the array - test_uuid = new UUID(); - test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - test_uuid.toByteArray(test_array, EXTRA_DATA_LENGTH/2); - // first check the data (in the middle of the array) - for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) - { - assertEquals("Expected array values did not match", - NULL_UUID_BYTE_ARRAY[i], - test_array[i + EXTRA_DATA_LENGTH/2]); - } - // and now check that the surrounding bytes were not changed - for (int i = 0; i < EXTRA_DATA_LENGTH/2; ++i) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i]); - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH/2]); - } - - // now test a good uuid case with extra data in the array - test_uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - test_uuid.toByteArray(test_array, 0); - for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) - { - assertEquals("Expected array values did not match", - VALID_UUID_BYTE_ARRAY[i], - test_array[i]); - } - for (int i = 0; i < EXTRA_DATA_LENGTH; i++) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + UUID_BYTE_ARRAY_LENGTH]); - } - - // now test a good uuid case with extra data in the array - // to make sure we aren't blowing the bounds of the buffer - test_uuid = new UUID(MIXED_CASE_VALID_UUID_STRING); - test_array = new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - test_uuid.toByteArray(test_array, EXTRA_DATA_LENGTH/2); - // first check the data (in the middle of the array) - for (int i = 0; i < UUID_BYTE_ARRAY_LENGTH; ++i) - { - assertEquals("Expected array values did not match", - VALID_UUID_BYTE_ARRAY[i], - test_array[i + EXTRA_DATA_LENGTH/2]); - } - // and now check that the surrounding bytes were not changed - for (int i = 0; i < EXTRA_DATA_LENGTH/2; ++i) - { - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i]); - assertEquals("Expected array fill value changed", - (byte)'x', - test_array[i + UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH/2]); - } - } - - /** - * Test of toString method, of class org.safehaus.uuid.UUID. - */ - public void testToString() - { - // test making a couple UUIDs and then check that the toString - // gives back the same value in string form that was used to create it - - // test the null uuid - UUID uuid = new UUID(); - assertEquals("null uuid string and toString did not match", - NULL_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test a non-null uuid - uuid = new UUID(VALID_UUID_BYTE_ARRAY); - assertEquals("uuid string and toString results did not match", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // The current UUID implementation returns strings all lowercase. - // Although relying on this behavior in code is not recommended, - // here is a unit test which will break if this assumption - // becomes bad. This will act as an early warning to anyone - // who relies on this particular behavior. - uuid = new UUID(VALID_UUID_BYTE_ARRAY); - assertFalse("mixed case uuid string and toString " + - "matched (expected toString to be all lower case)", - MIXED_CASE_VALID_UUID_STRING.equals(uuid.toString())); - assertEquals("mixed case string toLowerCase and " + - "toString results did not match (expected toString to " + - "be all lower case)", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString()); - } - - /** - * Test of valueOf(byte[]) method, of class org.safehaus.uuid.UUID. - */ - public void testValueOfByteArray() - { - // lets test some error cases - // first, passing null - try - { - UUID uuid = UUID.valueOf((byte[])null); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - UUID uuid = UUID.valueOf(new byte[UUID_BYTE_ARRAY_LENGTH - 1]); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // let's test that creating a uuid from an zero'd array - // gives us a null UUID (definition of a null UUID) - UUID test_uuid = UUID.valueOf(new byte[UUID_BYTE_ARRAY_LENGTH]); - assertEquals("UUID.valueOf did not create expected null UUID", - NULL_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - - // let's test creating an array from a good byte array - test_uuid = UUID.valueOf(VALID_UUID_BYTE_ARRAY); - assertEquals("UUID.valueOf did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - - // test creating an array from a good byte array with extra junk on end - test_uuid = UUID.valueOf(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END); - assertEquals("UUID.valueOf did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - } - - /** - * Test of valueOf(byte[], int) method, of class org.safehaus.uuid.UUID. - */ - public void testValueOfByteArrayFromOffset() - { - // constant data for use in this test - final int EXTRA_DATA_LENGTH = 9; - - // lets test some error cases - // first, passing null and 0 - try - { - UUID uuid = UUID.valueOf((byte[])null, 0); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an array that is too small - try - { - UUID uuid = UUID.valueOf(new byte[UUID_BYTE_ARRAY_LENGTH - 1], 0); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is negative - try - { - UUID uuid = UUID.valueOf(new byte[UUID_BYTE_ARRAY_LENGTH], -1); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is too big - try - { - UUID uuid = - UUID.valueOf( - new byte[UUID_BYTE_ARRAY_LENGTH], UUID_BYTE_ARRAY_LENGTH); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // now an index that is in the array, - // but without enough bytes to read UUID_BYTE_ARRAY_LENGTH - try - { - UUID uuid = UUID.valueOf(new byte[UUID_BYTE_ARRAY_LENGTH], 1); - - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // let's test that creating a uuid from an zero'd array - // gives us a null UUID (definition of a null UUID) - UUID test_uuid = UUID.valueOf(new byte[UUID_BYTE_ARRAY_LENGTH], 0); - assertEquals("UUID.valueOf did not create expected null UUID", - NULL_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - - // test that creating a uuid from an zero'd array with extra stuff - // on the front gives us a null UUID (definition of a null UUID) - byte[] null_uuid_array = - new byte[UUID_BYTE_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(null_uuid_array, 0, EXTRA_DATA_LENGTH, (byte)'x'); - test_uuid = UUID.valueOf(null_uuid_array, EXTRA_DATA_LENGTH); - assertEquals("UUID.valueOf did not create expected null UUID", - NULL_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - - // let's test creating an array from a good byte array - test_uuid = UUID.valueOf(VALID_UUID_BYTE_ARRAY, 0); - assertEquals("UUID.valueOf did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - - // test creating an array from a byte array with extra junk on end - test_uuid = UUID.valueOf(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END, 0); - assertEquals("UUID.valueOf did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - - // test creating an array from a byte array with extra junk on start - test_uuid = UUID.valueOf(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_START, 10); - assertEquals("UUID.valueOf did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - - // test creating an array from byte array with extra junk on both ends - test_uuid = UUID.valueOf(VALID_UUID_BYTE_ARRAY_WITH_EXTRA_BOTH, 10); - assertEquals("UUID.valueOf did not create expected null UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - test_uuid.toString().toLowerCase()); - } - - /** - * Test of valueOf(String) method, of class org.safehaus.uuid.UUID. - */ - public void testValueOfString() - { - // test a null string case - try - { - UUID uuid = UUID.valueOf((String)null); - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test some failure cases for the string constructor - badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_1); - badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_2); - badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_3); - badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_4); - badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_5); - badStringValueOfHelper(IMPROPER_NUM_DASHES_UUID_STRING_6); - badStringValueOfHelper(NON_HEX_UUID_STRING); - badStringValueOfHelper(RANDOM_PROPER_LENGTH_STRING); - - // test the good cases - goodStringValueOfHelper(NULL_UUID_STRING); - goodStringValueOfHelper(UPPER_CASE_VALID_UUID_STRING); - goodStringValueOfHelper(LOWER_CASE_VALID_UUID_STRING); - goodStringValueOfHelper(MIXED_CASE_VALID_UUID_STRING); - } - - /************************************************************************** - * Begin private helper functions for use in tests - *************************************************************************/ - private void badStringUUIDConstructorHelper(String uuidString) - { - try - { - UUID uuid = new UUID(uuidString); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - } - - private void goodStringUUIDConstructorHelper(String uuidString) - { - UUID temp_uuid = null; - try - { - temp_uuid = new UUID(uuidString); - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - assertEquals("uuid strings were not equal", - uuidString.toLowerCase(), - temp_uuid.toString().toLowerCase()); - } - - private void badStringValueOfHelper(String uuidString) - { - try - { - UUID uuid = UUID.valueOf(uuidString); - // if we reached here we failed because we didn't get an exception - fail("Expected exception not caught"); - } - catch (NumberFormatException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - } - - private void goodStringValueOfHelper(String uuidString) - { - UUID temp_uuid = null; - try - { - temp_uuid = UUID.valueOf(uuidString); - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - assertEquals("UUID strings were not equal", - uuidString.toLowerCase(), - temp_uuid.toString().toLowerCase()); - } - - private void assertUUIDsMatchHelper(UUID expected, UUID actual) - { - // technically, toString will always return lowercase uuid strings, - // but just to be paranoid, we will always do toLowerCase in this test - assertEquals("UUID strings did not match", - expected.toString().toLowerCase(), - actual.toString().toLowerCase()); - - assertEquals("UUID equals did not match", - expected, - actual); - } - - private void assertUUIDEqualOrderHelper(UUID uuid1, UUID uuid2) - { - assertTrue(uuid1 + " did not test as equal to " + uuid2, - 0 == uuid1.compareTo(uuid2)); - assertTrue(uuid2 + " did not test as equal to " + uuid1, - 0 == uuid2.compareTo(uuid1)); - } - - private void assertUUIDGreaterOrderHelper(UUID uuid1, UUID uuid2) - { - assertTrue(uuid1 + " did not test as larger then " + uuid2, - 0 < uuid1.compareTo(uuid2)); - assertTrue(uuid2 + " did not test as smaller then " + uuid1, - 0 > uuid2.compareTo(uuid1)); - } - /************************************************************************** - * End private helper functions for use in tests - *************************************************************************/ - - /************************************************************************** - * Begin private constants for use in tests above - *************************************************************************/ - private static final int UUID_BYTE_ARRAY_LENGTH = 16; - - // some strings for failure case tests - private static final String IMPROPER_NUM_DASHES_UUID_STRING_1 = - "01234567089AB-CDEF-0123-456789ABCDEF"; - private static final String IMPROPER_NUM_DASHES_UUID_STRING_2 = - "01234567-89AB0CDEF-0123-456789ABCDEF"; - private static final String IMPROPER_NUM_DASHES_UUID_STRING_3 = - "01234567-89AB-CDEF00123-456789ABCDEF"; - private static final String IMPROPER_NUM_DASHES_UUID_STRING_4 = - "01234567-89AB-CDEF-01230456789ABCDEF"; - private static final String IMPROPER_NUM_DASHES_UUID_STRING_5 = - "01234567089AB0CDEF001230456789ABCDEF"; - private static final String IMPROPER_NUM_DASHES_UUID_STRING_6 = - "0123-4567-89AB-CDEF-0123-456789ABCDE"; - private static final String NON_HEX_UUID_STRING = - "01THISIS-ANON-HEX0-UUID-FORSURE01234"; - private static final String RANDOM_PROPER_LENGTH_STRING = - "String Of The Same Length as a UUID!"; - - // some strings and matching byte arrays for the success case tests - private static final String NULL_UUID_STRING = - "00000000-0000-0000-0000-000000000000"; - private static final byte[] NULL_UUID_BYTE_ARRAY = - new byte[UUID_BYTE_ARRAY_LENGTH]; - - private static final String UPPER_CASE_VALID_UUID_STRING = - "4D687664-3A1E-4F30-ACC1-87F59306D30C"; - private static final String MIXED_CASE_VALID_UUID_STRING = - "4d687664-3A1e-4F30-aCc1-87F59306d30C"; - private static final String LOWER_CASE_VALID_UUID_STRING = - "4d687664-3a1e-4f30-acc1-87f59306d30c"; - private static final byte[] VALID_UUID_BYTE_ARRAY = - { - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c - }; - private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_START = - { - 'e', 'x', 't', 'r', 'a', ' ', 'j', 'u', 'n', 'k', - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c - }; - private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END = - { - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c, - 'o', 'n', ' ', 't', 'h', 'e', ' ', 'e', 'n', 'd', - ' ', 'a', 's', ' ', 'w', 'e', 'l', 'l' - }; - private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_BOTH = - { - 'e', 'x', 't', 'r', 'a', ' ', 'j', 'u', 'n', 'k', - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c, - 'o', 'n', ' ', 't', 'h', 'e', ' ', 'e', 'n', 'd', - ' ', 'a', 's', ' ', 'w', 'e', 'l', 'l' - }; - private static final String ANOTHER_VALID_UUID_STRING = - "4aba2d17-08c9-4376-92fe-4cdefbba5a1c"; - private static final byte[] ANOTHER_VALID_UUID_BYTE_ARRAY = - { - (byte)0x4a, (byte)0xba, (byte)0x2d, (byte)0x17, - (byte)0x08, (byte)0xc9, (byte)0x43, (byte)0x76, - (byte)0x92, (byte)0xfe, (byte)0x4c, (byte)0xde, - (byte)0xfb, (byte)0xba, (byte)0x5a, (byte)0x1c - }; - - // valid namespace based UUID string - private static final String NAME_BASED_UUID_STRING = - "71ee9b64-39d3-386c-bce3-c70549ca8829"; - private static final byte[] NAME_BASED_UUID_BYTE_ARRAY = - { - (byte)0x71, (byte)0xee, (byte)0x9b, (byte)0x64, - (byte)0x39, (byte)0xd3, (byte)0x38, (byte)0x6c, - (byte)0xbc, (byte)0xe3, (byte)0xc7, (byte)0x05, - (byte)0x49, (byte)0xca, (byte)0x88, (byte)0x29 - }; - - // dummy DCE based UUID string since I have no real examples to use - private static final String DCE_BASED_UUID_STRING = - "01234567-0123-2000-8000-0123456789ab"; - private static final byte[] DCE_BASED_UUID_BYTE_ARRAY = - { - (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, - (byte)0x01, (byte)0x23, (byte)0x20, (byte)0x00, - (byte)0x80, (byte)0x00, (byte)0x01, (byte)0x23, - (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xab - }; - - // some strings for the "ordered" uuid test cases - // notice that these uuid cases vary in the time portion and for each - // "exact time" there is a case for two different MAC addresses - // to insure the ordering test between different MAC addresses - private static final UUID NULL_UUID = UUID.getNullUUID(); - private static final UUID TIME1_MAC1_UUID = - new UUID("ebb8e8fe-b1b1-11d7-8adb-00b0d078fa18"); - private static final UUID TIME1_MAC2_UUID = - new UUID("ebb8e8fe-b1b1-11d7-8adb-baa07db6d227"); - private static final UUID TIME2_MAC1_UUID = - new UUID("ec3ffdda-b1b1-11d7-8adb-00b0d078fa18"); - private static final UUID TIME2_MAC2_UUID = - new UUID("ec3ffdda-b1b1-11d7-8adb-baa07db6d227"); - private static final UUID TIME3_MAC1_UUID = - new UUID("eca4c616-b1b1-11d7-8adb-00b0d078fa18"); - private static final UUID TIME3_MAC2_UUID = - new UUID("eca4c616-b1b1-11d7-8adb-baa07db6d227"); - private static final UUID TIME4_MAC1_UUID = - new UUID("ed17de08-b1b1-11d7-8adb-00b0d078fa18"); - private static final UUID TIME4_MAC2_UUID = - new UUID("ed17de08-b1b1-11d7-8adb-baa07db6d227"); - private static final UUID TIME5_MAC1_UUID = - new UUID("ed94244a-b1b1-11d7-8adb-00b0d078fa18"); - private static final UUID TIME5_MAC2_UUID = - new UUID("ed94244a-b1b1-11d7-8adb-baa07db6d227"); - /************************************************************************** - * End private constants for use in tests above - *************************************************************************/ -} diff -Nru jug-2.0.0/src/test/org/safehaus/uuid/test/UUIDTimerTest.java jug-3.1.5/src/test/org/safehaus/uuid/test/UUIDTimerTest.java --- jug-2.0.0/src/test/org/safehaus/uuid/test/UUIDTimerTest.java 2005-07-21 05:25:47.000000000 +0000 +++ jug-3.1.5/src/test/org/safehaus/uuid/test/UUIDTimerTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,373 +0,0 @@ -/* JUG Java Uuid Generator - * UUIDTimerTest.java - * Created on July 28, 2003, 10:09 PM - * - * Copyright (c) 2003 Eric Bie - * - * 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 org.safehaus.uuid.test; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.textui.TestRunner; - -import java.security.SecureRandom; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Set; - -import org.safehaus.uuid.UUIDTimer; - -/** - * JUnit Test class for the org.safehaus.uuid.UUIDTimer class. - * - * @author Eric Bie - */ -public class UUIDTimerTest extends TestCase -{ - // constants for use in the tests - private static final int UUID_TIMER_ARRAY_LENGTH = 10; - private static final int SIZE_OF_TEST_ARRAY = 10000; - - public UUIDTimerTest(java.lang.String testName) - { - super(testName); - } - - public static Test suite() - { - TestSuite suite = new TestSuite(UUIDTimerTest.class); - return suite; - } - - public static void main(String[] args) - { - TestRunner.run(suite()); - } - - /************************************************************************** - * Begin constructor tests - *************************************************************************/ - /** - * Test of UUIDTimer(SecureRandom) constructor, - * of class org.safehaus.uuid.UUIDTimer. - */ - public void testSecureRandomUUIDTimerConstructor() - { - // try passing a null SecureRandom argument - try - { - UUIDTimer uuid_timer = new UUIDTimer((SecureRandom)null); - // if we reach here we didn't catch what we should have - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // caught the expected exception, this is good, just go on - } - catch (Exception ex) - { - fail("Unexpected exception caught"); - } - - // now construct a valid case - SecureRandom secure_random = new SecureRandom(); - UUIDTimer uuid_timer = new UUIDTimer(secure_random); - - // we'll do a simple run to see that it at least produces output - byte[] test_array = new byte[UUID_TIMER_ARRAY_LENGTH]; - uuid_timer.getTimestamp(test_array); - // check that it's not all null - assertArrayNotEqual(test_array, - new byte[UUID_TIMER_ARRAY_LENGTH], - UUID_TIMER_ARRAY_LENGTH); - } - /************************************************************************** - * End constructor tests - *************************************************************************/ - - /** - * Test of getTimestamp method, of class org.safehaus.uuid.UUIDTimer. - */ - public void testGetTimestamp() - { - // constant for use in this test - final int EXTRA_DATA_LENGTH = 9; - - // construct a UUIDTimer - SecureRandom secure_random = new SecureRandom(); - UUIDTimer uuid_timer = new UUIDTimer(secure_random); - - // test an array thats too small - try - { - byte[] test_array = new byte[UUID_TIMER_ARRAY_LENGTH - 1]; - uuid_timer.getTimestamp(test_array); - // if we get here, we didn't catch the expected exception - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // caught the expected exception, this is good, just go on - } - catch (Exception ex) - { - fail("Unexpected exception caught"); - } - - // construct a valid array exactly big enough and see that it works - byte[] test_array = new byte[UUID_TIMER_ARRAY_LENGTH]; - uuid_timer.getTimestamp(test_array); - // check that it's not all null - assertArrayNotEqual(test_array, - new byte[UUID_TIMER_ARRAY_LENGTH], - UUID_TIMER_ARRAY_LENGTH); - - // construct a valid array bigger then we need - // and make sure getTimeStamp only touches the begining part - test_array = new byte[UUID_TIMER_ARRAY_LENGTH + EXTRA_DATA_LENGTH]; - Arrays.fill(test_array, (byte)'x'); - uuid_timer.getTimestamp(test_array); - for (int i = 0; i < EXTRA_DATA_LENGTH; ++i) - { - assertEquals("test_array element was corrupted", - (byte)'x', - test_array[i + UUID_TIMER_ARRAY_LENGTH]); - } - // check that the timer portion is not all null - assertArrayNotEqual(test_array, - new byte[UUID_TIMER_ARRAY_LENGTH], - UUID_TIMER_ARRAY_LENGTH); - - // now make a bunch of timer elements and validate that they are - // are well behaved timer elements - byte[][] array_of_uuid_timer_byte_arrays = - new byte[SIZE_OF_TEST_ARRAY][UUID_TIMER_ARRAY_LENGTH]; - - // before generating all the uuid timer arrays, get the start time - long start_time = System.currentTimeMillis(); - - // now create the array of uuid timer output arrays - for (int i = 0; i < array_of_uuid_timer_byte_arrays.length; i++) - { - uuid_timer.getTimestamp(array_of_uuid_timer_byte_arrays[i]); - } - - // now capture the end time - long end_time = System.currentTimeMillis(); - - // convert the array into array of longs holding the numerical values - Long[] uuid_timer_array_of_longs = - convertArrayOfByteArraysToArrayOfLongs( - array_of_uuid_timer_byte_arrays); - - // check that none of the UUID Timer arrays are all null - checkUUIDTimerLongArrayForNonNullTimes(uuid_timer_array_of_longs); - - // check that all UUID Timers were generated with correct order - checkUUIDTimerLongArrayForCorrectOrdering(uuid_timer_array_of_longs); - - // check that all UUID Timers were unique - checkUUIDTimerLongArrayForUniqueness(uuid_timer_array_of_longs); - - // check that all timestamps are between the start and end time - checkUUIDTimerLongArrayForCorrectCreationTime( - uuid_timer_array_of_longs, start_time, end_time); - } - - /************************************************************************** - * Begin private helper functions for use in tests - *************************************************************************/ - private Long[] convertArrayOfByteArraysToArrayOfLongs( - byte[][] uuidTimerArrayOfByteArrays) - { - Long[] array_of_longs = new Long[uuidTimerArrayOfByteArrays.length]; - for (int i = 0; i < uuidTimerArrayOfByteArrays.length; i++) - { - // collect the UUID time stamp which is - // the number of 100-nanosecond intervals since - // 00:00:00.00 15 October 1582 - long uuid_timer = 0L; - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][3] & 0xFFL) << 0); - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][2] & 0xFFL) << 8); - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][1] & 0xFFL) << 16); - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][0] & 0xFFL) << 24); - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][5] & 0xFFL) << 32); - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][4] & 0xFFL) << 40); - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][7] & 0xFFL) << 48); - uuid_timer |= ((uuidTimerArrayOfByteArrays[i][6] & 0xFFL) << 56); - - array_of_longs[i] = new Long(uuid_timer); - } - - return array_of_longs; - } - - private class ReverseOrderUUIDTimerLongComparator implements Comparator - { - // this Comparator class has a compare which orders reverse of the - // compare method in UUIDTimerArrayComparator (so we can be sure our - // arrays below are 'not ordered in sorted order' - // before we sort them). - public int compare(Object o1, Object o2) - { - Long uuid_timer_long1 = (Long)o1; - Long uuid_timer_long2 = (Long)o2; - - return -uuid_timer_long1.compareTo(uuid_timer_long2); - } - - // we are only implementing equals because it's needed, super should do - public boolean equals(Object o) - { - return super.equals(o); - } - } - - private void checkUUIDTimerLongArrayForCorrectOrdering( - Long[] uuidTimerLongArray) - { - // now we'll clone the array and reverse it - Long[] uuid_timer_sorted_arrays = (Long[])uuidTimerLongArray.clone(); - assertEquals("Cloned array length did not match", - uuidTimerLongArray.length, - uuid_timer_sorted_arrays.length); - - ReverseOrderUUIDTimerLongComparator rev_order_uuid_timer_comp = - new ReverseOrderUUIDTimerLongComparator(); - Arrays.sort(uuid_timer_sorted_arrays, rev_order_uuid_timer_comp); - - // let's check that the array is actually reversed - int sorted_arrays_length = uuid_timer_sorted_arrays.length; - for (int i = 0; i < sorted_arrays_length; i++) - { - assertTrue( - "Reverse order check on uuid timer arrays failed" + - " on element " + i + ": " + - uuidTimerLongArray[i].longValue() + " does not equal " + - uuid_timer_sorted_arrays[ - sorted_arrays_length - (1 + i)].longValue(), - uuidTimerLongArray[i].equals( - uuid_timer_sorted_arrays[sorted_arrays_length - (1 + i)])); - } - - // now let's sort the reversed array and check that it sorted to - // the same order as the original - Arrays.sort(uuid_timer_sorted_arrays); - for (int i = 0; i < sorted_arrays_length; i++) - { - assertTrue( - "Same order check on uuid timer arrays failed on element " + - i + ": " + uuidTimerLongArray[i].longValue() + - " does not equal " + - uuid_timer_sorted_arrays[i].longValue(), - uuidTimerLongArray[i].equals(uuid_timer_sorted_arrays[i])); - } - } - - private void checkUUIDTimerLongArrayForUniqueness( - Long[] uuidTimerLongArray) - { - // here we'll assert that all elements in the list are not equal to - // each other (aka, there should be no duplicates) we'll do this by - // inserting all elements into a Set and making sure none of them - // were already present (add will return false if it was already there) - Set set = new HashSet(); - for (int i = 0; i < uuidTimerLongArray.length; i++) - { - assertTrue("Uniqueness test failed on insert into HashSet", - set.add(uuidTimerLongArray[i])); - assertFalse( - "Paranoia Uniqueness test failed (second insert into HashSet)", - set.add(uuidTimerLongArray[i])); - } - } - - private void checkUUIDTimerLongArrayForCorrectCreationTime( - Long[] uuidTimerLongArray, - long startTime, - long endTime) - { - // we need to convert from 100-naonsecond units (as used in UUIDs) - // to millisecond units as used in UTC based time - final long MILLI_CONVERSION_FACTOR = 10000L; - // Since System.currentTimeMillis() returns time epoc time - // (from 1-Jan-1970), and UUIDs use time from the beginning of - // Gregorian calendar (15-Oct-1582) we have a offset for correction - final long GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET = - 122192928000000000L; - - assertTrue("Start time was not before the end time", - startTime < endTime); - - // let's check that all the uuid timer longs in the array have a - // timestamp which lands between the start and end time - for (int i = 0; i < uuidTimerLongArray.length; i++) - { - long uuid_time = uuidTimerLongArray[i].longValue(); - - // first we'll remove the gregorian offset - uuid_time -= GREGORIAN_CALENDAR_START_TO_UTC_START_OFFSET; - - // and convert to milliseconds as the system clock is in millis - uuid_time /= MILLI_CONVERSION_FACTOR; - - // now check that the times are correct - assertTrue( - "Start time: " + startTime + - " was not before UUID timestamp: " + uuid_time, - startTime <= uuid_time); - assertTrue( - "UUID timestamp: " + uuid_time + - " was not before the end time: " + endTime, - uuid_time <= endTime); - } - } - - private void checkUUIDTimerLongArrayForNonNullTimes( - Long[] uuidTimerLongArray) - { - for (int i = 0; i < uuidTimerLongArray.length; i++) - { - assertFalse("Timer Long was null", - 0 == uuidTimerLongArray[i].longValue()); - } - } - - private void assertArrayNotEqual(byte[] array1, byte[] array2, int length) - { - assertTrue("array1 was not equal or longer then length", - array1.length >= length); - assertTrue("array2 was not equal or longer then length", - array2.length >= length); - - for (int i = 0; i < length; ++i) - { - // we know the arrays aren't equal the first time we - // fine an array element that isn't equal. - // in that case just return - if (array1[i] != array2[i]) - { - return; - } - } - // if we get out of the loop, both arrays were identical, so fail - fail("All elements of Array1 were equal to all elements of Array2"); - } - /************************************************************************** - * End private helper functions for use in tests - *************************************************************************/ -} diff -Nru jug-2.0.0/src/test/org/safehaus/uuid/UUIDPackageAccessTest.java jug-3.1.5/src/test/org/safehaus/uuid/UUIDPackageAccessTest.java --- jug-2.0.0/src/test/org/safehaus/uuid/UUIDPackageAccessTest.java 2005-07-21 05:25:47.000000000 +0000 +++ jug-3.1.5/src/test/org/safehaus/uuid/UUIDPackageAccessTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -/* JUG Java Uuid Generator - * UUIDPackageAccessTest.java - * Created on October 7, 2003, 7:56 PM - * - * Copyright (c) 2003 Eric Bie - * - * 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 org.safehaus.uuid; - -import junit.framework.*; -import java.util.Arrays; - -import org.safehaus.uuid.UUID; - -/** - * JUnit Test class for checking the package access - * methods of the org.safehaus.uuid.UUID class. - * - * @author Eric Bie - */ -public class UUIDPackageAccessTest extends TestCase -{ - public UUIDPackageAccessTest(java.lang.String testName) - { - super(testName); - } - - public static Test suite() - { - TestSuite suite = new TestSuite(UUIDPackageAccessTest.class); - return suite; - } - - public static void main(String[] args) - { - junit.textui.TestRunner.run(suite()); - } - - /************************************************************************** - * Begin constructor tests - *************************************************************************/ - /** - * Test of UUID(int, byte[]) constructor, of class org.safehaus.uuid.UUID. - */ - public void testTypeAndByteArrayUUIDConstructor() - { - // passing null - try - { - UUID uuid = new UUID(UUID.TYPE_RANDOM_BASED, (byte[])null); - fail("Expected exception not caught"); - } - catch (NullPointerException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // passing array that is too small - try - { - UUID uuid = - new UUID(UUID.TYPE_RANDOM_BASED, - new byte[UUID_BYTE_ARRAY_LENGTH - 1]); - fail("Expected exception not caught"); - } - catch (ArrayIndexOutOfBoundsException ex) - { - // this is the success case so do nothing - } - catch (Exception ex) - { - fail("Caught unexpected exception: " + ex); - } - - // test creating an array from a good byte array with extra data on end - UUID uuid = - new UUID(UUID.TYPE_RANDOM_BASED, - VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END); - assertEquals("constructor did not create expected UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test creating an array from a good byte array with the right type - // Random UUID in this case - uuid = new UUID(UUID.TYPE_RANDOM_BASED, VALID_UUID_BYTE_ARRAY); - assertEquals("constructor did not create expected UUID", - MIXED_CASE_VALID_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test creating an array from a good byte array with the right type - // time based UUID in this case - uuid = new UUID(UUID.TYPE_TIME_BASED, TIME_BASED_UUID_BYTE_ARRAY); - assertEquals("constructor did not create expected UUID", - TIME_BASED_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test name based UUID in this case - uuid = new UUID(UUID.TYPE_NAME_BASED, NAME_BASED_UUID_BYTE_ARRAY); - assertEquals("constructor did not create expected UUID", - NAME_BASED_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - // test DCE based UUID in this case - uuid = new UUID(UUID.TYPE_DCE, DCE_BASED_UUID_BYTE_ARRAY); - assertEquals("constructor did not create expected UUID", - DCE_BASED_UUID_STRING.toLowerCase(), - uuid.toString().toLowerCase()); - - /* - * technically, this test does not work (this constructor always pokes - * a version into the UUID, even if you pass UUID.TYPE_NULL - * since this is a default access constructor, this is likely - * acceptable behavior, but test is here and commented out in case - * there is a desire for this to work differently - */ -// // test that creating a uuid from a zero'd array with TYPE_NULL -// // gives us a null UUID (null UUID is array of all 0s) -// uuid = new UUID(UUID.TYPE_NULL, new byte[UUID_BYTE_ARRAY_LENGTH]); -// assertEquals("constructor did not create expected null UUID", -// NULL_UUID_STRING, -// uuid.toString()); -// assertTrue("NULL UUID byte arrays were not equal", -// Arrays.equals(NULL_UUID_BYTE_ARRAY, uuid.toByteArray())); - } - /************************************************************************** - * End constructor tests - *************************************************************************/ - - /************************************************************************** - * Begin private constants for use in tests above - *************************************************************************/ - private static final int UUID_BYTE_ARRAY_LENGTH = 16; - - private static final String UPPER_CASE_VALID_UUID_STRING = - "4D687664-3A1E-4F30-ACC1-87F59306D30C"; - private static final String MIXED_CASE_VALID_UUID_STRING = - "4d687664-3A1e-4F30-aCc1-87F59306d30C"; - private static final String LOWER_CASE_VALID_UUID_STRING = - "4d687664-3a1e-4f30-acc1-87f59306d30c"; - private static final byte[] VALID_UUID_BYTE_ARRAY = - { - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c - }; - private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_START = - { - 'e', 'x', 't', 'r', 'a', ' ', 'j', 'u', 'n', 'k', - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c - }; - private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_END = - { - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c, - 'o', 'n', ' ', 't', 'h', 'e', ' ', 'e', 'n', 'd', - ' ', 'a', 's', ' ', 'w', 'e', 'l', 'l' - }; - private static final byte[] VALID_UUID_BYTE_ARRAY_WITH_EXTRA_BOTH = - { - 'e', 'x', 't', 'r', 'a', ' ', 'j', 'u', 'n', 'k', - (byte)0x4d, (byte)0x68, (byte)0x76, (byte)0x64, - (byte)0x3a, (byte)0x1e, (byte)0x4f, (byte)0x30, - (byte)0xac, (byte)0xc1, (byte)0x87, (byte)0xf5, - (byte)0x93, (byte)0x06, (byte)0xd3, (byte)0x0c, - 'o', 'n', ' ', 't', 'h', 'e', ' ', 'e', 'n', 'd', - ' ', 'a', 's', ' ', 'w', 'e', 'l', 'l' - }; - - // valid null UUID string - private static final String NULL_UUID_STRING = - "00000000-0000-0000-0000-000000000000"; - private static final byte[] NULL_UUID_BYTE_ARRAY = - new byte[UUID_BYTE_ARRAY_LENGTH]; - - // valid time based UUID string - private static final String TIME_BASED_UUID_STRING = - "ebb8e8fe-b1b1-11d7-8adb-00b0d078fa18"; - private static final byte[] TIME_BASED_UUID_BYTE_ARRAY = - { - (byte)0xeb, (byte)0xb8, (byte)0xe8, (byte)0xfe, - (byte)0xb1, (byte)0xb1, (byte)0x11, (byte)0xd7, - (byte)0x8a, (byte)0xdb, (byte)0x00, (byte)0xb0, - (byte)0xd0, (byte)0x78, (byte)0xfa, (byte)0x18 - }; - - // valid namespace based UUID string - private static final String NAME_BASED_UUID_STRING = - "71ee9b64-39d3-386c-bce3-c70549ca8829"; - private static final byte[] NAME_BASED_UUID_BYTE_ARRAY = - { - (byte)0x71, (byte)0xee, (byte)0x9b, (byte)0x64, - (byte)0x39, (byte)0xd3, (byte)0x38, (byte)0x6c, - (byte)0xbc, (byte)0xe3, (byte)0xc7, (byte)0x05, - (byte)0x49, (byte)0xca, (byte)0x88, (byte)0x29 - }; - - // dummy DCE based UUID string since I have no real examples to use - private static final String DCE_BASED_UUID_STRING = - "01234567-0123-2000-8000-0123456789ab"; - private static final byte[] DCE_BASED_UUID_BYTE_ARRAY = - { - (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, - (byte)0x01, (byte)0x23, (byte)0x20, (byte)0x00, - (byte)0x80, (byte)0x00, (byte)0x01, (byte)0x23, - (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xab - }; - /************************************************************************** - * End private constants for use in tests above - *************************************************************************/ -}