sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1640676 - in /sis/trunk: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/ core/sis-metadata/src/test/java/org/apache/sis/metadata/ core/sis-metadata/src/test/java/...
Date Thu, 20 Nov 2014 05:09:11 GMT
Author: desruisseaux
Date: Thu Nov 20 05:09:10 2014
New Revision: 1640676

URL: http://svn.apache.org/r1640676
Log:
Merge from the JDK6 branch only selected changes:
TopicCategory, PixelOrientation and Obligation CodeList became Enum on GeoAPI-SNAPSHOT
for ISO 19115 compliance, but we keep them in their old form on trunk for compatibility.
The incompatible changes on the branches will be merged to trunk at a later time yet to
be determined.

Added:
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/EnumMarshallingTest.java
      - copied unchanged from r1640672, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/EnumMarshallingTest.java
Modified:
    sis/trunk/   (props changed)
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java   (contents, props changed)
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/CodeListMarshallingTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/CodeListAdapter.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/trunk/core/sis-utility/src/main/resources/org/apache/sis/util/iso/class-index.properties
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/SystemRegistryTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java
    sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java

Propchange: sis/trunk/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK8:r1640284-1640667
  Merged /sis/branches/JDK7:r1640305-1640670
  Merged /sis/branches/JDK6:r1640309-1640672

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -190,9 +190,9 @@ public abstract class AbstractFeature im
     final Property createProperty(final String name) throws IllegalArgumentException {
         final AbstractIdentifiedType pt = type.getProperty(name);
         if (pt instanceof DefaultAttributeType<?>) {
-            return AbstractAttribute.create((DefaultAttributeType<?>) pt);
+            return ((DefaultAttributeType<?>) pt).newInstance();
         } else if (pt instanceof DefaultAssociationRole) {
-            return AbstractAssociation.create((DefaultAssociationRole) pt);
+            return ((DefaultAssociationRole) pt).newInstance();
         } else {
             throw unsupportedPropertyType(pt.getName());
         }

Propchange: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
------------------------------------------------------------------------------
  Merged /sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java:r1640309-1640672
  Merged /sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java:r1640284-1640393
  Merged /sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java:r1640305-1640394

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -226,7 +226,7 @@ final class CharacteristicMap extends Ab
             characterizedBy = new AbstractAttribute<?>[types.characterizedBy.length];
         }
         if (characterizedBy[index] == null) {
-            characterizedBy[index] = AbstractAttribute.create(types.characterizedBy[index]);
+            characterizedBy[index] = types.characterizedBy[index].newInstance();
             return true;
         }
         return false;

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/CodeListMarshallingTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/CodeListMarshallingTest.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/CodeListMarshallingTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/code/CodeListMarshallingTest.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -25,13 +25,12 @@ import org.opengis.metadata.citation.Rol
 import org.opengis.metadata.citation.DateType;
 import org.opengis.metadata.citation.CitationDate;
 import org.opengis.metadata.citation.ResponsibleParty;
-import org.opengis.metadata.identification.TopicCategory;
-import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
+import org.opengis.metadata.citation.PresentationForm;
+import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.internal.jaxb.Schemas;
 import org.apache.sis.xml.XML;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.xml.MarshallerPool;
-import org.apache.sis.util.CharSequences;
 import org.apache.sis.test.XMLTestCase;
 import org.junit.Test;
 
@@ -44,7 +43,7 @@ import static org.apache.sis.test.Assert
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Guilhem Legal (Geomatys)
  * @since   0.3 (derived from geotk-3.17)
- * @version 0.4
+ * @version 0.5
  * @module
  *
  * @see <a href="http://jira.geotoolkit.org/browse/GEOTK-121">GEOTK-121</a>
@@ -154,17 +153,23 @@ public final strictfp class CodeListMars
      */
     @Test
     public void testExtraCodes() throws JAXBException {
-        final DefaultDataIdentification id = new DefaultDataIdentification();
-        id.setTopicCategories(Arrays.asList(
-                TopicCategory.valueOf("oceans"), // New code
-                TopicCategory.valueOf("OCEANS"), // Existing code with UML id="oceans"
-                TopicCategory.valueOf("test"))); // New code
+        final DefaultCitation id = new DefaultCitation();
+        id.setPresentationForms(Arrays.asList(
+                PresentationForm.valueOf("IMAGE_DIGITAL"), // Existing code with UML id="imageDigital"
+                PresentationForm.valueOf("test")));        // New code
 
         final String xml = marshal(id);
 
-        // "OCEANS" is marshalled as "oceans" because is contains a UML id, which is lower-case.
-        assertEquals(2, CharSequences.count(xml, "<gmd:MD_TopicCategoryCode>oceans</gmd:MD_TopicCategoryCode>"));
-        assertEquals(0, CharSequences.count(xml, "<gmd:MD_TopicCategoryCode>OCEANS</gmd:MD_TopicCategoryCode>"));
-        assertEquals(1, CharSequences.count(xml, "<gmd:MD_TopicCategoryCode>test</gmd:MD_TopicCategoryCode>"));
+        // "IMAGE_DIGITAL" is marshalled as "imageDigital" because is contains a UML id, which is lower-case.
+        assertXmlEquals(
+                "<gmd:CI_Citation xmlns:gmd=\"" + Namespaces.GMD + "\">\n" +
+                "  <gmd:presentationForm>\n" +
+                "    <gmd:CI_PresentationFormCode codeListValue=\"imageDigital\">Image digital</gmd:CI_PresentationFormCode>\n" +
+                "  </gmd:presentationForm>\n" +
+                "  <gmd:presentationForm>\n" +
+                "    <gmd:CI_PresentationFormCode codeListValue=\"test\">Test</gmd:CI_PresentationFormCode>\n" +
+                "  </gmd:presentationForm>\n" +
+                "</gmd:CI_Citation>\n",
+                xml, "xmlns:*", "codeList", "codeSpace");
     }
 }

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -65,7 +65,7 @@ public abstract strictfp class MetadataT
      * Creates a new test suite for the given types.
      *
      * @param standard The standard implemented by the metadata objects to test.
-     * @param types The GeoAPI interfaces or {@link CodeList} types to test.
+     * @param types The GeoAPI interfaces, {@link CodeList} or {@link Enum} types to test.
      */
     protected MetadataTestCase(final MetadataStandard standard, final Class<?>... types) {
         super(types);
@@ -79,7 +79,7 @@ public abstract strictfp class MetadataT
      */
     @Override
     protected <T> Class<? extends T> getImplementation(final Class<T> type) {
-        assertTrue(standard.isMetadata(type));
+        assertTrue(type.getName(), standard.isMetadata(type));
         final Class<? extends T> impl = standard.getImplementation(type);
         assertNotNull(type.getName(), impl);
         return impl;
@@ -102,8 +102,8 @@ public abstract strictfp class MetadataT
 
     /**
      * Returns a dummy value of the given type. The default implementation returns values for
-     * {@link CharSequence}, {@link Number}, {@link Date}, {@link Locale}, {@link CodeList}
-     * and types in the {@link #types} list.
+     * {@link CharSequence}, {@link Number}, {@link Date}, {@link Locale}, {@link CodeList},
+     * {@link Enum} and types in the {@link #types} list.
      *
      * <p>The returned value may be of an other type than the given one if the
      * {@code PropertyAccessor} converter method know how to convert that type.</p>
@@ -137,7 +137,7 @@ public abstract strictfp class MetadataT
             if (type == CodeList.class) {
                 return null;
             }
-            final CodeList<?>[] codes = (CodeList<?>[]) type.getMethod("values", (Class[]) null).invoke(null, (Object[]) null);
+            final CodeList[] codes = (CodeList[]) type.getMethod("values", (Class[]) null).invoke(null, (Object[]) null);
             return codes[random.nextInt(codes.length)];
         } catch (Exception e) { // (ReflectiveOperationException) on JDK7 branch.
             fail(e.toString());

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -17,11 +17,9 @@
 package org.apache.sis.metadata;
 
 import java.util.Arrays;
-import java.util.Collections;
 import javax.measure.unit.SI;
 import org.opengis.metadata.citation.Role;
 import org.opengis.metadata.citation.PresentationForm;
-import org.opengis.metadata.identification.TopicCategory;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.TreeTableFormat;
@@ -32,7 +30,6 @@ import org.apache.sis.metadata.iso.citat
 import org.apache.sis.metadata.iso.citation.DefaultIndividual;
 import org.apache.sis.metadata.iso.citation.DefaultResponsibleParty;
 import org.apache.sis.metadata.iso.content.DefaultAttributeGroup;
-import org.apache.sis.metadata.iso.identification.DefaultKeywords;
 import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
 import org.apache.sis.metadata.iso.lineage.DefaultProcessing;
 import org.apache.sis.test.DependsOn;
@@ -185,34 +182,29 @@ public final strictfp class TreeTableFor
 
     /**
      * Tests the formatting of a {@link DefaultDataIdentification} object with custom code list elements
-     * Note that adding enumeration values is normally not allowed, so a future version of this test may
-     * need to change the code type.
      */
     @Test
     public void testTreeWithCustomElements() {
-        final DefaultKeywords keywords = new DefaultKeywords();
-        keywords.setKeywords(Arrays.asList(
+        final DefaultCitation citation = new DefaultCitation();
+        citation.setAlternateTitles(Arrays.asList(
                 new SimpleInternationalString("Apple"),
                 new SimpleInternationalString("Orange"),
                 new SimpleInternationalString("Kiwi")));
 
-        final DefaultDataIdentification identification = new DefaultDataIdentification();
-        identification.setDescriptiveKeywords(Collections.singleton(keywords));
-        identification.setTopicCategories(Arrays.asList(
-                TopicCategory.HEALTH,
-                TopicCategory.valueOf("OCEANS"), // Existing category
-                TopicCategory.valueOf("test"))); // Custom category
+        citation.setPresentationForms(Arrays.asList(
+                PresentationForm.IMAGE_DIGITAL,
+                PresentationForm.valueOf("AUDIO_DIGITAL"),  // Existing form
+                PresentationForm.valueOf("test")));         // Custom form
 
-        final String text = format.format(identification.asTreeTable());
+        final String text = format.format(citation.asTreeTable());
         assertMultilinesEquals(
-            "Data identification\n" +
-            "  ├─Descriptive keywords\n" +
-            "  │   ├─Keyword (1 of 3)…………… Apple\n" +
-            "  │   ├─Keyword (2 of 3)…………… Orange\n" +
-            "  │   └─Keyword (3 of 3)…………… Kiwi\n" +
-            "  ├─Topic category (1 of 3)…… Health\n" +
-            "  ├─Topic category (2 of 3)…… Oceans\n" +
-            "  └─Topic category (3 of 3)…… Test\n",
+            "Citation\n" +
+            "  ├─Alternate title (1 of 3)………… Apple\n" +
+            "  ├─Alternate title (2 of 3)………… Orange\n" +
+            "  ├─Alternate title (3 of 3)………… Kiwi\n" +
+            "  ├─Presentation form (1 of 3)…… Image digital\n" +
+            "  ├─Presentation form (2 of 3)…… AUDIO-DIGITAL\n" + // Missing localization resource for that one.
+            "  └─Presentation form (3 of 3)…… Test\n",
             text);
     }
 }

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -66,7 +66,6 @@ public final strictfp class AllMetadataT
             org.opengis.metadata.Identifier.class,
             org.opengis.metadata.Metadata.class,
             org.opengis.metadata.MetadataExtensionInformation.class,
-//          org.opengis.metadata.Obligation.class, // Excluded CodeList because it doesn't use the usual kind of adapter.
             org.opengis.metadata.PortrayalCatalogueReference.class,
             org.opengis.metadata.acquisition.AcquisitionInformation.class,
             org.opengis.metadata.acquisition.Context.class,

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -51,6 +51,7 @@ import org.junit.BeforeClass;
     org.apache.sis.metadata.AbstractMetadataTest.class,
 
     // XML marshalling.
+    org.apache.sis.internal.jaxb.code.EnumMarshallingTest.class,
     org.apache.sis.internal.jaxb.code.CodeListMarshallingTest.class,
     org.apache.sis.internal.jaxb.code.PT_LocaleTest.class,
     org.apache.sis.xml.FreeTextMarshallingTest.class,

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -873,7 +873,8 @@ public class AbstractIdentifiedObject ex
                 return implementsSameInterface(object);
             }
             default: {
-                throw new IllegalArgumentException(Errors.format(Errors.Keys.UnknownEnumValue_1, mode));
+                throw new IllegalArgumentException(Errors.format(
+                        Errors.Keys.UnknownEnumValue_2, ComparisonMode.class, mode));
             }
         }
     }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -850,7 +850,8 @@ public final class Matrices extends Stat
             case IGNORE_METADATA: return equals(m1, m2, 0, false);
             case DEBUG:           // Fall through
             case APPROXIMATIVE:   return equals(m1, m2, Numerics.COMPARISON_THRESHOLD, true);
-            default: throw new IllegalArgumentException(Errors.format(Errors.Keys.UnknownEnumValue_1, mode));
+            default: throw new IllegalArgumentException(Errors.format(
+                    Errors.Keys.UnknownEnumValue_2, ComparisonMode.class, mode));
         }
     }
 

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -125,4 +125,31 @@ class ObjectToString<S> extends SystemCo
             return (source != null) ? source.name() : null;
         }
     }
+
+
+    /**
+     * Specialized instance for {@link java.lang.Enum}.
+     * This class invokes {@link java.lang.Enum#name()} instead than {@code toString()}.
+     *
+     * @see org.apache.sis.internal.converter.StringConverter.Enum
+     */
+    static final class Enum<S extends java.lang.Enum<S>> extends ObjectToString<S> {
+        private static final long serialVersionUID = 5391817175838307542L;
+
+        /** Creates a new converter from the given type of enum to strings. */
+        Enum(final Class<S> sourceClass, final SystemConverter<String, S> inverse) {
+            super(sourceClass, inverse);
+        }
+
+        /** Function is bijective, because no duplicated enum name shall exist. */
+        @Override public Set<FunctionProperty> properties() {
+            return EnumSet.of(FunctionProperty.INJECTIVE, FunctionProperty.SURJECTIVE,
+                    FunctionProperty.INVERTIBLE);
+        }
+
+        /** Returns the name of the given code list element. */
+        @Override public String apply(final S source) {
+            return (source != null) ? source.name() : null;
+        }
+    }
 }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -341,7 +341,7 @@ abstract class StringConverter<T> extend
         }
 
         /** Converts the given string to the target type of this converter. */
-        @Override T doConvert(String source) {
+        @Override T doConvert(final String source) {
             final T code = Types.forCodeName(targetClass, source, false);
             if (code == null) {
                 throw new UnconvertibleObjectException(formatErrorMessage(source));
@@ -354,4 +354,36 @@ abstract class StringConverter<T> extend
             return new ObjectToString.CodeList<T>(targetClass, this);
         }
     }
+
+    /**
+     * Converter from {@link String} to {@link java.lang.Enum}.
+     * This converter is particular in that it requires the target class in argument
+     * to the constructor.
+     *
+     * <p>Instances of this class are created by
+     * {@link SystemRegistry#createConverter(Class, Class)}.</p>
+     */
+    static final class Enum<T extends java.lang.Enum<T>> extends StringConverter<T> {
+        /** For cross-version compatibility on serialization. */
+        private static final long serialVersionUID = -4124617013044304640L;
+
+        /** Creates a new converter for the given enumeration. */
+        Enum(final Class<T> targetClass) {
+            super(targetClass);
+        }
+
+        /** Converts the given string to the target type of this converter. */
+        @Override T doConvert(final String source) {
+            final T code = Types.forEnumName(targetClass, source);
+            if (code == null) {
+                throw new UnconvertibleObjectException(formatErrorMessage(source));
+            }
+            return code;
+        }
+
+        /** Invoked by the constructor for creating the inverse converter. */
+        @Override ObjectConverter<T, String> createInverse() {
+            return new ObjectToString.Enum<T>(targetClass, this);
+        }
+    }
 }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -140,6 +140,9 @@ public final class SystemRegistry extend
      *       We do not register every code lists in advance because there is too
      *       many of them, and a generic code is available for all of them.</li>
      * </ul>
+     *
+     * @return A newly generated converter from the specified source class to the target class,
+     *         or {@code null} if none.
      */
     @Override
     @SuppressWarnings({"unchecked","rawtypes"})
@@ -181,13 +184,17 @@ public final class SystemRegistry extend
                     targetClass, find(String.class, targetClass));
         }
         /*
-         * From String to CodeList.
+         * From String to CodeList or Enum.
          */
         if (sourceClass == String.class) {
             if (CodeList.class.isAssignableFrom(targetClass)) {
                 return (ObjectConverter<S,T>) new StringConverter.CodeList( // More checks in JDK7 branch.
                         targetClass.asSubclass(CodeList.class));
             }
+            if (targetClass.isEnum()) {
+                return (ObjectConverter<S,T>) new StringConverter.Enum( // More checks in JDK7 branch.
+                        targetClass.asSubclass(Enum.class));
+            }
         }
         /*
          * From Number to other kinds of Number.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -96,17 +96,14 @@ public abstract class CodeListAdapter<Va
 
     /**
      * Substitutes the adapter value read from an XML stream by the object which will
-     * contains the value. JAXB calls automatically this method at unmarshalling time.
+     * contain the value. JAXB calls automatically this method at unmarshalling time.
      *
      * @param  adapter The adapter for this metadata value.
      * @return A code list which represents the metadata value.
      */
     @Override
     public final BoundType unmarshal(final ValueType adapter) {
-        if (adapter == null) {
-            return null;
-        }
-        return Types.forCodeName(getCodeListClass(), adapter.proxy.identifier(), true);
+        return (adapter != null) ? Types.forCodeName(getCodeListClass(), adapter.proxy.identifier(), true) : null;
     }
 
     /**

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/CodeListAdapter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/CodeListAdapter.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/CodeListAdapter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/CodeListAdapter.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -59,7 +59,7 @@ public abstract class CodeListAdapter<Bo
 
     /**
      * Substitutes the adapter value read from an XML stream by the object which will
-     * contains the value. JAXB calls automatically this method at unmarshalling time.
+     * contain the value. JAXB calls automatically this method at unmarshalling time.
      *
      * @param  proxy The proxy for the GML value.
      * @return A code list which represents the GML value.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -61,11 +61,20 @@ final class CodeListFilter implements Co
      */
     @Override
     public boolean accept(final CodeList<?> code) {
-        for (final String name : code.names()) {
-            if (CharSequences.equalsFiltered(name, codename, Filter.LETTERS_AND_DIGITS, true)) {
+        for (final String candidate : code.names()) {
+            if (accept(candidate, codename)) {
                 return true;
             }
         }
         return false;
     }
+
+    /**
+     * Returns {@code true} if the given names matches the name we are looking for.
+     * This is defined in a separated method in order to ensure that all code paths
+     * use the same criterion.
+     */
+    static boolean accept(final String candidate, final String codename) {
+        return CharSequences.equalsFiltered(candidate, codename, Filter.LETTERS_AND_DIGITS, true);
+    }
 }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -437,6 +437,8 @@ public final class Types extends Static 
      * @param <T> The compile-time type given as the {@code codeType} parameter.
      * @param codeType The type of code list.
      * @return The list of values for the given code list, or an empty array if none.
+     *
+     * @see Class#getEnumConstants()
      */
     @SuppressWarnings("unchecked")
     public static <T extends CodeList<?>> T[] getCodeValues(final Class<T> codeType) {
@@ -514,10 +516,51 @@ public final class Types extends Static 
     }
 
     /**
-     * Returns the code of the given type that matches the given name, or optionally returns a new
-     * one if none match it. This method performs the same work than the GeoAPI {@code valueOf(…)}
-     * method, except that this method is more tolerant on string comparisons when looking for an
-     * existing code:
+     * Returns the enumeration value of the given type that matches the given name, or {@code null} if none.
+     * This method is similar to the standard {@code Enum.valueOf(…)} method, except that this method is more
+     * tolerant on string comparisons:
+     *
+     * <ul>
+     *   <li>Name comparisons are case-insensitive.</li>
+     *   <li>Only {@linkplain Character#isLetterOrDigit(int) letter and digit} characters are compared.
+     *       Spaces and punctuation characters like {@code '_'} and {@code '-'} are ignored.</li>
+     * </ul>
+     *
+     * If there is no match, this method returns {@code null} — it does not thrown an exception,
+     * unless the given class is not an enumeration.
+     *
+     * @param <T>      The compile-time type given as the {@code enumType} parameter.
+     * @param enumType The type of enumeration.
+     * @param name     The name of the enumeration value to obtain, or {@code null}.
+     * @return A value matching the given name, or {@code null} if the name is null
+     *         or if no matching enumeration is found.
+     *
+     * @see Enum#valueOf(Class, String)
+     *
+     * @since 0.5
+     */
+    public static <T extends Enum<T>> T forEnumName(final Class<T> enumType, String name) {
+        name = CharSequences.trimWhitespaces(name);
+        if (name != null && !name.isEmpty()) try {
+            return Enum.valueOf(enumType, name);
+        } catch (IllegalArgumentException e) {
+            final T[] values = enumType.getEnumConstants();
+            if (values == null) {
+                throw e;
+            }
+            for (final Enum<?> code : values) {
+                if (CodeListFilter.accept(code.name(), name)) {
+                    return enumType.cast(code);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the code of the given type that matches the given name, or optionally returns a new one if none
+     * match the name. This method performs the same work than the GeoAPI {@code CodeList.valueOf(…)} method,
+     * except that this method is more tolerant on string comparisons when looking for an existing code:
      *
      * <ul>
      *   <li>Name comparisons are case-insensitive.</li>
@@ -525,8 +568,8 @@ public final class Types extends Static 
      *       Spaces and punctuation characters like {@code '_'} and {@code '-'} are ignored.</li>
      * </ul>
      *
-     * If no match is found, then a new code is created only if the {@code canCreate} argument is
-     * {@code true}. Otherwise this method returns {@code null}.
+     * If no match is found, then a new code is created only if the {@code canCreate} argument is {@code true}.
+     * Otherwise this method returns {@code null}.
      *
      * @param <T>        The compile-time type given as the {@code codeType} parameter.
      * @param codeType   The type of code list.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -804,9 +804,9 @@ public final class Errors extends Indexe
         public static final short UnknownCommand_1 = 113;
 
         /**
-         * Unknown enumeration value: {0}.
+         * “{1}” is not a known or supported value for the ‘{0}’ enumeration.
          */
-        public static final short UnknownEnumValue_1 = 114;
+        public static final short UnknownEnumValue_2 = 114;
 
         /**
          * Format of “{0}” is not recognized.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Thu Nov 20 05:09:10 2014
@@ -172,7 +172,7 @@ UnitlessParameter_1               = Para
 UnknownAuthority_1                = Authority \u201c{0}\u201d is unknown.
 UnknownAxisDirection_1            = Axis direction \u201c{0}\u201d is unknown.
 UnknownCommand_1                  = Command \u201c{0}\u201d is not recognized.
-UnknownEnumValue_1                = Unknown enumeration value: {0}.
+UnknownEnumValue_2                = \u201c{1}\u201d is not a known or supported value for the \u2018{0}\u2019 enumeration.
 UnknownFormatFor_1                = Format of \u201c{0}\u201d is not recognized.
 UnknownOption_1                   = Option \u201c{0}\u201d is not recognized.
 UnknownType_1                     = Type \u2018{0}\u2019 is unknown in this context.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Thu Nov 20 05:09:10 2014
@@ -161,7 +161,7 @@ UnitlessParameter_1               = Le p
 UnknownAuthority_1                = L\u2019autorit\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnue.
 UnknownAxisDirection_1            = La direction d\u2019axe \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnue.
 UnknownCommand_1                  = La commande \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnue.
-UnknownEnumValue_1                = Valeur d\u2019\u00e9num\u00e9ration inconnue: {0}.
+UnknownEnumValue_2                = \u00ab\u202f{1}\u202f\u00bb n\u2019est pas une valeur connue ou support\u00e9e pour l\u2019\u00e9num\u00e9ration \u2018{0}\u2019.
 UnknownFormatFor_1                = Le format de \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnu.
 UnknownOption_1                   = L\u2019option \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnue.
 UnknownType_1                     = Le type \u2018{0}\u2019 n\u2019est pas reconnu dans ce contexte.

Modified: sis/trunk/core/sis-utility/src/main/resources/org/apache/sis/util/iso/class-index.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/resources/org/apache/sis/util/iso/class-index.properties?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/resources/org/apache/sis/util/iso/class-index.properties (original)
+++ sis/trunk/core/sis-utility/src/main/resources/org/apache/sis/util/iso/class-index.properties Thu Nov 20 05:09:10 2014
@@ -142,7 +142,6 @@ MD_MediumFormatCode=org.opengis.metadata
 MD_MediumNameCode=org.opengis.metadata.distribution.MediumName
 MD_Metadata=org.opengis.metadata.Metadata
 MD_MetadataExtensionInformation=org.opengis.metadata.MetadataExtensionInformation
-MD_ObligationCode=org.opengis.annotation.Obligation
 MD_ObligationCode=org.opengis.metadata.Obligation
 MD_PixelOrientationCode=org.opengis.metadata.spatial.PixelOrientation
 MD_PortrayalCatalogueReference=org.opengis.metadata.PortrayalCatalogueReference

Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -25,10 +25,11 @@ import java.net.URL;
 import java.net.URISyntaxException;
 import java.net.MalformedURLException;
 import java.nio.charset.Charset;
+import java.lang.annotation.ElementType;
 import javax.measure.unit.SI;
 import javax.measure.unit.Unit;
 import org.opengis.util.InternationalString;
-import org.opengis.metadata.spatial.PixelOrientation;
+import org.opengis.metadata.citation.OnLineFunction;
 import org.apache.sis.measure.Angle;
 import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.ObjectConverter;
@@ -49,7 +50,7 @@ import org.apache.sis.internal.jdk7.Stan
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
- * @version 0.3
+ * @version 0.5
  * @module
  */
 @DependsOn(org.apache.sis.measure.AngleTest.class)
@@ -295,8 +296,21 @@ public final strictfp class StringConver
      */
     @Test
     public void testCodeList() {
-        final ObjectConverter<String, PixelOrientation> c = new StringConverter.CodeList<PixelOrientation>(PixelOrientation.class);
-        runInvertibleConversion(c, "LOWER_RIGHT", PixelOrientation.LOWER_RIGHT);
+        final ObjectConverter<String, OnLineFunction> c = new StringConverter.CodeList<OnLineFunction>(OnLineFunction.class);
+        runInvertibleConversion(c, "OFFLINE_ACCESS", OnLineFunction.OFFLINE_ACCESS);
+        tryUnconvertibleValue(c);
+        assertSerializedEquals(c);
+    }
+
+    /**
+     * Tests conversions to {@link java.lang.Enum}.
+     *
+     * @since 0.5
+     */
+    @Test
+    public void testEnum() {
+        final ObjectConverter<String, ElementType> c = new StringConverter.Enum<ElementType>(ElementType.class);
+        runInvertibleConversion(c, "PACKAGE", ElementType.PACKAGE);
         tryUnconvertibleValue(c);
         assertSerializedEquals(c);
     }

Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/SystemRegistryTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/SystemRegistryTest.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/SystemRegistryTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/SystemRegistryTest.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -21,7 +21,8 @@ import java.net.URI;
 import java.util.Date;
 import java.util.List;
 import java.util.Collection;
-import org.opengis.metadata.spatial.PixelOrientation;
+import java.lang.annotation.ElementType;
+import org.opengis.metadata.citation.OnLineFunction;
 import org.apache.sis.measure.Angle;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.test.DependsOn;
@@ -39,7 +40,7 @@ import static org.apache.sis.internal.co
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
- * @version 0.3
+ * @version 0.5
  * @module
  */
 @DependsOn(ConverterRegistryTest.class)
@@ -64,10 +65,27 @@ public final strictfp class SystemRegist
      */
     @Test
     public void testStringCodeList() {
-        final ObjectConverter<String, PixelOrientation> c1 = INSTANCE.findExact(String.class, PixelOrientation.class);
-        final ObjectConverter<PixelOrientation, String> c2 = INSTANCE.findExact(PixelOrientation.class, String.class);
-        assertInstanceOf("PixelOrientation ← String", StringConverter.CodeList.class, c1);
-        assertInstanceOf("String ← PixelOrientation", ObjectToString.CodeList.class,  c2);
+        final ObjectConverter<String, OnLineFunction> c1 = INSTANCE.findExact(String.class, OnLineFunction.class);
+        final ObjectConverter<OnLineFunction, String> c2 = INSTANCE.findExact(OnLineFunction.class, String.class);
+        assertInstanceOf("OnLineFunction ← String", StringConverter.CodeList.class, c1);
+        assertInstanceOf("String ← OnLineFunction", ObjectToString.CodeList.class,  c2);
+        assertSame("inverse()", c2, c1.inverse());
+        assertSame("inverse()", c1, c2.inverse());
+        assertSame(c1, assertSerializedEquals(c1));
+        assertSame(c2, assertSerializedEquals(c2));
+    }
+
+    /**
+     * Tests the creation of an enum converter.
+     *
+     * @since 0.5
+     */
+    @Test
+    public void testStringEnum() {
+        final ObjectConverter<String, ElementType> c1 = INSTANCE.findExact(String.class, ElementType.class);
+        final ObjectConverter<ElementType, String> c2 = INSTANCE.findExact(ElementType.class, String.class);
+        assertInstanceOf("ElementType ← String", StringConverter.Enum.class, c1);
+        assertInstanceOf("String ← ElementType", ObjectToString.Enum.class,  c2);
         assertSame("inverse()", c2, c1.inverse());
         assertSame("inverse()", c1, c2.inverse());
         assertSame(c1, assertSerializedEquals(c1));

Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -18,6 +18,7 @@ package org.apache.sis.test;
 
 import java.util.Set;
 import java.util.HashSet;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import javax.xml.bind.annotation.XmlNs;
 import javax.xml.bind.annotation.XmlType;
@@ -71,7 +72,7 @@ public abstract strictfp class Annotatio
     private static final String DEFAULT = "##default";
 
     /**
-     * The GeoAPI interfaces or {@link CodeList} types to test.
+     * The GeoAPI interfaces, {@link CodeList} or {@link Enum} types to test.
      */
     protected final Class<?>[] types;
 
@@ -92,7 +93,7 @@ public abstract strictfp class Annotatio
     /**
      * Creates a new test suite for the given types.
      *
-     * @param types The GeoAPI interfaces or {@link CodeList} types to test.
+     * @param types The GeoAPI interfaces, {@link CodeList} or {@link Enum} types to test.
      */
     protected AnnotationsTestCase(final Class<?>... types) {
         this.types = types;
@@ -104,7 +105,7 @@ public abstract strictfp class Annotatio
      * interface is the {@link org.apache.sis.metadata.iso.citation.DefaultCitation} class.
      *
      * @param  <T>  The type represented by the {@code type} argument.
-     * @param  type The GeoAPI interface (never a {@link CodeList} type).
+     * @param  type The GeoAPI interface (never a {@link CodeList} or {@link Enum} type).
      * @return The SIS implementation for the given interface.
      */
     protected abstract <T> Class<? extends T> getImplementation(Class<T> type);
@@ -143,7 +144,7 @@ public abstract strictfp class Annotatio
      * <p>In SIS implementation, most wrappers are also {@link javax.xml.bind.annotation.adapters.XmlAdapter}.
      * But this is not a requirement.</p>
      *
-     * @param  type The GeoAPI interface or {@link CodeList} type.
+     * @param  type The GeoAPI interface, {@link CodeList} or {@link Enum} type.
      * @return The wrapper for the given type, or {@code null} if none.
      * @throws ClassNotFoundException If a wrapper was expected but not found.
      */
@@ -167,7 +168,7 @@ public abstract strictfp class Annotatio
      * Returns the value of {@link #getWrapperFor(Class)} for the given class, or for a parent
      * of the given class if {@code getWrapperFor(Class)} threw {@code ClassNotFoundException}.
      *
-     * @param  type The GeoAPI interface or {@link CodeList} type.
+     * @param  type The GeoAPI interface, {@link CodeList} or {@link Enum} type.
      * @return The wrapper for the given type. {@link WrapperClass#type} is {@code null} if
      *         no wrapper has been found.
      * @throws ClassNotFoundException If a wrapper was expected but not found in the
@@ -217,7 +218,7 @@ public abstract strictfp class Annotatio
      * <p>The prefix for the given namespace will be fetched by
      * {@link Namespaces#getPreferredPrefix(String, String)}.</p>
      *
-     * @param  impl The implementation class or {@link CodeList} type.
+     * @param  impl The implementation class, {@link CodeList} or {@link Enum} type.
      * @param  specification The specification that define the type, or {@code null} if unspecified.
      * @return The expected namespace.
      * @throws IllegalArgumentException If the given specification is unknown to this method.
@@ -616,22 +617,34 @@ public abstract strictfp class Annotatio
              * and verify that exactly one of @XmlElement or @XmlElementRef annotation is declared.
              */
             testingClass = wrapper.type.getCanonicalName();
-            final Method getter, setter;
-            try {
-                getter = wrapper.type.getMethod("getElement", (Class<?>[]) null);
-                setter = wrapper.type.getMethod("setElement", getter.getReturnType());
-            } catch (NoSuchMethodException e) {
-                fail(e.toString());
-                continue;
+            final XmlElement element;
+            if (type.isEnum()) {
+                final Field field;
+                try {
+                    field = wrapper.type.getDeclaredField("value");
+                } catch (NoSuchFieldException e) {
+                    fail(e.toString());
+                    continue;
+                }
+                element = field.getAnnotation(XmlElement.class);
+            } else {
+                final Method getter, setter;
+                try {
+                    getter = wrapper.type.getMethod("getElement", (Class<?>[]) null);
+                    setter = wrapper.type.getMethod("setElement", getter.getReturnType());
+                } catch (NoSuchMethodException e) {
+                    fail(e.toString());
+                    continue;
+                }
+                assertEquals("The setter method must be declared in the same class than the " +
+                             "getter method - not in a parent class, to avoid issues with JAXB.",
+                             getter.getDeclaringClass(), setter.getDeclaringClass());
+                assertEquals("The setter parameter type shall be the same than the getter return type.",
+                             getter.getReturnType(), getSingleton(setter.getParameterTypes()));
+                element = getter.getAnnotation(XmlElement.class);
+                assertEquals("Expected @XmlElement XOR @XmlElementRef.", (element == null),
+                             getter.isAnnotationPresent(XmlElementRef.class));
             }
-            assertEquals("The setter method must be declared in the same class than the " +
-                         "getter method - not in a parent class, to avoid issues with JAXB.",
-                         getter.getDeclaringClass(), setter.getDeclaringClass());
-            assertEquals("The setter parameter type shall be the same than the getter return type.",
-                         getter.getReturnType(), getSingleton(setter.getParameterTypes()));
-            final XmlElement element = getter.getAnnotation(XmlElement.class);
-            assertEquals("Expected @XmlElement XOR @XmlElementRef.", (element == null),
-                         getter.isAnnotationPresent(XmlElementRef.class));
             /*
              * If the annotation is @XmlElement, ensure that XmlElement.name() is equals to
              * the UML identifier. Then verify that the

Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -23,7 +23,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Random;
 import org.opengis.referencing.cs.AxisDirection;
-import org.opengis.metadata.spatial.PixelOrientation;
+import org.opengis.metadata.citation.OnLineFunction;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.util.iso.LargeCodeList;
@@ -69,11 +69,11 @@ public final strictfp class CodeListSetT
      * the same ordinal value than {@link AxisDirection#NORTH}, so we can detect if the
      * {@code SortedSet} confuses the code list types.
      */
-    private CodeListSet<PixelOrientation> createOtherKind() {
+    private CodeListSet<OnLineFunction> createOtherKind() {
         // For the validity of the tests, ordinal value must be the same.
-        assertEquals(NORTH.ordinal(), PixelOrientation.LOWER_LEFT.ordinal());
-        final CodeListSet<PixelOrientation> c = new CodeListSet<PixelOrientation>(PixelOrientation.class);
-        assertTrue(c.add(PixelOrientation.LOWER_LEFT));
+        assertEquals(NORTH.ordinal(), OnLineFunction.INFORMATION.ordinal());
+        final CodeListSet<OnLineFunction> c = new CodeListSet<OnLineFunction>(OnLineFunction.class);
+        assertTrue(c.add(OnLineFunction.INFORMATION));
         return c;
     }
 
@@ -115,7 +115,7 @@ public final strictfp class CodeListSetT
 
         assertFalse("Should be null-safe.", c.contains(null));
         assertFalse("Code list of other kind should not be included.",
-                c.contains(PixelOrientation.LOWER_LEFT));
+                c.contains(OnLineFunction.INFORMATION));
     }
 
     /**
@@ -127,7 +127,7 @@ public final strictfp class CodeListSetT
         final CodeListSet<AxisDirection> c = create(4);
         assertFalse("Should be null-safe.", c.remove(null));
         assertFalse("Code list of other kind should not be included.",
-                c.remove(PixelOrientation.LOWER_LEFT));
+                c.remove(OnLineFunction.INFORMATION));
 
         assertTrue ("NORTH",  c.remove  (NORTH));
         assertFalse("SOUTH",  c.remove  (SOUTH));

Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -21,6 +21,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.TreeMap;
 import java.util.Locale;
+import java.lang.annotation.ElementType;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.citation.Address;
 import org.opengis.metadata.citation.Citation;
@@ -104,6 +105,21 @@ public final strictfp class TypesTest ex
     }
 
     /**
+     * Tests the {@link Types#forEnumName(Class, String)} method with an enumeration from the JDK.
+     * Such enumerations do not implement the {@link org.opengis.util.Enumerated} interface.
+     *
+     * @since 0.5
+     */
+    @Test
+    public void testForStandardEnumName() {
+        assertSame(ElementType.LOCAL_VARIABLE, Types.forEnumName(ElementType.class, "LOCAL_VARIABLE"));
+        assertSame(ElementType.LOCAL_VARIABLE, Types.forEnumName(ElementType.class, "LOCALVARIABLE"));
+        assertSame(ElementType.LOCAL_VARIABLE, Types.forEnumName(ElementType.class, "local variable"));
+        assertSame(ElementType.LOCAL_VARIABLE, Types.forEnumName(ElementType.class, "local-variable"));
+        assertNull(Types.forEnumName(ElementType.class, "variable"));
+    }
+
+    /**
      * Tests the {@link Types#forCodeName(Class, String, boolean)} method.
      */
     @Test

Modified: sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java?rev=1640676&r1=1640675&r2=1640676&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] Thu Nov 20 05:09:10 2014
@@ -47,6 +47,7 @@ import org.opengis.metadata.maintenance.
 import org.opengis.metadata.constraint.Restriction;
 import org.opengis.referencing.crs.VerticalCRS;
 
+import org.opengis.util.CodeList;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.iso.DefaultNameFactory;
 import org.apache.sis.util.iso.SimpleInternationalString;
@@ -68,6 +69,7 @@ import org.apache.sis.internal.netcdf.Va
 import org.apache.sis.internal.netcdf.GridGeometry;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.metadata.Standards;
+import org.apache.sis.util.resources.Errors;
 
 // The following dependency is used only for static final String constants.
 // Consequently the compiled class files should not have this dependency.
@@ -104,7 +106,7 @@ import static org.apache.sis.storage.net
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.20)
- * @version 0.3
+ * @version 0.5
  * @module
  */
 final class MetadataReader {
@@ -189,13 +191,66 @@ final class MetadataReader {
     }
 
     /**
+     * Invoked when a non-fatal exception occurred while reading metadata.
+     * This method will send a record to the registered listeners if any,
+     * or will log the record otherwise.
+     */
+    private void warning(final Exception e) {
+        decoder.listeners.warning(null, e);
+    }
+
+    /**
+     * Reads the attribute value for the given name, then trims the leading and trailing spaces.
+     * If the value is null, empty or contains only spaces, then this method returns {@code null}.
+     */
+    private String stringValue(final String name) throws IOException {
+        String value = decoder.stringValue(name);
+        if (value != null) {
+            value = value.trim();
+            if (value.isEmpty()) {
+                value = null;
+            }
+        }
+        return value;
+    }
+
+    /**
      * Returns the given string as an {@code InternationalString} if non-null, or {@code null} otherwise.
+     * This method does not trim leading or trailing spaces, since this is often already done by the caller.
      */
     private static InternationalString toInternationalString(final String value) {
         return (value != null) ? new SimpleInternationalString(value) : null;
     }
 
     /**
+     * Returns the enumeration constant for the given name, or {@code null} if the given name is not recognized.
+     * In the later case, this method emits a warning.
+     */
+    private <T extends Enum<T>> T forEnumName(final Class<T> enumType, final String name) {
+        final T code = Types.forEnumName(enumType, name);
+        if (code == null && name != null) {
+            decoder.listeners.warning(Errors.format(Errors.Keys.UnknownEnumValue_2, enumType, name), null);
+        }
+        return code;
+    }
+
+    /**
+     * Returns the code value for the given name, or {@code null} if the given name is not recognized.
+     * In the later case, this method emits a warning.
+     */
+    private <T extends CodeList<T>> T forCodeName(final Class<T> codeType, final String name) {
+        final T code = Types.forCodeName(codeType, name, false);
+        if (code == null && name != null) {
+            /*
+             * CodeLists are not enums, but using the error message for enums is not completly wrong since
+             * if we did not allowed CodeList to create new elements, then we are using it like an enum.
+             */
+            decoder.listeners.warning(Errors.format(Errors.Keys.UnknownEnumValue_2, codeType, name), null);
+        }
+        return code;
+    }
+
+    /**
      * Returns the first element of the given collection.
      */
     private static <T> T first(final Collection<T> collection) {
@@ -289,7 +344,7 @@ final class MetadataReader {
             resource.setFunction(OnLineFunction.INFORMATION);
             return resource;
         } catch (URISyntaxException e) {
-            decoder.listeners.warning(null, e);
+            warning(e);
         }
         return null;
     }
@@ -339,14 +394,14 @@ final class MetadataReader {
     private ResponsibleParty createResponsibleParty(final Responsible keys, final boolean isPointOfContact)
             throws IOException
     {
-        final String individualName   = decoder.stringValue(keys.NAME);
-        final String organisationName = decoder.stringValue(keys.INSTITUTION);
-        final String email            = decoder.stringValue(keys.EMAIL);
-        final String url              = decoder.stringValue(keys.URL);
+        final String individualName   = stringValue(keys.NAME);
+        final String organisationName = stringValue(keys.INSTITUTION);
+        final String email            = stringValue(keys.EMAIL);
+        final String url              = stringValue(keys.URL);
         if (individualName == null && organisationName == null && email == null && url == null) {
             return null;
         }
-        Role role = Types.forCodeName(Role.class, decoder.stringValue(keys.ROLE), true);
+        Role role = forCodeName(Role.class, stringValue(keys.ROLE));
         if (role == null) {
             role = isPointOfContact ? Role.POINT_OF_CONTACT : keys.DEFAULT_ROLE;
         }
@@ -416,11 +471,11 @@ final class MetadataReader {
      * @throws IOException If an I/O operation was necessary but failed.
      */
     private Citation createCitation(final Identifier identifier) throws IOException {
-        String title = decoder.stringValue(TITLE);
+        String title = stringValue(TITLE);
         if (title == null) {
-            title = decoder.stringValue("full_name"); // THREDDS attribute documented in TITLE javadoc.
+            title = stringValue("full_name"); // THREDDS attribute documented in TITLE javadoc.
             if (title == null) {
-                title = decoder.stringValue("name"); // THREDDS attribute documented in TITLE javadoc.
+                title = stringValue("name"); // THREDDS attribute documented in TITLE javadoc.
                 if (title == null) {
                     title = decoder.getTitle();
                 }
@@ -429,7 +484,7 @@ final class MetadataReader {
         final Date   creation   = decoder.dateValue(DATE_CREATED);
         final Date   modified   = decoder.dateValue(DATE_MODIFIED);
         final Date   issued     = decoder.dateValue(DATE_ISSUED);
-        final String references = decoder.stringValue(REFERENCES);
+        final String references =       stringValue(REFERENCES);
         final DefaultCitation citation = new DefaultCitation(title);
         if (identifier != null) {
             citation.setIdentifiers(singleton(identifier));
@@ -451,7 +506,9 @@ final class MetadataReader {
             }
         }
         decoder.setSearchPath(searchPath);
-        citation.setOtherCitationDetails(toInternationalString(references));
+        if (references != null) {
+            citation.setOtherCitationDetails(new SimpleInternationalString(references));
+        }
         return citation.isEmpty() ? null : citation;
     }
 
@@ -474,18 +531,18 @@ final class MetadataReader {
             decoder.setSearchPath(path);
             final Keywords standard = createKeywords(KeywordType.THEME, true);
             final Keywords keywords = createKeywords(KeywordType.THEME, false);
-            final String   topic    = decoder.stringValue(TOPIC_CATEGORY);
-            final String   type     = decoder.stringValue(DATA_TYPE);
-            final String   credits  = decoder.stringValue(ACKNOWLEDGMENT);
-            final String   license  = decoder.stringValue(LICENSE);
-            final String   access   = decoder.stringValue(ACCESS_CONSTRAINT);
+            final String   topic    = stringValue(TOPIC_CATEGORY);
+            final String   type     = stringValue(DATA_TYPE);
+            final String   credits  = stringValue(ACKNOWLEDGMENT);
+            final String   license  = stringValue(LICENSE);
+            final String   access   = stringValue(ACCESS_CONSTRAINT);
             final Extent   extent   = hasExtent ? null : createExtent();
             if (standard!=null || keywords!=null || topic != null || type!=null || credits!=null || license!=null || access!= null || extent!=null) {
                 if (identification == null) {
                     identification = new DefaultDataIdentification();
                 }
-                if (topic    != null) addIfAbsent(identification.getTopicCategories(), Types.forCodeName(TopicCategory.class, topic, true));
-                if (type     != null) addIfAbsent(identification.getSpatialRepresentationTypes(), Types.forCodeName(SpatialRepresentationType.class, type, true));
+                if (topic    != null) addIfAbsent(identification.getTopicCategories(), forCodeName(TopicCategory.class, topic));
+                if (type     != null) addIfAbsent(identification.getSpatialRepresentationTypes(), forCodeName(SpatialRepresentationType.class, type));
                 if (standard != null) addIfAbsent(identification.getDescriptiveKeywords(), standard);
                 if (keywords != null) addIfAbsent(identification.getDescriptiveKeywords(), keywords);
                 if (credits  != null) addIfAbsent(identification.getCredits(), credits);
@@ -497,7 +554,7 @@ final class MetadataReader {
                             if (constraints == null) {
                                 identification.getResourceConstraints().add(constraints = new DefaultLegalConstraints());
                             }
-                            addIfAbsent(constraints.getAccessConstraints(), Types.forCodeName(Restriction.class, keyword, true));
+                            addIfAbsent(constraints.getAccessConstraints(), forCodeName(Restriction.class, keyword));
                         }
                     }
                 }
@@ -509,12 +566,12 @@ final class MetadataReader {
                     hasExtent = true;
                 }
             }
-            project = addIfNonNull(project, toInternationalString(decoder.stringValue(PROJECT)));
+            project = addIfNonNull(project, toInternationalString(stringValue(PROJECT)));
         }
         decoder.setSearchPath(searchPath);
         final Citation citation = createCitation(identifier);
-        final String   summary  = decoder.stringValue(SUMMARY);
-        final String   purpose  = decoder.stringValue(PURPOSE);
+        final String   summary  = stringValue(SUMMARY);
+        final String   purpose  = stringValue(PURPOSE);
         if (identification == null) {
             if (citation==null && summary==null && purpose==null && project==null && publisher==null && pointOfContact==null) {
                 return null;
@@ -527,22 +584,22 @@ final class MetadataReader {
         if (pointOfContact != null) {
             identification.setPointOfContacts(singleton(pointOfContact));
         }
-        addKeywords(identification, project,   "project"); // Not necessarily the same string than PROJECT.
-        addKeywords(identification, publisher, "dataCenter");
-        identification.setSupplementalInformation(toInternationalString(decoder.stringValue(COMMENT)));
+        addKeywords(identification, project,   KeywordType.valueOf("project"));
+        addKeywords(identification, publisher, KeywordType.valueOf("dataCenter"));
+        identification.setSupplementalInformation(toInternationalString(stringValue(COMMENT)));
         return identification;
     }
 
     /**
      * Adds the given keywords to the given identification info if the given set is non-null.
      */
-    private static void addKeywords(final DefaultDataIdentification addTo,
-            final Set<InternationalString> words, final String type)
+    private void addKeywords(final DefaultDataIdentification addTo,
+            final Set<InternationalString> words, final KeywordType type)
     {
         if (words != null) {
             final DefaultKeywords keywords = new DefaultKeywords();
             keywords.setKeywords(words);
-            keywords.setType(Types.forCodeName(KeywordType.class, type, true));
+            keywords.setType(type);
             addTo.getDescriptiveKeywords().add(keywords);
         }
     }
@@ -555,7 +612,7 @@ final class MetadataReader {
      * @throws IOException If an I/O operation was necessary but failed.
      */
     private Keywords createKeywords(final KeywordType type, final boolean standard) throws IOException {
-        final String list = decoder.stringValue(standard ? STANDARD_NAME : KEYWORDS);
+        final String list = stringValue(standard ? STANDARD_NAME : KEYWORDS);
         DefaultKeywords keywords = null;
         if (list != null) {
             final Set<InternationalString> words = new LinkedHashSet<InternationalString>();
@@ -569,7 +626,7 @@ final class MetadataReader {
                 keywords = new DefaultKeywords();
                 keywords.setKeywords(words);
                 keywords.setType(type);
-                final String vocabulary = decoder.stringValue(standard ? STANDARD_NAME_VOCABULARY : VOCABULARY);
+                final String vocabulary = stringValue(standard ? STANDARD_NAME_VOCABULARY : VOCABULARY);
                 if (vocabulary != null) {
                     keywords.setThesaurusName(new DefaultCitation(vocabulary));
                 }
@@ -639,7 +696,7 @@ final class MetadataReader {
             final UnitConverter c = getConverterTo(decoder.unitValue(VERTICAL.UNITS), SI.METRE);
             double min = valueOf(zmin, c);
             double max = valueOf(zmax, c);
-            if (CF.POSITIVE_DOWN.equals(decoder.stringValue(VERTICAL.POSITIVE))) {
+            if (CF.POSITIVE_DOWN.equals(stringValue(VERTICAL.POSITIVE))) {
                 final double tmp = min;
                 min = -max;
                 max = -tmp;
@@ -659,7 +716,7 @@ final class MetadataReader {
             final Number tmin = decoder.numericValue(TIME.MINIMUM);
             final Number tmax = decoder.numericValue(TIME.MAXIMUM);
             if (tmin != null || tmax != null) {
-                final String symbol = decoder.stringValue(TIME.UNITS);
+                final String symbol = stringValue(TIME.UNITS);
                 if (symbol != null) {
                     final Date[] dates = decoder.numberToDate(symbol, tmin, tmax);
                     startTime = dates[0];
@@ -680,12 +737,12 @@ final class MetadataReader {
             }
             extent.setTemporalElements(singleton(t));
         } catch (UnsupportedOperationException e) {
-            decoder.listeners.warning(null, e);
+            warning(e);
         }
         /*
          * Add the geographic identifier, if present.
          */
-        final String identifier = decoder.stringValue(GEOGRAPHIC_IDENTIFIER);
+        final String identifier = stringValue(GEOGRAPHIC_IDENTIFIER);
         if (identifier != null) {
             if (extent == null) {
                 extent = new DefaultExtent();
@@ -703,7 +760,7 @@ final class MetadataReader {
         if (source != null) try {
             return source.getConverterToAny(target);
         } catch (ConversionException e) {
-            decoder.listeners.warning(null, e);
+            warning(e);
         }
         return null;
     }
@@ -732,7 +789,7 @@ final class MetadataReader {
     private Collection<DefaultCoverageDescription> createContentInfo() throws IOException {
         final Map<List<String>, DefaultCoverageDescription> contents =
                 new HashMap<List<String>, DefaultCoverageDescription>(4);
-        final String processingLevel = decoder.stringValue(PROCESSING_LEVEL);
+        final String processingLevel = stringValue(PROCESSING_LEVEL);
         for (final Variable variable : decoder.getVariables()) {
             if (!variable.isCoverage(2)) {
                 continue;
@@ -803,7 +860,7 @@ final class MetadataReader {
         }
         String description = variable.getDescription();
         if (description != null && !(description = description.trim()).isEmpty() && !description.equals(name)) {
-            band.setDescription(toInternationalString(description));
+            band.setDescription(new SimpleInternationalString(description));
         }
 //TODO: Can't store the units, because the Band interface restricts it to length.
 //      We need the SampleDimension interface proposed in ISO 19115 revision draft.
@@ -830,8 +887,8 @@ final class MetadataReader {
     {
         if (name != null && meaning != null) {
             final DefaultRangeElementDescription element = new DefaultRangeElementDescription();
-            element.setName(toInternationalString(name));
-            element.setDefinition(toInternationalString(meaning));
+            element.setName(new SimpleInternationalString(name));
+            element.setDefinition(new SimpleInternationalString(meaning));
             // TODO: create a record from values (and possibly from the masks).
             //       if (pixel & mask == value) then we have that range element.
             return element;
@@ -852,14 +909,14 @@ final class MetadataReader {
      * @throws IOException If an I/O operation was necessary but failed.
      */
     private Identifier getFileIdentifier() throws IOException {
-        String identifier = decoder.stringValue(IDENTIFIER);
+        String identifier = stringValue(IDENTIFIER);
         if (identifier == null) {
             identifier = decoder.getId();
             if (identifier == null) {
                 return null;
             }
         }
-        final String namespace  = decoder.stringValue(NAMING_AUTHORITY);
+        final String namespace = stringValue(NAMING_AUTHORITY);
         return new DefaultIdentifier((namespace != null) ? new DefaultCitation(namespace) : null, identifier);
     }
 
@@ -880,7 +937,7 @@ final class MetadataReader {
         }
         metadata.setMetadataScopes(singleton(new DefaultMetadataScope(ScopeCode.DATASET, null)));
         for (final String service : SERVICES) {
-            final String name = decoder.stringValue(service);
+            final String name = stringValue(service);
             if (name != null) {
                 addIfAbsent(metadata.getMetadataScopes(), new DefaultMetadataScope(ScopeCode.SERVICE, name));
             }
@@ -921,7 +978,7 @@ final class MetadataReader {
                 publisher = addIfNonNull(publisher, toInternationalString(r.getIndividualName()));
             }
             // Also add history.
-            final String history = decoder.stringValue(HISTORY);
+            final String history = stringValue(HISTORY);
             if (history != null) {
                 final DefaultDataQuality quality = new DefaultDataQuality();
                 final DefaultLineage lineage = new DefaultLineage();



Mime
View raw message