mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Nicolas Capponi
26.31.2013 efa949b25f472d7e4c39733678d8f0e5229f8201
opendj-sdk/opendj-admin/src/main/java/org/opends/server/admin/DurationUnit.java
@@ -25,360 +25,325 @@
 */
package org.opends.server.admin;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * This enumeration defines various duration units.
 */
public enum DurationUnit {
  /**
   * A day unit.
   */
  DAYS((long) 24 * 60 * 60 * 1000, "d", "days"),
    /**
     * A day unit.
     */
    DAYS((long) 24 * 60 * 60 * 1000, "d", "days"),
  /**
   * An hour unit.
   */
  HOURS((long) 60 * 60 * 1000, "h", "hours"),
    /**
     * An hour unit.
     */
    HOURS((long) 60 * 60 * 1000, "h", "hours"),
  /**
   * A millisecond unit.
   */
  MILLI_SECONDS(1L, "ms", "milliseconds"),
    /**
     * A millisecond unit.
     */
    MILLI_SECONDS(1L, "ms", "milliseconds"),
  /**
   * A minute unit.
   */
  MINUTES((long) 60 * 1000, "m", "minutes"),
    /**
     * A minute unit.
     */
    MINUTES((long) 60 * 1000, "m", "minutes"),
  /**
   * A second unit.
   */
  SECONDS(1000L, "s", "seconds"),
    /**
     * A second unit.
     */
    SECONDS(1000L, "s", "seconds"),
  /**
   * A week unit.
   */
  WEEKS((long) 7 * 24 * 60 * 60 * 1000, "w", "weeks");
    /**
     * A week unit.
     */
    WEEKS((long) 7 * 24 * 60 * 60 * 1000, "w", "weeks");
  // A lookup table for resolving a unit from its name.
  private static final Map<String, DurationUnit> nameToUnit;
  static {
    nameToUnit = new HashMap<String, DurationUnit>();
    // A lookup table for resolving a unit from its name.
    private static final Map<String, DurationUnit> NAME_TO_UNIT;
    static {
        NAME_TO_UNIT = new HashMap<String, DurationUnit>();
    for (DurationUnit unit : DurationUnit.values()) {
      nameToUnit.put(unit.shortName, unit);
      nameToUnit.put(unit.longName, unit);
    }
  }
  /**
   * Get the unit corresponding to the provided unit name.
   *
   * @param s
   *          The name of the unit. Can be the abbreviated or long
   *          name and can contain white space and mixed case
   *          characters.
   * @return Returns the unit corresponding to the provided unit name.
   * @throws IllegalArgumentException
   *           If the provided name did not correspond to a known
   *           duration unit.
   */
  public static DurationUnit getUnit(String s) throws IllegalArgumentException {
    DurationUnit unit = nameToUnit.get(s.trim().toLowerCase());
    if (unit == null) {
      throw new IllegalArgumentException("Illegal duration unit \"" + s + "\"");
    }
    return unit;
  }
  /**
   * Parse the provided duration string and return its equivalent
   * duration in milliseconds. The duration string must specify the
   * unit e.g. "10s". This method will parse duration string
   * representations produced from the {@link #toString(long)} method.
   * Therefore, a duration can comprise of multiple duration
   * specifiers, for example <code>1d15m25s</code>.
   *
   * @param s
   *          The duration string to be parsed.
   * @return Returns the parsed duration in milliseconds.
   * @throws NumberFormatException
   *           If the provided duration string could not be parsed.
   * @see #toString(long)
   */
  public static long parseValue(String s) throws NumberFormatException {
    return parseValue(s, null);
  }
  /**
   * Parse the provided duration string and return its equivalent
   * duration in milliseconds. This method will parse duration string
   * representations produced from the {@link #toString(long)} method.
   * Therefore, a duration can comprise of multiple duration
   * specifiers, for example <code>1d15m25s</code>.
   *
   * @param s
   *          The duration string to be parsed.
   * @param defaultUnit
   *          The default unit to use if there is no unit specified in
   *          the duration string, or <code>null</code> if the
   *          string must always contain a unit.
   * @return Returns the parsed duration in milliseconds.
   * @throws NumberFormatException
   *           If the provided duration string could not be parsed.
   * @see #toString(long)
   */
  public static long parseValue(String s, DurationUnit defaultUnit)
      throws NumberFormatException {
    String ns = s.trim();
    if (ns.length() == 0) {
      throw new NumberFormatException("Empty duration value \"" + s + "\"");
        for (DurationUnit unit : DurationUnit.values()) {
            NAME_TO_UNIT.put(unit.shortName, unit);
            NAME_TO_UNIT.put(unit.longName, unit);
        }
    }
    Pattern p1 = Pattern.compile("^\\s*((\\d+)\\s*w)?" + "\\s*((\\d+)\\s*d)?"
        + "\\s*((\\d+)\\s*h)?" + "\\s*((\\d+)\\s*m)?" + "\\s*((\\d+)\\s*s)?"
        + "\\s*((\\d+)\\s*ms)?\\s*$", Pattern.CASE_INSENSITIVE);
    Matcher m1 = p1.matcher(ns);
    if (m1.matches()) {
      // Value must be of the form produced by toString(long).
      String weeks = m1.group(2);
      String days = m1.group(4);
      String hours = m1.group(6);
      String minutes = m1.group(8);
      String seconds = m1.group(10);
      String ms = m1.group(12);
    /**
     * Get the unit corresponding to the provided unit name.
     *
     * @param s
     *            The name of the unit. Can be the abbreviated or long name and
     *            can contain white space and mixed case characters.
     * @return Returns the unit corresponding to the provided unit name.
     * @throws IllegalArgumentException
     *             If the provided name did not correspond to a known duration
     *             unit.
     */
    public static DurationUnit getUnit(String s) {
        DurationUnit unit = NAME_TO_UNIT.get(s.trim().toLowerCase());
        if (unit == null) {
            throw new IllegalArgumentException("Illegal duration unit \"" + s + "\"");
        }
        return unit;
    }
      long duration = 0;
    /**
     * Parse the provided duration string and return its equivalent duration in
     * milliseconds. The duration string must specify the unit e.g. "10s". This
     * method will parse duration string representations produced from the
     * {@link #toString(long)} method. Therefore, a duration can comprise of
     * multiple duration specifiers, for example <code>1d15m25s</code>.
     *
     * @param s
     *            The duration string to be parsed.
     * @return Returns the parsed duration in milliseconds.
     * @throws NumberFormatException
     *             If the provided duration string could not be parsed.
     * @see #toString(long)
     */
    public static long parseValue(String s) {
        return parseValue(s, null);
    }
      try {
        if (weeks != null) {
          duration += Long.valueOf(weeks) * WEEKS.getDuration();
    /**
     * Parse the provided duration string and return its equivalent duration in
     * milliseconds. This method will parse duration string representations
     * produced from the {@link #toString(long)} method. Therefore, a duration
     * can comprise of multiple duration specifiers, for example
     * <code>1d15m25s</code>.
     *
     * @param s
     *            The duration string to be parsed.
     * @param defaultUnit
     *            The default unit to use if there is no unit specified in the
     *            duration string, or <code>null</code> if the string must
     *            always contain a unit.
     * @return Returns the parsed duration in milliseconds.
     * @throws NumberFormatException
     *             If the provided duration string could not be parsed.
     * @see #toString(long)
     */
    public static long parseValue(String s, DurationUnit defaultUnit) {
        String ns = s.trim();
        if (ns.length() == 0) {
            throw new NumberFormatException("Empty duration value \"" + s + "\"");
        }
        if (days != null) {
          duration += Long.valueOf(days) * DAYS.getDuration();
        }
        Pattern p1 =
            Pattern.compile("^\\s*((\\d+)\\s*w)?" + "\\s*((\\d+)\\s*d)?" + "\\s*((\\d+)\\s*h)?"
                + "\\s*((\\d+)\\s*m)?" + "\\s*((\\d+)\\s*s)?" + "\\s*((\\d+)\\s*ms)?\\s*$", Pattern.CASE_INSENSITIVE);
        Matcher m1 = p1.matcher(ns);
        if (m1.matches()) {
            // Value must be of the form produced by toString(long).
            String weeks = m1.group(2);
            String days = m1.group(4);
            String hours = m1.group(6);
            String minutes = m1.group(8);
            String seconds = m1.group(10);
            String ms = m1.group(12);
        if (hours != null) {
          duration += Long.valueOf(hours) * HOURS.getDuration();
        }
            long duration = 0;
        if (minutes != null) {
          duration += Long.valueOf(minutes) * MINUTES.getDuration();
        }
            try {
                if (weeks != null) {
                    duration += Long.valueOf(weeks) * WEEKS.getDuration();
                }
        if (seconds != null) {
          duration += Long.valueOf(seconds) * SECONDS.getDuration();
        }
                if (days != null) {
                    duration += Long.valueOf(days) * DAYS.getDuration();
                }
        if (ms != null) {
          duration += Long.valueOf(ms) * MILLI_SECONDS.getDuration();
        }
      } catch (NumberFormatException e) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
      }
                if (hours != null) {
                    duration += Long.valueOf(hours) * HOURS.getDuration();
                }
      return duration;
    } else {
      // Value must be a floating point number followed by a unit.
      Pattern p2 = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)?\\s*$");
      Matcher m2 = p2.matcher(ns);
                if (minutes != null) {
                    duration += Long.valueOf(minutes) * MINUTES.getDuration();
                }
      if (!m2.matches()) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
      }
                if (seconds != null) {
                    duration += Long.valueOf(seconds) * SECONDS.getDuration();
                }
      // Group 1 is the float.
      double d;
      try {
        d = Double.valueOf(m2.group(1));
      } catch (NumberFormatException e) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
      }
                if (ms != null) {
                    duration += Long.valueOf(ms) * MILLI_SECONDS.getDuration();
                }
            } catch (NumberFormatException e) {
                throw new NumberFormatException("Invalid duration value \"" + s + "\"");
            }
      // Group 3 is the unit.
      String unitString = m2.group(3);
      DurationUnit unit;
      if (unitString == null) {
        if (defaultUnit == null) {
          throw new NumberFormatException("Invalid duration value \"" + s
              + "\"");
            return duration;
        } else {
          unit = defaultUnit;
            // Value must be a floating point number followed by a unit.
            Pattern p2 = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)?\\s*$");
            Matcher m2 = p2.matcher(ns);
            if (!m2.matches()) {
                throw new NumberFormatException("Invalid duration value \"" + s + "\"");
            }
            // Group 1 is the float.
            double d;
            try {
                d = Double.valueOf(m2.group(1));
            } catch (NumberFormatException e) {
                throw new NumberFormatException("Invalid duration value \"" + s + "\"");
            }
            // Group 3 is the unit.
            String unitString = m2.group(3);
            DurationUnit unit;
            if (unitString == null) {
                if (defaultUnit == null) {
                    throw new NumberFormatException("Invalid duration value \"" + s + "\"");
                } else {
                    unit = defaultUnit;
                }
            } else {
                try {
                    unit = getUnit(unitString);
                } catch (IllegalArgumentException e) {
                    throw new NumberFormatException("Invalid duration value \"" + s + "\"");
                }
            }
            return unit.toMilliSeconds(d);
        }
      } else {
        try {
          unit = getUnit(unitString);
        } catch (IllegalArgumentException e) {
          throw new NumberFormatException("Invalid duration value \"" + s
              + "\"");
    }
    /**
     * Returns a string representation of the provided duration. The string
     * representation can be parsed using the {@link #parseValue(String)}
     * method. The string representation is comprised of one or more of the
     * number of weeks, days, hours, minutes, seconds, and milliseconds. Here
     * are some examples:
     *
     * <pre>
     * toString(0)       // 0 ms
     * toString(999)     // 999 ms
     * toString(1000)    // 1 s
     * toString(1500)    // 1 s 500 ms
     * toString(3650000) // 1 h 50 s
     * toString(3700000) // 1 h 1 m 40 s
     * </pre>
     *
     * @param duration
     *            The duration in milliseconds.
     * @return Returns a string representation of the provided duration.
     * @throws IllegalArgumentException
     *             If the provided duration is negative.
     * @see #parseValue(String)
     * @see #parseValue(String, DurationUnit)
     */
    public static String toString(long duration) {
        if (duration < 0) {
            throw new IllegalArgumentException("Negative duration " + duration);
        }
      }
      return unit.toMilliSeconds(d);
    }
  }
  /**
   * Returns a string representation of the provided duration. The
   * string representation can be parsed using the
   * {@link #parseValue(String)} method. The string representation is
   * comprised of one or more of the number of weeks, days, hours,
   * minutes, seconds, and milliseconds. Here are some examples:
   *
   * <pre>
   * toString(0)       // 0 ms
   * toString(999)     // 999 ms
   * toString(1000)    // 1 s
   * toString(1500)    // 1 s 500 ms
   * toString(3650000) // 1 h 50 s
   * toString(3700000) // 1 h 1 m 40 s
   * </pre>
   *
   * @param duration
   *          The duration in milliseconds.
   * @return Returns a string representation of the provided duration.
   * @throws IllegalArgumentException
   *           If the provided duration is negative.
   * @see #parseValue(String)
   * @see #parseValue(String, DurationUnit)
   */
  public static String toString(long duration) throws IllegalArgumentException {
    if (duration < 0) {
      throw new IllegalArgumentException("Negative duration " + duration);
    }
    if (duration == 0) {
      return "0 ms";
    }
    DurationUnit[] units = new DurationUnit[] { WEEKS, DAYS, HOURS, MINUTES,
        SECONDS, MILLI_SECONDS };
    long remainder = duration;
    StringBuilder builder = new StringBuilder();
    boolean isFirst = true;
    for (DurationUnit unit : units) {
      long count = remainder / unit.getDuration();
      if (count > 0) {
        if (!isFirst) {
          builder.append(' ');
        if (duration == 0) {
            return "0 ms";
        }
        builder.append(count);
        builder.append(' ');
        builder.append(unit.getShortName());
        remainder = remainder - (count * unit.getDuration());
        isFirst = false;
      }
        DurationUnit[] units = new DurationUnit[] { WEEKS, DAYS, HOURS, MINUTES, SECONDS, MILLI_SECONDS };
        long remainder = duration;
        StringBuilder builder = new StringBuilder();
        boolean isFirst = true;
        for (DurationUnit unit : units) {
            long count = remainder / unit.getDuration();
            if (count > 0) {
                if (!isFirst) {
                    builder.append(' ');
                }
                builder.append(count);
                builder.append(' ');
                builder.append(unit.getShortName());
                remainder = remainder - (count * unit.getDuration());
                isFirst = false;
            }
        }
        return builder.toString();
    }
    return builder.toString();
  }
  // The long name of the unit.
  private final String longName;
    // The long name of the unit.
    private final String longName;
  // The abbreviation of the unit.
  private final String shortName;
    // The abbreviation of the unit.
    private final String shortName;
  // The size of the unit in milliseconds.
  private final long sz;
    // The size of the unit in milliseconds.
    private final long sz;
    // Private constructor.
    private DurationUnit(long sz, String shortName, String longName) {
        this.sz = sz;
        this.shortName = shortName;
        this.longName = longName;
    }
    /**
     * Converts the specified duration in milliseconds to this unit.
     *
     * @param duration
     *            The duration in milliseconds.
     * @return Returns milliseconds in this unit.
     */
    public double fromMilliSeconds(long duration) {
        return ((double) duration / sz);
    }
  // Private constructor.
  private DurationUnit(long sz, String shortName, String longName) {
    this.sz = sz;
    this.shortName = shortName;
    this.longName = longName;
  }
    /**
     * Get the number of milliseconds that this unit represents.
     *
     * @return Returns the number of milliseconds that this unit represents.
     */
    public long getDuration() {
        return sz;
    }
    /**
     * Get the long name of this unit.
     *
     * @return Returns the long name of this unit.
     */
    public String getLongName() {
        return longName;
    }
    /**
     * Get the abbreviated name of this unit.
     *
     * @return Returns the abbreviated name of this unit.
     */
    public String getShortName() {
        return shortName;
    }
  /**
   * Converts the specified duration in milliseconds to this unit.
   *
   * @param duration
   *          The duration in milliseconds.
   * @return Returns milliseconds in this unit.
   */
  public double fromMilliSeconds(long duration) {
    return ((double) duration / sz);
  }
    /**
     * Converts the specified duration in this unit to milliseconds.
     *
     * @param duration
     *            The duration as a quantity of this unit.
     * @return Returns the number of milliseconds that the duration represents.
     */
    public long toMilliSeconds(double duration) {
        return (long) (sz * duration);
    }
  /**
   * Get the number of milliseconds that this unit represents.
   *
   * @return Returns the number of milliseconds that this unit
   *         represents.
   */
  public long getDuration() {
    return sz;
  }
  /**
   * Get the long name of this unit.
   *
   * @return Returns the long name of this unit.
   */
  public String getLongName() {
    return longName;
  }
  /**
   * Get the abbreviated name of this unit.
   *
   * @return Returns the abbreviated name of this unit.
   */
  public String getShortName() {
    return shortName;
  }
  /**
   * Converts the specified duration in this unit to milliseconds.
   *
   * @param duration
   *          The duration as a quantity of this unit.
   * @return Returns the number of milliseconds that the duration
   *         represents.
   */
  public long toMilliSeconds(double duration) {
    return (long) (sz * duration);
  }
  /**
   * {@inheritDoc}
   * <p>
   * This implementation returns the abbreviated name of this duration
   * unit.
   */
  @Override
  public String toString() {
    return shortName;
  }
    /**
     * {@inheritDoc}
     * <p>
     * This implementation returns the abbreviated name of this duration unit.
     */
    @Override
    public String toString() {
        return shortName;
    }
}