sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1576108 [1/2] - in /sis/branches/JDK7/core: sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/main/java/org/apache/sis/parameter/ sis-referencing/src/ma...
Date Mon, 10 Mar 2014 22:24:32 GMT
Author: desruisseaux
Date: Mon Mar 10 22:24:31 2014
New Revision: 1576108

URL: http://svn.apache.org/r1576108
Log:
Initial port of ParameterFormat (in order to implement ParameterDescriptorGroup formatting),
and partial cleaning (not yet completed).

Added:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/NameToIdentifier.java   (with props)
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java   (with props)
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterTableRow.java   (with props)
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java   (with props)
Modified:
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/io/TableAppenderTest.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/MeasurementRangeTest.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/RangeFormatTest.java

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -445,14 +445,8 @@ public class WKTFormat extends CompoundF
     /**
      * Creates a new format to use for parsing and formatting values of the given type.
      * This method is invoked the first time that a format is needed for the given type.
-     * The {@code valueType} can be one of the following classes:
-     *
-     * <table class="sis">
-     *   <tr><th>Value type</th>     <th>Format to create</th></tr>
-     *   <tr><td>{@link Number}</td> <td>{@link NumberFormat}</td></tr>
-     *   <tr><td>{@link Date}</td>   <td>{@link DateFormat}</td></tr>
-     *   <tr><td>{@link Unit}</td>   <td>{@link UnitFormat}</td></tr>
-     * </table>
+     * The {@code valueType} can be any types declared in the
+     * {@linkplain CompoundFormat#createFormat(Class) parent class}.
      *
      * @param  valueType The base type of values to parse or format.
      * @return The format to use for parsing of formatting values of the given type, or {@code null} if none.
@@ -462,9 +456,6 @@ public class WKTFormat extends CompoundF
         if (valueType == Number.class) {
             return symbols.createNumberFormat();
         }
-        if (valueType == Unit.class) {
-            return UnitFormat.getInstance(symbols.getLocale());
-        }
         if (valueType == Date.class) {
             final DateFormat format = new SimpleDateFormat(DATE_PATTERN, symbols.getLocale());
             format.setTimeZone(getTimeZone());

Added: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/NameToIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/NameToIdentifier.java?rev=1576108&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/NameToIdentifier.java (added)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/NameToIdentifier.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.referencing;
+
+import org.opengis.util.NameSpace;
+import org.opengis.util.ScopedName;
+import org.opengis.util.GenericName;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.apache.sis.metadata.iso.citation.Citations;
+
+import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+
+
+/**
+ * Does the unobvious mapping between {@link ReferenceIdentifier} properties and {@link GenericName} ones.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.4
+ * @version 0.4
+ * @module
+ */
+public final class NameToIdentifier implements ReferenceIdentifier {
+    /**
+     * The name from which to infer the identifier attributes.
+     */
+    private final GenericName name;
+
+    /**
+     * Infers the attributes from the given name.
+     *
+     * @param name The name from which to infer the identifier properties.
+     */
+    public NameToIdentifier(final GenericName name) {
+        ensureNonNull("name", name);
+        this.name = name;
+    }
+
+    /**
+     * Infers the authority from the scope.
+     */
+    @Override
+    public Citation getAuthority() {
+        final NameSpace scope = name.scope();
+        if (scope == null || scope.isGlobal()) {
+            return null;
+        }
+        return Citations.fromName(scope.name().tip().toString());
+    }
+
+    /**
+     * Takes everything except the tip as the code space.
+     *
+     * @param name The name from which to get the code space.
+     * @return The code space, or {@code null} if none.
+     */
+    public static String getCodeSpace(final GenericName name) {
+        if (name instanceof ScopedName) {
+            return ((ScopedName) name).path().toString();
+        }
+        if (name.depth() == 2) {
+            // May happen on GenericName implementation that do not implement the ScopedName interface.
+            // The most importance case is org.apache.sis.referencing.NamedIdentifier.
+            return name.head().toString();
+        }
+        return null;
+    }
+
+    /**
+     * Takes everything except the tip as the code space.
+     */
+    @Override
+    public String getCodeSpace() {
+        return getCodeSpace(name);
+    }
+
+    /**
+     * Takes the last element as the code.
+     */
+    @Override
+    public String getCode() {
+        return name.tip().toString();
+    }
+
+    /**
+     * Names are not versioned.
+     */
+    @Override
+    public String getVersion() {
+        return null;
+    }
+}

Propchange: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/NameToIdentifier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/NameToIdentifier.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -266,11 +266,7 @@ public class DefaultParameterDescriptor<
         valueClass   = descriptor.getValueClass();
         validValues  = descriptor.getValidValues();
         defaultValue = descriptor.getDefaultValue();
-        if (Number.class.isAssignableFrom(valueClass) && Comparable.class.isAssignableFrom(valueClass)) {
-            valueDomain = Parameters.getValueDomain((ParameterDescriptor) descriptor);
-        } else {
-            valueDomain = null;
-        }
+        valueDomain  = Parameters.getValueDomain(descriptor);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -156,7 +156,7 @@ public class DefaultParameterDescriptorG
         super(properties);
         this.minimumOccurs = minimumOccurs;
         this.maximumOccurs = maximumOccurs;
-        if (minimumOccurs < 0  || minimumOccurs > maximumOccurs) {
+        if (minimumOccurs < 0  || minimumOccurs > maximumOccurs || maximumOccurs == 0) {
             throw new IllegalArgumentException(Errors.getResources(properties).getString(
                     Errors.Keys.IllegalRange_2, minimumOccurs, maximumOccurs));
         }

Added: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java?rev=1576108&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java (added)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -0,0 +1,724 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.parameter;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.io.IOException;
+import java.text.Format;
+import java.text.ParsePosition;
+import java.text.ParseException;
+import javax.measure.unit.Unit;
+
+import org.opengis.parameter.*;
+import org.opengis.util.ScopedName;
+import org.opengis.util.GenericName;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.operation.OperationMethod;
+
+import org.apache.sis.measure.Range;
+import org.apache.sis.io.wkt.Colors;
+import org.apache.sis.io.TableAppender;
+import org.apache.sis.io.CompoundFormat;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.resources.Vocabulary;
+import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.internal.util.X364;
+
+import static org.apache.sis.util.collection.Containers.hashMapCapacity;
+
+
+/**
+ * Formats {@linkplain DefaultParameterDescriptorGroup parameter descriptors} or
+ * {@linkplain DefaultParameterValueGroup parameter values} in a tabular format.
+ * This format assumes a monospaced font and an encoding supporting drawing box
+ * characters (e.g. UTF-8).
+ *
+ * <div class="note"><b>Example:</b>
+ * The <cite>Mercator (variant A)</cite> example given in {@link DefaultParameterDescriptorGroup} javadoc
+ * can be formatted as below:
+ *
+ * {@preformat text
+ *   EPSG: Mercator (variant A)
+ *   ┌────────────────────────────────┬────────┬───────────────┬───────────────┐
+ *   │ Name                           │ Type   │ Value domain  │ Default value │
+ *   ├────────────────────────────────┼────────┼───────────────┼───────────────┤
+ *   │ Latitude of natural origin     │ Double │ [-80 … 84]°   │ 40.0°         │
+ *   │ Longitude of natural origin    │ Double │ [-180 … 180]° │ -60.0°        │
+ *   │ Scale factor at natural origin │ Double │ (0 … ∞)       │ 1.0           │
+ *   │ False easting                  │ Double │ (-∞ … ∞) m    │ 5000.0 m      │
+ *   │ False northing                 │ Double │ (-∞ … ∞) m    │ 10000.0 m     │
+ *   └────────────────────────────────┴────────┴───────────────┴───────────────┘
+ * }
+ * </div>
+ *
+ * <div class="warning"><b>Limitation:</b>
+ * Current implementation supports only formatting, not parsing.
+ * </div>
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.4 (derived from geotk-2.1)
+ * @version 0.4
+ * @module
+ */
+public class ParameterFormat extends CompoundFormat<Object> {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -1345231739800152411L;
+
+    /**
+     * Special codespace for requesting the display of EPSG codes.
+     */
+    private static final String SHOW_EPSG_CODES = "EPSG:#";
+
+    /**
+     * The amount of information to put in the table to be formatted by {@link ParameterFormat}.
+     *
+     * @since   0.4
+     * @version 0.4
+     * @module
+     */
+    public static enum ContentLevel {
+        /**
+         * The most detailed content, which includes
+         * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName() name} and
+         * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getAlias() aliases}.
+         * Each parameter may be formatted on many lines if they have aliases.
+         */
+        DETAILED,
+
+        /**
+         * A medium level of content which formats each parameter on a single line. For each parameter only the
+         * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName() name} is formatted —
+         * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getAlias() aliases} and
+         * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getIdentifiers() identifiers} are omitted.
+         */
+        BRIEF,
+
+        /**
+         * Limits the content to names and aliases in a tabular format. In addition to parameters,
+         * this level can also format array of operation method, coordinate reference system, <i>etc.</i>
+         * The summary contains the identifier names and aliases aligned in a table.
+         *
+         * <p><b>Tip:</b> The table formatted by default may be quite large. It is recommended to invoke
+         * {@link ParameterFormat#setPreferredCodespaces(String[])} before to format in order to reduce the
+         * amount of columns to display.</p>
+         */
+        NAME_SUMMARY
+    }
+
+    /**
+     * The locale for international strings.
+     */
+    private final Locale displayLocale;
+
+    /**
+     * The amount of information to put in the table.
+     *
+     * @see #getContentLevel()
+     */
+    private ContentLevel contentLevel = ContentLevel.BRIEF;
+
+    /**
+     * If the identifier should be written only for some code spaces, those code spaces.
+     * Otherwise {@code null}.
+     *
+     * @see #getPreferredCodespaces()
+     */
+    private Set<String> preferredCodespaces;
+
+    /**
+     * The colors for an output on X3.64 compatible terminal, or {@code null} if none.
+     *
+     * @see #getColors()
+     */
+    private Colors colors;
+
+    /**
+     * Creates a new formatter for the default locale and timezone.
+     */
+    public ParameterFormat() {
+        super(Locale.getDefault(Locale.Category.FORMAT), TimeZone.getDefault());
+        displayLocale = Locale.getDefault(Locale.Category.DISPLAY);
+    }
+
+    /**
+     * Creates a new formatter for the given locale and timezone.
+     *
+     * @param locale   The locale, or {@code null} for {@code Locale.ROOT}.
+     * @param timezone The timezone, or {@code null} for UTC.
+     */
+    public ParameterFormat(final Locale locale, final TimeZone timezone) {
+        super(locale, timezone);
+        displayLocale = (locale != null) ? locale : Locale.ROOT;
+    }
+
+    /**
+     * Returns the base type of values parsed and formatted by this {@code Format} instance.
+     * The default implementation returns {@code Object.class} since it is the only common parent
+     * of classes formatted by this object.
+     *
+     * @return The common parent of object classes formatted by this {@code ParameterFormat}.
+     */
+    @Override
+    public Class<? extends Object> getValueType() {
+        return Object.class;
+    }
+
+    /**
+     * Returns the locale for the given category.
+     *
+     * <ul>
+     *   <li>{@link java.util.Locale.Category#FORMAT} specifies the locale to use for values.</li>
+     *   <li>{@link java.util.Locale.Category#DISPLAY} specifies the locale to use for labels.</li>
+     * </ul>
+     *
+     * @param  category The category for which a locale is desired.
+     * @return The locale for the given category (never {@code null}).
+     */
+    @Override
+    public Locale getLocale(final Locale.Category category) {
+        return (category == Locale.Category.DISPLAY) ? displayLocale : super.getLocale(category);
+    }
+
+    /**
+     * Returns the amount of information to put in the table.
+     * The default value is {@link org.apache.sis.parameter.ParameterFormat.ContentLevel#BRIEF}.
+     *
+     * @return The table content.
+     */
+    public ContentLevel getContentLevel() {
+        return contentLevel;
+    }
+
+    /**
+     * Sets the amount of information to put in the table.
+     *
+     * @param level The amount of information to put in the table.
+     */
+    public void setContentLevel(final ContentLevel level) {
+        ArgumentChecks.ensureNonNull("level", level);
+        this.contentLevel = level;
+    }
+
+    /**
+     * Returns the code spaces of names and identifiers to show, or {@code null} if there is no restriction.
+     * This method returns the sequence specified by the last call to {@link #setPreferredCodespaces(String[])}.
+     * The default value is {@code null}.
+     *
+     * @return The code spaces of names and identifiers to show, or {@code null} if no restriction.
+     */
+    public String[] getPreferredCodespaces() {
+        return (preferredCodespaces != null) ? preferredCodespaces.toArray(new String[preferredCodespaces.size()]) : null;
+    }
+
+    /**
+     * Filters names and identifiers by their code spaces. If the given array is non-null, then the only names,
+     * aliases and identifiers to be formatted are those having a {@link ReferenceIdentifier#getCodeSpace()},
+     * {@link GenericName#scope()} or {@link ScopedName#head()} value in the given list, unless no name or alias
+     * matches this criterion.
+     *
+     * <p>Additional effects:</p>
+     * <ul>
+     *   <li>With {@link org.apache.sis.parameter.ParameterFormat.ContentLevel#BRIEF}, the given list determines
+     *       the preference order to choosing the name or identifier to format.</li>
+     *   <li>With {@link org.apache.sis.parameter.ParameterFormat.ContentLevel#NAME_SUMMARY}, the given list
+     *       sets the column order.</li>
+     * </ul>
+     *
+     * @param codespaces The preferred code spaces of names, aliases and identifiers to format, or {@code null}
+     *        for accepting all of them. Some typical values are {@code "EPSG"}, {@code "OGC"} or {@code "GeoTIFF"}.
+     */
+    public void setPreferredCodespaces(final String... codespaces) {
+        Set<String> copy = null;
+        if (codespaces != null) {
+            copy = CollectionsExt.immutableSet(true, codespaces);
+        }
+        this.preferredCodespaces = copy;
+    }
+
+    /**
+     * Returns the colors for an output on X3.64 compatible terminal, or {@code null} if none.
+     * The default value is {@code null}.
+     *
+     * @return The colors for an output on X3.64 compatible terminal, or {@code null} if none.
+     */
+    public Colors getColors() {
+        return colors;
+    }
+
+    /**
+     * Sets the colors for an output on X3.64 compatible terminal.
+     * This is used for example in order to emphases the identifier in a list of alias.
+     *
+     * @param colors The colors for an output on X3.64 compatible terminal, or {@code null} if none.
+     */
+    public void setColors(final Colors colors) {
+        this.colors = colors;
+    }
+
+    /**
+     * Formats the given object to the given stream of buffer.
+     * The object may be an instance of any of the following types:
+     *
+     * <ul>
+     *   <li>{@link ParameterValueGroup}</li>
+     *   <li>{@link ParameterDescriptorGroup}</li>
+     *   <li>{@link OperationMethod}</li>
+     *   <li><code>{@linkplain IdentifiedObject}[]</code> — accepted only for
+     *       {@link org.apache.sis.parameter.ParameterFormat.ContentLevel#NAME_SUMMARY}.</li>
+     * </ul>
+     *
+     * @throws IOException If an error occurred while writing to the given appendable.
+     */
+    @Override
+    public void format(final Object object, final Appendable toAppendTo) throws IOException {
+        ArgumentChecks.ensureNonNull("object",     object);
+        ArgumentChecks.ensureNonNull("toAppendTo", toAppendTo);
+        final boolean isSummary = contentLevel == ContentLevel.NAME_SUMMARY;
+        final ParameterDescriptorGroup descriptor;
+        final ParameterValueGroup      values;
+        final ReferenceIdentifier      name;
+        if (object instanceof ParameterValueGroup) {
+            values     = (ParameterValueGroup) object;
+            descriptor = values.getDescriptor();
+            name       = descriptor.getName();
+        } else if (object instanceof ParameterDescriptorGroup) {
+            descriptor = (ParameterDescriptorGroup) object;
+            values     = null;
+            name       = descriptor.getName();
+        } else if (object instanceof OperationMethod) {
+            final OperationMethod operation = (OperationMethod) object;
+            descriptor = operation.getParameters();
+            values     = null;
+            name       = operation.getName();
+        } else if (isSummary && object instanceof IdentifiedObject[]) {
+            formatSummary((IdentifiedObject[]) object, toAppendTo);
+            return;
+        } else {
+            throw new IllegalArgumentException(Errors.getResources(displayLocale)
+                    .getString(Errors.Keys.UnsupportedType_1, object.getClass()));
+        }
+        if (isSummary) {
+            final List<GeneralParameterDescriptor> parameters = descriptor.descriptors();
+            formatSummary(parameters.toArray(new IdentifiedObject[parameters.size()]), toAppendTo);
+        } else {
+            format(name.getCode(), descriptor, values, toAppendTo);
+        }
+    }
+
+    /**
+     * Implementation of public {@code format(…)} methods for all content levels except {@code NAME_SUMMARY}.
+     *
+     * @param  name       The group name, usually {@code descriptor.getName().getCode()}.
+     * @param  descriptor The parameter descriptor, usually {@code values.getDescriptor()}.
+     * @param  values     The parameter values, or {@code null} if none.
+     * @throws IOException If an error occurred while writing to the given appendable.
+     */
+    private void format(final String name, final ParameterDescriptorGroup group,
+            final ParameterValueGroup values, final Appendable out) throws IOException
+    {
+        final boolean isBrief       = (contentLevel == ContentLevel.BRIEF);
+        final boolean hasColors     = (colors != null);
+        final String  lineSeparator = System.lineSeparator();
+        final Vocabulary resources  = Vocabulary.getResources(displayLocale);
+        new ParameterTableRow(group, displayLocale, isBrief).appendIdentifiers(out, hasColors, false, lineSeparator);
+        out.append(lineSeparator);
+        /*
+         * Formats the table header (i.e. the column names).
+         */
+        final char horizontalBorder = isBrief ? '─' : '═';
+        final TableAppender table = isBrief ? new TableAppender(out, " │ ") : new TableAppender(out);
+        table.setMultiLinesCells(true);
+        table.nextLine(horizontalBorder);
+        for (int i=0; ; i++) {
+            boolean end = false;
+            final short key;
+            switch (i) {
+                case 0: key = Vocabulary.Keys.Name; break;
+                case 1: key = Vocabulary.Keys.Type; break;
+                case 2: key = Vocabulary.Keys.ValueDomain; break;
+                case 3: key = (values == null) ? Vocabulary.Keys.DefaultValue : Vocabulary.Keys.Value; end = true; break;
+                default: throw new AssertionError(i);
+            }
+            if (hasColors) table.append(X364.BOLD.sequence());
+            table.append(resources.getString(key));
+            if (hasColors) table.append(X364.NORMAL.sequence());
+            if (end) break;
+            table.nextColumn();
+        }
+        table.nextLine();
+        /*
+         * Prepares the informations to be printed later as table rows. We scan all rows before to print them
+         * in order to compute the width of codespaces. During this process, we split the objects to be printed
+         * later in two collections: simple parameters are stored as (descriptor,value) pairs, while groups are
+         * stored in an other collection for deferred printing after the simple parameters.
+         */
+        int codespaceWidth = 0;
+        final Collection<?> elements = (values != null) ? values.values() : group.descriptors();
+        final Map<GeneralParameterDescriptor, ParameterTableRow> descriptorValues =
+                new LinkedHashMap<>(hashMapCapacity(elements.size()));
+        List<Object> deferredGroups = null; // To be created only if needed (it is usually not).
+        for (final Object element : elements) {
+            final GeneralParameterValue parameter;
+            final GeneralParameterDescriptor descriptor;
+            if (values != null) {
+                parameter  = (GeneralParameterValue) element;
+                descriptor = parameter.getDescriptor();
+            } else {
+                parameter  = null;
+                descriptor = (GeneralParameterDescriptor) element;
+            }
+            if (descriptor instanceof ParameterDescriptorGroup) {
+                if (deferredGroups == null) {
+                    deferredGroups = new ArrayList<>(4);
+                }
+                deferredGroups.add(element);
+                continue;
+            }
+            /*
+             * In the vast majority of cases, there is only one value for each parameter. However
+             * if we find more than one value, we will append all extra occurrences in a "multiple
+             * values" list to be formatted in the same row.
+             */
+            Object value = null;
+            Unit<?> unit = null;
+            if (parameter instanceof ParameterValue<?>) {
+                final ParameterValue<?> p = (ParameterValue<?>) parameter;
+                value = p.getValue();
+                unit  = p.getUnit();
+            } else if (descriptor instanceof ParameterDescriptor<?>) {
+                final ParameterDescriptor<?> p = (ParameterDescriptor<?>) descriptor;
+                value = p.getDefaultValue();
+                unit  = p.getUnit();
+            }
+            ParameterTableRow row = descriptorValues.get(descriptor);
+            if (row == null) {
+                row = new ParameterTableRow(descriptor, displayLocale, isBrief);
+                descriptorValues.put(descriptor, row);
+            }
+            row.values.add(value);
+            row.units .add(unit);
+            if (row.codespaceWidth > codespaceWidth) {
+                codespaceWidth = row.codespaceWidth;
+            }
+        }
+        /*
+         * Now process to the formatting of (descriptor,value) pairs. Each descriptor alias
+         * will be formatted on its own line in a table row. If there is more than one value,
+         * then each value will be formatted on its own line as well. Note that the values may
+         * be null if there is none.
+         */
+        char horizontalLine = horizontalBorder;
+        for (final Map.Entry<GeneralParameterDescriptor,ParameterTableRow> entry : descriptorValues.entrySet()) {
+            if (horizontalLine != 0) {
+                table.nextLine('─');
+            }
+            horizontalLine = isBrief ? 0 : '─';
+            final ParameterTableRow row = entry.getValue();
+            row.codespaceWidth = codespaceWidth;
+            row.appendIdentifiers(table, false, hasColors, lineSeparator);
+            table.nextColumn();
+            final GeneralParameterDescriptor generalDescriptor = entry.getKey();
+            if (generalDescriptor instanceof ParameterDescriptor<?>) {
+                /*
+                 * Writes value type.
+                 */
+                final ParameterDescriptor<?> descriptor = (ParameterDescriptor<?>) generalDescriptor;
+                final Class<?> valueClass = descriptor.getValueClass();
+                table.append(getFormat(Class.class).format(valueClass));
+                table.nextColumn();
+                /*
+                 * Writes minimum and maximum values, together with the unit of measurement (if any).
+                 */
+                final Range<?> valueDomain = Parameters.getValueDomain(descriptor);
+                if (valueDomain != null) {
+                    table.append(getFormat(Range.class).format(valueDomain));
+                }
+                table.nextColumn();
+                /*
+                 * Wraps the value in an array. Because it may be an array of primitive type,
+                 * we can't cast to Object[]. Then, each array's element will be formatted on
+                 * its own line.
+                 */
+                row.expandSingleton();
+                final int length = row.values.size();
+                for (int i=0; i<length; i++) {
+                    final Object value = row.values.get(i);
+                    if (value != null) {
+                        if (i != 0) {
+                            table.append(lineSeparator);
+                        }
+                        final Format format = getFormat(value.getClass());
+                        table.append(format != null ? format.format(value) : value.toString());
+                        final Unit<?> unit = row.units.get(i);
+                        if (unit != null) {
+                            final String symbol = getFormat(Unit.class).format(unit);
+                            if (!symbol.isEmpty()) {
+                                if (Character.isLetterOrDigit(symbol.codePointAt(0))) {
+                                    table.append(' ');
+                                }
+                                table.append(symbol);
+                            }
+                        }
+                    }
+                }
+            }
+            table.nextLine();
+        }
+        table.nextLine(horizontalBorder);
+        table.flush();
+        /*
+         * Now formats all groups deferred to the end of this table, with recursive calls to
+         * this method (recursive calls use their own TableWriter instance, so they may result
+         * in a different cell layout). Most of the time, there is no such additional group.
+         */
+        if (deferredGroups != null) {
+            for (final Object element : deferredGroups) {
+                final ParameterValueGroup value;
+                final ParameterDescriptorGroup descriptor;
+                if (element instanceof ParameterValueGroup) {
+                    value = (ParameterValueGroup) element;
+                    descriptor = value.getDescriptor();
+                } else {
+                    value = null;
+                    descriptor = (ParameterDescriptorGroup) element;
+                }
+                out.append(lineSeparator);
+                format(name + '/' + descriptor.getName().getCode(), descriptor, value, out);
+            }
+        }
+    }
+
+    /**
+     * Implementation of public {@code format(…)} methods for {@code NAME_SUMMARY} content level.
+     *
+     * @param  objects The collection of objects to format.
+     * @param  out The stream or buffer where to write the summary.
+     * @throws IOException if an error occurred will writing to the given appendable.
+     */
+    private void formatSummary(final IdentifiedObject[] objects, final Appendable out) throws IOException {
+        /*
+         * Prepares all rows before we write them to the output stream, because not all
+         * identified objects may have names with the same scopes in the same order. We
+         * also need to iterate over all rows in order to know the number of columns.
+         *
+         * The two first columns are treated especially.  The first one is the optional
+         * EPSG code. The second one is the main identifier (usually the EPSG name). We
+         * put SHOW_EPSG_CODE and null as special values for their column names,  to be
+         * replaced later by "EPSG" and "Identifier" in user locale. We can not put the
+         * localized strings in the map right now because they could conflict with the
+         * scope of some alias to be processed below.
+         */
+        final Map<Object,Integer> header = new LinkedHashMap<>();
+        final List<String[]>        rows = new ArrayList<>();
+        final List<String>     epsgNames = new ArrayList<>();
+        final Set<String>     codespaces = this.preferredCodespaces;
+        final Vocabulary       resources = Vocabulary.getResources(displayLocale);
+        final int          showEpsgCodes = ((codespaces == null) || codespaces.contains(SHOW_EPSG_CODES)) ? 1 : 0;
+        if (showEpsgCodes != 0) {
+            header.put(SHOW_EPSG_CODES, 0);
+        }
+        header.put(null, showEpsgCodes); // See above comment for the meaning of "null" here.
+        for (final IdentifiedObject element : objects) {
+            /*
+             * Prepares a row: puts the name in the "identifier" column, which is the
+             * first or the second one depending if we display EPSG codes or not.
+             */
+            String epsgName = null;
+            String[] row = new String[header.size()];
+            row[showEpsgCodes] = element.getName().getCode();
+            int numUnscoped = 0;
+            final Collection<GenericName> aliases = element.getAlias();
+            if (aliases != null) {
+                /*
+                 * Adds alias (without scope) to the row. Each alias will be put in the column
+                 * appropriate for its scope. If a name has no scope, we will create one using
+                 * sequential number ("numUnscoped" is the count of such names without scope).
+                 */
+                for (final GenericName alias : aliases) {
+                    final GenericName scope = alias.scope().name();
+                    final String name = alias.tip().toInternationalString().toString(displayLocale);
+                    final Object columnName;
+                    if (scope != null) {
+                        columnName = scope.toInternationalString().toString(displayLocale);
+                    } else {
+                        columnName = ++numUnscoped;
+                    }
+                    if (columnName.equals("EPSG")) {
+                        epsgName = name;
+                    }
+                    if (codespaces != null && !codespaces.contains(scope.toString())) {
+                        /*
+                         * The user requested only for a few authorities and the current alias
+                         * is not a member of this subset. Continue the search to other alias.
+                         */
+                        continue;
+                    }
+                    /*
+                     * Now stores the alias name at the position we just determined above. If
+                     * more than one value are assigned to the same column, keep the first one.
+                     */
+                    row = putIfAbsent(row, getColumnIndex(header, columnName), name);
+                }
+            }
+            /*
+             * After the aliases, search for the identifiers. The code in this block is similar
+             * to the one we just did for aliases. By doing this operation after the aliases we
+             * ensure that if both an identifier and a name is defined for the same column, the
+             * name is given precedence.
+             */
+            final Collection<ReferenceIdentifier> identifiers = element.getIdentifiers();
+            if (identifiers != null) {
+                for (final ReferenceIdentifier identifier : identifiers) {
+                    final String scope = identifier.getCodeSpace();
+                    final String name = identifier.getCode();
+                    final Object columnName = (scope != null) ? scope : ++numUnscoped;
+                    int columnIndex;
+                    if (showEpsgCodes != 0 && columnName.equals("EPSG")) {
+                        columnIndex = 0;
+                    } else {
+                        if (codespaces!=null && !codespaces.contains(scope)) {
+                            continue;
+                        }
+                        columnIndex = getColumnIndex(header, columnName);
+                    }
+                    row = putIfAbsent(row, columnIndex, name);
+                }
+            }
+            rows.add(row);
+            epsgNames.add(epsgName);
+        }
+        /*
+         * Writes the table. The header will contains one column for each alias's scope
+         * (or authority) declared in 'titles', in the same order. The column for Geotk
+         * names will treated especially, because cit ontains ambiguous names.
+         */
+        final boolean hasColors = (colors != null);
+        final TableAppender table = new TableAppender(out, " │ ");
+        table.setMultiLinesCells(true);
+        table.appendHorizontalSeparator();
+        /*
+         * Writes all column headers.
+         */
+        int column = 0;
+        int geotoolkitColumn = -1;
+        for (final Object element : header.keySet()) {
+            String title;
+            if (element == null) {
+                title = resources.getString(Vocabulary.Keys.Identifier);
+            } else if (element == SHOW_EPSG_CODES) {
+                title = "EPSG";
+            } else if (element instanceof String) {
+                title = (String) element;
+                if (title.equalsIgnoreCase("geotk") ||
+                    title.equalsIgnoreCase("Geotoolkit.org") ||
+                    title.equalsIgnoreCase("Geotoolkit")) // Legacy
+                {
+                    geotoolkitColumn = column;
+                    title = resources.getString(Vocabulary.Keys.Description);
+                }
+            } else { // Should be a Number
+                title = resources.getString(Vocabulary.Keys.Aliases) + ' ' + element;
+            }
+            if (hasColors) {
+                title = X364.BOLD.sequence() + title + X364.NORMAL.sequence();
+            }
+            table.append(title);
+            table.nextColumn();
+            column++;
+        }
+        table.appendHorizontalSeparator();
+        /*
+         * Writes all rows.
+         */
+        final int numRows    = rows.size();
+        final int numColumns = header.size();
+        for (int rowIndex=0; rowIndex<numRows; rowIndex++) {
+            final String[] aliases = rows.get(rowIndex);
+            for (column=0; column<numColumns; column++) {
+                if (column < aliases.length) {
+                    String alias = aliases[column];
+                    if (column == geotoolkitColumn) {
+                        if (alias == null) {
+                            alias = epsgNames.get(rowIndex);
+                        } else if (hasColors) {
+                            if (!alias.equals(aliases[showEpsgCodes])) {
+                                alias = X364.FAINT.sequence() + alias + X364.NORMAL.sequence();
+                            }
+                        }
+                    }
+                    if (alias != null) {
+                        table.append(alias);
+                    }
+                }
+                table.nextColumn();
+            }
+            table.nextLine();
+        }
+        table.appendHorizontalSeparator();
+        table.flush();
+    }
+
+    /**
+     * Returns the index of the column of the given name. If no such column
+     * exists, then a new column is appended at the right of the table.
+     */
+    private static int getColumnIndex(final Map<Object,Integer> header, final Object columnName) {
+        Integer position = header.get(columnName);
+        if (position == null) {
+            position = header.size();
+            header.put(columnName, position);
+        }
+        return position;
+    }
+
+    /**
+     * Stores a value at the given position in the given row, expanding the array if needed.
+     * This operation is performed only if no value already exists at the given index.
+     */
+    private static String[] putIfAbsent(String[] row, final int columnIndex, final String name) {
+        if (columnIndex >= row.length) {
+            row = Arrays.copyOf(row, columnIndex+1);
+        }
+        if (row[columnIndex] == null) {
+            row[columnIndex] = name;
+        }
+        return row;
+    }
+
+    /**
+     * Not yet supported.
+     *
+     * @return Currently never return.
+     * @throws ParseException Currently always thrown.
+     */
+    @Override
+    public Object parse(final CharSequence text, final ParsePosition pos) throws ParseException {
+        throw new ParseException("Not supported yet.", 0);
+    }
+}

Propchange: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterTableRow.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterTableRow.java?rev=1576108&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterTableRow.java (added)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterTableRow.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.parameter;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.Locale;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.LinkedHashMap;
+import java.lang.reflect.Array;
+import java.io.IOException;
+import javax.measure.unit.Unit;
+import org.opengis.util.GenericName;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.util.InternationalString;
+import org.opengis.util.NameSpace;
+import org.apache.sis.internal.referencing.NameToIdentifier;
+import org.apache.sis.internal.util.X364;
+
+import static org.apache.sis.internal.util.X364.*;
+import static org.apache.sis.util.CharSequences.spaces;
+
+
+/**
+ * A row in the table to be formatted by {@link ParameterFormat}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.4 (derived from geotk-3.00)
+ * @version 0.4
+ * @module
+ */
+final class ParameterTableRow {
+    /**
+     * The (<var>codespace(s)</var>, <var>name(s)</var>) entries for the identifier and all aliases
+     * declared in the constructor. The codespace key may be null, but the name values shall never be null.
+     *
+     * <p>Values can be of two kinds:</p>
+     * <ul>
+     *   <li>{@link String} for names or aliases.</li>
+     *   <li>{@link ReferenceIdentifier} for identifiers.</li>
+     * </ul>
+     */
+    private final Map<String,Set<Object>> identifiers;
+
+    /**
+     * The values. Some elements in this list may be null.
+     */
+    final List<Object> values;
+
+    /**
+     * The units of measurement. The size of this list shall be the same than {@link #values}.
+     * The list may contain null elements.
+     */
+    final List<Unit<?>> units;
+
+    /**
+     * The largest codespace width, in number of Unicode code points.
+     */
+    int codespaceWidth;
+
+    /**
+     * Creates a new row in a table to be formatted by {@link ParameterFormat}.
+     *
+     * @param object The object for which to get the (<var>codespace(s)</var>, <var>name(s)</var>).
+     * @param locale The locale for formatting the names.
+     */
+    ParameterTableRow(final IdentifiedObject object, final Locale locale, final boolean brief) {
+        values = new ArrayList<>(2); // In the vast majority of cases, we will have only one value.
+        units  = new ArrayList<>(2);
+        /*
+         * Creates a collection which will contain the identifier and all aliases
+         * found for the given IdentifiedObject. We begin with the primary name.
+         */
+        identifiers = new LinkedHashMap<>();
+        final ReferenceIdentifier identifier = object.getName();
+        addIdentifier(identifier.getCodeSpace(), identifier.getCode()); // Value needs to be a String here.
+        if (!brief) {
+            final Collection<GenericName> aliases = object.getAlias();
+            if (aliases != null) { // Paranoiac check.
+                for (GenericName alias : aliases) {
+                    String codespace = NameToIdentifier.getCodeSpace(alias);
+                    if (codespace != null) {
+                        alias = alias.tip();
+                    } else {
+                        final NameSpace scope = alias.scope();
+                        if (scope != null && !scope.isGlobal()) {
+                            codespace = toString(scope.name().tip(), locale);
+                        }
+                    }
+                    addIdentifier(codespace, toString(alias, locale));
+                }
+            }
+            final Collection<? extends ReferenceIdentifier> ids = object.getIdentifiers();
+            if (ids != null) { // Paranoiac check.
+                for (final ReferenceIdentifier id : ids) {
+                    addIdentifier(id.getCodeSpace(), id); // No .getCode() here.
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds an identifier for the given code space.
+     * As a side effect, this method remembers the length of the widest code space.
+     */
+    private void addIdentifier(final String codespace, final Object identifier) {
+        if (codespace != null) {
+            final int width = codespace.codePointCount(0, codespace.length());
+            if (width > codespaceWidth) {
+                codespaceWidth = width;
+            }
+        }
+        Set<Object> ids = identifiers.get(codespace);
+        if (ids == null) {
+            ids = new LinkedHashSet<>(8);
+            identifiers.put(codespace, ids);
+        }
+        ids.add(identifier);
+    }
+
+    /**
+     * If the list has only one element and this element is an array or a collection, expands it.
+     * This method shall be invoked only after the caller finished to add all elements in the
+     * {@link #values} and {@link #units} lists.
+     */
+    final void expandSingleton() {
+        assert values.size() == units.size();
+        if (values.size() == 1) {
+            Object value = values.get(0);
+            if (value != null) {
+                if (value instanceof Collection<?>) {
+                    value = ((Collection<?>) value).toArray();
+                }
+                if (value.getClass().isArray()) {
+                    final int length = Array.getLength(value);
+                    final Unit<?> unit = units.get(0);
+                    values.clear();
+                    units.clear();
+                    for (int i=0; i<length; i++) {
+                        values.add(Array.get(value, i));
+                        units.add(unit);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Writes the given color if {@code colorEnabled} is {@code true}.
+     */
+    private static void appendColor(final Appendable out, final X364 color, final boolean colorEnabled)
+            throws IOException
+    {
+        if (colorEnabled) {
+            out.append(color.sequence());
+        }
+    }
+
+    /**
+     * Writes the identifiers. At most one of {@code colorsForTitle} and {@code colorsForRows}
+     * can be set to {@code true}.
+     *
+     * @param  out             Where to write.
+     * @param  colorsForTitle  {@code true} if syntax coloring should be applied for table title.
+     * @param  colorsForRows   {@code true} if syntax coloring should be applied for table rows.
+     * @param  lineSeparator   The system-dependent line separator.
+     * @throws IOException     If an exception occurred while writing.
+     */
+    final void appendIdentifiers(final Appendable out, final boolean colorsForTitle,
+            final boolean colorsForRows, final String lineSeparator) throws IOException
+    {
+        boolean continuing = false;
+        for (final Map.Entry<String,Set<Object>> entry : identifiers.entrySet()) {
+            if (continuing) {
+                out.append(lineSeparator);
+            }
+            continuing = true;
+            int length = codespaceWidth + 1;
+            final String authority  = entry.getKey();
+            appendColor(out, FOREGROUND_GREEN, colorsForTitle);
+            if (authority != null) {
+                appendColor(out, FAINT, colorsForRows);
+                out.append(authority);
+                out.append(':');
+                appendColor(out, NORMAL, colorsForRows);
+                length -= authority.length();
+            }
+            out.append(spaces(length));
+            appendColor(out, BOLD, colorsForTitle);
+            final Iterator<Object> it = entry.getValue().iterator();
+            out.append(toString(it.next()));
+            appendColor(out, RESET, colorsForTitle);
+            boolean hasMore = false;
+            while (it.hasNext()) {
+                out.append(hasMore ? ", " : " (");
+                final Object id = it.next();
+                final X364 color, normal;
+                if (id instanceof ReferenceIdentifier) {
+                    color  = FOREGROUND_YELLOW;
+                    normal = FOREGROUND_DEFAULT;
+                } else {
+                    color  = FAINT;
+                    normal = NORMAL;
+                }
+                appendColor(out, color, colorsForTitle);
+                out.append(toString(id));
+                appendColor(out, normal, colorsForTitle);
+                hasMore = true;
+            }
+            if (hasMore) {
+                out.append(')');
+            }
+            appendColor(out, RESET, colorsForTitle);
+        }
+    }
+
+    /**
+     * Returns a string representation of the given name in the given locale, with paranoiac checks against null value.
+     * Such null values should never happen since the properties used here are mandatory, but we try to make this class
+     * robust to broken implementations.
+     */
+    private static String toString(final GenericName name, final Locale locale) {
+        if (name != null) {
+            final InternationalString i18n = name.toInternationalString();
+            return (i18n != null) ? i18n.toString(locale) : name.toString();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string representation of the given parameter name.
+     */
+    private static String toString(Object parameter) {
+        if (parameter instanceof ReferenceIdentifier) {
+            parameter = ((ReferenceIdentifier) parameter).getCode();
+        }
+        return parameter.toString();
+    }
+}

Propchange: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterTableRow.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterTableRow.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -102,32 +102,35 @@ public final class Parameters extends St
      * {@linkplain DefaultParameterDescriptor#getMaximumValue() maximum value} and, if the values are numeric, from
      * the {@linkplain DefaultParameterDescriptor#getUnit() unit}.
      *
-     * @param  <T> The type of parameter values.
      * @param  descriptor The parameter descriptor, or {@code null}.
      * @return The domain of valid values, or {@code null} if none.
      *
      * @see DefaultParameterDescriptor#getValueDomain()
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
-    public static <T extends Comparable<? super T>> Range<T> getValueDomain(final ParameterDescriptor<T> descriptor) {
+    public static Range<?> getValueDomain(final ParameterDescriptor<?> descriptor) {
         if (descriptor != null) {
             if (descriptor instanceof DefaultParameterDescriptor<?>) {
-                return (Range) ((DefaultParameterDescriptor<T>) descriptor).getValueDomain();
+                return ((DefaultParameterDescriptor<?>) descriptor).getValueDomain();
             }
-            final Class<T> valueClass = descriptor.getValueClass();
-            final T minimumValue = valueClass.cast(descriptor.getMinimumValue());
-            final T maximumValue = valueClass.cast(descriptor.getMaximumValue());
-            if (Number.class.isAssignableFrom(valueClass)) {
-                final Unit<?> unit = descriptor.getUnit();
-                if (unit != null) {
-                    return new MeasurementRange((Class) valueClass,
-                            (Number) minimumValue, true, (Number) maximumValue, true, unit);
+            final Class<?> valueClass = descriptor.getValueClass();
+            final Comparable<?> minimumValue = descriptor.getMinimumValue();
+            final Comparable<?> maximumValue = descriptor.getMaximumValue();
+            if ((minimumValue == null || valueClass.isInstance(minimumValue)) &&
+                (maximumValue == null || valueClass.isInstance(maximumValue)))
+            {
+                if (Number.class.isAssignableFrom(valueClass)) {
+                    final Unit<?> unit = descriptor.getUnit();
+                    if (unit != null) {
+                        return new MeasurementRange((Class) valueClass,
+                                (Number) minimumValue, true, (Number) maximumValue, true, unit);
+                    } else if (minimumValue != null || maximumValue != null) {
+                        return new NumberRange((Class) valueClass,
+                                (Number) minimumValue, true, (Number) maximumValue, true);
+                    }
                 } else if (minimumValue != null || maximumValue != null) {
-                    return new NumberRange((Class) valueClass,
-                            (Number) minimumValue, true, (Number) maximumValue, true);
+                    return new Range(valueClass, minimumValue, true, maximumValue, true);
                 }
-            } else if (minimumValue != null || maximumValue != null) {
-                return new Range<>(valueClass, minimumValue, true, maximumValue, true);
             }
         }
         return null;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -32,13 +32,12 @@ import org.opengis.metadata.citation.Cit
 import org.opengis.metadata.Identifier;
 import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.parameter.InvalidParameterValueException;
+import org.apache.sis.internal.referencing.NameToIdentifier;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.metadata.iso.ImmutableIdentifier;
 import org.apache.sis.util.collection.WeakValueHashMap;
 
-import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
-
 // Related to JDK7
 import java.util.Objects;
 
@@ -142,7 +141,7 @@ public class NamedIdentifier extends Imm
      * @param name The name to wrap.
      */
     public NamedIdentifier(final GenericName name) {
-        super(name instanceof ReferenceIdentifier ? (ReferenceIdentifier) name : new Adapter(name));
+        super(name instanceof ReferenceIdentifier ? (ReferenceIdentifier) name : new NameToIdentifier(name));
         this.name = name;
         isNameSupplied = true;
     }
@@ -260,44 +259,6 @@ public class NamedIdentifier extends Imm
     }
 
     /**
-     * The converse of {@link NamedIdentifier#createName(Citation, CharSequence)}.
-     */
-    private static final class Adapter implements ReferenceIdentifier {
-        /** The name from which to infer the identifier attributes. */
-        private final GenericName name;
-
-        /** Infers the attributes from the given name. */
-        Adapter(final GenericName name) {
-            ensureNonNull("name", name);
-            this.name = name;
-        }
-
-        /** Infers the authority from the scope. */
-        @Override public Citation getAuthority() {
-            final NameSpace scope = name.scope();
-            if (scope == null || scope.isGlobal()) {
-                return null;
-            }
-            return Citations.fromName(scope.name().tip().toString());
-        }
-
-        /** Takes everything except the tip as the code space. */
-        @Override public String getCodeSpace() {
-            return (name instanceof ScopedName) ? ((ScopedName) name).path().toString() : null;
-        }
-
-        /** Takes the last element as the code. */
-        @Override public String getCode() {
-            return name.tip().toString();
-        }
-
-        /** Names are not versioned. */
-        @Override public String getVersion() {
-            return null;
-        }
-    }
-
-    /**
      * The last element in the sequence of {@linkplain #getParsedNames() parsed names}.
      * By default, this is the same value than the {@linkplain #getCode() code} provided as a local name.
      *

Added: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java?rev=1576108&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java (added)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.parameter;
+
+import java.util.List;
+import javax.measure.unit.SI;
+import javax.measure.unit.NonSI;
+import javax.measure.unit.Unit;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import static org.apache.sis.metadata.iso.citation.HardCodedCitations.OGC;
+import static org.apache.sis.metadata.iso.citation.HardCodedCitations.OGP;
+
+
+/**
+ * Tests the {@link ParameterBuilder} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.4
+ * @version 0.4
+ * @module
+ */
+@DependsOn(ParameterBuilderTest.class)
+public final strictfp class ParameterFormatTest extends TestCase {
+    /**
+     * The parameter descriptors used for all tests in this class.
+     */
+    private static ParameterDescriptorGroup descriptor;
+
+    /**
+     * Creates the parameter descriptors to be used by all tests in this class. This method creates
+     * a variant of the example documented in the {@link DefaultParameterDescriptorGroup} javadoc
+     * with arbitrary non-zero default values.
+     */
+    @BeforeClass
+    public static void createParameters() {
+        ParameterBuilder builder = new ParameterBuilder();
+        builder.setCodeSpace(OGP, "EPSG").setRequired(true);
+        ParameterDescriptor<?>[] parameters = {
+            builder.addName("Latitude of natural origin")    .addName(OGC, "latitude_of_origin").createBounded( -80,  +84,  40, NonSI.DEGREE_ANGLE),
+            builder.addName("Longitude of natural origin")   .addName(OGC, "central_meridian")  .createBounded(-180, +180, -60, NonSI.DEGREE_ANGLE),
+            builder.addName("Scale factor at natural origin").addName(OGC, "scale_factor")      .createStrictlyPositive(1, Unit.ONE),
+            builder.addName("False easting")                 .addName(OGC, "FalseEasting")      .create( 5000, SI.METRE),
+            builder.addName("False northing")                .addName(OGC, "FalseNorthing")     .create(10000, SI.METRE)
+        };
+        builder.addIdentifier("9804")
+               .addName("Mercator (variant A)")
+               .addName("Mercator (1SP)")
+               .addName(OGC, "Mercator_1SP");
+        descriptor = builder.createGroup(parameters);
+    }
+
+    /**
+     * Forgets the parameter descriptors after all tests are done.
+     */
+    @AfterClass
+    public static void clearParameters() {
+        descriptor = null;
+    }
+
+    /**
+     * Tests {@link ParameterFormat#format(Object, Appendable)} for a {@link ParameterDescriptorGroup}.
+     */
+    @Test
+    public void testFormatDescriptor() {
+        final ParameterFormat format = new ParameterFormat(null, null);
+        String text = format.format(descriptor);
+        // TODO: verify output
+
+        format.setContentLevel(ParameterFormat.ContentLevel.DETAILED);
+        text = format.format(descriptor);
+        // TODO: verify output
+    }
+
+    @Test
+    public void testFormatIdentifiedObjects() throws Exception {
+        final ParameterFormat format = new ParameterFormat(null, null);
+        format.setContentLevel(ParameterFormat.ContentLevel.NAME_SUMMARY);
+        final List<GeneralParameterDescriptor> parameters = descriptor.descriptors();
+        final String text = format.format(parameters.toArray(new IdentifiedObject[parameters.size()]));
+        // TODO: verify output
+    }
+}

Propchange: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -57,6 +57,7 @@ import org.junit.BeforeClass;
     org.apache.sis.parameter.DefaultParameterValueGroupTest.class,
     org.apache.sis.parameter.ParametersTest.class,
     org.apache.sis.parameter.ParameterBuilderTest.class,
+    org.apache.sis.parameter.ParameterFormatTest.class,
     org.apache.sis.referencing.datum.BursaWolfParametersTest.class,
     org.apache.sis.referencing.datum.TimeDependentBWPTest.class,
     org.apache.sis.referencing.datum.DefaultEllipsoidTest.class,

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -29,9 +29,13 @@ import java.text.ParsePosition;
 import java.text.NumberFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import javax.measure.unit.Unit;
+import javax.measure.unit.UnitFormat;
 
 import org.apache.sis.measure.Angle;
 import org.apache.sis.measure.AngleFormat;
+import org.apache.sis.measure.Range;
+import org.apache.sis.measure.RangeFormat;
 import org.apache.sis.util.Localized;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.collection.BackingStoreException;
@@ -300,7 +304,7 @@ public abstract class CompoundFormat<T> 
      *
      * @param  object      The object to format.
      * @param  toAppendTo  Where to format the object.
-     * @throws IOException If an error occurred while writing in the given appender.
+     * @throws IOException If an error occurred while writing to the given appendable.
      */
     public abstract void format(T object, Appendable toAppendTo) throws IOException;
 
@@ -393,6 +397,9 @@ public abstract class CompoundFormat<T> 
      *   <tr><td>{@link Angle}</td>  <td>{@link AngleFormat}</td></tr>
      *   <tr><td>{@link Date}</td>   <td>{@link DateFormat}</td></tr>
      *   <tr><td>{@link Number}</td> <td>{@link NumberFormat}</td></tr>
+     *   <tr><td>{@link Unit}</td>   <td>{@link UnitFormat}</td></tr>
+     *   <tr><td>{@link Range}</td>  <td>{@link RangeFormat}</td></tr>
+     *   <tr><td>{@link Class}</td>  <td>(internal)</td></tr>
      * </table>
      *
      * Subclasses can override this method for adding more types, or for configuring the
@@ -432,6 +439,10 @@ public abstract class CompoundFormat<T> 
             return format;
         } else if (valueType == Angle.class) {
             return AngleFormat.getInstance(locale);
+        } else if (valueType == Unit.class) {
+            return UnitFormat.getInstance(locale);
+        } else if (valueType == Range.class) {
+            return new RangeFormat(locale);
         } else if (valueType == Class.class) {
             return ClassFormat.INSTANCE;
         }

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -523,6 +523,14 @@ public class TableAppender extends Appen
     /**
      * Writes an horizontal separator.
      */
+    public void appendHorizontalSeparator() {
+        writeHorizontalSeparator();
+    }
+
+    /**
+     * @deprecated Renamed {@link #appendHorizontalSeparator()}.
+     */
+    @Deprecated
     public void writeHorizontalSeparator() {
         if (currentColumn != 0 || buffer.length() != 0) {
             nextLine();

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -253,7 +253,7 @@ public class StatisticsFormat extends Ta
      *
      * @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.
+     * @throws IOException If an error occurred while writing to the given appendable.
      */
     @Override
     public void format(Statistics stats, final Appendable toAppendTo) throws IOException {
@@ -272,7 +272,7 @@ public class StatisticsFormat extends Ta
      *
      * @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.
+     * @throws IOException If an error occurred while writing to the given appendable.
      */
     public void format(final Statistics[] stats, final Appendable toAppendTo) throws IOException {
         /*

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -664,6 +664,8 @@ public class Range<E extends Comparable<
         }
         final Unit<?> unit = unit();
         if (unit != null) {
+            // No need to check if we should omit the space because Unit.toString()
+            // uses UCUM format, so we will never have symbol like the ° one.
             buffer.append(' ').append(unit);
         }
         return buffer.toString();

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/RangeFormat.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.measure;
 
+import java.util.Map;
+import java.util.HashMap;
 import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
@@ -89,7 +91,7 @@ import org.apache.sis.util.resources.Err
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.06)
- * @version 0.3
+ * @version 0.4
  * @module
  *
  * @see Range#toString()
@@ -289,6 +291,13 @@ public class RangeFormat extends Format 
     protected final UnitFormat unitFormat;
 
     /**
+     * Whether we should insert a space between the bracket and the unit symbol.
+     *
+     * @see #insertSpaceBeforeUnit(Unit)
+     */
+    private transient Map<Unit<?>,Boolean> insertSpaceBeforeUnit;
+
+    /**
      * Creates a new format for parsing and formatting {@linkplain NumberRange number ranges}
      * using the {@linkplain Locale#getDefault() default locale}.
      */
@@ -461,6 +470,23 @@ public class RangeFormat extends Format 
     }
 
     /**
+     * Returns whether we should insert a space between the bracket and the unit symbol.
+     * We cache the result because checking for this condition forces us to format the unit symbol twice.
+     */
+    private boolean insertSpaceBeforeUnit(final Unit<?> unit) {
+        if (insertSpaceBeforeUnit == null) {
+            insertSpaceBeforeUnit = new HashMap<>();
+        }
+        Boolean value = insertSpaceBeforeUnit.get(unit);
+        if (value == null) {
+            final String symbol = unitFormat.format(unit);
+            value = !symbol.isEmpty() && Character.isLetterOrDigit(symbol.codePointAt(0));
+            insertSpaceBeforeUnit.put(unit, value);
+        }
+        return value;
+    }
+
+    /**
      * Returns the {@code *_FIELD} constant for the given field position, or -1 if none.
      */
     private static int getField(final FieldPosition position) {
@@ -574,7 +600,9 @@ public class RangeFormat extends Format 
             } else {
                 final Format format;
                 if (field == UNIT_FIELD) {
-                    startPosition = toAppendTo.append(' ').length();
+                    if (insertSpaceBeforeUnit((Unit) value)) {
+                        startPosition = toAppendTo.append(' ').length();
+                    }
                     format = unitFormat;
                 } else {
                     format = elementFormat;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -593,7 +593,7 @@ public class TreeTableFormat extends Tab
         private final Map<Object,Object> parentObjects;
 
         /**
-         * Creates a new instance which will write in the given appendable.
+         * Creates a new instance which will write to the given appendable.
          *
          * @param out           Where to format the tree.
          * @param column        The columns of the tree table to format.
@@ -731,7 +731,7 @@ public class TreeTableFormat extends Tab
      *
      * @param  tree        The tree to format.
      * @param  toAppendTo  Where to format the tree.
-     * @throws IOException If an error occurred while writing in the given appender.
+     * @throws IOException If an error occurred while writing to the given appendable.
      *
      * @see TreeTables#toString(TreeTable)
      */

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -55,6 +55,11 @@ public final class Vocabulary extends In
         }
 
         /**
+         * Aliases
+         */
+        public static final short Aliases = 74;
+
+        /**
          * Angle
          */
         public static final short Angle = 0;
@@ -130,6 +135,16 @@ public final class Vocabulary extends In
         public static final short DaylightTime = 13;
 
         /**
+         * Default value
+         */
+        public static final short DefaultValue = 71;
+
+        /**
+         * Description
+         */
+        public static final short Description = 75;
+
+        /**
          * Destination
          */
         public static final short Destination = 14;
@@ -365,6 +380,11 @@ public final class Vocabulary extends In
         public static final short UnavailableContent = 57;
 
         /**
+         * Units
+         */
+        public static final short Units = 72;
+
+        /**
          * Unnamed
          */
         public static final short Unnamed = 65;
@@ -385,6 +405,11 @@ public final class Vocabulary extends In
         public static final short Value = 60;
 
         /**
+         * Value domain
+         */
+        public static final short ValueDomain = 73;
+
+        /**
          * Variables
          */
         public static final short Variables = 61;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] Mon Mar 10 22:24:31 2014
@@ -14,6 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+Aliases                 = Aliases
 Angle                   = Angle
 AngularDegrees          = Degrees
 AngularMinutes          = Minutes
@@ -29,6 +30,8 @@ CurrentDateTime         = Current date a
 CurrentDirectory        = Current directory
 CycleOmitted            = Cycle omitted
 DaylightTime            = Daylight time
+DefaultValue            = Default value
+Description             = Description
 Destination             = Destination
 Dimensions              = Dimensions
 Directory               = Directory
@@ -78,8 +81,10 @@ Type                    = Type
 Unnamed                 = Unnamed
 Untitled                = Untitled
 UnavailableContent      = Unavailable content.
+Units                   = Units
 UserHome                = User home directory
 Value                   = Value
+ValueDomain             = Value domain
 Variables               = Variables
 Version_2               = {0} version {1}
 Versions                = Versions

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] Mon Mar 10 22:24:31 2014
@@ -14,6 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+Aliases                 = Alias
 Angle                   = Angle
 AngularDegrees          = Degr\u00e9s
 AngularMinutes          = Minutes
@@ -29,6 +30,8 @@ CurrentDateTime         = Date et heure 
 CurrentDirectory        = R\u00e9pertoire courant
 CycleOmitted            = Cycle omit
 DaylightTime            = Heure normale
+DefaultValue            = Valeur par d\u00e9faut
+Description             = Description
 Destination             = Destination
 Dimensions              = Dimensions
 Directory               = R\u00e9pertoire
@@ -78,8 +81,10 @@ Type                    = Type
 Unnamed                 = Sans nom
 Untitled                = Sans titre
 UnavailableContent      = Contenu non-disponible.
+Units                   = Unit\u00e9s
 UserHome                = R\u00e9pertoire de l'utilisateur
 Value                   = Valeur
+ValueDomain             = Domaine des valeurs
 Variables               = Variables
 Version_2               = {0} version {1}
 Versions                = Versions

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/io/TableAppenderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/io/TableAppenderTest.java?rev=1576108&r1=1576107&r2=1576108&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/io/TableAppenderTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/io/TableAppenderTest.java [UTF-8] Mon Mar 10 22:24:31 2014
@@ -61,7 +61,7 @@ public final strictfp class TableAppende
         // r.e.d. = Equatorial diameter Measured relative to the Earth.
         // Source: "Planet" on wikipedia on July 25, 2008.
         assertSame(out, out.append("English\tFrench\tr.e.d." + lineSeparator));
-        table.writeHorizontalSeparator();
+        table.appendHorizontalSeparator();
         assertSame(out, out.append("Mercury\tMercure\t0.382" + lineSeparator));
         assertSame(out, out.append("Venus\tVénus\t0.949"     + lineSeparator));
         assertSame(out, out.append("Earth\tTerre"));
@@ -135,7 +135,7 @@ public final strictfp class TableAppende
      */
     private static void testToString(final TableAppender table, final String expected) {
         table.nextLine('═');
-        table.append("English\tFrench\tr.e.d.\n").writeHorizontalSeparator();
+        table.append("English\tFrench\tr.e.d.\n").appendHorizontalSeparator();
         table.append("Mercury\tMercure\t0.382\n")
              .append("Venus\tVénus\t0.949\n")
              .append("Earth\tTerre\t1.00\n")



Mime
View raw message