sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1425581 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/io/ main/java/org/apache/sis/math/ main/java/org/apache/sis/util/collection/ main/java/org/apache/sis/util/resources/ test/java/org/apache/sis/math/ test/java/org/ap...
Date Mon, 24 Dec 2012 03:22:36 GMT
Author: desruisseaux
Date: Mon Dec 24 03:22:35 2012
New Revision: 1425581

URL: http://svn.apache.org/viewvc?rev=1425581&view=rev
Log:
Tuned the StatisticsFormat API in order to make it a little bit more customizable.
In this case, this is useful to CacheTest.

Added:
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsFormatTest.java
      - copied, changed from r1425402, sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/Statistics.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java Mon Dec 24 03:22:35 2012
@@ -38,8 +38,8 @@ import org.apache.sis.util.resources.Err
  *   <li>{@link #setColumnSeparatorPattern(String)}</li>
  * </ul>
  *
- * For implementors, this base class takes care of splitting a column separator pattern into its
- * components ({@link #columnSeparator}, {@link #separatorPrefix} and {@link #separatorSuffix})
+ * For implementors, this base class takes care of splitting a column separator pattern into
+ * its components ({@link #beforeFill}, {@link #fillCharacter} and {@link #columnSeparator})
  * for easier usage in {@code format(…)} method implementations. Subclasses can use those fields
  * like below:
  *
@@ -50,16 +50,16 @@ import org.apache.sis.util.resources.Err
  * {@preformat java
  *     TableFormatter table = new TableFormatter(out, "");
  *     // ... do some work, then add a column separator:
- *     table.append(separatorPrefix);
- *     table.nextColumn(columnSeparator);
- *     table.append(separatorSuffix);
+ *     table.append(beforeFill);
+ *     table.nextColumn(fillCharacter);
+ *     table.append(columnSeparator);
  * }
  * </td><td>
  * {@preformat java
- *     TableFormatter table = new TableFormatter(out, separatorSuffix);
+ *     TableFormatter table = new TableFormatter(out, columnSeparator);
  *     // ... do some work, then add a column separator:
- *     table.append(separatorPrefix);
- *     table.nextColumn(columnSeparator);
+ *     table.append(beforeFill);
+ *     table.nextColumn(fillCharacter);
  * }
  * </td></tr></table>
  *
@@ -89,27 +89,27 @@ public abstract class TabularFormat<T> e
     protected String lineSeparator;
 
     /**
-     * The column separator to use at formatting time if there is more than one column.
-     * This is the character between the "{@code [ ]}" pair of brackets in the pattern
-     * given to the {@link #setColumnSeparatorPattern(String)} method.
-     *
-     * Subclasses will typically use this value in calls to {@link TableFormatter#nextColumn(char)}.
+     * The string to write after the {@link #fillCharacter}, or an empty string if none.
+     * This is the sequence of characters after the "{@code [ ]}" pair of brackets in the
+     * pattern given to the {@link #setColumnSeparatorPattern(String)} method.
      */
-    protected char columnSeparator;
+    protected String columnSeparator;
 
     /**
-     * The string to write before the {@link #columnSeparator}, or an empty string if none.
-     * This is the sequence of characters before the "{@code [ ]}" pair of brackets in the
-     * pattern given to the {@link #setColumnSeparatorPattern(String)} method.
+     * The character to repeat after the content of a cell for alignment with the next column.
+     * This is the character between the "{@code [ ]}" pair of brackets in the pattern given
+     * to the {@link #setColumnSeparatorPattern(String)} method.
+     *
+     * Subclasses will typically use this value in calls to {@link TableFormatter#nextColumn(char)}.
      */
-    protected String separatorPrefix;
+    protected char fillCharacter;
 
     /**
-     * The string to write after the {@link #columnSeparator}, or an empty string if none.
-     * This is the sequence of characters after the "{@code [ ]}" pair of brackets in the
+     * The string to write before the {@link #fillCharacter}, or an empty string if none.
+     * This is the sequence of characters before the "{@code [ ]}" pair of brackets in the
      * pattern given to the {@link #setColumnSeparatorPattern(String)} method.
      */
-    protected String separatorSuffix;
+    protected String beforeFill;
 
     /**
      * {@code true} if the trailing {@code null} values shall be omitted at formatting time.
@@ -137,9 +137,9 @@ public abstract class TabularFormat<T> e
      */
     public TabularFormat(final Locale locale, final TimeZone timezone) {
         super(locale, timezone);
-        separatorPrefix = "";
-        columnSeparator = ' ';
-        separatorSuffix = " ";
+        beforeFill      = "";
+        fillCharacter   = ' ';
+        columnSeparator = " ";
         lineSeparator   = System.lineSeparator();
     }
 
@@ -171,7 +171,7 @@ public abstract class TabularFormat<T> e
      */
     public String getColumnSeparatorPattern() {
         final StringBuilder buffer = new StringBuilder(8);
-        buffer.append(separatorPrefix).append('\uFFFF').append(separatorSuffix);
+        buffer.append(beforeFill).append('\uFFFF').append(columnSeparator);
         StringBuilders.replace(buffer, "\\", "\\\\");
         StringBuilders.replace(buffer, "?",  "\\?");
         StringBuilders.replace(buffer, "[",  "\\[");
@@ -181,7 +181,7 @@ public abstract class TabularFormat<T> e
             buffer.insert(0, '?');
         }
         final int insertAt = buffer.indexOf("\uFFFF");
-        buffer.replace(insertAt, insertAt+1, "[\uFFFF]").setCharAt(insertAt+1, columnSeparator);
+        buffer.replace(insertAt, insertAt+1, "[\uFFFF]").setCharAt(insertAt+1, fillCharacter);
         if (isParsePatternDefined) {
             buffer.append('/').append(parsePattern.pattern());
         }
@@ -304,9 +304,9 @@ scan:   for (int i=0; i<length; i++) {
             isParsePatternDefined = false;
         }
         omitTrailingNulls = trim;
-        separatorPrefix   = prefix;
-        separatorSuffix   = buffer.toString();
-        columnSeparator   = pattern.charAt(separatorIndex);
+        beforeFill        = prefix;
+        columnSeparator   = buffer.toString();
+        fillCharacter     = pattern.charAt(separatorIndex);
     }
 
     /**
@@ -318,11 +318,11 @@ scan:   for (int i=0; i<length; i++) {
      */
     protected Matcher getColumnSeparatorMatcher(final CharSequence text) {
         if (parsePattern == null) {
-            final StringBuilder pattern = new StringBuilder(separatorPrefix).append(columnSeparator);
+            final StringBuilder pattern = new StringBuilder(beforeFill).append(fillCharacter);
             String tmp = pattern.toString();
             pattern.setLength(0);
             pattern.append(Pattern.quote(tmp)).append('*');
-            tmp = separatorSuffix;
+            tmp = columnSeparator;
             if (tmp.length() != 0) {
                 pattern.append(Pattern.quote(tmp));
             }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/Statistics.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/Statistics.java?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/Statistics.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/Statistics.java Mon Dec 24 03:22:35 2012
@@ -17,13 +17,18 @@
 package org.apache.sis.math;
 
 import java.io.Serializable;
+import org.opengis.util.InternationalString;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.iso.Types;
 
 import static java.lang.Math.*;
 import static java.lang.Double.NaN;
 import static java.lang.Double.isNaN;
 import static java.lang.Double.doubleToLongBits;
 
+// Related to JDK7
+import java.util.Objects;
+
 
 /**
  * Holds some statistics derived from a series of sample values.
@@ -57,7 +62,7 @@ import static java.lang.Double.doubleToL
  * is defined. A simple usage is:
  *
  * {@preformat java
- *     Statistics stats = new Statistics();
+ *     Statistics stats = new Statistics("y");
  *     for (int i=0; i<numberOfValues; i++) {
  *         stats.add(f(i));
  *     }
@@ -70,7 +75,7 @@ import static java.lang.Double.doubleToL
  * {@preformat java
  *     final double x₀ = ...; // Put here the x value at i=0
  *     final double Δx = ...; // Put here the interval between x values
- *     Statistics stats = Statistics.forSeries(2);
+ *     Statistics stats = Statistics.forSeries("y", "∂y/∂x", "∂²y/∂x²");
  *     for (int i=0; i<numberOfValues; i++) {
  *         stats.add(f(x₀ + i*Δx));
  *     }
@@ -90,6 +95,15 @@ public class Statistics implements Clone
     private static final long serialVersionUID = -22884277805533726L;
 
     /**
+     * The name of the phenomenon for which this object is collecting statistics.
+     * If non-null, then this name will be shown as column header in the table formatted
+     * by {@link StatisticsFormat}.
+     *
+     * @see #name()
+     */
+    private final InternationalString name;
+
+    /**
      * The minimal value given to the {@link #add(double)} method.
      */
     private double minimum = NaN;
@@ -138,10 +152,15 @@ public class Statistics implements Clone
      * and all other statistical values are initialized to {@link Double#NaN}.
      *
      * <p>Instances created by this constructor do not compute differences between sample values.
-     * If differences or discrete derivatives are wanted, use the {@link #forSeries(int)} method
-     * instead.</p>
+     * If differences or discrete derivatives are wanted, use the {@link #forSeries forSeries(…)}
+     * method instead.</p>
+     *
+     * @param name The phenomenon for which this object is collecting statistics, or {@code null}
+     *             if none. If non-null, then this name will be shown as column header in the table
+     *             formatted by {@link StatisticsFormat}.
      */
-    public Statistics() {
+    public Statistics(final CharSequence name) {
+        this.name = Types.toInternationalString(name);
     }
 
     /**
@@ -159,34 +178,53 @@ public class Statistics implements Clone
      *     statistics.differences().scale(1/Δx);
      * }
      *
-     * The {@code order} argument can be interpreted as below:
+     * The maximal "derivative" order is determined by the length of the {@code differenceNames} array:
      *
      * <ul>
-     *   <li>0 if no differences are needed;</li>
+     *   <li>0 if no differences are needed (equivalent to direct instantiation of a new
+     *       {@code Statistics} object).</li>
      *   <li>1 for computing the statistics on the differences between consecutive samples
      *       (proportional to the statistics on the first discrete derivatives) in addition
-     *       to the sample statistics;</li>
+     *       to the sample statistics.</li>
      *   <li>2 for computing also the statistics on the differences between consecutive differences
      *       (proportional to the statistics on the second discrete derivatives) in addition to the
-     *       above;</li>
+     *       above.</li>
      *   <li><i>etc</i>.</li>
      * </ul>
      *
-     * @param  order The discrete derivative order, as a value equals or greater than 0.
+     *
+     *
+     * @param  name  The phenomenon for which this object is collecting statistics, or {@code null}
+     *               if none. If non-null, then this name will be shown as column header in the table
+     *               formatted by {@link StatisticsFormat}.
+     * @param  differenceNames The names of the statistics on differences.
+     *         The given array can not be null, but can contain null elements.
      * @return The newly constructed, initially empty, set of statistics.
      *
      * @see #differences()
      */
-    public static Statistics forSeries(int order) {
-        ArgumentChecks.ensurePositive("order", order);
-        Statistics stats = new Statistics();
-        while (--order >= 0) {
-            stats = new WithDelta(stats);
+    public static Statistics forSeries(final CharSequence name, final CharSequence... differenceNames) {
+        ArgumentChecks.ensureNonNull("differenceNames", differenceNames);
+        Statistics stats = null;
+        for (int i=differenceNames.length; --i >= -1;) {
+            final CharSequence n = (i >= 0) ? differenceNames[i] : name;
+            stats = (stats == null) ? new Statistics(n) : new WithDelta(n, stats);
         }
         return stats;
     }
 
     /**
+     * Returns the name of the phenomenon for which this object is collecting statistics.
+     * If non-null, then this name will be shown as column header in the table formatted
+     * by {@link StatisticsFormat}.
+     *
+     * @return The phenomenon for which this object is collecting statistics, or {@code null} if none.
+     */
+    public InternationalString name() {
+        return name;
+    }
+
+    /**
      * Resets this object state as if it was just created.
      * The {@linkplain #count()} and the {@link #sum()} are set to zero
      * and all other statistical values are set to {@link Double#NaN}.
@@ -286,7 +324,8 @@ public class Statistics implements Clone
      * {@code add(…)} had been first multiplied by the given factor.
      *
      * <p>This method is useful for computing discrete derivatives from the differences between
-     * sample values. See {@link #differences()} or {@link #forSeries(int)} for more information.</p>
+     * sample values. See {@link #differences()} or {@link #forSeries forSeries(…)} for more
+     * information.</p>
      *
      * @param factor The factor by which to multiply the statistics.
      */
@@ -431,15 +470,15 @@ public class Statistics implements Clone
      *     // Do not invoke scale(1/Δx) again.
      * }
      *
-     * This method is supported only if this {@code Statistics} instance has been created by a
-     * call to the {@link #forSeries(int)} method with an {@code order} argument greater than zero.
-     * More generally, calls to this method can be chained up to {@code order} time for
+     * This method returns a non-null value only if this {@code Statistics} instance has been created by a
+     * call to the {@link #forSeries forSeries(…)} method with a non-empty {@code differenceNames} array.
+     * More generally, calls to this method can be chained up to {@code differenceNames.length} times for
      * fetching second or higher order derivatives, as in the above example.
      *
      * @return The statistics on the differences between consecutive sample values,
      *         or {@code null} if not calculated by this object.
      *
-     * @see #forSeries(int)
+     * @see #forSeries(CharSequence, CharSequence[])
      * @see #scale(double)
      */
     public Statistics differences() {
@@ -460,6 +499,8 @@ public class Statistics implements Clone
      * }
      *
      * @return A string representation of this statistics object.
+     *
+     * @see StatisticsFormat
      */
     @Override
     public String toString() {
@@ -503,7 +544,8 @@ public class Statistics implements Clone
     public boolean equals(final Object object) {
         if (object != null && getClass() == object.getClass()) {
             final Statistics cast = (Statistics) object;
-            return count == cast.count && countNaN == cast.countNaN
+            return Objects.equals(name, cast.name)
+                    && count == cast.count && countNaN == cast.countNaN
                     && doubleToLongBits(minimum)   == doubleToLongBits(cast.minimum)
                     && doubleToLongBits(maximum)   == doubleToLongBits(cast.maximum)
                     && doubleToLongBits(sum)       == doubleToLongBits(cast.sum)
@@ -565,9 +607,11 @@ public class Statistics implements Clone
          * consecutive sample values. Other kinds of {@link Statistics} object could be
          * chained as well.
          *
+         * @param name  The phenomenon for which this object is collecting statistics, or {@code null}.
          * @param delta The object where to stores delta statistics.
          */
-        public WithDelta(final Statistics delta) {
+        WithDelta(final CharSequence name, final Statistics delta) {
+            super(name);
             this.delta = delta;
             delta.decrementCountNaN(); // Do not count the first NaN, which will always be the first value.
         }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java Mon Dec 24 03:22:35 2012
@@ -26,12 +26,15 @@ import java.text.NumberFormat;
 import java.text.DecimalFormat;
 import java.text.ParsePosition;
 import java.text.ParseException;
-
+import org.opengis.util.InternationalString;
 import org.apache.sis.io.TableFormatter;
 import org.apache.sis.io.TabularFormat;
 import org.apache.sis.util.resources.Vocabulary;
 
 import static java.lang.Math.*;
+import java.text.FieldPosition;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.collection.BackingStoreException;
 
 
 /**
@@ -61,15 +64,25 @@ public class StatisticsFormat extends Ta
     private static final int ADDITIONAL_DIGITS = 2;
 
     /**
-     * The locale for row labels. This is usually the same than the format locale,
-     * but not necessarily.
+     * The locale for row and column headers.
+     * This is usually the same than the format locale, but not necessarily.
+     */
+    private final Locale headerLocale;
+
+    /**
+     * The "width" of the border to drawn around the table, in number of lines.
+     *
+     * @see #getBorderWidth()
+     * @see #setBorderWidth(int)
      */
-    private final Locale labelLocale;
+    private byte borderWidth;
 
     /**
      * {@code true} if the sample values given to {@code Statistics.add(…)} methods were the
      * totality of the population under study, or {@code false} if they were only a sampling.
      *
+     * @see #isForAllPopulation()
+     * @see #setForAllPopulation(boolean)
      * @see Statistics#standardDeviation(boolean)
      */
     private boolean allPopulation;
@@ -86,28 +99,26 @@ public class StatisticsFormat extends Ta
     }
 
     /**
-     * Constructs a new format for the given locales.
-     * The timezone is used only if the values added to the {@link Statistics} are dates.
+     * Returns an instance for the given locale.
      *
-     * @param locale      The locale, or {@code null} for unlocalized format.
-     * @param labelLocale The locale for row labels. Usually, but not necessarily, same as {@code locale}.
-     * @param timezone    The timezone, or {@code null} for UTC.
+     * @param  locale The locale for which to get a {@code StatisticsFormat} instance.
+     * @return A statistics format instance for the given locale.
      */
-    private StatisticsFormat(final Locale locale, final Locale labelLocale, final TimeZone timezone) {
-        super(locale, timezone);
-        this.labelLocale = labelLocale;
+    public static StatisticsFormat getInstance(final Locale locale) {
+        return new StatisticsFormat(locale, locale, null);
     }
 
     /**
-     * Constructs a new format for the given locale.
+     * Constructs a new format for the given numeric and header locales.
      * The timezone is used only if the values added to the {@link Statistics} are dates.
      *
-     * @param locale   The locale, or {@code null} for unlocalized format.
-     * @param timezone The timezone, or {@code null} for UTC.
+     * @param locale       The locale for numeric values, or {@code null} for unlocalized format.
+     * @param headerLocale The locale for row and column headers. Usually same as {@code locale}.
+     * @param timezone     The timezone, or {@code null} for UTC.
      */
-    public StatisticsFormat(final Locale locale, final TimeZone timezone) {
+    public StatisticsFormat(final Locale locale, final Locale headerLocale, final TimeZone timezone) {
         super(locale, timezone);
-        labelLocale = locale;
+        this.headerLocale = headerLocale;
     }
 
     /**
@@ -146,6 +157,33 @@ public class StatisticsFormat extends Ta
     }
 
     /**
+     * Returns the "width" of the border to drawn around the table, in number of lines.
+     * The default width is 0, which stands for no border.
+     *
+     * @return The border "width" in number of lines.
+     */
+    public int getBorderWidth() {
+        return borderWidth;
+    }
+
+    /**
+     * Sets the "width" of the border to drawn around the table, in number of lines.
+     * The value can be any of the following:
+     *
+     * <ul>
+     *  <li>0 (the default) for no border</li>
+     *  <li>1 for single line ({@code │},{@code ─})</li>
+     *  <li>2 for double lines ({@code ║},{@code ═})</li>
+     * </ul>
+     *
+     * @param borderWidth The border width, in number of lines.
+     */
+    public void setBorderWidth(final int borderWidth) {
+        ArgumentChecks.ensureBetween("borderWidth", 0, 2, borderWidth);
+        this.borderWidth = (byte) borderWidth;
+    }
+
+    /**
      * Not yet implemented.
      */
     @Override
@@ -154,19 +192,31 @@ public class StatisticsFormat extends Ta
     }
 
     /**
-     * The resource keys of the rows to formats. Array index must be consistent with
-     * the switch statements inside the {@link #format(Statistics)} method (we define
-     * this static field close to the format methods for this purpose).
+     * Formats the given statistics. This method will delegates to one of the following methods,
+     * depending on the type of the given object:
+     *
+     * <ul>
+     *   <li>{@link #format(Statistics, Appendable)}</li>
+     *   <li>{@link #format(Statistics[], Appendable)}</li>
+     * </ul>
+     *
+     * @param  object      The object to format.
+     * @param  toAppendTo  Where to format the object.
+     * @param  pos         Ignored in current implementation.
+     * @return             The given buffer, returned for convenience.
      */
-    private static final int[] KEYS = {
-        Vocabulary.Keys.NumberOfValues,
-        Vocabulary.Keys.NumberOfNaN,
-        Vocabulary.Keys.MinimumValue,
-        Vocabulary.Keys.MaximumValue,
-        Vocabulary.Keys.MeanValue,
-        Vocabulary.Keys.RootMeanSquare,
-        Vocabulary.Keys.StandardDeviation
-    };
+    @Override
+    public StringBuffer format(final Object object, final StringBuffer toAppendTo, final FieldPosition pos) {
+        if (object instanceof Statistics[]) try {
+            format((Statistics[]) object, toAppendTo);
+            return toAppendTo;
+        } catch (IOException e) {
+            // Same exception handling than in the super-class.
+            throw new BackingStoreException(e);
+        } else {
+            return super.format(object, toAppendTo, pos);
+        }
+    }
 
     /**
      * Formats a localized string representation of the given statistics.
@@ -174,7 +224,7 @@ public class StatisticsFormat extends Ta
      * are associated to the given object, they will be formatted too.
      *
      * @param  stats       The statistics to format.
-     * @param  toAppendTo  Where to format the object.
+     * @param  toAppendTo  Where to format the statistics.
      * @throws IOException If an error occurred while writing in the given appender.
      */
     @Override
@@ -191,20 +241,56 @@ public class StatisticsFormat extends Ta
      * Formats the given statistics in a tabular format. This method does not check
      * for the statistics on {@linkplain Statistics#differences() differences} - if
      * such statistics are wanted, they must be included in the given array.
+     *
+     * @param  stats       The statistics to format.
+     * @param  toAppendTo  Where to format the statistics.
+     * @throws IOException If an error occurred while writing in the given appender.
      */
-    private void format(final Statistics[] stats, final Appendable toAppendTo) throws IOException {
+    public void format(final Statistics[] stats, final Appendable toAppendTo) throws IOException {
         /*
-         * Verify if we can omit the count of NaN values.
+         * Inspect the given statistics in order to determine if we shall omit the headers,
+         * and if we shall omit the count of NaN values.
          */
+        final String[] headers = new String[stats.length];
+        boolean showHeaders  = false;
         boolean showNaNCount = false;
-        for (final Statistics s : stats) {
-            if (s.countNaN() != 0) {
-                showNaNCount = true;
-                break;
+        for (int i=0; i<stats.length; i++) {
+            final Statistics s = stats[i];
+            showNaNCount |= (s.countNaN() != 0);
+            final InternationalString header = s.name();
+            if (header != null) {
+                headers[i] = header.toString(headerLocale);
+                showHeaders |= (headers[i] != null);
+            }
+        }
+        char horizontalLine = 0;
+        String separator = columnSeparator;
+        switch (borderWidth) {
+            case 1: horizontalLine = '─'; separator += "│ "; break;
+            case 2: horizontalLine = '═'; separator += "║ "; break;
+        }
+        final TableFormatter table = new TableFormatter(toAppendTo, separator);
+        final Vocabulary resources = Vocabulary.getResources(headerLocale);
+        /*
+         * If there is a header for at least one statistics, write the full headers row.
+         */
+        if (horizontalLine != 0) {
+            table.nextLine(horizontalLine);
+        }
+        if (showHeaders) {
+            table.nextColumn();
+            for (final String header : headers) {
+                if (header != null) {
+                    table.append(header);
+                    table.setCellAlignment(TableFormatter.ALIGN_CENTER);
+                }
+                table.nextColumn();
+            }
+            table.append(lineSeparator);
+            if (horizontalLine != 0) {
+                table.nextLine(horizontalLine);
             }
         }
-        final TableFormatter table = new TableFormatter(toAppendTo, separatorSuffix);
-        final Vocabulary resources = Vocabulary.getResources(labelLocale);
         /*
          * Initialize the NumberFormat for formatting integers without scientific notation.
          * This is necessary since the format may have been modified by a previous execution
@@ -249,13 +335,16 @@ public class StatisticsFormat extends Ta
                 if (needsConfigure) {
                     configure(format, s);
                 }
-                table.append(separatorPrefix);
-                table.nextColumn(columnSeparator);
+                table.append(beforeFill);
+                table.nextColumn(fillCharacter);
                 table.append(format.format(value));
                 table.setCellAlignment(TableFormatter.ALIGN_RIGHT);
             }
             table.append(lineSeparator);
         }
+        if (horizontalLine != 0) {
+            table.nextLine(horizontalLine);
+        }
         /*
          * TableFormatter needs to be explicitly flushed in order to format the values.
          */
@@ -263,6 +352,21 @@ public class StatisticsFormat extends Ta
     }
 
     /**
+     * The resource keys of the rows to formats. Array index must be consistent with the
+     * switch statements inside the {@link #format(Statistics[], Appendable)} method
+     * (we define this static field close to the format methods for this purpose).
+     */
+    private static final int[] KEYS = {
+        Vocabulary.Keys.NumberOfValues,
+        Vocabulary.Keys.NumberOfNaN,
+        Vocabulary.Keys.MinimumValue,
+        Vocabulary.Keys.MaximumValue,
+        Vocabulary.Keys.MeanValue,
+        Vocabulary.Keys.RootMeanSquare,
+        Vocabulary.Keys.StandardDeviation
+    };
+
+    /**
      * Configures the given formatter for writing a set of data described by the given statistics.
      * This method configures the formatter using heuristic rules based on the range of values and
      * their standard deviation. It can be used for reasonable default formatting when the user

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java Mon Dec 24 03:22:35 2012
@@ -142,9 +142,8 @@ public class TreeTableFormat extends Tab
     public TreeTableFormat(final Locale locale, final TimeZone timezone) {
         super(locale, timezone);
         indentation       = 4;
-        separatorPrefix   = "……";
-        columnSeparator   = '…';
-        separatorSuffix   = " ";
+        beforeFill        = "……";
+        fillCharacter     = '…';
         omitTrailingNulls = true;
     }
 
@@ -511,8 +510,8 @@ public class TreeTableFormat extends Tab
      */
     final void writeColumnSeparator(final Appendable out) throws IOException {
         // We have a TableFormatter instance if and only if there is 2 or more columns.
-        ((TableFormatter) out.append(separatorPrefix)).nextColumn(columnSeparator);
-        out.append(separatorSuffix);
+        ((TableFormatter) out.append(beforeFill)).nextColumn(fillCharacter);
+        out.append(columnSeparator);
     }
 
     /**

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties Mon Dec 24 03:22:35 2012
@@ -24,6 +24,6 @@ Name              = Name
 NumberOfValues    = Number of values
 NumberOfNaN       = Number of \u2018NaN\u2019
 RootMeanSquare    = Root Mean Square
-StandardDeviation = Standard deviation
 Seconds           = Seconds
+StandardDeviation = Standard deviation
 Type              = Type

Copied: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsFormatTest.java (from r1425402, sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsFormatTest.java?p2=sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsFormatTest.java&p1=sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java&r1=1425402&r2=1425581&rev=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsFormatTest.java Mon Dec 24 03:22:35 2012
@@ -16,238 +16,32 @@
  */
 package org.apache.sis.math;
 
-import java.util.Random;
 import java.util.Locale;
-import java.io.IOException;
 import org.junit.Test;
 import org.apache.sis.test.TestCase;
+import org.apache.sis.test.DependsOnMethod;
 
-import static java.lang.StrictMath.*;
-import static java.lang.Double.NaN;
-import static java.lang.Double.isNaN;
 import static org.apache.sis.test.Assert.*;
 
 
 /**
- * Tests {@link Statistics}.
+ * Tests {@link StatisticsFormat}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
  * @version 0.3
  * @module
  */
-public final strictfp class StatisticsTest extends TestCase {
+public final strictfp class StatisticsFormatTest extends TestCase {
     /**
-     * For floating point comparisons.
-     */
-    private static final double EPS = 1E-10;
-
-    /**
-     * Tests the initial state of newly constructed instance.
-     */
-    @Test
-    public void testInitialState() {
-        final Statistics statistics = new Statistics();
-        assertEquals(0,  statistics.count());
-        assertEquals(0,  statistics.countNaN());
-        assertTrue(isNaN(statistics.minimum()));
-        assertTrue(isNaN(statistics.maximum()));
-        assertTrue(isNaN(statistics.mean()));
-        assertTrue(isNaN(statistics.rms()));
-        assertTrue(isNaN(statistics.standardDeviation(true)));
-        assertTrue(isNaN(statistics.standardDeviation(false)));
-    }
-
-    /**
-     * Tests the statistics over a large range of Gaussian values.
-     * Means should be close to 0, RMS and standard deviation should be close to 1.
+     * Tests the formatting of {@code Statistics} without column headers.
+     * We instantiate the {@link StatisticsFormat} directly in order to fix the locale
+     * to a hard-coded value. But except for the localization, the result should be
+     * nearly identical to a call to the {@link Statistics#toString()} method.
      */
     @Test
-    public void testGaussian() {
-        final Random random = new Random(317780561);
-        final Statistics statistics = new Statistics();
-        for (int i=0; i<10000; i++) {
-            statistics.add(random.nextGaussian());
-        }
-        assertEquals(0, statistics.countNaN());
-        assertEquals(10000, statistics.count());
-        assertEquals(0, statistics.mean(), 0.01);
-        assertEquals(1, statistics.rms (), 0.01);
-        assertEquals(1, statistics.standardDeviation(false), 0.01);
-    }
-
-    /**
-     * Tests the statistics over a large range of values distributed between 0 and 1.
-     * Means should be close to 0, minimum and maximum close to -1 and +1 respectively.
-     */
-    @Test
-    public void testUniform() {
-        // Theorical values for uniform distribution.
-        final double lower  = -1;
-        final double upper  = +1;
-        final double range  = upper - lower;
-        final double stdDev = sqrt(range*range / 12);
-
-        // Now tests.
-        final Random random = new Random(309080660);
-        final Statistics statistics = new Statistics();
-        for (int i=0; i<10000; i++) {
-            statistics.add(random.nextDouble()*range + lower);
-        }
-        assertEquals(0,      statistics.countNaN());
-        assertEquals(10000,  statistics.count());
-        assertEquals(0.0,    statistics.mean(),    0.01);
-        assertEquals(lower,  statistics.minimum(), 0.01);
-        assertEquals(upper,  statistics.maximum(), 0.01);
-        assertEquals(stdDev, statistics.rms(),     0.01);
-        assertEquals(stdDev, statistics.standardDeviation(false), 0.01);
-    }
-
-    /**
-     * Same than {@link #testUniform()}, but on integer values.
-     * Used for testing {@link Statistics#add(long)}.
-     */
-    @Test
-    public void testUniformUsingIntegers() {
-        // Theorical values for uniform distribution.
-        final int    lower  = -1000;
-        final int    upper  = +1000;
-        final int    range  = upper - lower;
-        final double stdDev = sqrt(range*range / 12.0);
-
-        // Now tests.
-        final Random random = new Random(309080660);
-        final Statistics statistics = new Statistics();
-        for (int i=0; i<10000; i++) {
-            statistics.add(random.nextInt(range) + lower);
-        }
-        assertEquals(0,      statistics.countNaN());
-        assertEquals(10000,  statistics.count());
-        assertEquals(0.0,    statistics.mean(),    10.0);
-        assertEquals(lower,  statistics.minimum(), 10.0);
-        assertEquals(upper,  statistics.maximum(), 10.0);
-        assertEquals(stdDev, statistics.rms(),     10.0);
-        assertEquals(stdDev, statistics.standardDeviation(false), 10.0);
-    }
-
-    /**
-     * Tests the statistics starting with a number big enough to make the code fails if we were
-     * not using the <a href="http://en.wikipedia.org/wiki/Kahan_summation_algorithm">Kahan
-     * summation algorithm</a>.
-     */
-    @Test
-    public void testKahanAlgorithm() {
-        final double[] offsetAndTolerancePairs = {
-            // Starting with a reasonably small value, the result should be accurate
-            // with or without Kahan algorithm. So we use that for testing the test.
-            1000, 0.002,
-
-            // First power of 10 for which the summation
-            // fails if we don't use the Kahan algorithm.
-            1E+16, 0.003,
-
-            // Kahan algorithm still good here.
-            1E+18, 0.003,
-
-            // Last power of 10 before the summation fails
-            // using the Kahan algorithm. Quality is lower.
-            1E+19, 0.125,
-
-            // Starting with this number fails in all case using our algorithm.
-            // We test this value only in order to test our test method...
-            1E+20, 0
-        };
-        final Random random = new Random(223386491);
-        final Statistics statistics = new Statistics();
-        for (int k=0; k<offsetAndTolerancePairs.length; k++) {
-            final double offset = offsetAndTolerancePairs[k];
-            final double tolerance = offsetAndTolerancePairs[++k];
-            assertTrue("Possible misorder in offsetAndTolerancePairs", offset > 10);
-            assertTrue("Possible misorder in offsetAndTolerancePairs", tolerance < 0.2);
-            statistics.reset();
-            statistics.add(offset);
-            for (int i=0; i<10000; i++) {
-                statistics.add(random.nextDouble());
-            }
-            final double r = statistics.mean() - offset / statistics.count();
-            final double expected = (tolerance != 0) ? 0.5 : 0;
-            assertEquals(expected, r, tolerance);
-
-            statistics.add(-offset); // Accuracy will be better than in previous test.
-            assertEquals(expected, statistics.mean(), min(tolerance, 0.1));
-        }
-    }
-
-    /**
-     * Tests the concatenation of many {@link Statistics} objects.
-     */
-    @Test
-    public void testConcatenation() {
-        final Random random = new Random(429323868);
-        final Statistics global = new Statistics();
-        final Statistics byBlock = new Statistics();
-        for (int i=0; i<10; i++) {
-            final Statistics block = new Statistics();
-            for (int j=0; j<1000; j++) {
-                final double value;
-                if (random.nextInt(800) == 0) {
-                    value = Double.NaN;
-                } else {
-                    value = random.nextGaussian() + 10*random.nextDouble();
-                }
-                global.add(value);
-                block.add(value);
-            }
-            byBlock.add(block);
-            if (i == 0) {
-                assertEquals("Adding for the first time; should have the same amount of data.",   block,  byBlock);
-                assertEquals("Adding for the first time; should have got exactly the same data.", global, byBlock);
-            } else {
-                assertFalse("Should have more data that the block we just computed.",
-                        byBlock.equals(block));
-            }
-            assertEquals(global.count(),    byBlock.count());
-            assertEquals(global.countNaN(), byBlock.countNaN());
-            assertEquals(global.minimum(),  byBlock.minimum(), 0.0);
-            assertEquals(global.maximum(),  byBlock.maximum(), 0.0);
-            assertEquals(global.mean(),     byBlock.mean(),    1E-15);
-            assertEquals(global.rms(),      byBlock.rms(),     1E-15);
-        }
-    }
-
-    /**
-     * Tests the serialization.
-     *
-     * @throws IOException Should never happen.
-     */
-    @Test
-    public void testSerialization() throws IOException {
-        final Statistics statistics = new Statistics();
-        statistics.add(40);
-        statistics.add(10);
-        statistics.add(NaN);
-        statistics.add(20);
-        final Statistics after = assertSerializedEquals(statistics);
-        assertNotSame(statistics, after);
-        assertEquals( 3,                 after.count());
-        assertEquals( 1,                 after.countNaN());
-        assertEquals(10.0,               after.minimum(),                0.0);
-        assertEquals(40.0,               after.maximum(),                0.0);
-        assertEquals(23.333333333333333, after.mean(),                   EPS);
-        assertEquals(26.457513110645905, after.rms(),                    EPS);
-        assertEquals(12.472191289246473, after.standardDeviation(true),  EPS);
-        assertEquals(15.275252316519468, after.standardDeviation(false), EPS);
-    }
-
-    /**
-     * Tests the formatting of {@link Statistics}.
-     * Actually, we will instantiate the {@link StatisticsFormat} directly in order to fix the
-     * locale to a hard-coded value. But except for the localization, the result should be nearly
-     * identical to a call to the {@link Statistics#toString()} method.
-     */
-    @Test
-    public void testFormatting() {
-        final Statistics statistics = Statistics.forSeries(2);
+    public void testFormattingWithoutHeader() {
+        final Statistics statistics = Statistics.forSeries(null, null, null);
         statistics.add(10);
         statistics.add(15);
         statistics.add(22);
@@ -255,7 +49,7 @@ public final strictfp class StatisticsTe
         statistics.add(12);
         statistics.add( 3);
 
-        final StatisticsFormat format = new StatisticsFormat(Locale.US, null);
+        final StatisticsFormat format = StatisticsFormat.getInstance(Locale.US);
         final String text = format.format(statistics);
         assertMultilinesEquals(
                 "Number of values:       6     5      4\n" +
@@ -265,4 +59,35 @@ public final strictfp class StatisticsTe
                 "Root Mean Square:   14.44  6.40   6.40\n" +
                 "Standard deviation:  6.49  6.99   6.19\n", text);
     }
+
+    /**
+     * Tests the formatting of {@code Statistics} with column headers and a border.
+     * This test uses the same numerical values than {@link #testFormattingWithoutHeader()}.
+     */
+    @Test
+    @DependsOnMethod("testFormattingWithoutHeader")
+    public void testFormattingWithBorder() {
+        final Statistics statistics = Statistics.forSeries("Temperature", "∂T/∂t", "∂²T/∂t²");
+        statistics.add(10);
+        statistics.add(15);
+        statistics.add(22);
+        statistics.add(17);
+        statistics.add(12);
+        statistics.add( 3);
+
+        final StatisticsFormat format = StatisticsFormat.getInstance(Locale.US);
+        format.setBorderWidth(1);
+        final String text = format.format(statistics);
+        assertMultilinesEquals(
+                "┌─────────────────────┬─────────────┬───────┬─────────┐\n" +
+                "│                     │ Temperature │ ∂T/∂t │ ∂²T/∂t² │\n" +
+                "├─────────────────────┼─────────────┼───────┼─────────┤\n" +
+                "│ Number of values:   │           6 │     5 │       4 │\n" +
+                "│ Minimum value:      │        3.00 │ -9.00 │  -12.00 │\n" +
+                "│ Maximum value:      │       22.00 │  7.00 │    2.00 │\n" +
+                "│ Mean value:         │       13.17 │ -1.40 │   -3.50 │\n" +
+                "│ Root Mean Square:   │       14.44 │  6.40 │    6.40 │\n" +
+                "│ Standard deviation: │        6.49 │  6.99 │    6.19 │\n" +
+                "└─────────────────────┴─────────────┴───────┴─────────┘\n", text);
+    }
 }

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java Mon Dec 24 03:22:35 2012
@@ -17,7 +17,6 @@
 package org.apache.sis.math;
 
 import java.util.Random;
-import java.util.Locale;
 import java.io.IOException;
 import org.junit.Test;
 import org.apache.sis.test.TestCase;
@@ -47,7 +46,7 @@ public final strictfp class StatisticsTe
      */
     @Test
     public void testInitialState() {
-        final Statistics statistics = new Statistics();
+        final Statistics statistics = new Statistics(null);
         assertEquals(0,  statistics.count());
         assertEquals(0,  statistics.countNaN());
         assertTrue(isNaN(statistics.minimum()));
@@ -65,7 +64,7 @@ public final strictfp class StatisticsTe
     @Test
     public void testGaussian() {
         final Random random = new Random(317780561);
-        final Statistics statistics = new Statistics();
+        final Statistics statistics = new Statistics(null);
         for (int i=0; i<10000; i++) {
             statistics.add(random.nextGaussian());
         }
@@ -90,7 +89,7 @@ public final strictfp class StatisticsTe
 
         // Now tests.
         final Random random = new Random(309080660);
-        final Statistics statistics = new Statistics();
+        final Statistics statistics = new Statistics(null);
         for (int i=0; i<10000; i++) {
             statistics.add(random.nextDouble()*range + lower);
         }
@@ -117,7 +116,7 @@ public final strictfp class StatisticsTe
 
         // Now tests.
         final Random random = new Random(309080660);
-        final Statistics statistics = new Statistics();
+        final Statistics statistics = new Statistics(null);
         for (int i=0; i<10000; i++) {
             statistics.add(random.nextInt(range) + lower);
         }
@@ -158,7 +157,7 @@ public final strictfp class StatisticsTe
             1E+20, 0
         };
         final Random random = new Random(223386491);
-        final Statistics statistics = new Statistics();
+        final Statistics statistics = new Statistics(null);
         for (int k=0; k<offsetAndTolerancePairs.length; k++) {
             final double offset = offsetAndTolerancePairs[k];
             final double tolerance = offsetAndTolerancePairs[++k];
@@ -184,10 +183,10 @@ public final strictfp class StatisticsTe
     @Test
     public void testConcatenation() {
         final Random random = new Random(429323868);
-        final Statistics global = new Statistics();
-        final Statistics byBlock = new Statistics();
+        final Statistics global = new Statistics(null);
+        final Statistics byBlock = new Statistics(null);
         for (int i=0; i<10; i++) {
-            final Statistics block = new Statistics();
+            final Statistics block = new Statistics(null);
             for (int j=0; j<1000; j++) {
                 final double value;
                 if (random.nextInt(800) == 0) {
@@ -222,7 +221,7 @@ public final strictfp class StatisticsTe
      */
     @Test
     public void testSerialization() throws IOException {
-        final Statistics statistics = new Statistics();
+        final Statistics statistics = new Statistics(null);
         statistics.add(40);
         statistics.add(10);
         statistics.add(NaN);
@@ -238,31 +237,4 @@ public final strictfp class StatisticsTe
         assertEquals(12.472191289246473, after.standardDeviation(true),  EPS);
         assertEquals(15.275252316519468, after.standardDeviation(false), EPS);
     }
-
-    /**
-     * Tests the formatting of {@link Statistics}.
-     * Actually, we will instantiate the {@link StatisticsFormat} directly in order to fix the
-     * locale to a hard-coded value. But except for the localization, the result should be nearly
-     * identical to a call to the {@link Statistics#toString()} method.
-     */
-    @Test
-    public void testFormatting() {
-        final Statistics statistics = Statistics.forSeries(2);
-        statistics.add(10);
-        statistics.add(15);
-        statistics.add(22);
-        statistics.add(17);
-        statistics.add(12);
-        statistics.add( 3);
-
-        final StatisticsFormat format = new StatisticsFormat(Locale.US, null);
-        final String text = format.format(statistics);
-        assertMultilinesEquals(
-                "Number of values:       6     5      4\n" +
-                "Minimum value:       3.00 -9.00 -12.00\n" +
-                "Maximum value:      22.00  7.00   2.00\n" +
-                "Mean value:         13.17 -1.40  -3.50\n" +
-                "Root Mean Square:   14.44  6.40   6.40\n" +
-                "Standard deviation:  6.49  6.99   6.19\n", text);
-    }
 }

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java Mon Dec 24 03:22:35 2012
@@ -46,6 +46,7 @@ import org.junit.runners.Suite;
     org.apache.sis.util.logging.PerformanceLevelTest.class,
     org.apache.sis.math.MathFunctionsTest.class,
     org.apache.sis.math.StatisticsTest.class,
+    org.apache.sis.math.StatisticsFormatTest.class,
 
     // Collections.
     org.apache.sis.internal.util.ReferenceQueueConsumerTest.class,

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java?rev=1425581&r1=1425580&r2=1425581&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CacheTest.java Mon Dec 24 03:22:35 2012
@@ -25,7 +25,7 @@ import java.io.IOException;
 import java.io.PrintWriter;
 
 import org.apache.sis.math.Statistics;
-import org.apache.sis.io.TableFormatter;
+import org.apache.sis.math.StatisticsFormat;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.TestCase;
@@ -181,11 +181,12 @@ public final strictfp class CacheTest ex
      * Validates the entries created by the {@link #stress()} test. The check performed in
      * this method shall obviously be consistent with the values created by {@code stress()}.
      *
+     * @param  name  The name of the value being measured.
      * @param  cache The cache to validate.
      * @return Statistics on the key values of the given map.
      */
-    private static Statistics validateStressEntries(final Map<Integer,Integer> cache) {
-        final Statistics statistics = new Statistics();
+    private static Statistics validateStressEntries(final String name, final Map<Integer,Integer> cache) {
+        final Statistics statistics = new Statistics(name);
         for (final Map.Entry<Integer,Integer> entry : cache.entrySet()) {
             final int key = entry.getKey();
             final int value = entry.getValue();
@@ -258,7 +259,7 @@ public final strictfp class CacheTest ex
         /*
          * Verifies the values.
          */
-        final Statistics beforeGC = validateStressEntries(cache);
+        final Statistics beforeGC = validateStressEntries("Before GC", cache);
         assertTrue("Should not have more entries than what we put in.", cache.size() <= count);
         assertFalse("Some entries should be retained by strong references.", cache.isEmpty());
         /*
@@ -304,20 +305,14 @@ public final strictfp class CacheTest ex
          * information in case of failure.
          */
         System.gc();
-        final Statistics afterGC = validateStressEntries(cache);
+        final Statistics afterGC = validateStressEntries("After GC", cache);
         if (out != null) {
-            final TableFormatter table = new TableFormatter(out, " │ ");
-            table.setMultiLinesCells(true);
-            table.append("Statistics on the keys before garbage collection:");
-            table.nextColumn();
-            table.append("Statistics on the keys after garbage collection.\n" +
-                         "The minimum and the mean values should be greater.");
-            table.nextLine();
-            table.append(beforeGC.toString());
-            table.nextColumn();
-            table.append(afterGC.toString());
+            out.println("Statistics on the keys before and after garbage collection.");
+            out.println("The minimum and the mean values should be greater after GC.");
+            final StatisticsFormat format = StatisticsFormat.getInstance();
+            format.setBorderWidth(1);
             try {
-                table.flush();
+                format.format(new Statistics[] {beforeGC, afterGC}, out);
             } catch (IOException e) {
                 throw new AssertionError(e);
             }



Mime
View raw message