001/*
002 * JPPF.
003 * Copyright (C) 2005-2015 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.jppf.utils;
019
020import java.io.Serializable;
021import java.security.SecureRandom;
022import java.util.*;
023
024/**
025 * Instances of this class serve as unique identifiers for messages sent to and from
026 * remote execution services.
027 * The identifier is generated as a string with the following elements:
028 * <ul>
029 * <li>sender host IP address</li>
030 * <li>current system time in milliseconds</li>
031 * <li>a random integer value between 0 and {@link java.lang.Integer#MAX_VALUE Integer.MAX_VALUE}</li>
032 * </ul>
033 * @author Laurent Cohen
034 */
035public class JPPFUuid implements Serializable {
036  /**
037   * Explicit serialVersionUID.
038   */
039  private static final long serialVersionUID = 1L;
040  /**
041   * Set of characters used to compose a uuid, including more than alphanumeric characters.
042   */
043  public static final char[] ALPHABET_SUPERSET_CHAR = {
044    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
045    'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
046    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\'', '!', '@', '#',
047    '$', '%', '^', '&', '*', '(', ')', '_', '+', '|', '{', '}', '[', ']', '-', '=', '/', ',', '.', '?', ':', ';'
048  };
049  /**
050   * Set of characters used to compose a uuid, including only hexadecimal digits in lower case.
051   */
052  public static final char[] HEXADECIMAL_CHAR = {
053    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
054  };
055  /**
056   * Set of characters used to compose a uuid, including only hexadecimal digits in lower case.
057   */
058  public static final char[] HEXADECIMAL_UPPER_CHAR = {
059    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
060  };
061  /**
062   * Random number generator, static to ensure generated uuid are unique.
063   */
064  private final Random rand = createRandom();
065  /**
066   * String holding a generated unique identifier.
067   */
068  private String uuid = null;
069  /**
070   * The set of codes from which to choose randomly to build the uuid.
071   */
072  private char[] codes_char = ALPHABET_SUPERSET_CHAR;
073  /**
074   * Number of codes to use to build the uuid.
075   */
076  private int length = 20;
077
078  /**
079   * Instantiate this JPPFUuid with a generated unique identifier.
080   */
081  public JPPFUuid() {
082    this.uuid = UUID.randomUUID().toString().toUpperCase();
083  }
084
085  /**
086   * Instantiate this JPPFUuid with a generated unique identifier.
087   * @param codes the set of codes from which to choose randomly to build the uuid.
088   * @param length number of codes to use to build the uuid.
089   */
090  public JPPFUuid(final char[] codes, final int length) {
091    if ((codes != null) && (codes.length > 0)) this.codes_char = codes;
092    if (length > 0) this.length = length;
093    uuid = generateUuid();
094  }
095
096  /**
097   * Generate a unique uuid.
098   * @return the uuid as a string.
099   */
100  private String generateUuid() {
101    int len = codes_char.length;
102    StringBuilder sb = new StringBuilder(length);
103    for (int i=0; i<length; i++) sb.append(codes_char[rand.nextInt(len)]);
104    return sb.toString();
105  }
106
107  @Override
108  public String toString() {
109    return uuid;
110  }
111
112  /**
113   * Create a pseudo random number generator.
114   * @return a {@link Random} instance.
115   */
116  private static Random createRandom() {
117    return new SecureRandom();
118  }
119
120  /**
121   * Create a UUID in a standard format as described in {@link java.util.UUID#toString()}.
122   * @return a normalized UUID represented as a string.
123   */
124  public static String normalUUID() {
125    return UUID.randomUUID().toString().toUpperCase();
126  }
127}