ObjectVersion.java 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package com.yihu.hos.common;
  2. import java.io.Serializable;
  3. import java.security.SecureRandom;
  4. import java.util.Date;
  5. import java.util.concurrent.atomic.AtomicInteger;
  6. /**
  7. * @author HZY
  8. * @vsrsion 1.0
  9. * Created at 2016/8/8.
  10. */
  11. public final class ObjectVersion implements Comparable<ObjectVersion>, Serializable {
  12. private static final long serialVersionUID = 789056789654456072L;
  13. private static final int BYTE_ARRAY_LENGTH = 6;
  14. private static final AtomicInteger NEXT_COUNTER = new AtomicInteger((new SecureRandom()).nextInt());
  15. private static final char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  16. private final int timestamp;
  17. private final short counter;
  18. public static boolean isValid(String hexString) {
  19. if(hexString == null) {
  20. throw new IllegalArgumentException();
  21. } else {
  22. int len = hexString.length();
  23. if(len != 12) {
  24. return false;
  25. } else {
  26. for(int i = 0; i < len; ++i) {
  27. char c = hexString.charAt(i);
  28. if((c < 48 || c > 57) && (c < 97 || c > 102) && (c < 65 || c > 70)) {
  29. return false;
  30. }
  31. }
  32. return true;
  33. }
  34. }
  35. }
  36. public static int getCurrentCounter() {
  37. return NEXT_COUNTER.get();
  38. }
  39. public ObjectVersion() {
  40. this(new Date());
  41. }
  42. public ObjectVersion(Date date) {
  43. this(dateToTimestampSeconds(date), (short)NEXT_COUNTER.getAndIncrement());
  44. }
  45. public ObjectVersion(Date date, short counter) {
  46. this(dateToTimestampSeconds(date), counter);
  47. }
  48. public ObjectVersion(int timestamp, short counter) {
  49. this.timestamp = timestamp;
  50. this.counter = counter;
  51. }
  52. public ObjectVersion(String hexString) {
  53. this(parseHexString(hexString));
  54. }
  55. public ObjectVersion(byte[] bytes) {
  56. if(bytes == null) {
  57. throw new IllegalArgumentException();
  58. } else if(bytes.length != 6) {
  59. throw new IllegalArgumentException("need 6 bytes");
  60. } else {
  61. this.timestamp = makeInt(bytes[0], bytes[1], bytes[2], bytes[3]);
  62. this.counter = (short)makeInt((byte)0, (byte)0, bytes[4], bytes[5]);
  63. }
  64. }
  65. public byte[] toByteArray() {
  66. byte[] bytes = new byte[]{int3(this.timestamp), int2(this.timestamp), int1(this.timestamp), int0(this.timestamp), int1(this.counter), int0(this.counter)};
  67. return bytes;
  68. }
  69. public Date getDate() {
  70. return new Date((long)this.timestamp * 1000L);
  71. }
  72. public int getTimestamp() {
  73. return this.timestamp;
  74. }
  75. public short getCounter() {
  76. return this.counter;
  77. }
  78. public String toHexString() {
  79. char[] chars = new char[12];
  80. int i = 0;
  81. byte[] var3 = this.toByteArray();
  82. int var4 = var3.length;
  83. for(int var5 = 0; var5 < var4; ++var5) {
  84. byte b = var3[var5];
  85. chars[i++] = HEX_CHARS[b >> 4 & 15];
  86. chars[i++] = HEX_CHARS[b & 15];
  87. }
  88. return new String(chars);
  89. }
  90. public boolean equals(Object o) {
  91. if(this == o) {
  92. return true;
  93. } else if(o != null && this.getClass() == o.getClass()) {
  94. ObjectVersion objectId = (ObjectVersion)o;
  95. return this.counter != objectId.counter?false:this.timestamp == objectId.timestamp;
  96. } else {
  97. return false;
  98. }
  99. }
  100. public int hashCode() {
  101. int result = this.timestamp;
  102. result = 31 * result + this.counter;
  103. return result;
  104. }
  105. public int compareTo(ObjectVersion other) {
  106. if(other == null) {
  107. throw new NullPointerException();
  108. } else {
  109. byte[] byteArray = this.toByteArray();
  110. byte[] otherByteArray = other.toByteArray();
  111. for(int i = 0; i < 6; ++i) {
  112. if(byteArray[i] != otherByteArray[i]) {
  113. return (byteArray[i] & 255) < (otherByteArray[i] & 255)?-1:1;
  114. }
  115. }
  116. return 0;
  117. }
  118. }
  119. public String toString() {
  120. return this.toHexString();
  121. }
  122. private static byte[] parseHexString(String s) {
  123. if(!isValid(s)) {
  124. throw new IllegalArgumentException("invalid hexadecimal representation of an ObjectId: [" + s + "]");
  125. } else {
  126. byte[] b = new byte[6];
  127. for(int i = 0; i < b.length; ++i) {
  128. b[i] = (byte)Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16);
  129. }
  130. return b;
  131. }
  132. }
  133. private static int dateToTimestampSeconds(Date time) {
  134. return (int)(time.getTime() / 1000L);
  135. }
  136. private static int makeInt(byte b3, byte b2, byte b1, byte b0) {
  137. return b3 << 24 | (b2 & 255) << 16 | (b1 & 255) << 8 | b0 & 255;
  138. }
  139. private static byte int3(int x) {
  140. return (byte)(x >> 24);
  141. }
  142. private static byte int2(int x) {
  143. return (byte)(x >> 16);
  144. }
  145. private static byte int1(int x) {
  146. return (byte)(x >> 8);
  147. }
  148. private static byte int0(int x) {
  149. return (byte)x;
  150. }
  151. }