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.codehaus.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 $ 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 39 static { 40 String stub = ""; 41 boolean canAccessSystemProps = true; 42 try { 43 SecurityManager sm = System.getSecurityManager(); 44 if (sm != null) { 45 sm.checkPropertiesAccess(); 46 } 47 } 48 catch (SecurityException se) { 49 canAccessSystemProps = false; 50 } 51 if (canAccessSystemProps) { 52 try { 53 hostName = InetAddress.getLocalHost().getHostName(); 54 ServerSocket ss = new ServerSocket(0); 55 stub = "ID:" + hostName + "-" + ss.getLocalPort() + "-" + System.currentTimeMillis() + "-"; 56 Thread.sleep(100); 57 ss.close(); 58 } 59 catch (Exception ioe) { 60 log.warn("could not generate unique stub", ioe); 61 } 62 } 63 else { 64 hostName = "localhost"; 65 stub = "ID:" + hostName + "-1-" + System.currentTimeMillis() + "-"; 66 } 67 UNIQUE_STUB = stub; 68 } 69 70 /*** 71 * As we have to find the hostname as a side-affect of generating a unique stub, we allow it's easy retrevial here 72 * 73 * @return the local host name 74 */ 75 public static String getHostName() { 76 return hostName; 77 } 78 79 /*** 80 * Construct an IdGenerator 81 */ 82 public IdGenerator() { 83 synchronized (UNIQUE_STUB) { 84 this.seed = UNIQUE_STUB + (instanceCount++) + ":"; 85 } 86 } 87 88 /*** 89 * Generate a unqiue id 90 * 91 * @return a unique id 92 */ 93 public synchronized String generateId() { 94 return this.seed + (this.sequence++); 95 } 96 97 /*** 98 * @return the unique seed used by this generator 99 */ 100 public String getSeed() { 101 return seed; 102 } 103 104 /*** 105 * From a generated id - return the seed (i.e. minus the count) 106 * 107 * @param id the generated identifer 108 * @return 109 */ 110 public static String getSeedFromId(String id) { 111 String result = id; 112 if (id != null) { 113 int index = id.lastIndexOf(':'); 114 if (index > 0 && (index + 1) < id.length()) { 115 result = id.substring(0, index + 1); 116 } 117 } 118 return result; 119 } 120 121 /*** 122 * From a generated id - return the generator count 123 * 124 * @param id 125 * @return the count 126 */ 127 public static long getCountFromId(String id) { 128 long result = -1; 129 if (id != null) { 130 int index = id.lastIndexOf(':'); 131 132 if (index > 0 && (index + 1) < id.length()) { 133 String numStr = id.substring(index + 1, id.length()); 134 result = Long.parseLong(numStr); 135 } 136 } 137 return result; 138 } 139 140 /*** 141 * Does a proper compare on the ids 142 * 143 * @param id1 144 * @param id2 145 * @return 146 */ 147 148 public static int compare(String id1, String id2) { 149 int result = -1; 150 String seed1 = IdGenerator.getSeedFromId(id1); 151 String seed2 = IdGenerator.getSeedFromId(id2); 152 if (seed1 != null && seed2 != null) { 153 result = seed1.compareTo(seed2); 154 if (result == 0) { 155 long count1 = IdGenerator.getCountFromId(id1); 156 long count2 = IdGenerator.getCountFromId(id2); 157 result = (int) (count1 - count2); 158 } 159 } 160 return result; 161 162 } 163 }