Source code: org/activemq/util/IdGenerator.java
1 /**
2 *
3 * Copyright 2004 Protique Ltd
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.activemq.util;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import java.net.InetAddress;
24 import java.net.ServerSocket;
25
26 /**
27 * Generator for globally unique Strings
28 *
29 * @version $Revision: 1.1.1.1 $
30 */
31 public class IdGenerator {
32 private static final Log log = LogFactory.getLog(IdGenerator.class);
33 private static final String UNIQUE_STUB;
34 private static int instanceCount;
35 private static String hostName;
36 private String seed;
37 private long sequence;
38 private short shortSequence;
39
40 static {
41 String stub = "";
42 boolean canAccessSystemProps = true;
43 try {
44 SecurityManager sm = System.getSecurityManager();
45 if (sm != null) {
46 sm.checkPropertiesAccess();
47 }
48 }
49 catch (SecurityException se) {
50 canAccessSystemProps = false;
51 }
52 if (canAccessSystemProps) {
53 try {
54 hostName = InetAddress.getLocalHost().getHostName();
55 ServerSocket ss = new ServerSocket(0);
56 stub = "ID:" + hostName + "-" + ss.getLocalPort() + "-" + System.currentTimeMillis() + "-";
57 Thread.sleep(100);
58 ss.close();
59 }
60 catch (Exception ioe) {
61 log.warn("could not generate unique stub", ioe);
62 }
63 }
64 else {
65 hostName = "localhost";
66 stub = "ID:" + hostName + "-1-" + System.currentTimeMillis() + "-";
67 }
68 UNIQUE_STUB = stub;
69 }
70
71 /**
72 * As we have to find the hostname as a side-affect of generating a unique stub, we allow it's easy retrevial here
73 *
74 * @return the local host name
75 */
76 public static String getHostName() {
77 return hostName;
78 }
79
80 /**
81 * Construct an IdGenerator
82 */
83 public IdGenerator() {
84 synchronized (UNIQUE_STUB) {
85 this.seed = UNIQUE_STUB + (instanceCount++) + ":";
86 }
87 }
88
89 /**
90 * Construct an IdGenerator using the seed provided
91 * @param seed
92 */
93 public IdGenerator(String seed){
94 this.seed = seed;
95 }
96
97
98 /**
99 * Generate a unqiue id
100 *
101 * @return a unique id
102 */
103 public synchronized String generateId() {
104 return this.seed + (this.sequence++);
105 }
106
107 /**
108 * @return the unique seed used by this generator
109 */
110 public String getSeed() {
111 return seed;
112 }
113
114 /**
115 * @return the next sequence
116 */
117 public synchronized long getNextSequence(){
118 return this.sequence++;
119 }
120
121 /**
122 * @return the next short sequence
123 */
124 public synchronized short getNextShortSequence(){
125 //need to start with 1 for some wire protocols
126 return ++this.shortSequence;
127 }
128
129 /**
130 * From a generated id - return the seed (i.e. minus the count)
131 *
132 * @param id the generated identifer
133 * @return
134 */
135 public static String getSeedFromId(String id) {
136 String result = id;
137 if (id != null) {
138 int index = id.lastIndexOf(':');
139 if (index > 0 && (index + 1) < id.length()) {
140 result = id.substring(0, index + 1);
141 }
142 }
143 return result;
144 }
145
146 /**
147 * From a generated id - return the generator count
148 *
149 * @param id
150 * @return the count
151 */
152 public static long getCountFromId(String id) {
153 long result = -1;
154 if (id != null) {
155 int index = id.lastIndexOf(':');
156
157 if (index > 0 && (index + 1) < id.length()) {
158 String numStr = id.substring(index + 1, id.length());
159 result = Long.parseLong(numStr);
160 }
161 }
162 return result;
163 }
164
165 /**
166 * Does a proper compare on the ids
167 *
168 * @param id1
169 * @param id2
170 * @return
171 */
172
173 public static int compare(String id1, String id2) {
174 int result = -1;
175 String seed1 = IdGenerator.getSeedFromId(id1);
176 String seed2 = IdGenerator.getSeedFromId(id2);
177 if (seed1 != null && seed2 != null) {
178 result = seed1.compareTo(seed2);
179 if (result == 0) {
180 long count1 = IdGenerator.getCountFromId(id1);
181 long count2 = IdGenerator.getCountFromId(id2);
182 result = (int) (count1 - count2);
183 }
184 }
185 return result;
186
187 }
188 }