TimeBasedGenerator.js
上传用户:kimgenplus
上传日期:2016-06-05
资源大小:20877k
文件大小:8k
源码类别:

OA系统

开发平台:

Java

  1. /*
  2. Copyright (c) 2004-2006, The Dojo Foundation
  3. All Rights Reserved.
  4. Licensed under the Academic Free License version 2.1 or above OR the
  5. modified BSD license. For more information on Dojo licensing, see:
  6. http://dojotoolkit.org/community/licensing.shtml
  7. */
  8. dojo.provide("dojo.uuid.TimeBasedGenerator");
  9. dojo.require("dojo.lang.common");
  10. dojo.require("dojo.lang.type");
  11. dojo.require("dojo.lang.assert");
  12. dojo.uuid.TimeBasedGenerator = new function () {
  13. this.GREGORIAN_CHANGE_OFFSET_IN_HOURS = 3394248;
  14. var _uuidPseudoNodeString = null;
  15. var _uuidClockSeqString = null;
  16. var _dateValueOfPreviousUuid = null;
  17. var _nextIntraMillisecondIncrement = 0;
  18. var _cachedMillisecondsBetween1582and1970 = null;
  19. var _cachedHundredNanosecondIntervalsPerMillisecond = null;
  20. var _uniformNode = null;
  21. var HEX_RADIX = 16;
  22. function _carry(arrayA) {
  23. arrayA[2] += arrayA[3] >>> 16;
  24. arrayA[3] &= 65535;
  25. arrayA[1] += arrayA[2] >>> 16;
  26. arrayA[2] &= 65535;
  27. arrayA[0] += arrayA[1] >>> 16;
  28. arrayA[1] &= 65535;
  29. dojo.lang.assert((arrayA[0] >>> 16) === 0);
  30. }
  31. function _get64bitArrayFromFloat(x) {
  32. var result = new Array(0, 0, 0, 0);
  33. result[3] = x % 65536;
  34. x -= result[3];
  35. x /= 65536;
  36. result[2] = x % 65536;
  37. x -= result[2];
  38. x /= 65536;
  39. result[1] = x % 65536;
  40. x -= result[1];
  41. x /= 65536;
  42. result[0] = x;
  43. return result;
  44. }
  45. function _addTwo64bitArrays(arrayA, arrayB) {
  46. dojo.lang.assertType(arrayA, Array);
  47. dojo.lang.assertType(arrayB, Array);
  48. dojo.lang.assert(arrayA.length == 4);
  49. dojo.lang.assert(arrayB.length == 4);
  50. var result = new Array(0, 0, 0, 0);
  51. result[3] = arrayA[3] + arrayB[3];
  52. result[2] = arrayA[2] + arrayB[2];
  53. result[1] = arrayA[1] + arrayB[1];
  54. result[0] = arrayA[0] + arrayB[0];
  55. _carry(result);
  56. return result;
  57. }
  58. function _multiplyTwo64bitArrays(arrayA, arrayB) {
  59. dojo.lang.assertType(arrayA, Array);
  60. dojo.lang.assertType(arrayB, Array);
  61. dojo.lang.assert(arrayA.length == 4);
  62. dojo.lang.assert(arrayB.length == 4);
  63. var overflow = false;
  64. if (arrayA[0] * arrayB[0] !== 0) {
  65. overflow = true;
  66. }
  67. if (arrayA[0] * arrayB[1] !== 0) {
  68. overflow = true;
  69. }
  70. if (arrayA[0] * arrayB[2] !== 0) {
  71. overflow = true;
  72. }
  73. if (arrayA[1] * arrayB[0] !== 0) {
  74. overflow = true;
  75. }
  76. if (arrayA[1] * arrayB[1] !== 0) {
  77. overflow = true;
  78. }
  79. if (arrayA[2] * arrayB[0] !== 0) {
  80. overflow = true;
  81. }
  82. dojo.lang.assert(!overflow);
  83. var result = new Array(0, 0, 0, 0);
  84. result[0] += arrayA[0] * arrayB[3];
  85. _carry(result);
  86. result[0] += arrayA[1] * arrayB[2];
  87. _carry(result);
  88. result[0] += arrayA[2] * arrayB[1];
  89. _carry(result);
  90. result[0] += arrayA[3] * arrayB[0];
  91. _carry(result);
  92. result[1] += arrayA[1] * arrayB[3];
  93. _carry(result);
  94. result[1] += arrayA[2] * arrayB[2];
  95. _carry(result);
  96. result[1] += arrayA[3] * arrayB[1];
  97. _carry(result);
  98. result[2] += arrayA[2] * arrayB[3];
  99. _carry(result);
  100. result[2] += arrayA[3] * arrayB[2];
  101. _carry(result);
  102. result[3] += arrayA[3] * arrayB[3];
  103. _carry(result);
  104. return result;
  105. }
  106. function _padWithLeadingZeros(string, desiredLength) {
  107. while (string.length < desiredLength) {
  108. string = "0" + string;
  109. }
  110. return string;
  111. }
  112. function _generateRandomEightCharacterHexString() {
  113. var random32bitNumber = Math.floor((Math.random() % 1) * Math.pow(2, 32));
  114. var eightCharacterString = random32bitNumber.toString(HEX_RADIX);
  115. while (eightCharacterString.length < 8) {
  116. eightCharacterString = "0" + eightCharacterString;
  117. }
  118. return eightCharacterString;
  119. }
  120. function _generateUuidString(node) {
  121. dojo.lang.assertType(node, String, {optional:true});
  122. if (node) {
  123. dojo.lang.assert(node.length == 12);
  124. } else {
  125. if (_uniformNode) {
  126. node = _uniformNode;
  127. } else {
  128. if (!_uuidPseudoNodeString) {
  129. var pseudoNodeIndicatorBit = 32768;
  130. var random15bitNumber = Math.floor((Math.random() % 1) * Math.pow(2, 15));
  131. var leftmost4HexCharacters = (pseudoNodeIndicatorBit | random15bitNumber).toString(HEX_RADIX);
  132. _uuidPseudoNodeString = leftmost4HexCharacters + _generateRandomEightCharacterHexString();
  133. }
  134. node = _uuidPseudoNodeString;
  135. }
  136. }
  137. if (!_uuidClockSeqString) {
  138. var variantCodeForDCEUuids = 32768;
  139. var random14bitNumber = Math.floor((Math.random() % 1) * Math.pow(2, 14));
  140. _uuidClockSeqString = (variantCodeForDCEUuids | random14bitNumber).toString(HEX_RADIX);
  141. }
  142. var now = new Date();
  143. var millisecondsSince1970 = now.valueOf();
  144. var nowArray = _get64bitArrayFromFloat(millisecondsSince1970);
  145. if (!_cachedMillisecondsBetween1582and1970) {
  146. var arraySecondsPerHour = _get64bitArrayFromFloat(60 * 60);
  147. var arrayHoursBetween1582and1970 = _get64bitArrayFromFloat(dojo.uuid.TimeBasedGenerator.GREGORIAN_CHANGE_OFFSET_IN_HOURS);
  148. var arraySecondsBetween1582and1970 = _multiplyTwo64bitArrays(arrayHoursBetween1582and1970, arraySecondsPerHour);
  149. var arrayMillisecondsPerSecond = _get64bitArrayFromFloat(1000);
  150. _cachedMillisecondsBetween1582and1970 = _multiplyTwo64bitArrays(arraySecondsBetween1582and1970, arrayMillisecondsPerSecond);
  151. _cachedHundredNanosecondIntervalsPerMillisecond = _get64bitArrayFromFloat(10000);
  152. }
  153. var arrayMillisecondsSince1970 = nowArray;
  154. var arrayMillisecondsSince1582 = _addTwo64bitArrays(_cachedMillisecondsBetween1582and1970, arrayMillisecondsSince1970);
  155. var arrayHundredNanosecondIntervalsSince1582 = _multiplyTwo64bitArrays(arrayMillisecondsSince1582, _cachedHundredNanosecondIntervalsPerMillisecond);
  156. if (now.valueOf() == _dateValueOfPreviousUuid) {
  157. arrayHundredNanosecondIntervalsSince1582[3] += _nextIntraMillisecondIncrement;
  158. _carry(arrayHundredNanosecondIntervalsSince1582);
  159. _nextIntraMillisecondIncrement += 1;
  160. if (_nextIntraMillisecondIncrement == 10000) {
  161. while (now.valueOf() == _dateValueOfPreviousUuid) {
  162. now = new Date();
  163. }
  164. }
  165. } else {
  166. _dateValueOfPreviousUuid = now.valueOf();
  167. _nextIntraMillisecondIncrement = 1;
  168. }
  169. var hexTimeLowLeftHalf = arrayHundredNanosecondIntervalsSince1582[2].toString(HEX_RADIX);
  170. var hexTimeLowRightHalf = arrayHundredNanosecondIntervalsSince1582[3].toString(HEX_RADIX);
  171. var hexTimeLow = _padWithLeadingZeros(hexTimeLowLeftHalf, 4) + _padWithLeadingZeros(hexTimeLowRightHalf, 4);
  172. var hexTimeMid = arrayHundredNanosecondIntervalsSince1582[1].toString(HEX_RADIX);
  173. hexTimeMid = _padWithLeadingZeros(hexTimeMid, 4);
  174. var hexTimeHigh = arrayHundredNanosecondIntervalsSince1582[0].toString(HEX_RADIX);
  175. hexTimeHigh = _padWithLeadingZeros(hexTimeHigh, 3);
  176. var hyphen = "-";
  177. var versionCodeForTimeBasedUuids = "1";
  178. var resultUuid = hexTimeLow + hyphen + hexTimeMid + hyphen + versionCodeForTimeBasedUuids + hexTimeHigh + hyphen + _uuidClockSeqString + hyphen + node;
  179. resultUuid = resultUuid.toLowerCase();
  180. return resultUuid;
  181. }
  182. this.setNode = function (node) {
  183. dojo.lang.assert((node === null) || (node.length == 12));
  184. _uniformNode = node;
  185. };
  186. this.getNode = function () {
  187. return _uniformNode;
  188. };
  189. this.generate = function (input) {
  190. var nodeString = null;
  191. var returnType = null;
  192. if (input) {
  193. if (dojo.lang.isObject(input) && !dojo.lang.isBuiltIn(input)) {
  194. var namedParameters = input;
  195. dojo.lang.assertValidKeywords(namedParameters, ["node", "hardwareNode", "pseudoNode", "returnType"]);
  196. var node = namedParameters["node"];
  197. var hardwareNode = namedParameters["hardwareNode"];
  198. var pseudoNode = namedParameters["pseudoNode"];
  199. nodeString = (node || pseudoNode || hardwareNode);
  200. if (nodeString) {
  201. var firstCharacter = nodeString.charAt(0);
  202. var firstDigit = parseInt(firstCharacter, HEX_RADIX);
  203. if (hardwareNode) {
  204. dojo.lang.assert((firstDigit >= 0) && (firstDigit <= 7));
  205. }
  206. if (pseudoNode) {
  207. dojo.lang.assert((firstDigit >= 8) && (firstDigit <= 15));
  208. }
  209. }
  210. returnType = namedParameters["returnType"];
  211. dojo.lang.assertType(returnType, Function, {optional:true});
  212. } else {
  213. if (dojo.lang.isString(input)) {
  214. nodeString = input;
  215. returnType = null;
  216. } else {
  217. if (dojo.lang.isFunction(input)) {
  218. nodeString = null;
  219. returnType = input;
  220. }
  221. }
  222. }
  223. if (nodeString) {
  224. dojo.lang.assert(nodeString.length == 12);
  225. var integer = parseInt(nodeString, HEX_RADIX);
  226. dojo.lang.assert(isFinite(integer));
  227. }
  228. dojo.lang.assertType(returnType, Function, {optional:true});
  229. }
  230. var uuidString = _generateUuidString(nodeString);
  231. var returnValue;
  232. if (returnType && (returnType != String)) {
  233. returnValue = new returnType(uuidString);
  234. } else {
  235. returnValue = uuidString;
  236. }
  237. return returnValue;
  238. };
  239. }();