View Javadoc

    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 }