From c4b20d52fa50404b6b8d0a910a41b3fc47cfb90e Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Tue, 24 Apr 2007 08:21:24 +0000
Subject: [PATCH] This change (no associated issue no.) addresses some counter-intuitive behavior discovered when specifying some duration based properties:

---
 opends/src/server/org/opends/server/admin/DurationUnit.java |  210 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 144 insertions(+), 66 deletions(-)

diff --git a/opends/src/server/org/opends/server/admin/DurationUnit.java b/opends/src/server/org/opends/server/admin/DurationUnit.java
index 2fa0c5a..7b8c0ae 100644
--- a/opends/src/server/org/opends/server/admin/DurationUnit.java
+++ b/opends/src/server/org/opends/server/admin/DurationUnit.java
@@ -30,6 +30,8 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 
 
@@ -79,6 +81,99 @@
     }
   }
 
+
+
+  /**
+   * 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 milli-seconds. The duration string must specify the
+   * unit e.g. "10s".
+   *
+   * @param s
+   *          The duration string to be parsed.
+   * @return Returns the parsed duration in milli-seconds.
+   * @throws NumberFormatException
+   *           If the provided duration string could not be parsed.
+   */
+  public static long parseValue(String s) throws NumberFormatException {
+    return parseValue(s, null);
+  }
+
+
+
+  /**
+   * Parse the provided duration string and return its equivalent
+   * duration in milli-seconds.
+   *
+   * @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 milli-seconds.
+   * @throws NumberFormatException
+   *           If the provided duration string could not be parsed.
+   */
+  public static long parseValue(String s, DurationUnit defaultUnit)
+      throws NumberFormatException {
+    // Value must be a floating point number followed by a unit.
+    Pattern p = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)?\\s*$");
+    Matcher m = p.matcher(s);
+
+    if (!m.matches()) {
+      throw new NumberFormatException("Invalid duration value \"" + s + "\"");
+    }
+
+    // Group 1 is the float.
+    double d;
+    try {
+      d = Double.valueOf(m.group(1));
+    } catch (NumberFormatException e) {
+      throw new NumberFormatException("Invalid duration value \"" + s + "\"");
+    }
+
+    // Group 3 is the unit.
+    String unitString = m.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);
+  }
+
   // The size of the unit in milli-seconds.
   private final long sz;
 
@@ -100,32 +195,54 @@
 
 
   /**
-   * Get the unit corresponding to the provided unit name.
+   * Converts the specified duration in milli-seconds to this unit.
    *
-   * @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.
+   * @param duration
+   *          The duration in milli-seconds.
+   * @return Returns milli-seconds in this 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;
+  public double fromMilliSeconds(long duration) {
+    return ((double) duration / sz);
   }
 
 
 
   /**
-   * Get the abbreviated name of this unit.
+   * Get the best-fit unit for the specified duration in this unit.
+   * For example, if this unit is minutes and the duration 120 is
+   * provided, then the best fit unit is hours: 2h. Similarly, if the
+   * duration is 0.5, then the best fit unit will by seconds: 30s.
    *
-   * @return Returns the abbreviated name of this unit.
+   * @param duration
+   *          The duration.
+   * @return Returns the best-fit unit for the specified duration in
+   *         this unit.
    */
-  public String getShortName() {
-    return shortName;
+  public DurationUnit getBestFitUnit(double duration) {
+    long ms = toMilliSeconds(duration);
+    if (ms == 0) {
+      return this;
+    } else if (ms > 0) {
+      for (DurationUnit unit : new DurationUnit[] { WEEKS, DAYS, HOURS,
+          MINUTES, SECONDS }) {
+        if ((ms % unit.sz) == 0) {
+          return unit;
+        }
+      }
+    }
+    return MILLI_SECONDS;
+  }
+
+
+
+  /**
+   * Get the number of milli-seconds that this unit represents.
+   *
+   * @return Returns the number of milli-seconds that this unit
+   *         represents.
+   */
+  public long getDuration() {
+    return sz;
   }
 
 
@@ -142,12 +259,12 @@
 
 
   /**
-   * Get the number of milli-seconds that this unit represents.
+   * Get the abbreviated name of this unit.
    *
-   * @return Returns the number of milli-seconds that this unit represents.
+   * @return Returns the abbreviated name of this unit.
    */
-  public long getDuration() {
-    return sz;
+  public String getShortName() {
+    return shortName;
   }
 
 
@@ -156,60 +273,21 @@
    * Converts the specified duration in this unit to milli-seconds.
    *
    * @param duration
-   *          The duration.
-   * @return Returns the number of milli-seconds that the duration represents.
+   *          The duration as a quantity of this unit.
+   * @return Returns the number of milli-seconds that the duration
+   *         represents.
    */
-  public long getDuration(double duration) {
+  public long toMilliSeconds(double duration) {
     return (long) (sz * duration);
   }
 
 
 
   /**
-   * Converts a duration in this unit to the specified unit.
-   *
-   * @param duration
-   *          The duration.
-   * @param unit
-   *          The required unit.
-   * @return Returns a value representing the duration in the specified unit.
-   */
-  public double getDuration(double duration, DurationUnit unit) {
-    return (sz * duration) / unit.sz;
-  }
-
-
-
-  /**
-   * Get the best-fit unit for the specified duration in this unit. For example,
-   * if this unit is minutes and the duration 120 is provided, then the best fit
-   * unit is hours: 2h. Similarly, if the duration is 0.5, then the best fit
-   * unit will by seconds: 30s.
-   *
-   * @param duration
-   *          The duration.
-   * @return Returns the best-fit unit for the specified duration in this unit.
-   */
-  public DurationUnit getBestFitUnit(double duration) {
-    for (DurationUnit unit :
-            new DurationUnit[]{WEEKS, DAYS, HOURS, MINUTES, SECONDS}) {
-      double v = getDuration(duration, unit);
-      if (Double.isInfinite(v) || Double.isNaN(v) || v == 0) {
-        return this;
-      }
-      if (v >= 1 && Math.floor(v) == Math.ceil(v)) {
-        return unit;
-      }
-    }
-    return MILLI_SECONDS;
-  }
-
-
-
-  /**
    * {@inheritDoc}
    * <p>
-   * This implementation returns the abbreviated name of this duration unit.
+   * This implementation returns the abbreviated name of this duration
+   * unit.
    */
   @Override
   public String toString() {

--
Gitblit v1.10.0