sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1792304 [1/2] - in /sis/branches/JDK7: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/main/java/org/apache/sis/feature/builder/ core/sis-feature/src/test/java/org/apache/sis/feature/ core/sis-metadata/src/ma...
Date Sat, 22 Apr 2017 16:46:01 GMT
Author: desruisseaux
Date: Sat Apr 22 16:46:00 2017
New Revision: 1792304

URL: http://svn.apache.org/viewvc?rev=1792304&view=rev
Log:
Merge from the JDK8 branch.

Added:
    sis/branches/JDK7/storage/sis-xmlstore/src/main/resources/org/
      - copied from r1792299, sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/org/
    sis/branches/JDK7/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java
      - copied unchanged from r1792299, sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java
Modified:
    sis/branches/JDK7/   (props changed)
    sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
    sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
    sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java
    sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java
    sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
    sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    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/ide-project/NetBeans/build.xml
    sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
    sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
    sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
    sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
    sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java
    sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
    sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
    sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
    sis/branches/JDK7/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java
    sis/branches/JDK7/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/MetadataTest.java
    sis/branches/JDK7/storage/sis-xmlstore/src/test/java/org/apache/sis/test/suite/GPXTestSuite.java

Propchange: sis/branches/JDK7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Apr 22 16:46:00 2017
@@ -1,5 +1,5 @@
 /sis/branches/Android:1430670-1480699
 /sis/branches/JDK6:1394913-1508480
-/sis/branches/JDK8:1584960-1791988
+/sis/branches/JDK8:1584960-1792299
 /sis/branches/JDK9:1773327-1789983
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -18,6 +18,8 @@ package org.apache.sis.feature;
 
 import java.util.List;
 import java.util.ArrayList;
+import java.util.Set;
+import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.TimeZone;
@@ -49,6 +51,7 @@ import org.opengis.feature.Attribute;
 import org.opengis.feature.AttributeType;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
+import org.opengis.feature.FeatureAssociation;
 import org.opengis.feature.FeatureAssociationRole;
 import org.opengis.feature.Operation;
 import org.apache.sis.util.Characters;
@@ -88,7 +91,7 @@ public class FeatureFormat extends Tabul
     /**
      * For cross-version compatibility.
      */
-    private static final long serialVersionUID = 8866440357566645070L;
+    private static final long serialVersionUID = -5792086817264884947L;
 
     /**
      * An instance created when first needed and potentially shared.
@@ -101,6 +104,12 @@ public class FeatureFormat extends Tabul
     private final Locale displayLocale;
 
     /**
+     * The columns to include in the table formatted by this {@code FeatureFormat}.
+     * By default, all columns having at least one value are included.
+     */
+    private final EnumSet<Column> columns = EnumSet.allOf(Column.class);
+
+    /**
      * Maximal length of attribute values, in number of characters.
      * If a value is longer than this length, it will be truncated.
      *
@@ -159,6 +168,104 @@ public class FeatureFormat extends Tabul
     }
 
     /**
+     * Returns all columns that may be shown in the tables to format.
+     * The columns included in the set may be shown, but not necessarily;
+     * some columns will still be omitted if they are completely empty.
+     * However columns <em>not</em> included in the set are guaranteed to be omitted.
+     *
+     * @return all columns that may be shown in the tables to format.
+     *
+     * @since 0.8
+     */
+    public Set<Column> getAllowedColumns() {
+        return columns.clone();
+    }
+
+    /**
+     * Sets all columns that may be shown in the tables to format.
+     * Note that the columns specified to this method are not guaranteed to be shown;
+     * some columns will still be omitted if they are completely empty.
+     *
+     * @param inclusion  all columns that may be shown in the tables to format.
+     *
+     * @since 0.8
+     */
+    public void setAllowedColumns(final Set<Column> inclusion) {
+        ArgumentChecks.ensureNonNull("inclusion", inclusion);
+        columns.clear();
+        columns.addAll(inclusion);
+    }
+
+    /**
+     * Identifies the columns to include in the table formatted by {@code FeatureFormat}.
+     * By default, all columns having at least one non-null value are shown. But a smaller
+     * set of columns can be specified to the {@link FeatureFormat#setAllowedColumns(Set)}
+     * method for formatting narrower tables.
+     *
+     * @see FeatureFormat#setAllowedColumns(Set)
+     *
+     * @since 0.8
+     */
+    public enum Column {
+        /**
+         * Natural language designator for the property.
+         * This is the character sequence returned by {@link PropertyType#getDesignation()}.
+         * This column is omitted if no property has a designation.
+         */
+        DESIGNATION(Vocabulary.Keys.Designation),
+
+        /**
+         * Name of the property.
+         * This is the character sequence returned by {@link PropertyType#getName()}.
+         */
+        NAME(Vocabulary.Keys.Name),
+
+        /**
+         * Type of property values. This is the type returned by {@link AttributeType#getValueClass()} or
+         * {@link FeatureAssociationRole#getValueType()}.
+         */
+        TYPE(Vocabulary.Keys.Type),
+
+        /**
+         * The minimum and maximum occurrences of attribute values. This is made from the numbers returned
+         * by {@link AttributeType#getMinimumOccurs()} and {@link AttributeType#getMaximumOccurs()}.
+         */
+        CARDINALITY(Vocabulary.Keys.Cardinality),
+
+        /**
+         * Property value (for properties) or default value (for property types).
+         * This is the value returned by {@link Attribute#getValue()}, {@link FeatureAssociation#getValue()}
+         * or {@link AttributeType#getDefaultValue()}.
+         */
+        VALUE(Vocabulary.Keys.Value),
+
+        /**
+         * Other attributes that describes the attribute.
+         * This is made from the map returned by {@link Attribute#characteristics()}.
+         * This column is omitted if no property has characteristics.
+         */
+        CHARACTERISTICS(Vocabulary.Keys.Characteristics),
+
+        /**
+         * Whether a property is deprecated, or other remarks.
+         * This column is omitted if no property has remarks.
+         */
+        REMARKS(Vocabulary.Keys.Remarks);
+
+        /**
+         * The {@link Vocabulary} key to use for formatting the header of this column.
+         */
+        final short resourceKey;
+
+        /**
+         * Creates a new column enumeration constant.
+         */
+        private Column(final short key) {
+            resourceKey = key;
+        }
+    }
+
+    /**
      * Invoked when the formatter needs to move to the next column.
      */
     private void nextColumn(final TableAppender table) {
@@ -197,18 +304,30 @@ public class FeatureFormat extends Tabul
                     .getString(Errors.Keys.UnsupportedType_1, object.getClass()));
         }
         /*
-         * Check if at least one attribute has at least one characteritic. In many cases there is none.
-         * In none we will ommit the "characteristics" column, which is the last column.
+         * Computes the columns to show. We start with the set of columns specified by setAllowedColumns(Set),
+         * then we check if some of those columns are empty. For example in many cases there is no attribute
+         * with characteritic, in which case we will ommit the whole "characteristics" column. We perform such
+         * check only for optional information, not for mandatory information like property names.
          */
-        boolean hasCharacteristics = false;
-        boolean hasDeprecatedTypes = false;
-        for (final PropertyType propertyType : featureType.getProperties(true)) {
-            if (!hasCharacteristics && propertyType instanceof AttributeType<?>) {
-                hasCharacteristics = !((AttributeType<?>) propertyType).characteristics().isEmpty();
-            }
-            if (!hasDeprecatedTypes && propertyType instanceof Deprecable) {
-                hasDeprecatedTypes = ((Deprecable) propertyType).isDeprecated();
+        final EnumSet<Column> visibleColumns = columns.clone();
+        {
+            boolean hasDesignation     = false;
+            boolean hasCharacteristics = false;
+            boolean hasDeprecatedTypes = false;
+            for (final PropertyType propertyType : featureType.getProperties(true)) {
+                if (!hasDesignation) {
+                    hasDesignation = propertyType.getDesignation() != null;
+                }
+                if (!hasCharacteristics && propertyType instanceof AttributeType<?>) {
+                    hasCharacteristics = !((AttributeType<?>) propertyType).characteristics().isEmpty();
+                }
+                if (!hasDeprecatedTypes && propertyType instanceof Deprecable) {
+                    hasDeprecatedTypes = ((Deprecable) propertyType).isDeprecated();
+                }
             }
+            if (!hasDesignation)     visibleColumns.remove(Column.DESIGNATION);
+            if (!hasCharacteristics) visibleColumns.remove(Column.CHARACTERISTICS);
+            if (!hasDeprecatedTypes) visibleColumns.remove(Column.REMARKS);
         }
         /*
          * Format the feature type name. In the case of feature type, format also the names of super-type
@@ -218,37 +337,37 @@ public class FeatureFormat extends Tabul
          */
         toAppendTo.append(toString(featureType.getName()));
         if (feature == null) {
-            String separator = " ⇾ ";   // UML symbol for inheritance.
+            String separator = " ⇾ ";                                       // UML symbol for inheritance.
             for (final FeatureType parent : featureType.getSuperTypes()) {
                 toAppendTo.append(separator).append(toString(parent.getName()));
                 separator = ", ";
             }
         }
         toAppendTo.append(getLineSeparator());
+        /*
+         * Create a table and format the header. Columns will be shown in Column enumeration order.
+         */
         final Vocabulary resources = Vocabulary.getResources(displayLocale);
         final TableAppender table = new TableAppender(toAppendTo, columnSeparator);
         table.setMultiLinesCells(true);
         table.nextLine('─');
-header: for (int i=0; ; i++) {
-            final short key;
-            switch (i) {
-                case 0:                     key = Vocabulary.Keys.Name; break;
-                case 1:  nextColumn(table); key = Vocabulary.Keys.Type; break;
-                case 2:  nextColumn(table); key = Vocabulary.Keys.Cardinality; break;
-                case 3:  nextColumn(table); key = (feature != null) ? Vocabulary.Keys.Value : Vocabulary.Keys.DefaultValue; break;
-                case 4:  if (!hasCharacteristics) continue;
-                         nextColumn(table); key = Vocabulary.Keys.Characteristics; break;
-                case 5:  if (!hasDeprecatedTypes) continue;
-                         nextColumn(table); key = Vocabulary.Keys.Remarks; break;
-                default: break header;
+        boolean isFirstColumn = true;
+        for (final Column column : visibleColumns) {
+            short key = column.resourceKey;
+            if (key == Vocabulary.Keys.Value && feature == null) {
+                key = Vocabulary.Keys.DefaultValue;
             }
+            if (!isFirstColumn) nextColumn(table);
             table.append(resources.getString(key));
+            isFirstColumn = false;
         }
         table.nextLine();
         table.nextLine('─');
         /*
-         * Done writing the header. Now write all property rows.
-         * Rows without value will be skipped only if optional.
+         * Done writing the header. Now write all property rows.  For each row, the first part in the loop
+         * extracts all information needed without formatting anything yet. If we detect in that part that
+         * a row has no value, it will be skipped if and only if that row is optional (minimum occurrence
+         * of zero).
          */
         final StringBuffer  buffer  = new StringBuffer();
         final FieldPosition dummyFP = new FieldPosition(-1);
@@ -291,14 +410,6 @@ header: for (int i=0; ; i++) {
                 value = CharSequences.trimWhitespaces(buffer).toString();
                 buffer.setLength(0);
             }
-            /*
-             * Column 0 - Name.
-             */
-            table.append(toString(propertyType.getName()));
-            nextColumn(table);
-            /*
-             * Column 1 and 2 - Type and cardinality.
-             */
             final String   valueType;                       // The value to write in the type column.
             final Class<?> valueClass;                      // AttributeType.getValueClass() if applicable.
             final int minimumOccurs, maximumOccurs;         // Negative values mean no cardinality.
@@ -327,82 +438,98 @@ header: for (int i=0; ; i++) {
                 minimumOccurs = -1;
                 maximumOccurs = -1;
             }
-            table.append(valueType);
-            nextColumn(table);
-            if (maximumOccurs >= 0) {
-                final Format format = getFormat(Integer.class);
-                table.append('[').append(format.format(minimumOccurs, buffer, dummyFP)).append(" … ");
-                buffer.setLength(0);
-                if (maximumOccurs != Integer.MAX_VALUE) {
-                    table.append(format.format(maximumOccurs, buffer, dummyFP));
-                } else {
-                    table.append('∞');
-                }
-                buffer.setLength(0);
-                table.append(']');
-            }
-            nextColumn(table);
             /*
-             * Column 3 - Value or default value.
+             * At this point we determined that the row should not be skipped
+             * and we got all information to format.
              */
-            if (value != null) {
-                final Format format = getFormat(valueClass);                            // Null if valueClass is null.
-                final Iterator<?> it = CollectionsExt.toCollection(value).iterator();
-                String separator = "";
-                int length = 0;
-                while (it.hasNext()) {
-                    value = it.next();
-                    if (value != null) {
-                        if (format != null && valueClass.isInstance(value)) {
-                            value = format.format(value, buffer, dummyFP);
-                        } else if (value instanceof Feature && propertyType instanceof FeatureAssociationRole) {
-                            final String p = DefaultAssociationRole.getTitleProperty((FeatureAssociationRole) propertyType);
-                            if (p != null) {
-                                value = ((Feature) value).getPropertyValue(p);
-                                if (value == null) continue;
+            isFirstColumn = true;
+            for (final Column column : visibleColumns) {
+                if (!isFirstColumn) nextColumn(table);
+                isFirstColumn = false;
+                switch (column) {
+                    case DESIGNATION: {
+                        final InternationalString d = propertyType.getDesignation();
+                        if (d != null) table.append(d.toString(displayLocale));
+                        break;
+                    }
+                    case NAME: {
+                        table.append(toString(propertyType.getName()));
+                        break;
+                    }
+                    case TYPE: {
+                        table.append(valueType);
+                        break;
+                    }
+                    case CARDINALITY: {
+                        if (maximumOccurs >= 0) {
+                            final Format format = getFormat(Integer.class);
+                            table.append('[').append(format.format(minimumOccurs, buffer, dummyFP)).append(" … ");
+                            buffer.setLength(0);
+                            if (maximumOccurs != Integer.MAX_VALUE) {
+                                table.append(format.format(maximumOccurs, buffer, dummyFP));
+                            } else {
+                                table.append('∞');
                             }
+                            buffer.setLength(0);
+                            table.append(']');
                         }
-                        length = formatValue(value, table.append(separator), length);
-                        buffer.setLength(0);
-                        separator = ", ";
-                        if (length < 0) break;      // Value is too long, abandon remaining iterations.
+                        break;
                     }
-                }
-            }
-            /*
-             * Column 4 - Characteristics.
-             */
-            if (hasCharacteristics) {
-                nextColumn(table);
-                if (propertyType instanceof AttributeType<?>) {
-                    String separator = "";
-                    for (final AttributeType<?> attribute : ((AttributeType<?>) propertyType).characteristics().values()) {
-                        table.append(separator).append(toString(attribute.getName()));
-                        Object c = attribute.getDefaultValue();
-                        if (feature != null) {
-                            final Property p = feature.getProperty(propertyType.getName().toString());
-                            if (p instanceof Attribute<?>) {            // Should always be true, but we are paranoiac.
-                                c = ((Attribute<?>) p).characteristics().get(attribute.getName().toString());
+                    case VALUE: {
+                        final Format format = getFormat(valueClass);                        // Null if valueClass is null.
+                        final Iterator<?> it = CollectionsExt.toCollection(value).iterator();
+                        String separator = "";
+                        int length = 0;
+                        while (it.hasNext()) {
+                            value = it.next();
+                            if (value != null) {
+                                if (format != null && valueClass.isInstance(value)) {       // Null safe of getFormat(valueClass) contract.
+                                    value = format.format(value, buffer, dummyFP);
+                                } else if (value instanceof Feature && propertyType instanceof FeatureAssociationRole) {
+                                    final String p = DefaultAssociationRole.getTitleProperty((FeatureAssociationRole) propertyType);
+                                    if (p != null) {
+                                        value = ((Feature) value).getPropertyValue(p);
+                                        if (value == null) continue;
+                                    }
+                                }
+                                length = formatValue(value, table.append(separator), length);
+                                buffer.setLength(0);
+                                separator = ", ";
+                                if (length < 0) break;      // Value is too long, abandon remaining iterations.
                             }
                         }
-                        if (c != null) {
-                            formatValue(c, table.append(" = "), 0);
+                        break;
+                    }
+                    case CHARACTERISTICS: {
+                        if (propertyType instanceof AttributeType<?>) {
+                            String separator = "";
+                            for (final AttributeType<?> attribute : ((AttributeType<?>) propertyType).characteristics().values()) {
+                                table.append(separator).append(toString(attribute.getName()));
+                                Object c = attribute.getDefaultValue();
+                                if (feature != null) {
+                                    final Property p = feature.getProperty(propertyType.getName().toString());
+                                    if (p instanceof Attribute<?>) {            // Should always be true, but we are paranoiac.
+                                        c = ((Attribute<?>) p).characteristics().get(attribute.getName().toString());
+                                    }
+                                }
+                                if (c != null) {
+                                    formatValue(c, table.append(" = "), 0);
+                                }
+                                separator = ", ";
+                            }
                         }
-                        separator = ", ";
+                        break;
                     }
-                }
-            }
-            /*
-             * Column 5 - Deprecation
-             */
-            if (hasDeprecatedTypes) {
-                nextColumn(table);
-                if (org.apache.sis.feature.Field.isDeprecated(propertyType)) {
-                    table.append(resources.getString(Vocabulary.Keys.Deprecated));
-                    final InternationalString r = ((Deprecable) propertyType).getRemarks();
-                    if (r != null) {
-                        remarks.add(r.toString(displayLocale));
-                        appendSuperscript(remarks.size(), table);
+                    case REMARKS: {
+                        if (org.apache.sis.feature.Field.isDeprecated(propertyType)) {
+                            table.append(resources.getString(Vocabulary.Keys.Deprecated));
+                            final InternationalString r = ((Deprecable) propertyType).getRemarks();
+                            if (r != null) {
+                                remarks.add(r.toString(displayLocale));
+                                appendSuperscript(remarks.size(), table);
+                            }
+                        }
+                        break;
                     }
                 }
             }

Modified: sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -54,8 +54,49 @@ import org.opengis.feature.Operation;
  * This builder can create the arguments to be given to the
  * {@linkplain DefaultFeatureType#DefaultFeatureType feature type constructor}
  * from simpler parameters given to this builder.
+ * The main methods provided in this class are:
  *
- * <p>{@code FeatureTypeBuilder} should be short lived.
+ * <ul>
+ *   <li>Various {@link #setName(CharSequence) setName(...)} methods for specifying the feature type name (mandatory).</li>
+ *   <li>Methods for optionally setting {@linkplain #setDesignation designation}, {@linkplain #setDefinition definition} or
+ *       {@linkplain #setDescription description} texts, or the {@linkplain #setDeprecated deprecation status}.</li>
+ *   <li>Methods for optionally specifying the feature type hierarchy: its {@linkplain #setSuperTypes super types}
+ *       and whether the feature type is {@linkplain #setAbstract abstract}.</li>
+ *   <li>Convenience methods for setting the {@linkplain #setNameSpace name space} and the
+ *       {@linkplain #setDefaultCardinality default cardinality} of properties to be added to the feature type.</li>
+ *   <li>Methods for {@linkplain #addAttribute(Class) adding an attribute}, {@linkplain #addAssociation(FeatureType)
+ *       an association} or {@linkplain #addProperty an operation}.</li>
+ *   <li>Method for listing the previously added {@linkplain #properties() properties}.</li>
+ *   <li>A {@link #build()} method for creating the {@code FeatureType} instance from all previous information.</li>
+ * </ul>
+ *
+ * The following example creates a city named "Utopia" by default:
+ *
+ * {@preformat java
+ *     FeatureTypeBuilder builder;
+ *
+ *     // Create a feature type for a city, which contains a name and a population.
+ *     builder = new FeatureTypeBuilder() .setName("City");
+ *     builder.addAttribute(String.class) .setName("name").setDefaultValue("Utopia");
+ *     builder.addAttribute(Integer.class).setName("population");
+ *     FeatureType city = builder.build();
+ * }
+ *
+ * A call to {@code System.out.println(city)} prints the following table:
+ *
+ * {@preformat text
+ *   City
+ *   ┌────────────┬─────────┬─────────────┬───────────────┐
+ *   │ Name       │ Type    │ Cardinality │ Default value │
+ *   ├────────────┼─────────┼─────────────┼───────────────┤
+ *   │ name       │ String  │ [1 … 1]     │ Utopia        │
+ *   │ population │ Integer │ [1 … 1]     │               │
+ *   └────────────┴─────────┴─────────────┴───────────────┘
+ * }
+ *
+ *
+ *
+ * <p>{@code FeatureTypeBuilder} instances should be short lived.
  * After the {@code FeatureType} has been created, the builder should be discarded.</p>
  *
  * @author  Johann Sorel (Geomatys)
@@ -334,12 +375,21 @@ public class FeatureTypeBuilder extends
      * Sets the namespace of the next names to be created by {@code setName(CharSequence...)} method calls.
      * This method applies only to the next calls to {@link #setName(CharSequence)} or
      * {@link #setName(CharSequence...)} methods; the result of all previous calls stay unmodified.
+     * Example:
+     *
+     * {@preformat java
+     *     FeatureTypeBuilder builder = new FeatureTypeBuilder().setNameSpace("MyNameSpace").setName("City");
+     *     FeatureType city = builder.build();
+     *
+     *     System.out.println(city.getName());                              // Prints "City"
+     *     System.out.println(city.getName().toFullyQualifiedName());       // Prints "MyNameSpace:City"
+     * }
      *
-     * <p>There is different conventions about the use of name spaces. ISO 19109 suggests that the namespace of all
+     * There is different conventions about the use of name spaces. ISO 19109 suggests that the namespace of all
      * {@code AttributeType} names is the name of the enclosing {@code FeatureType}, but this is not mandatory.
      * Users who want to apply this convention can invoke {@code setNameSpace(featureName)} after
      * <code>{@linkplain #setName(CharSequence) FeatureTypeBuilder.setName}(featureName)</code> but before
-     * <code>{@linkplain AttributeTypeBuilder#setName(CharSequence) AttributeTypeBuilder.setName}(attributeName)</code>.</p>
+     * <code>{@linkplain AttributeTypeBuilder#setName(CharSequence) AttributeTypeBuilder.setName}(attributeName)</code>.
      *
      * @param  ns  the new namespace, or {@code null} if none.
      * @return {@code this} for allowing method calls chaining.

Modified: sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -50,6 +50,10 @@ import org.opengis.feature.PropertyNotFo
  *   <li>the description — information beyond that required for concise definition of the element.</li>
  * </ul>
  *
+ * The name is mandatory and can be specified as either {@link org.opengis.util.LocalName},
+ * {@link org.opengis.util.ScopedName}, {@link String} or {@link InternationalString} instance.
+ * All other properties are optional.
+ *
  * <div class="section">Default namespace</div>
  * In many cases, the names of all {@code AttributeType}s and {@code AssociationRole}s to create
  * within a {@code FeatureType} share the same namespace.
@@ -59,6 +63,15 @@ import org.opengis.feature.PropertyNotFo
  * Note that namespaces will not be visible in the name {@linkplain org.apache.sis.util.iso.DefaultLocalName#toString()
  * string representation} unless the {@linkplain org.apache.sis.util.iso.DefaultLocalName#toFullyQualifiedName() fully
  * qualified name} is requested.
+ * Example:
+ *
+ * {@preformat java
+ *     FeatureTypeBuilder builder = new FeatureTypeBuilder().setNameSpace("MyNameSpace").setName("City");
+ *     FeatureType city = builder.build();
+ *
+ *     System.out.println(city.getName());                              // Prints "City"
+ *     System.out.println(city.getName().toFullyQualifiedName());       // Prints "MyNameSpace:City"
+ * }
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)

Modified: sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -25,9 +25,11 @@
  * named "Utopia" by default:</p>
  *
  * {@preformat java
+ *     FeatureTypeBuilder builder;
+ *
  *     // Create a feature type for a city, which contains a name and a population.
- *     FeatureTypeBuilder builder = new FeatureTypeBuilder().setName("City");
- *     builder.addAttribute(String.class).setName("name").setDefaultValue("Utopia");
+ *     builder = new FeatureTypeBuilder() .setName("City");
+ *     builder.addAttribute(String.class) .setName("name").setDefaultValue("Utopia");
  *     builder.addAttribute(Integer.class).setName("population");
  *     FeatureType city = builder.build();
  *

Modified: sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -18,6 +18,7 @@ package org.apache.sis.feature;
 
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.Locale;
 import java.util.Map;
 import java.util.HashMap;
@@ -47,12 +48,23 @@ import org.opengis.feature.PropertyType;
 })
 public final strictfp class FeatureFormatTest extends TestCase {
     /**
+     * Creates the formatter instance to be used for the tests.
+     */
+    private static FeatureFormat create() {
+        final FeatureFormat format = new FeatureFormat(Locale.US, null);
+        format.setAllowedColumns(EnumSet.of(FeatureFormat.Column.NAME,            FeatureFormat.Column.TYPE,
+                                            FeatureFormat.Column.CARDINALITY,     FeatureFormat.Column.VALUE,
+                                            FeatureFormat.Column.CHARACTERISTICS, FeatureFormat.Column.REMARKS));
+        return format;
+    }
+
+    /**
      * Tests the formatting of a {@link DefaultFeatureType}.
      */
     @Test
     public void testFeatureType() {
         final DefaultFeatureType feature = DefaultFeatureTypeTest.worldMetropolis();
-        final FeatureFormat format = new FeatureFormat(Locale.US, null);
+        final FeatureFormat format = create();
         final String text = format.format(feature);
         assertMultilinesEquals("World metropolis ⇾ Metropolis, University city\n" +
                 "┌──────────────┬─────────────────────┬─────────────┬───────────────┬────────────────────────────┐\n" +
@@ -80,7 +92,7 @@ public final strictfp class FeatureForma
                 FeatureOperations.compound(name("anotherId"), ":", "<", ">", city, feature.getProperty("population")),
                 AbstractOperationTest.foundCity());
 
-        final FeatureFormat format = new FeatureFormat(Locale.US, null);
+        final FeatureFormat format = create();
         final String text = format.format(feature);
         assertMultilinesEquals("Identified city ⇾ City\n" +
                 "┌────────────┬─────────┬─────────────┬─────────────────────┐\n" +
@@ -114,7 +126,7 @@ public final strictfp class FeatureForma
         feature = new DefaultFeatureType(name("City for human"), false, new DefaultFeatureType[] {feature},
                 new DefaultAttributeType<>(properties, String.class, 0, 2, null));
 
-        final FeatureFormat format = new FeatureFormat(Locale.US, null);
+        final FeatureFormat format = create();
         final String text = format.format(feature);
         assertMultilinesEquals("City for human ⇾ City\n" +
                 "┌────────────┬─────────┬─────────────┬───────────────┬─────────────┐\n" +
@@ -141,7 +153,7 @@ public final strictfp class FeatureForma
         feature.setPropertyValue("population", 13185502);                               // In 2011.
         feature.setPropertyValue("universities", Arrays.asList("Waseda", "Keio"));
 
-        final FeatureFormat format = new FeatureFormat(Locale.US, null);
+        final FeatureFormat format = create();
         final String text = format.format(feature);
         assertMultilinesEquals("World metropolis\n" +
                 "┌──────────────┬─────────────────────┬─────────────┬──────────────┬─────────────────┐\n" +
@@ -174,7 +186,7 @@ public final strictfp class FeatureForma
         feature.setPropertyValue("population", 143174);                     // December 31th, 2011
         feature.setPropertyValue("twin town", twinTown);
 
-        final FeatureFormat format = new FeatureFormat(Locale.US, null);
+        final FeatureFormat format = create();
         final String text = format.format(feature);
         assertMultilinesEquals("Twin town\n" +
                 "┌────────────┬─────────┬─────────────┬───────────┐\n" +

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -41,7 +41,7 @@ import static org.apache.sis.util.Charac
  * Current version does not yet work with URN or HTTP syntax.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.4
  * @module
  */
@@ -207,6 +207,32 @@ public final class NameToIdentifier impl
     }
 
     /**
+     * Returns {@code true} if the given identifier to search matches one of the object identifiers.
+     *
+     * @param  identifiers  the identifiers to compare against {@code toSearch}.
+     * @param  toSearch     the identifier to check for equality.
+     * @return {@code true} if the identifier to search is found in the given set of identifiers.
+     *
+     * @since 0.8
+     */
+    public static boolean isHeuristicMatchForIdentifier(final Iterable<? extends Identifier> identifiers, final String toSearch) {
+        if (toSearch != null && identifiers != null) {
+            for (int s = toSearch.indexOf(DefaultNameSpace.DEFAULT_SEPARATOR); s >= 0;
+                     s = toSearch.indexOf(DefaultNameSpace.DEFAULT_SEPARATOR, s))
+            {
+                final String codespace = toSearch.substring(0, s).trim();
+                final String code = toSearch.substring(++s).trim();
+                for (final Identifier id : identifiers) {
+                    if (codespace.equalsIgnoreCase(id.getCodeSpace()) && code.equalsIgnoreCase(id.getCode())) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * Returns {@code true} if the given {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName()
      * primary name} or one of the given aliases matches the given name. The comparison ignores case, some Latin
      * diacritical signs and any characters that are not letters or digits.
@@ -222,28 +248,30 @@ public final class NameToIdentifier impl
     public static boolean isHeuristicMatchForName(final Identifier name, final Collection<GenericName> aliases,
             CharSequence toSearch, final Simplifier simplifier)
     {
-        toSearch = simplifier.apply(toSearch);
-        if (name != null) {                                                                 // Paranoiac check.
-            final CharSequence code = simplifier.apply(name.getCode());
-            if (code != null) {                                                             // Paranoiac check.
-                if (CharSequences.equalsFiltered(toSearch, code, LETTERS_AND_DIGITS, true)) {
-                    return true;
-                }
+        if (toSearch != null) {
+            CharSequence code = (name != null) ? name.getCode() : null;
+            if (toSearch.equals(code)) {
+                return true;                                                    // Optimization for a common case.
             }
-        }
-        if (aliases != null) {
-            for (final GenericName alias : aliases) {
-                if (alias != null) {                                                        // Paranoiac check.
-                    final CharSequence tip = simplifier.apply(alias.tip().toString());
-                    if (CharSequences.equalsFiltered(toSearch, tip, LETTERS_AND_DIGITS, true)) {
-                        return true;
+            toSearch = simplifier.apply(toSearch);
+            code     = simplifier.apply(code);
+            if (CharSequences.equalsFiltered(toSearch, code, LETTERS_AND_DIGITS, true)) {
+                return true;
+            }
+            if (aliases != null) {
+                for (final GenericName alias : aliases) {
+                    if (alias != null) {                                                        // Paranoiac check.
+                        final CharSequence tip = simplifier.apply(alias.tip().toString());
+                        if (CharSequences.equalsFiltered(toSearch, tip, LETTERS_AND_DIGITS, true)) {
+                            return true;
+                        }
+                        /*
+                         * Note: a previous version compared also the scoped names. We removed that part,
+                         * because experience has shown that this method is used only for the "code" part
+                         * of an object name. If we really want to compare scoped name, it would probably
+                         * be better to take a GenericName argument instead than String.
+                         */
                     }
-                    /*
-                     * Note: a previous version compared also the scoped names. We removed that part,
-                     * because experience has shown that this method is used only for the "code" part
-                     * of an object name. If we really want to compare scoped name, it would probably
-                     * be better to take a GenericName argument instead than String.
-                     */
                 }
             }
         }

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -25,7 +25,6 @@ import javax.measure.Unit;
 import javax.measure.quantity.Length;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
-import org.opengis.metadata.Identifier;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.crs.CRSFactory;
@@ -59,7 +58,6 @@ import org.apache.sis.internal.system.Op
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.util.ArraysExt;
-import org.apache.sis.util.iso.DefaultNameSpace;
 import org.apache.sis.util.Deprecable;
 
 
@@ -131,14 +129,6 @@ public class ReferencingServices extends
     public static final String CS_FACTORY = "csFactory";
 
     /**
-     * The separator character between an identifier and its namespace in the argument given to
-     * {@link #getOperationMethod(Iterable, String)}. For example this is the separator in {@code "EPSG:9807"}.
-     *
-     * This is defined as a constant for now, but we may make it configurable in a future version.
-     */
-    private static final char IDENTIFIER_SEPARATOR = DefaultNameSpace.DEFAULT_SEPARATOR;
-
-    /**
      * The services, fetched when first needed.
      */
     private static volatile ReferencingServices instance;
@@ -645,33 +635,6 @@ public class ReferencingServices extends
     }
 
     /**
-     * Returns {@code true} if the name or an identifier of the given method matches the given {@code identifier}.
-     *
-     * @param  method      the method to test for a match.
-     * @param  identifier  the name or identifier of the operation method to search.
-     * @return {@code true} if the given method is a match for the given identifier.
-     *
-     * @since 0.6
-     */
-    private boolean matches(final OperationMethod method, final String identifier) {
-        if (isHeuristicMatchForName(method, identifier)) {
-            return true;
-        }
-        for (int s = identifier.indexOf(IDENTIFIER_SEPARATOR); s >= 0;
-                 s = identifier.indexOf(IDENTIFIER_SEPARATOR, s))
-        {
-            final String codespace = identifier.substring(0, s).trim();
-            final String code = identifier.substring(++s).trim();
-            for (final Identifier id : method.getIdentifiers()) {
-                if (codespace.equalsIgnoreCase(id.getCodeSpace()) && code.equalsIgnoreCase(id.getCode())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
      * Returns the operation method for the specified name or identifier. The given argument shall be either a
      * method name (e.g. <cite>"Transverse Mercator"</cite>) or one of its identifiers (e.g. {@code "EPSG:9807"}).
      *
@@ -687,7 +650,9 @@ public class ReferencingServices extends
     public final OperationMethod getOperationMethod(final Iterable<? extends OperationMethod> methods, final String identifier) {
         OperationMethod fallback = null;
         for (final OperationMethod method : methods) {
-            if (matches(method, identifier)) {
+            if (isHeuristicMatchForName(method, identifier) ||
+                    NameToIdentifier.isHeuristicMatchForIdentifier(method.getIdentifiers(), identifier))
+            {
                 /*
                  * Stop the iteration at the first non-deprecated method.
                  * If we find only deprecated methods, take the first one.

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -518,6 +518,9 @@ public class DefaultMetadata extends ISO
 
     /**
      * Returns the character coding standard used for the metadata set.
+     * ISO 19115:2014 represents character sets by references to the
+     * <a href="http://www.iana.org/assignments/character-sets">IANA Character Set register</a>,
+     * which is represented in Java by {@link java.nio.charset.Charset}.
      * Instances can be obtained by a call to {@link Charset#forName(String)}.
      *
      * <div class="note"><b>Examples:</b>

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -348,7 +348,7 @@ public final class Citations extends Sta
      *
      * @since 0.4
      */
-    public static final IdentifierSpace<Integer> GEOTIFF = new CitationConstant.Authority<>("GeoTIFF");
+    public static final IdentifierSpace<Integer> GEOTIFF = new CitationConstant.Authority<>(Constants.GEOTIFF);
 
     /**
      * The authority for identifiers of objects defined by the <a href="http://trac.osgeo.org/proj/">Proj.4</a> project.

Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -55,7 +55,7 @@ public final strictfp class CitationsTes
         assertSame(IOGP,             fromName("OGP"));
         assertSame(ESRI,             fromName("ESRI"));          // Handled in a way very similar to "OGC".
         assertSame(NETCDF,           fromName("NetCDF"));
-        assertSame(GEOTIFF,          fromName("GeoTIFF"));
+        assertSame(GEOTIFF,          fromName(Constants.GEOTIFF));
         assertSame(PROJ4,            fromName("Proj.4"));
         assertSame(PROJ4,            fromName("Proj4"));
         assertSame(MAP_INFO,         fromName("MapInfo"));

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -24,7 +24,10 @@ import javax.measure.quantity.Angle;
 import org.opengis.annotation.UML;
 import org.opengis.annotation.Specification;
 import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
 import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.GeneralParameterDescriptor;
 import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
 import org.opengis.referencing.IdentifiedObject;
@@ -36,6 +39,7 @@ import org.apache.sis.internal.system.De
 import org.apache.sis.util.Static;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.datum.DefaultPrimeMeridian;
@@ -396,4 +400,36 @@ public final class ReferencingUtilities
                 factory.createDefiningConversion(properties,
                         factory.getOperationMethod(parameters.getDescriptor().getName().getCode()), parameters), cs);
     }
+
+    /**
+     * Returns the mapping between parameter identifiers and parameter names as defined by the given authority.
+     * This method assumes that the identifiers of all parameters defined by that authority are numeric.
+     * Examples of authorities defining numeric parameters are EPSG and GeoTIFF.
+     *
+     * <p>The map returned by this method is modifiable. Callers are free to add or remove entries.</p>
+     *
+     * @param  parameters  the parameters for which to get a mapping from identifiers to names.
+     * @param  authority   the authority defining the parameters.
+     * @return mapping from parameter identifiers to parameter names defined by the given authority.
+     * @throws NumberFormatException if a parameter identifier of the given authority is not numeric.
+     * @throws IllegalArgumentException if the same identifier is used for two or more parameters.
+     *
+     * @since 0.8
+     */
+    public static Map<Integer,String> identifierToName(final ParameterDescriptorGroup parameters, final Citation authority) {
+        final Map<Integer,String> mapping = new HashMap<>();
+        for (final GeneralParameterDescriptor descriptor : parameters.descriptors()) {
+            final Identifier id = IdentifiedObjects.getIdentifier(descriptor, authority);
+            if (id != null) {
+                String name = IdentifiedObjects.getName(descriptor, authority);
+                if (name == null) {
+                    name = IdentifiedObjects.getName(descriptor, null);
+                }
+                if (mapping.put(Integer.valueOf(id.getCode()), name) != null) {
+                    throw new IllegalArgumentException(Errors.format(Errors.Keys.DuplicatedIdentifier_1, id));
+                }
+            }
+        }
+        return mapping;
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -23,7 +23,7 @@ import org.apache.sis.util.iso.AbstractI
 
 
 /**
- * Comments telling whether a parameter value use the same sign or the opposite sign for the inverse operation.
+ * Comments telling whether a parameter value uses the same sign or the opposite sign for the inverse operation.
  * Those comments are used for encoding the {@code PARAM_SIGN_REVERSAL} boolean value in the
  * {@code [Coordinate_Operation Parameter Usage]} table of the EPSG dataset.
  *

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -22,6 +22,7 @@ import java.util.LinkedList;
 import java.util.Map;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
+import java.util.Objects;
 import java.io.Serializable;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
@@ -43,9 +44,6 @@ import org.apache.sis.util.resources.Err
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * A group of related parameter values. Parameter groups have some similarities with {@code java.util.Map}:
@@ -103,7 +101,7 @@ import java.util.Objects;
  * <p>Calls to {@code values().clear()} restore this {@code DefaultParameterValueGroup} to its initial state.</p>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 0.8
  *
  * @see DefaultParameterDescriptorGroup
  * @see DefaultParameterValue
@@ -283,48 +281,41 @@ public class DefaultParameterValueGroup
      */
     @Override
     ParameterValue<?> parameterIfExist(final String name) throws ParameterNotFoundException {
-        final ParameterValueList values = this.values; // Protect against accidental changes.
+        final ParameterValueList values = this.values;          // Protect against accidental changes.
         /*
-         * Quick search for an exact match. By invoking 'descriptor(i)' instead of 'get(i)',
-         * we avoid the creation of mandatory ParameterValue which was deferred. If we find
-         * a matching name, the ParameterValue will be lazily created (if not already done)
-         * by the call to 'get(i)'.
+         * Search for an exact match. By invoking 'descriptor(i)' instead of 'get(i)', we avoid the
+         * creation of mandatory ParameterValue which was deferred. If we find a matching name, the
+         * ParameterValue will be lazily created (if not already done) by the call to 'get(i)'.
          */
-        final int size = values.size();
-        for (int i=0; i<size; i++) {
-            final GeneralParameterDescriptor descriptor = values.descriptor(i);
-            if (descriptor instanceof ParameterDescriptor<?>) {
-                if (name.equals(descriptor.getName().toString())) {
-                    return (ParameterValue<?>) values.get(i);
-                }
-            }
-        }
-        /*
-         * More costly search, including aliases, before to give up.
-         */
-        int fallback  = -1;
+        int index     = -1;
         int ambiguity = -1;
+        final int size = values.size();
         for (int i=0; i<size; i++) {
             final GeneralParameterDescriptor descriptor = values.descriptor(i);
             if (descriptor instanceof ParameterDescriptor<?>) {
                 if (IdentifiedObjects.isHeuristicMatchForName(descriptor, name)) {
-                    if (fallback < 0) {
-                        fallback = i;
+                    if (index < 0) {
+                        index = i;
                     } else {
                         ambiguity = i;
                     }
                 }
             }
         }
-        if (fallback >= 0) {
-            if (ambiguity < 0) {
-                return (ParameterValue<?>) values.get(fallback);   // May lazily create a ParameterValue.
-            }
-            throw new ParameterNotFoundException(Errors.format(Errors.Keys.AmbiguousName_3,
-                    IdentifiedObjects.toString(values.descriptor(fallback) .getName()),
-                    IdentifiedObjects.toString(values.descriptor(ambiguity).getName()), name), name);
+        if (ambiguity < 0) {
+            return (index >= 0) ? (ParameterValue<?>) values.get(index) : null;     // May lazily create a ParameterValue.
+        }
+        final GeneralParameterDescriptor d1 = values.descriptor(index);
+        final GeneralParameterDescriptor d2 = values.descriptor(ambiguity);
+        final String message;
+        if (d1 == d2) {
+            message = Errors.format(Errors.Keys.MultiOccurenceValueAtIndices_3, name, index, ambiguity);
+        } else {
+            message = Errors.format(Errors.Keys.AmbiguousName_3,
+                        IdentifiedObjects.toString(d1.getName()),
+                        IdentifiedObjects.toString(d2.getName()), name);
         }
-        return null;
+        throw new ParameterNotFoundException(message, name);
     }
 
     /**

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=1792304&r1=1792303&r2=1792304&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] Sat Apr 22 16:46:00 2017
@@ -37,8 +37,6 @@ import org.apache.sis.util.ObjectConvert
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.Debug;
 
-import static org.apache.sis.referencing.IdentifiedObjects.isHeuristicMatchForName;
-
 // Branch-dependent imports
 import org.apache.sis.internal.jdk8.JDK8;
 
@@ -48,7 +46,7 @@ import org.apache.sis.internal.jdk8.JDK8
  * See {@link DefaultParameterValueGroup} javadoc for a description of the standard way to get and set a particular
  * parameter in a group. The remaining of this javadoc is specific to Apache SIS.
  *
- * <div class="section">Convenience static methods</div>
+ * <div class="section">Convenience methods</div>
  * This class provides the following convenience static methods:
  * <ul>
  *   <li>{@link #cast(ParameterValue, Class) cast(…, Class)} for type safety with parameterized types.</li>
@@ -57,32 +55,8 @@ import org.apache.sis.internal.jdk8.JDK8
  *   <li>{@link #copy(ParameterValueGroup, ParameterValueGroup)} for copying values into an existing instance.</li>
  * </ul>
  *
- *
- * <div class="section">Fetching parameter values despite different names, types or units</div>
- * The common way to get a parameter is to invoke the {@link #parameter(String)} method.
- * This {@code Parameters} class provides an alternative way, using a {@link ParameterDescriptor} argument
- * instead than a {@code String}. The methods in this class use the additional information provided by the
- * descriptor for choosing a {@code String} argument that the above-cited {@code parameter(String)} method
- * is more likely to know (by giving preference to a {@linkplain DefaultParameterDescriptor#getName() name}
- * or {@linkplain DefaultParameterDescriptor#getAlias() alias} defined by a common
- * {@linkplain org.apache.sis.metadata.iso.ImmutableIdentifier#getAuthority() authority}),
- * and for applying type and unit conversions.
- *
- * <div class="note"><b>Example:</b>
- * The same parameter may be known under different names. For example the
- * {@linkplain org.apache.sis.referencing.datum.DefaultEllipsoid#getSemiMajorAxis()
- * length of the semi-major axis of the ellipsoid} is commonly known as {@code "semi_major"}.
- * But that parameter can also be named {@code "semi_major_axis"}, {@code "earth_radius"} or simply {@code "a"}
- * in other libraries. When fetching parameter values, we do not always know in advance which of the above-cited
- * names is recognized by an arbitrary {@code ParameterValueGroup} implementation.
- *
- * <p>This uncertainty is mitigated with the Apache SIS implementation since
- * {@link DefaultParameterValueGroup#parameter(String)} compares the given {@code String} argument
- * against all parameter's {@linkplain DefaultParameterDescriptor#getAlias() aliases} in addition
- * to the {@linkplain DefaultParameterDescriptor#getName() name}.
- * However we do not have the guarantee that all implementations do that.</p></div>
- *
- * The method names in this class follow the names of methods provided by the {@link ParameterValue} interface.
+ * Most instance methods in this class follow the same naming pattern
+ * than the methods provided by the {@link ParameterValue} interface.
  * Those methods are themselves inspired by JDK methods:
  *
  * <table class="sis">
@@ -98,21 +72,38 @@ import org.apache.sis.internal.jdk8.JDK8
  * </table>
  *
  *
+ * <div class="section">Fetching parameter values despite different names, types or units</div>
+ * The common way to get a parameter is to invoke the {@link #parameter(String)} method.
+ * This {@code Parameters} class provides alternative ways, using a {@link ParameterDescriptor} argument
+ * instead than a {@code String} argument. Those descriptors provide additional information like the various
+ * {@linkplain DefaultParameterDescriptor#getAlias() aliases} under which the same parameter may be known.
+ * By using this information, {@code Parameters} can choose the most appropriate parameter name or alias
+ * (by searching for a common {@linkplain org.apache.sis.metadata.iso.ImmutableIdentifier#getAuthority() authority})
+ * when it delegates its work to the {@code parameter(String)} method.
+ *
+ * <div class="note"><b>Example:</b>
+ * The same parameter may be known under different names. For example the
+ * {@linkplain org.apache.sis.referencing.datum.DefaultEllipsoid#getSemiMajorAxis()
+ * length of the semi-major axis of the ellipsoid} is commonly known as {@code "semi_major"}.
+ * But that parameter can also be named {@code "semi_major_axis"}, {@code "earth_radius"} or simply {@code "a"}
+ * in other libraries. When fetching parameter values, we do not always know in advance which of the above-cited
+ * names is recognized by an arbitrary {@code ParameterValueGroup} instance.</div>
+ *
+ * {@code Parameters} uses also the descriptor information for applying type and unit conversions
+ * (i.e. returned values are converted to the units of measurement specified by the given parameter descriptor).
+ *
+ *
  * <div class="section">Note for subclass implementors</div>
+ * This class does not implement any method from the {@link ParameterValueGroup} interface
+ * (this class is not named “{@code AbstractParameterValueGroup}” for that reason).
+ * Extending this class or extending {@link Object} make almost no difference for implementors;
+ * {@code Parameters} purpose is mostly to extend the API for users convenience.
  * All methods in this class get their information from the {@link ParameterValueGroup} methods.
- * In addition, each method in this class is isolated from all others: overriding one method has
- * no impact on other methods.
- *
- * <div class="note"><b>Note on this class name:</b>
- * Despite implementing the {@link ParameterValueGroup} interface, this class is not named
- * {@code AbstractParameterValueGroup} because it does not implement any method from the interface.
- * Extending this class or extending {@link Object} make almost no difference for implementors.
- * The intend of this {@code Parameters} class is rather to extend the API with methods
- * that are convenient for the way Apache SIS uses parameters.
- * In other words, this class is intended for users rather than implementors.</div>
+ * In addition, unless otherwise specified, methods in this class is isolated from all others:
+ * overriding one method has no impact on other methods.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.4
  * @module
  */
@@ -350,13 +341,14 @@ public abstract class Parameters impleme
      * If no name or alias for this group's authority can be found, then the primary name will be returned.
      *
      * @param  source  the parameter for which the name is wanted.
-     * @return the name of the given parameter.
+     * @return the name of the given parameter. May be {@code null} if there is no name at all,
+     *         but such nameless descriptors are not legal.
      */
     private String getName(final GeneralParameterDescriptor source) {
         final ParameterDescriptorGroup descriptor = getDescriptor();
-        if (descriptor != null) {   // Paranoiac check (should never be null)
+        if (descriptor != null) {                                   // Paranoiac check (should never be null)
             final Identifier group = descriptor.getName();
-            if (group != null) {    // Paranoiac check (should never be null)
+            if (group != null) {                                    // Paranoiac check (should never be null)
                 final Citation authority = group.getAuthority();
                 final String name = IdentifiedObjects.getName(source, authority);
                 if (name != null || authority == null) {
@@ -375,30 +367,52 @@ public abstract class Parameters impleme
      */
     @SuppressWarnings("null")
     ParameterValue<?> parameterIfExist(final String name) throws ParameterNotFoundException {
-        ParameterValue<?> fallback  = null;
+        int i1 = 0, i2 = 0;
+        ParameterValue<?> first     = null;
         ParameterValue<?> ambiguity = null;
-        for (final GeneralParameterValue value : values()) {
+        final List<GeneralParameterValue> values = values();
+        final int size = values.size();
+        for (int i=0; i<size; i++) {
+            final GeneralParameterValue value = values.get(i);
             if (value instanceof ParameterValue<?>) {
                 final ParameterValue<?> param = (ParameterValue<?>) value;
-                final ParameterDescriptor<?> descriptor = param.getDescriptor();
-                if (name.equals(descriptor.getName().toString())) {
-                    return param;
-                }
-                if (isHeuristicMatchForName(descriptor, name)) {
-                    if (fallback == null) {
-                        fallback = param;
+                if (IdentifiedObjects.isHeuristicMatchForName(param.getDescriptor(), name)) {
+                    if (first == null) {
+                        first = param;
+                        i1 = i;
                     } else {
                         ambiguity = param;
+                        i2 = i;
                     }
                 }
             }
         }
-        if (ambiguity != null) {
-            throw new ParameterNotFoundException(Errors.format(Errors.Keys.AmbiguousName_3,
-                    IdentifiedObjects.toString(fallback .getDescriptor().getName()),
-                    IdentifiedObjects.toString(ambiguity.getDescriptor().getName()), name), name);
+        /*
+         * If there is no ambiguity, we are done. In case of ambiguity we should throw an exception.
+         * However we will not throw the exception if this method is invoked from the getParameter(…)
+         * method of a Parameters instance wrapping a non-SIS implementation. The reason is that for
+         * foreigner implementations, the package-private getParameter(…) method will conservatively
+         * delegate to the public parameter(…) method, in case the implementor overrides it. But for
+         * Apache SIS implementations in this package, we rely on the exception being thrown.
+         *
+         * Note that all classes in this package except UnmodifiableParameterValueGroup override this
+         * method in a way that unconditionally throw the exception.  UnmodifiableParameterValueGroup
+         * is the class that needs the exception to be thrown.
+         */
+        if (ambiguity == null || !isKnownImplementation()) {
+            return first;
+        }
+        final GeneralParameterDescriptor d1 = first    .getDescriptor();
+        final GeneralParameterDescriptor d2 = ambiguity.getDescriptor();
+        final String message;
+        if (d1 == d2) {
+            message = Errors.format(Errors.Keys.MultiOccurenceValueAtIndices_3, name, i1, i2);
+        } else {
+            message = Errors.format(Errors.Keys.AmbiguousName_3,
+                        IdentifiedObjects.toString(d1.getName()),
+                        IdentifiedObjects.toString(d2.getName()), name);
         }
-        return fallback;
+        throw new ParameterNotFoundException(message, name);
     }
 
     /**
@@ -477,6 +491,8 @@ public abstract class Parameters impleme
      *         default value} otherwise (which may be {@code null}).
      * @throws ParameterNotFoundException if the given {@code parameter} name or alias is not legal for this group.
      *
+     * @see #getMandatoryValue(ParameterDescriptor)
+     * @see #getOrCreate(ParameterDescriptor)
      * @see DefaultParameterValueGroup#parameter(String)
      * @see DefaultParameterValue#getValue()
      *
@@ -514,6 +530,9 @@ public abstract class Parameters impleme
      * @throws ParameterNotFoundException if the given {@code parameter} name or alias is not legal for this group.
      * @throws IllegalStateException if the value is not defined and there is no default value.
      *
+     * @see #getValue(ParameterDescriptor)
+     * @see #getOrCreate(ParameterDescriptor)
+     *
      * @since 0.7
      */
     public <T> T getMandatoryValue(final ParameterDescriptor<T> parameter) throws ParameterNotFoundException {
@@ -696,6 +715,8 @@ public abstract class Parameters impleme
      * @return the requested parameter instance.
      * @throws ParameterNotFoundException if the given {@code parameter} name or alias is not legal for this group.
      *
+     * @see #getValue(ParameterDescriptor)
+     * @see #getMandatoryValue(ParameterDescriptor)
      * @see DefaultParameterValueGroup#parameter(String)
      *
      * @since 0.6

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -157,7 +157,7 @@ public final strictfp class ParametersTe
         final ParameterValueGroup source = descriptor.createValue();
         final ParameterValueGroup sourceSubgroup = source.addGroup(subgroupName);
         final ParameterValue<?> o1 = sourceSubgroup.parameter("Optional 4");
-        final ParameterValue<?> o2 = o1.getDescriptor().createValue(); // See ParameterFormatTest.testMultiOccurrence()
+        final ParameterValue<?> o2 = o1.getDescriptor().createValue();      // See ParameterFormatTest.testMultiOccurrence()
         sourceSubgroup.parameter("Mandatory 2").setValue(20);
         sourceSubgroup.values().add(o2);
         o1.setValue(40);
@@ -169,8 +169,8 @@ public final strictfp class ParametersTe
          */
         final ParameterValueGroup target = descriptor.createValue();
         final ParameterValueGroup targetSubgroup = target.addGroup(subgroupName);
-        targetSubgroup.parameter("Mandatory 1").setValue(-10);  // We expect this value to be overwritten.
-        targetSubgroup.parameter("Optional 3") .setValue( 30);  // We expect this value to be preserved.
+        targetSubgroup.parameter("Mandatory 1").setValue(-10);      // We expect this value to be overwritten.
+        targetSubgroup.parameter("Optional 3") .setValue( 30);      // We expect this value to be preserved.
         target.parameter("A parent parameter") .setValue("A value to be overwritten");
         /*
          * The actual test.
@@ -179,12 +179,11 @@ public final strictfp class ParametersTe
         assertSame(sourceSubgroup, TestUtilities.getSingleton(source.groups(subgroupName)));
         assertSame(targetSubgroup, TestUtilities.getSingleton(target.groups(subgroupName)));
         assertEquals("A value from the source", target.parameter("A parent parameter").getValue());
-        assertEquals("Mandatory 1", 10, targetSubgroup.parameter("Mandatory 1").intValue());
-        assertEquals("Mandatory 2", 20, targetSubgroup.parameter("Mandatory 2").intValue());
-        assertEquals("Optional 3",  30, targetSubgroup.parameter("Optional 3") .intValue());
-        assertEquals("Optional 4",  40, targetSubgroup.parameter("Optional 4") .intValue());
-        assertEquals("Optional 4 (second occurrence)", 50,
-                ((ParameterValue<?>) targetSubgroup.values().get(4)).intValue());
+        assertEquals("Mandatory 1",    10, targetSubgroup.parameter("Mandatory 1").intValue());
+        assertEquals("Mandatory 2",    20, targetSubgroup.parameter("Mandatory 2").intValue());
+        assertEquals("Optional 3",     30, targetSubgroup.parameter("Optional 3") .intValue());
+        assertEquals("Optional 4",     40, ((ParameterValue<?>) targetSubgroup.values().get(3)).intValue());
+        assertEquals("Optional 4 bis", 50, ((ParameterValue<?>) targetSubgroup.values().get(4)).intValue());
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -47,6 +47,11 @@ public final class Constants extends Sta
     /**
      * The {@value} code space.
      */
+    public static final String GEOTIFF = "GeoTIFF";
+
+    /**
+     * The {@value} code space.
+     */
     public static final String EPSG = "EPSG";
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -138,10 +138,12 @@ public class ResourceInternationalString
      *
      * @param  locale  the locale for which to get the resource bundle.
      * @return the resource bundle for the given locale.
+     * @throws MissingResourceException if no resource bundle can be found for the base name specified
+     *         at {@linkplain #ResourceInternationalString(String, String) construction time}.
      *
      * @see ResourceBundle#getBundle(String, Locale, ClassLoader)
      */
-    protected ResourceBundle getBundle(final Locale locale) {
+    protected ResourceBundle getBundle(final Locale locale) throws MissingResourceException {
         return ResourceBundle.getBundle(resources, locale);
     }
 
@@ -157,7 +159,8 @@ public class ResourceInternationalString
      *
      * @param  locale  the desired locale for the string to be returned.
      * @return the string in the specified locale, or in a fallback locale.
-     * @throws MissingResourceException if the key given to the constructor is invalid.
+     * @throws MissingResourceException if no resource can be found for the base name or for the key
+     *         specified at {@linkplain #ResourceInternationalString(String, String) construction time}.
      */
     @Override
     public String toString(Locale locale) throws MissingResourceException {

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Sat Apr 22 16:46:00 2017
@@ -535,6 +535,12 @@ public final class Errors extends Indexe
         public static final short MissingValueInColumn_1 = 90;
 
         /**
+         * Can not return a single value for “{0}” because there is at least two occurrences, at
+         * indices {1} and {2}.
+         */
+        public static final short MultiOccurenceValueAtIndices_3 = 173;
+
+        /**
          * Options “{0}” and “{1}” are mutually exclusive.
          */
         public static final short MutuallyExclusiveOptions_2 = 91;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Sat Apr 22 16:46:00 2017
@@ -117,6 +117,7 @@ MissingRequiredModule_1           = This
 MissingValueForOption_1           = Missing value for \u201c{0}\u201d option.
 MissingValueForProperty_1         = Missing value for \u201c{0}\u201d property.
 MissingValueInColumn_1            = Missing value in the \u201c{0}\u201d column.
+MultiOccurenceValueAtIndices_3    = Can not return a single value for \u201c{0}\u201d because there is at least two occurrences, at indices {1} and {2}.
 MutuallyExclusiveOptions_2        = Options \u201c{0}\u201d and \u201c{1}\u201d are mutually exclusive.
 NegativeArgument_2                = Argument \u2018{0}\u2019 shall not be negative. The given value was {1}.
 NegativeArrayLength_1             = Can not create a \u201c{0}\u201d array of negative length.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1792304&r1=1792303&r2=1792304&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Sat Apr 22 16:46:00 2017
@@ -114,6 +114,7 @@ MissingRequiredModule_1           = Cett
 MissingValueForOption_1           = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour l\u2019option \u00ab\u202f{0}\u202f\u00bb.
 MissingValueForProperty_1         = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb.
 MissingValueInColumn_1            = Il manque une valeur dans la colonne \u00ab\u202f{0}\u202f\u00bb.
+MultiOccurenceValueAtIndices_3    = Ne peut pas retourner une valeur unique pour \u00ab\u202f{0}\u202f\u00bb parce qu\u2019il y a au moins deux occurrences, aux index {1} et {2}.
 MutuallyExclusiveOptions_2        = Les options \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb sont mutuellement exclusives.
 NegativeArgument_2                = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre n\u00e9gatif. La valeur donn\u00e9e \u00e9tait {1}.
 NegativeArrayLength_1             = Ne peut pas cr\u00e9er un tableau \u00ab\u202f{0}\u202f\u00bb de longueur n\u00e9gative.

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=1792304&r1=1792303&r2=1792304&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] Sat Apr 22 16:46:00 2017
@@ -242,6 +242,11 @@ public final class Vocabulary extends In
         public static final short Description = 31;
 
         /**
+         * Designation
+         */
+        public static final short Designation = 142;
+
+        /**
          * Destination
          */
         public static final short Destination = 32;

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=1792304&r1=1792303&r2=1792304&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] Sat Apr 22 16:46:00 2017
@@ -51,6 +51,7 @@ DefaultValue            = Default value
 Deprecated              = Deprecated
 DerivedFrom_1           = Derived from {0}
 Description             = Description
+Designation             = Designation
 Destination             = Destination
 Details                 = Details
 Dimensions              = Dimensions

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=1792304&r1=1792303&r2=1792304&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] Sat Apr 22 16:46:00 2017
@@ -58,6 +58,7 @@ DefaultValue            = Valeur par d\u
 Deprecated              = Obsol\u00e8te
 DerivedFrom_1           = D\u00e9riv\u00e9 de {0}
 Description             = Description
+Designation             = D\u00e9signation
 Destination             = Destination
 Details                 = D\u00e9tails
 Dimensions              = Dimensions



Mime
View raw message