Implement framework UUID for OSGi R4.3. (FELIX-3122)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1173297 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 8dd32a2..2585ddf 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -600,6 +600,13 @@
}
}
}
+
+ // Generate a framework UUID.
+ // Spec says we get a new UUID for each invocation of init().
+ m_configMutableMap.put(
+ FelixConstants.FRAMEWORK_UUID,
+ Util.randomUUID());
+
// Get any system bundle activators.
m_activatorList = (List) m_configMutableMap.get(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP);
m_activatorList = (m_activatorList == null) ? new ArrayList() : new ArrayList(m_activatorList);
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index 41e4305..0e843c9 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/Util.java
@@ -21,6 +21,7 @@
import java.io.*;
import java.net.URL;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -676,4 +677,113 @@
}
return fragments;
}
+
+ //
+ // UUID code copied from Apache Harmony java.util.UUID
+ //
+
+ /**
+ * <p>
+ * Generates a variant 2, version 4 (randomly generated number) UUID as per
+ * <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
+ *
+ * @return an UUID instance.
+ */
+ public static String randomUUID() {
+ byte[] data;
+ // lock on the class to protect lazy init
+ SecureRandom rng = new SecureRandom();
+ rng.nextBytes(data = new byte[16]);
+ long mostSigBits = (data[0] & 0xFFL) << 56;
+ mostSigBits |= (data[1] & 0xFFL) << 48;
+ mostSigBits |= (data[2] & 0xFFL) << 40;
+ mostSigBits |= (data[3] & 0xFFL) << 32;
+ mostSigBits |= (data[4] & 0xFFL) << 24;
+ mostSigBits |= (data[5] & 0xFFL) << 16;
+ mostSigBits |= (data[6] & 0x0FL) << 8;
+ mostSigBits |= (0x4L << 12); // set the version to 4
+ mostSigBits |= (data[7] & 0xFFL);
+
+ long leastSigBits = (data[8] & 0x3FL) << 56;
+ leastSigBits |= (0x2L << 62); // set the variant to bits 01
+ leastSigBits |= (data[9] & 0xFFL) << 48;
+ leastSigBits |= (data[10] & 0xFFL) << 40;
+ leastSigBits |= (data[11] & 0xFFL) << 32;
+ leastSigBits |= (data[12] & 0xFFL) << 24;
+ leastSigBits |= (data[13] & 0xFFL) << 16;
+ leastSigBits |= (data[14] & 0xFFL) << 8;
+ leastSigBits |= (data[15] & 0xFFL);
+
+ //
+ // UUID.init()
+ //
+
+ int variant;
+ int version;
+ long timestamp;
+ int clockSequence;
+ long node;
+ int hash;
+
+ // setup hash field
+ int msbHash = (int) (mostSigBits ^ (mostSigBits >>> 32));
+ int lsbHash = (int) (leastSigBits ^ (leastSigBits >>> 32));
+ hash = msbHash ^ lsbHash;
+
+ // setup variant field
+ if ((leastSigBits & 0x8000000000000000L) == 0) {
+ // MSB0 not set, NCS backwards compatibility variant
+ variant = 0;
+ } else if ((leastSigBits & 0x4000000000000000L) != 0) {
+ // MSB1 set, either MS reserved or future reserved
+ variant = (int) ((leastSigBits & 0xE000000000000000L) >>> 61);
+ } else {
+ // MSB1 not set, RFC 4122 variant
+ variant = 2;
+ }
+
+ // setup version field
+ version = (int) ((mostSigBits & 0x000000000000F000) >>> 12);
+
+ if (!(variant != 2 && version != 1)) {
+ // setup timestamp field
+ long timeLow = (mostSigBits & 0xFFFFFFFF00000000L) >>> 32;
+ long timeMid = (mostSigBits & 0x00000000FFFF0000L) << 16;
+ long timeHigh = (mostSigBits & 0x0000000000000FFFL) << 48;
+ timestamp = timeLow | timeMid | timeHigh;
+
+ // setup clock sequence field
+ clockSequence = (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
+
+ // setup node field
+ node = (leastSigBits & 0x0000FFFFFFFFFFFFL);
+ }
+
+ //
+ // UUID.toString()
+ //
+
+ StringBuffer builder = new StringBuffer(36);
+ String msbStr = Long.toHexString(mostSigBits);
+ if (msbStr.length() < 16) {
+ int diff = 16 - msbStr.length();
+ for (int i = 0; i < diff; i++) {
+ builder.append('0');
+ }
+ }
+ builder.append(msbStr);
+ builder.insert(8, '-');
+ builder.insert(13, '-');
+ builder.append('-');
+ String lsbStr = Long.toHexString(leastSigBits);
+ if (lsbStr.length() < 16) {
+ int diff = 16 - lsbStr.length();
+ for (int i = 0; i < diff; i++) {
+ builder.append('0');
+ }
+ }
+ builder.append(lsbStr);
+ builder.insert(23, '-');
+ return builder.toString();
+ }
}
\ No newline at end of file