sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1457601 [1/2] - in /sis/trunk: ./ ide-project/NetBeans/ sis-metadata/src/main/java/org/apache/sis/metadata/ sis-metadata/src/main/java/org/apache/sis/metadata/iso/ sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/ sis-metada...
Date Sun, 17 Mar 2013 23:53:55 GMT
Author: desruisseaux
Date: Sun Mar 17 23:53:53 2013
New Revision: 1457601

URL: http://svn.apache.org/r1457601
Log:
Merge from the JDK6 branch.

Added:
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/InvalidMetadataException.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/metadata/InvalidMetadataException.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataMap.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataMap.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyMap.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyMap.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/Pruner.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/metadata/Pruner.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
    sis/trunk/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
    sis/trunk/sis-metadata/src/test/java/org/apache/sis/metadata/iso/
      - copied from r1457600, sis/branches/JDK6/sis-metadata/src/test/java/org/apache/sis/metadata/iso/
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/converter/
      - copied from r1457600, sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/converter/
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jdk7/
      - copied from r1457600, sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jdk7/
    sis/trunk/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java
    sis/trunk/sis-utility/src/main/resources/META-INF/
      - copied from r1457600, sis/branches/JDK6/sis-utility/src/main/resources/META-INF/
    sis/trunk/sis-utility/src/test/java/org/apache/sis/internal/converter/
      - copied from r1457600, sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/internal/converter/
    sis/trunk/sis-utility/src/test/java/org/apache/sis/test/PlatformDependentTest.java
      - copied unchanged from r1457600, sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/PlatformDependentTest.java
Removed:
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/JDK7.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Objects.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/SurjectiveConverter.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java
Modified:
    sis/trunk/   (props changed)
    sis/trunk/ide-project/NetBeans/build.xml
    sis/trunk/pom.xml
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyDescriptor.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/TypeValuePolicy.java
    sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java
    sis/trunk/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyDescriptorTest.java
    sis/trunk/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
    sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java
    sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
    sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
    sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java
    sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
    sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
    sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ImmutableEnvelope.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCases.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/LocalisedCharacterString.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/TextGroup.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmx/Anchor.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/io/Appender.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/math/Statistics.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/Range.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/About.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Classes.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Exceptions.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/ObjectConverter.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Utilities.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/UnmodifiableArrayList.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/WeakHashSet.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/WeakValueHashMap.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultInternationalString.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/iso/SimpleInternationalString.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
    sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/xml/XLink.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/io/TableAppenderTest.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/io/WordWrapTest.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/test/Assert.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/util/ClassesTest.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/util/NumbersTest.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTablesTest.java
    sis/trunk/sis-webapp/pom.xml
    sis/trunk/src/site/apt/index.apt

Propchange: sis/trunk/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1452375-1457583
  Merged /sis/branches/JDK6:r1452390-1457600

Modified: sis/trunk/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/trunk/ide-project/NetBeans/build.xml?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/ide-project/NetBeans/build.xml (original)
+++ sis/trunk/ide-project/NetBeans/build.xml Sun Mar 17 23:53:53 2013
@@ -24,9 +24,10 @@
     </copy>
 
     <!-- Following are classical properties resources files. -->
-    <copy todir="${build.classes.dir}/org/apache/sis/internal/util">
-      <fileset dir="${project.root}/sis-utility/src/main/resources/org/apache/sis/internal/util">
-        <include name="*.properties"/>
+    <copy todir="${build.classes.dir}">
+      <fileset dir="${project.root}/sis-utility/src/main/resources">
+        <include name="META-INF/services/*"/>
+        <include name="**/*.properties"/>
       </fileset>
     </copy>
   </target>

Modified: sis/trunk/pom.xml
URL: http://svn.apache.org/viewvc/sis/trunk/pom.xml?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/pom.xml (original)
+++ sis/trunk/pom.xml Sun Mar 17 23:53:53 2013
@@ -344,6 +344,7 @@ Apache SIS is a toolkit for describing l
               <Specification-Vendor>Open Geospatial Consortium</Specification-Vendor>
             </manifestEntries>
           </archive>
+          <skipIfEmpty>true</skipIfEmpty>
         </configuration>
         <executions>
           <execution>
@@ -598,9 +599,9 @@ Apache SIS is a toolkit for describing l
        ============================================================== -->
   <modules>
     <module>sis-build-helper</module>
-    <module>sis-referencing</module>
     <module>sis-utility</module>
     <module>sis-metadata</module>
+    <module>sis-referencing</module>
     <module>sis-webapp</module>
     <module>sis-app</module>
   </modules>

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -16,34 +16,52 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Map;
 import java.util.logging.Logger;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.LenientComparable;
+import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.logging.Logging;
 
+import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+
 
 /**
- * Base class for metadata implementations, providing basic operations using Java reflection.
- * All {@code AbstractMetadata} instances shall be associated to a {@link MetadataStandard},
- * which is provided by subclasses in the {@link #getStandard()} method. There is typically
- * a large number of {@code AbstractMetadata} subclasses (not necessarily as direct children)
- * for the same standard.
+ * Provides basic operations using Java reflection for metadata implementations.
+ * All {@code AbstractMetadata} instances shall be associated to a {@link MetadataStandard}.
+ * The metadata standard is given by the {@link #getStandard()} method and is typically a
+ * constant fixed by the subclass.
  *
- * <p>This base class reduces the effort required to implement metadata interface by providing
+ * <p>There is a large number of {@code AbstractMetadata} subclasses (not necessarily as direct children)
+ * for the same standard, where each subclass implement one Java interface defined by the metadata standard.
+ * This base class reduces the effort required to implement those metadata interfaces by providing
  * {@link #equals(Object)}, {@link #hashCode()} and {@link #toString()} implementations.
  * Those methods are implemented using Java reflection for invoking the getter methods
  * defined by the {@code MetadataStandard}.</p>
  *
- * <p>{@code AbstractMetadata} may be read-only or read/write, at implementation choice.
- * The {@link ModifiableMetadata} subclass provides the basis of most SIS metadata classes
- * having writing capabilities.</p>
- *
- * {@section Synchronization}
- * The methods in this class are not synchronized. Synchronizations may be done by getter and
- * setter methods in subclasses, at implementation choice. We never synchronize the methods that
- * perform deep traversal of the metadata tree (like {@code equals(Object)}, {@code hashCode()}
- * or {@code toString()}) because such synchronizations are deadlock prone. For example if
- * subclasses synchronize their getter methods, then many locks may be acquired in various orders.
+ * {@note This class does not synchronize the methods that perform deep traversal of the metadata tree
+ * (like <code>equals(Object)</code>, <code>hashCode()</code> or <code>toString()</code>) because such
+ * synchronizations are deadlock prone. For example if subclasses synchronize their getter methods,
+ * then many locks may be acquired in various orders.}
+ *
+ * {@code AbstractMetadata} subclasses may be read-only or read/write, at implementation choice.
+ * The methods that modify the metadata may throw {@link UnmodifiableMetadataException} if the
+ * metadata does not support the operation. Those methods are:
+ *
+ * <ul>
+ *   <li>{@link #prune()}</li>
+ *   <li>{@link #shallowCopy(Object)}</li>
+ *   <li>{@link #asMap()} with {@code put} operations</li>
+ * </ul>
+ *
+ * Read-only operations operating on metadata values are:
+ *
+ * <ul>
+ *   <li>{@link #isEmpty()}</li>
+ *   <li>{@link #asMap()} with {@code get} operations</li>
+ *   <li>{@link #asTreeTable()}</li>
+ *   <li>{@link #equals(Object, ComparisonMode)}</li>
+ * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
@@ -57,6 +75,13 @@ public abstract class AbstractMetadata i
     protected static final Logger LOGGER = Logging.getLogger(AbstractMetadata.class);
 
     /**
+     * A view of this metadata as a map. Will be created only when first needed.
+     *
+     * @see #asMap()
+     */
+    private transient Map<String,Object> asMap;
+
+    /**
      * Creates an initially empty metadata.
      */
     protected AbstractMetadata() {
@@ -64,15 +89,12 @@ public abstract class AbstractMetadata i
 
     /**
      * Returns the metadata standard implemented by subclasses.
+     * Subclasses will typically return a hard-coded constant such as
+     * {@link MetadataStandard#ISO_19115}.
      *
      * @return The metadata standard implemented.
-     *
-     * @todo This method returns {@link MetadataStandard#ISO_19115} for now,
-     *       but will become an abstract method soon.
      */
-    public MetadataStandard getStandard() {
-        return MetadataStandard.ISO_19115;
-    }
+    public abstract MetadataStandard getStandard();
 
     /**
      * Returns the metadata interface implemented by this class. It should be one of the
@@ -89,6 +111,105 @@ public abstract class AbstractMetadata i
     }
 
     /**
+     * Returns {@code true} if this metadata contains only {@code null} or empty properties.
+     * A property is considered empty in any of the following cases:
+     *
+     * <ul>
+     *   <li>An empty {@linkplain CharSequence character sequences}.</li>
+     *   <li>An {@linkplain java.util.Collection#isEmpty() empty collection} or an empty array.</li>
+     *   <li>A collection or array containing only {@code null} or empty elements.</li>
+     *   <li>An other metadata object containing only {@code null} or empty attributes.</li>
+     * </ul>
+     *
+     * Note that empty properties can be removed by calling the {@link ModifiableMetadata#prune()}
+     * method.
+     *
+     * {@section Note for implementors}
+     * The default implementation uses Java reflection indirectly, by iterating over all entries
+     * returned by {@link MetadataStandard#asMap(Object, KeyNamePolicy, ValueExistencePolicy)}.
+     * Subclasses that override this method should usually not invoke {@code super.isEmpty()},
+     * because the Java reflection will discover and process the properties defined in the
+     * subclasses - which is usually not the intend when overriding a method.
+     *
+     * @return {@code true} if this metadata is empty.
+     *
+     * @see org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#isEmpty()
+     */
+    public boolean isEmpty() {
+        return Pruner.isEmpty(this, false);
+    }
+
+    /**
+     * Removes all references to empty properties. The default implementation iterates over all
+     * {@linkplain ValueExistencePolicy#NON_NULL non null} properties, and sets to {@code null}
+     * the properties for which {@link #isEmpty()} returned {@code true}.
+     *
+     * @throws UnmodifiableMetadataException If this metadata is not modifiable.
+     */
+    public void prune() {
+        Pruner.isEmpty(this, true);
+    }
+
+    /**
+     * Copies the values from the specified metadata. The {@code source} metadata must implements
+     * the same metadata interface (defined by the {@linkplain #getStandard() standard}) than this
+     * class, but doesn't need to be the same implementation class.
+     * The default implementation performs the copy using Java reflections.
+     *
+     * {@note This method is intended to provide the functionality of a <cite>copy constructor</cite>.
+     * We do not provide copy constructor directly because usage of Java reflection in this context
+     * is unsafe (we could invoke subclass methods before the subclasses construction is completed).}
+     *
+     * @param  source The metadata to copy values from.
+     * @throws ClassCastException if the specified metadata doesn't implements the expected
+     *         metadata interface.
+     * @throws UnmodifiableMetadataException if this class doesn't define {@code set*(…)} methods
+     *         corresponding to the {@code get*()} methods found in the implemented interface, or
+     *         if this instance is not modifiable for some other reason.
+     */
+    public void shallowCopy(final Object source) throws ClassCastException, UnmodifiableMetadataException {
+        ensureNonNull("source", source);
+        getStandard().shallowCopy(source, this);
+    }
+
+    /**
+     * Returns a view of the property values in a {@link Map}. The map is backed by this metadata
+     * object, so changes in the underlying metadata object are immediately reflected in the map
+     * and conversely.
+     *
+     * <p>The map supports the {@link Map#put(Object, Object) put(…)} and {@link Map#remove(Object)
+     * remove(…)} operations if the underlying metadata object contains setter methods.
+     * The keys are case-insensitive and can be either the JavaBeans property name or
+     * the UML identifier.</p>
+     *
+     * <p>The default implementation is equivalent to the following method call:</p>
+     * {@preformat java
+     *   return getStandard().asMap(this, KeyNamePolicy.JAVABEANS_PROPERTY, ValueExistencePolicy.NON_EMPTY);
+     * }
+     *
+     * @return A view of this metadata object as a map.
+     *
+     * @see MetadataStandard#asMap(Object, KeyNamePolicy, ValueExistencePolicy)
+     */
+    public synchronized Map<String,Object> asMap() {
+        if (asMap == null) {
+            asMap = getStandard().asMap(this, KeyNamePolicy.JAVABEANS_PROPERTY, ValueExistencePolicy.NON_EMPTY);
+        }
+        return asMap;
+    }
+
+    /**
+     * Returns the property types and values as a tree table.
+     * In the current implementation, the tree is not live (i.e. changes in metadata are not
+     * reflected in the tree). However it may be improved in a future SIS implementation.
+     *
+     * @return The property types and values as a tree table.
+     */
+    public TreeTable asTreeTable() {
+        return getStandard().asTreeTable(this);
+    }
+
+    /**
      * Compares this metadata with the specified object for equality. The default
      * implementation uses Java reflection. Subclasses may override this method
      * for better performances, or for comparing "hidden" properties not specified
@@ -158,10 +279,9 @@ public abstract class AbstractMetadata i
      * similar contract than {@link java.util.Set#hashCode()} and ensures that the hash code
      * value is insensitive to the ordering of properties.
      *
-     * {@section Performance note}
-     * This method does not cache the value because current implementation has no notification
-     * mechanism for tracking changes in children properties. If this metadata is known to be
-     * immutable, then subclasses may consider caching the hash code value at their choice.
+     * {@note This method does not cache the value because current implementation has no notification
+     *        mechanism for tracking changes in children properties. If this metadata is known to be
+     *        immutable, then subclasses may consider caching the hash code value at their choice.}
      *
      * @see MetadataStandard#hashCode(Object)
      */
@@ -169,4 +289,20 @@ public abstract class AbstractMetadata i
     public int hashCode() {
         return getStandard().hashCode(this);
     }
+
+    /**
+     * Returns a string representation of this metadata.
+     * The default implementation is as below:
+     *
+     * {@preformat java
+     *     return asTreeTable().toString();
+     * }
+     *
+     * Note that this make extensive use of Unicode characters
+     * and is better rendered with a monospaced font.
+     */
+    @Override
+    public String toString() {
+        return asTreeTable().toString();
+    }
 }

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -27,6 +27,7 @@ import org.opengis.metadata.citation.Cit
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.internal.util.SystemListener;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -419,6 +420,56 @@ public class MetadataStandard {
     }
 
     /**
+     * Returns a view of the specified metadata object as a {@link Map}.
+     * The map is backed by the metadata object using Java reflection, so changes in the
+     * underlying metadata object are immediately reflected in the map and conversely.
+     *
+     * <p>The map content is determined by the arguments: {@code metadata} determines the set of
+     * keys, {@code keyPolicy} determines their {@code String} representations of those keys and
+     * {@code valuePolicy} determines whether entries having a null value or an empty collection
+     * shall be included in the map.</p>
+     *
+     * <p>The map supports the {@link Map#put(Object, Object) put(…)} and {@link Map#remove(Object)
+     * remove(…)} operations if the underlying metadata object contains setter methods.
+     * The keys are case-insensitive and can be either the JavaBeans property name or
+     * the UML identifier.</p>
+     *
+     * @param  metadata The metadata object to view as a map.
+     * @param  keyPolicy Determines the string representation of map keys.
+     * @param  valuePolicy Whether the entries having null value or empty collection shall be
+     *         included in the map.
+     * @return A map view over the metadata object.
+     * @throws ClassCastException if the metadata object doesn't implement a metadata
+     *         interface of the expected package.
+     *
+     * @see AbstractMetadata#asMap()
+     */
+    public Map<String,Object> asMap(final Object metadata, final KeyNamePolicy keyPolicy,
+            final ValueExistencePolicy valuePolicy) throws ClassCastException
+    {
+        ensureNonNull("metadata",    metadata);
+        ensureNonNull("keyPolicy",   keyPolicy);
+        ensureNonNull("valuePolicy", valuePolicy);
+        return new PropertyMap(metadata, getAccessor(metadata.getClass(), true), keyPolicy, valuePolicy);
+    }
+
+    /**
+     * Returns the specified metadata object as a tree table.
+     * In the current implementation, the tree is not live (i.e. changes in metadata are not
+     * reflected in the tree). However it may be improved in a future SIS implementation.
+     *
+     * @param  metadata The metadata object to formats as a tree table.
+     * @return A tree table representation of the specified metadata.
+     * @throws ClassCastException if the metadata object doesn't implement a metadata
+     *         interface of the expected package.
+     *
+     * @see AbstractMetadata#asTreeTable()
+     */
+    public TreeTable asTreeTable(final Object metadata) throws ClassCastException {
+        throw new UnsupportedOperationException("Not yet implemented"); // TODO
+    }
+
+    /**
      * Replaces every properties in the specified metadata by their
      * {@linkplain ModifiableMetadata#unmodifiable() unmodifiable variant}.
      *

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -35,13 +35,9 @@ import static org.apache.sis.util.collec
 
 
 /**
- * Base class for metadata that may (or may not) be modifiable. Implementations will typically
- * provide {@code set*(...)} methods for each corresponding {@code get*()} method. An initially
- * modifiable metadata may become unmodifiable at a later stage (typically after its construction
- * is completed) by the call to the {@link #freeze()} method.
- *
- * {@section Guidline for implementors}
- * Subclasses should follow the pattern below for every {@code get} and {@code set} methods,
+ * Provides convenience methods for support of modifiable properties in metadata implementations.
+ * Implementations typically provide {@code set*(…)} methods for each corresponding {@code get*()}
+ * method. Subclasses can follow the pattern below for every {@code get} and {@code set} methods,
  * with a different processing for singleton value or for {@linkplain Collection collections}.
  *
  * <p>For singleton value:</p>
@@ -77,6 +73,10 @@ import static org.apache.sis.util.collec
  *     }
  * }
  *
+ * An initially modifiable metadata may become unmodifiable at a later stage
+ * (typically after its construction is completed) by the call to the
+ * {@link #freeze()} method.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.1)
  * @version 0.3
@@ -600,15 +600,13 @@ public abstract class ModifiableMetadata
 
     /**
      * Returns a shallow copy of this metadata.
-     *
-     * {@section Usage}
-     * While {@linkplain Cloneable cloneable}, this class do not provides the {@code clone()}
+     * While {@linkplain Cloneable cloneable}, this class does not provides the {@code clone()}
      * operation as part of the public API. The clone operation is required for the internal
-     * working of the {@link #unmodifiable()} method, which needs <strong>shallow</strong>
+     * working of the {@link #unmodifiable()} method, which needs <em>shallow</em>
      * copies of metadata entities. The default {@link Object#clone()} implementation is
      * sufficient in most cases.
      *
-     * @return A <strong>shallow</strong> copy of this metadata.
+     * @return A <em>shallow</em> copy of this metadata.
      * @throws CloneNotSupportedException if the clone is not supported.
      */
     @Override

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -264,11 +264,11 @@ final class PropertyAccessor {
             Method getter  = getters[i];
             String name    = getter.getName();
             final int base = prefix(name).length();
-            addMapping(names[i] = toPropertyName(name, base), index);
             addMapping(name, index);
+            addMappingWithLowerCase(names[i] = toPropertyName(name, base), index);
             final UML annotation = getter.getAnnotation(UML.class);
             if (annotation != null) {
-                addMapping(annotation.identifier(), index);
+                addMappingWithLowerCase(annotation.identifier().intern(), index);
             }
             /*
              * Now try to infer the setter from the getter. We replace the "get" prefix by
@@ -277,12 +277,12 @@ final class PropertyAccessor {
             Class<?> returnType = getter.getReturnType();
             arguments[0] = returnType;
             if (name.length() > base) {
-                final char lo = name.charAt(base);
-                final char up = Character.toUpperCase(lo);
+                final int lo = name.codePointAt(base);
+                final int up = Character.toUpperCase(lo);
                 final int length = name.length();
-                final StringBuilder buffer = new StringBuilder(length - base + 3).append(SET);
+                final StringBuilder buffer = new StringBuilder(length - base + 5).append(SET);
                 if (lo != up) {
-                    buffer.append(up).append(name, base+1, length);
+                    buffer.appendCodePoint(up).append(name, base + Character.charCount(lo), length);
                 } else {
                     buffer.append(name, base, length);
                 }
@@ -349,18 +349,24 @@ final class PropertyAccessor {
      * Adds the given (name, index) pair to {@link #mapping}, making sure we don't
      * overwrite an existing entry with different value.
      */
-    private void addMapping(String name, final Integer index) throws IllegalArgumentException {
+    private void addMapping(final String name, final Integer index) {
         if (!name.isEmpty()) {
-            String original;
-            do {
-                final Integer old = mapping.put(name, index);
-                if (old != null && !old.equals(index)) {
-                    throw new IllegalStateException(Errors.format(Errors.Keys.DuplicatedValue_1,
-                            Classes.getShortName(type) + '.' + name));
-                }
-                original = name;
-                name = CharSequences.trimWhitespaces(name.toLowerCase(Locale.ROOT));
-            } while (!name.equals(original));
+            final Integer old = mapping.put(name, index);
+            if (old != null && !old.equals(index)) {
+                throw new IllegalStateException(Errors.format(Errors.Keys.DuplicatedValue_1,
+                        Classes.getShortName(type) + '.' + name));
+            }
+        }
+    }
+
+    /**
+     * Adds the given (name, index) pair and its lower-case variant.
+     */
+    private void addMappingWithLowerCase(final String name, final Integer index) {
+        addMapping(name, index);
+        final String lower = name.toLowerCase(Locale.ROOT);
+        if (lower != name) { // Identity comparison is okay here.
+            addMapping(lower, index);
         }
     }
 
@@ -494,7 +500,7 @@ final class PropertyAccessor {
                 }
             }
         }
-        return CharSequences.trimWhitespaces(name).intern();
+        return name.intern();
     }
 
     /**
@@ -534,30 +540,17 @@ final class PropertyAccessor {
     }
 
     /**
-     * Returns the declaring class of the getter at the given index.
-     *
-     * @param  index The index of the property for which to get the declaring class.
-     * @return The declaring class at the given index, or {@code null} if the index is out of bounds.
-     */
-    final Class<?> getDeclaringClass(final int index) {
-        if (index >= 0 && index < names.length) {
-            return getters[index].getDeclaringClass();
-        }
-        return null;
-    }
-
-    /**
      * Returns the name of the property at the given index, or {@code null} if none.
      *
      * @param  index The index of the property for which to get the name.
-     * @param  keyName The kind of name to return.
+     * @param  keyPolicy The kind of name to return.
      * @return The name of the given kind at the given index,
      *         or {@code null} if the index is out of bounds.
      */
     @SuppressWarnings("fallthrough")
-    final String name(final int index, final KeyNamePolicy keyName) {
+    final String name(final int index, final KeyNamePolicy keyPolicy) {
         if (index >= 0 && index < names.length) {
-            switch (keyName) {
+            switch (keyPolicy) {
                 case UML_IDENTIFIER: {
                     final UML uml = getters[index].getAnnotation(UML.class);
                     if (uml != null) {
@@ -667,15 +660,14 @@ final class PropertyAccessor {
     }
 
     /**
-     * Returns {@code true} if the property at the given index is writable.
-     */
-    final boolean isWritable(final int index) {
-        return (index >= 0) && (index < standardCount) && (setters != null) && (setters[index] != null);
-    }
-
-    /**
      * Returns the value for the specified metadata, or {@code null} if none.
+     * If the given index is out of bounds, then this method returns {@code null},
+     * so it is safe to invoke this method even if {@link #indexOf(String, boolean)}
+     * returned -1.
      *
+     * @param  index The index of the property for which to get a value.
+     * @param  metadata The metadata object to query.
+     * @return The value, or {@code null} if none or if the given is out of bounds.
      * @throws BackingStoreException If the implementation threw a checked exception.
      */
     final Object get(final int index, final Object metadata) throws BackingStoreException {
@@ -719,6 +711,12 @@ final class PropertyAccessor {
      * a new collection or map before the new value is set, because the setter methods typically
      * copy the new collection in their existing instance.
      *
+     * <p>If the given index is out of bounds, then this method does nothing and return {@code null}.
+     * We do that because the {@link PropertyMap#remove(Object)} method may invoke this method with
+     * an index of -1 if the {@link #indexOf(String, boolean)} method didn't found the property name.
+     * However the given value will be silently discarded, so index out-of-bounds shall be used only
+     * in the context of {@code remove} operations (this is not verified).</p>
+     *
      * @param  index    The index of the property to set.
      * @param  metadata The metadata object on which to set the value.
      * @param  value    The new value.
@@ -731,7 +729,10 @@ final class PropertyAccessor {
     final Object set(final int index, final Object metadata, final Object value, final boolean getOld)
             throws UnmodifiableMetadataException, ClassCastException, BackingStoreException
     {
-        if (index >= 0 && index < standardCount && setters != null) {
+        if (index < 0 || index >= standardCount) {
+            return null;
+        }
+        if (setters != null) {
             final Method getter = getters[index];
             final Method setter = setters[index];
             if (setter != null) {
@@ -1031,7 +1032,7 @@ final class PropertyAccessor {
 
     /**
      * Replaces every properties in the specified metadata by their
-     * {@linkplain ModifiableMetadata#unmodifiable unmodifiable variant}.
+     * {@linkplain ModifiableMetadata#unmodifiable() unmodifiable variant}.
      *
      * @throws BackingStoreException If the implementation threw a checked exception.
      */
@@ -1088,6 +1089,7 @@ final class PropertyAccessor {
     /**
      * Counts the number of non-empty properties.
      *
+     * @param  max Stop the count if we reach that value.
      * @throws BackingStoreException If the implementation threw a checked exception.
      */
     public int count(final Object metadata, final int max) throws BackingStoreException {

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -26,7 +26,7 @@ import org.opengis.annotation.Obligation
 
 /**
  * The comparator for sorting method order. This comparator puts mandatory methods first,
- * which is necessary for reducing the risk of ambiguity in {@link PropertyTree#parse}.
+ * which is necessary for reducing the risk of ambiguity in {@link MetadataTreeFormat#parse}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyDescriptor.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyDescriptor.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyDescriptor.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyDescriptor.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -35,7 +35,7 @@ import org.apache.sis.measure.ValueRange
 import org.apache.sis.util.iso.Types;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/TypeValuePolicy.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/TypeValuePolicy.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/TypeValuePolicy.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/TypeValuePolicy.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -18,9 +18,9 @@ package org.apache.sis.metadata;
 
 
 /**
- * Whatever {@link MetadataStandard#asTypeMap MetadataStandard.asTypeMap(…)} shall return values
- * for the property types, the element types (same as property types except for collections) or
- * the declaring classes.
+ * The kind of values in the {@link MetadataStandard#asTypeMap MetadataStandard.asTypeMap(…)}.
+ * This enumeration specifies whether the values shall be property types, element types (same
+ * as property types except for collections) or the declaring classes.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.03)

Modified: sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -18,7 +18,6 @@ package org.apache.sis.metadata.iso.cita
 
 import java.util.Date;
 import java.util.Collection;
-
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.citation.CitationDate;
@@ -26,8 +25,7 @@ import org.opengis.metadata.citation.Pre
 import org.opengis.metadata.citation.ResponsibleParty;
 import org.opengis.metadata.citation.Series;
 import org.opengis.util.InternationalString;
-
-import org.apache.sis.metadata.ModifiableMetadata;
+import org.apache.sis.metadata.iso.ISOMetadata;
 
 
 /**
@@ -39,7 +37,7 @@ import org.apache.sis.metadata.Modifiabl
  * @version 0.3
  * @module
  */
-public class DefaultCitation extends ModifiableMetadata implements Citation {
+public class DefaultCitation extends ISOMetadata implements Citation {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -204,7 +202,7 @@ public class DefaultCitation extends Mod
      */
     @Override
     public Collection<Identifier> getIdentifiers() {
-        return null; // Not yet implemented on intend.
+        return java.util.Collections.emptyList(); // TODO: Not yet implemented on intend.
     }
 
     /**

Modified: sis/trunk/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyDescriptorTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyDescriptorTest.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyDescriptorTest.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyDescriptorTest.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -18,9 +18,10 @@ package org.apache.sis.metadata;
 
 import java.util.Locale;
 import org.opengis.util.InternationalString;
+import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.citation.PresentationForm;
-import org.apache.sis.internal.simple.SimpleCitation;
+import org.apache.sis.metadata.iso.citation.HardCodedCitations;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -47,7 +48,7 @@ public final strictfp class PropertyDesc
     private static <T> PropertyDescriptor<T> create(final Class<T> elementType, final String method,
             final String property) throws NoSuchMethodException
     {
-        return new PropertyDescriptor<T>(elementType, new SimpleCitation("ISO 19115"), property,
+        return new PropertyDescriptor<T>(elementType, HardCodedCitations.ISO_19115, property,
                 Citation.class.getMethod(method));
     }
 
@@ -59,10 +60,17 @@ public final strictfp class PropertyDesc
      */
     @Test
     public void testTitle() throws NoSuchMethodException {
-        final PropertyDescriptor<?> descriptor = create(InternationalString.class, "getTitle", "title");
+        validateTitle(create(InternationalString.class, "getTitle", "title"));
+    }
+
+    /**
+     * Validates a descriptor for {@link Citation#getTitle()}.
+     * This is validation code to be shared with {@link PropertyAccessorTest#testDescriptor()}.
+     */
+    static void validateTitle(final ParameterDescriptor<?> descriptor) {
         assertEquals("ISO 19115",   descriptor.getName().getAuthority().getTitle().toString());
-        assertEquals("CI_Citation", descriptor.getCodeSpace());
-        assertEquals("title",       descriptor.getCode());
+        assertEquals("CI_Citation", descriptor.getName().getCodeSpace());
+        assertEquals("title",       descriptor.getName().getCode());
         final InternationalString remarks = descriptor.getRemarks();
         assertEquals("Name by which the cited resource is known.", remarks.toString(Locale.ENGLISH));
         // Test other locale here, if any.
@@ -80,10 +88,17 @@ public final strictfp class PropertyDesc
      */
     @Test
     public void testPresentationForm() throws NoSuchMethodException {
-        final PropertyDescriptor<?> descriptor = create(PresentationForm.class, "getPresentationForms", "presentationForm");
+        validatePresentationForm(create(PresentationForm.class, "getPresentationForms", "presentationForm"));
+    }
+
+    /**
+     * Validates a descriptor for {@link Citation#getPresentationForms()}.
+     * This is validation code to be shared with {@link PropertyAccessorTest#testDescriptor()}.
+     */
+    static void validatePresentationForm(final ParameterDescriptor<?> descriptor) {
         assertEquals("ISO 19115",        descriptor.getName().getAuthority().getTitle().toString());
-        assertEquals("CI_Citation",      descriptor.getCodeSpace());
-        assertEquals("presentationForm", descriptor.getCode());
+        assertEquals("CI_Citation",      descriptor.getName().getCodeSpace());
+        assertEquals("presentationForm", descriptor.getName().getCode());
         final InternationalString remarks = descriptor.getRemarks();
         assertEquals("Mode in which the resource is represented.", remarks.toString(Locale.ENGLISH));
         // Test other locale here, if any.

Modified: sis/trunk/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/trunk/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -29,7 +29,8 @@ import org.junit.runners.Suite;
  * @module
  */
 @Suite.SuiteClasses({
-    org.apache.sis.metadata.PropertyDescriptorTest.class
+    org.apache.sis.metadata.PropertyDescriptorTest.class,
+    org.apache.sis.metadata.PropertyAccessorTest.class
 })
 public final strictfp class MetadataTestSuite extends TestSuite {
 }

Modified: sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java [UTF-8] (original)
+++ sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -38,7 +38,7 @@ import static org.apache.sis.util.String
 import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] (original)
+++ sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -45,7 +45,7 @@ import static org.apache.sis.math.MathFu
 import static org.apache.sis.math.MathFunctions.isPositive;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**
@@ -937,7 +937,7 @@ public abstract class AbstractEnvelope i
      * @param  isSimplePrecision {@code true} if every lower and upper corner values can be casted to {@code float}.
      * @return The envelope as a {@code BOX2D} or {@code BOX3D} (most typical dimensions) in WKT format.
      *
-     * @see GeneralEnvelope#GeneralEnvelope(String)
+     * @see GeneralEnvelope#GeneralEnvelope(CharSequence)
      * @see org.apache.sis.measure.CoordinateFormat
      * @see org.apache.sis.io.wkt
      */

Modified: sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java [UTF-8] (original)
+++ sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -40,7 +40,7 @@ import static org.apache.sis.math.MathFu
 import static org.apache.sis.internal.referencing.Utilities.isPoleToPole;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**
@@ -194,7 +194,7 @@ class ArrayEnvelope extends AbstractEnve
      * }
      *
      * However this constructor is lenient to other geometry types like {@code POLYGON}.
-     * See the javadoc of the {@link GeneralEnvelope#GeneralEnvelope(String) GeneralEnvelope}
+     * See the javadoc of the {@link GeneralEnvelope#GeneralEnvelope(CharSequence) GeneralEnvelope}
      * constructor for more information.
      *
      * @param  wkt The {@code BOX}, {@code POLYGON} or other kind of element to parse.

Modified: sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java [UTF-8] (original)
+++ sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -28,7 +28,7 @@ import static org.apache.sis.util.Argume
 import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] (original)
+++ sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -49,7 +49,7 @@ import static org.apache.sis.geometry.Ab
 import static org.apache.sis.geometry.AbstractEnvelope.isNegativeUnsafe;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] (original)
+++ sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -32,7 +32,7 @@ import org.apache.sis.util.resources.Err
 import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches;
 
 // JDK7 related
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ImmutableEnvelope.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ImmutableEnvelope.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ImmutableEnvelope.java [UTF-8] (original)
+++ sis/trunk/sis-referencing/src/main/java/org/apache/sis/geometry/ImmutableEnvelope.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -138,7 +138,7 @@ public final class ImmutableEnvelope ext
      * }
      *
      * However this constructor is lenient to other geometry types like {@code POLYGON}.
-     * See the javadoc of the {@link GeneralEnvelope#GeneralEnvelope(String) GeneralEnvelope}
+     * See the javadoc of the {@link GeneralEnvelope#GeneralEnvelope(CharSequence) GeneralEnvelope}
      * constructor for more information.
      *
      * @param  wkt The {@code BOX}, {@code POLYGON} or other kind of element to parse.

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -34,7 +34,7 @@ import org.apache.sis.xml.IdentifierSpac
 import static org.apache.sis.util.collection.CollectionsExt.hashMapCapacity;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCases.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCases.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCases.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapWithSpecialCases.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -25,7 +25,7 @@ import org.apache.sis.xml.IdentifierSpac
 import org.apache.sis.xml.XLink;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -29,7 +29,7 @@ import org.apache.sis.util.logging.Loggi
 import org.apache.sis.internal.util.Citations;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/LocalisedCharacterString.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/LocalisedCharacterString.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/LocalisedCharacterString.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/LocalisedCharacterString.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -22,7 +22,7 @@ import javax.xml.bind.annotation.XmlAttr
 import org.apache.sis.internal.jaxb.MarshalContext;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/TextGroup.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/TextGroup.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/TextGroup.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/TextGroup.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -20,7 +20,7 @@ import java.util.Locale;
 import javax.xml.bind.annotation.XmlElement;
 
 // Related to JDK7
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmx/Anchor.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmx/Anchor.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmx/Anchor.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmx/Anchor.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -24,7 +24,7 @@ import org.opengis.util.InternationalStr
 import org.apache.sis.xml.XLink;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -31,7 +31,7 @@ import org.opengis.util.InternationalStr
 import org.apache.sis.util.iso.SimpleInternationalString;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -27,7 +27,7 @@ import org.apache.sis.util.Classes;
 import static org.apache.sis.util.iso.DefaultNameSpace.DEFAULT_SEPARATOR;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.util;
 
+import org.apache.sis.internal.jdk7.Objects;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/io/Appender.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/io/Appender.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/io/Appender.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/io/Appender.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -24,7 +24,7 @@ import org.apache.sis.util.ArgumentCheck
 import static org.apache.sis.util.Characters.isLineOrParagraphSeparator;
 
 // Related to JDK7
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -387,6 +387,8 @@ public abstract class CompoundFormat<T> 
             return format;
         } else if (valueType == Angle.class) {
             return AngleFormat.getInstance(locale);
+        } else if (valueType == Class.class) {
+            return ClassFormat.INSTANCE;
         }
         return null;
     }

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -20,8 +20,10 @@ import java.text.Format;
 import java.text.FieldPosition;
 import java.text.ParsePosition;
 import java.text.ParseException;
+import java.io.InvalidObjectException;
 import net.jcip.annotations.ThreadSafe;
 import org.apache.sis.util.Numbers;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.internal.util.LocalizedParseException;
 
 
@@ -45,6 +47,7 @@ final class DefaultFormat extends Format
 
     /**
      * The array for storing singleton instances for types {@code byte} to {@code double}.
+     * The value at index 0 is reserved for the generic {@link Number} type.
      */
     private static final Format[] INSTANCES = new Format[Numbers.DOUBLE - Numbers.BYTE + 2];
 
@@ -104,7 +107,8 @@ final class DefaultFormat extends Format
      * Parses the given string as a number of the type given at construction time.
      */
     @Override
-    public Object parseObject(final String source) throws ParseException {
+    public Object parseObject(String source) throws ParseException {
+        source = CharSequences.trimWhitespaces(source);
         try {
             return valueOf(source);
         } catch (NumberFormatException cause) {
@@ -119,8 +123,9 @@ final class DefaultFormat extends Format
      */
     @Override
     public Object parseObject(String source, final ParsePosition pos) {
-        final int index = pos.getIndex();
-        source = source.substring(index);
+        final int length = source.length();
+        final int index = CharSequences.skipLeadingWhitespaces(source, pos.getIndex(), length);
+        source = source.substring(index, CharSequences.skipTrailingWhitespaces(source, index, length));
         try {
             return valueOf(source);
         } catch (NumberFormatException cause) {
@@ -128,4 +133,12 @@ final class DefaultFormat extends Format
             return null;
         }
     }
+
+    /**
+     * Resolves to the singleton instance on deserialization.
+     */
+    private Object readResolve() throws InvalidObjectException {
+        final Format format = getInstance(type);
+        return (format != null) ? format : this;
+    }
 }

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -25,7 +25,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.internal.util.X364;
 
 // Related to JK7
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -31,7 +31,7 @@ import org.apache.sis.internal.util.X364
 import static org.apache.sis.util.Characters.isLineOrParagraphSeparator;
 
 // Related to JK7
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -27,7 +27,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.resources.Errors;
 
 // Related to JK7
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/math/Statistics.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/math/Statistics.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/math/Statistics.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/math/Statistics.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -27,7 +27,7 @@ import static java.lang.Double.isNaN;
 import static java.lang.Double.doubleToLongBits;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -44,7 +44,7 @@ import static org.apache.sis.math.MathFu
 import static org.apache.sis.math.MathFunctions.fractionDigitsForDelta;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -27,7 +27,7 @@ import java.text.Format;
 import java.text.AttributedCharacterIterator;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.collection.CollectionsExt;
-import org.apache.sis.internal.util.SurjectiveConverter;
+import org.apache.sis.internal.converter.SurjectiveConverter;
 import org.apache.sis.internal.simple.SimpleCharacterIterator;
 
 

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -24,7 +24,7 @@ import org.apache.sis.util.Numbers;
 import org.apache.sis.util.resources.Errors;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/Range.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/Range.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/Range.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/measure/Range.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -24,7 +24,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.Numbers;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/About.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/About.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/About.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/About.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -52,7 +52,7 @@ import static org.apache.sis.util.collec
 import static org.apache.sis.util.collection.TableColumn.VALUE_AS_TEXT;
 
 // JDK7 related
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -21,7 +21,7 @@ import java.util.Comparator;
 import java.lang.reflect.Array;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -23,8 +23,8 @@ import static java.lang.Character.*;
 import static org.apache.sis.util.StringBuilders.replace;
 
 // Related to JDK7
-import static org.apache.sis.internal.util.JDK7.lowSurrogate;
-import static org.apache.sis.internal.util.JDK7.highSurrogate;
+import static org.apache.sis.internal.jdk7.JDK7.lowSurrogate;
+import static org.apache.sis.internal.jdk7.JDK7.highSurrogate;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Classes.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Classes.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -225,32 +225,6 @@ public final class Classes extends Stati
     }
 
     /**
-     * Casts the {@code type} class to represent a subclass of the class represented by the
-     * {@code sub} argument. Checks that the cast is valid, and returns {@code null} if it
-     * is not.
-     *
-     * <p>This method performs the same work than
-     * <code>type.{@linkplain Class#asSubclass(Class) asSubclass}(sub)</code>,
-     * except that {@code null} is returned instead than throwing an exception
-     * if the cast is not valid or if any of the argument is {@code null}.</p>
-     *
-     * @param  <U>  The compile-time bounds of the {@code sub} argument.
-     * @param  type The class to cast to a sub-class, or {@code null}.
-     * @param  sub  The subclass to cast to, or {@code null}.
-     * @return The {@code type} argument casted to a subclass of the {@code sub} argument,
-     *         or {@code null} if this cast can not be performed.
-     *
-     * @see Class#asSubclass(Class)
-     */
-    @SuppressWarnings({"unchecked","rawtypes"})
-    public static <U> Class<? extends U> asSubclassOrNull(final Class<?> type, final Class<U> sub) {
-        // Design note: We are required to return null if 'sub' is null (not to return 'type'
-        // unchanged), because if we returned 'type', we would have an unsafe cast if this
-        // method is invoked indirectly from a parameterized method.
-        return (type != null && sub != null && sub.isAssignableFrom(type)) ? (Class) type : null;
-    }
-
-    /**
      * Returns the class of the specified object, or {@code null} if {@code object} is null.
      * This method is also useful for fetching the class of an object known only by its bound
      * type. As of Java 6, the usual pattern:
@@ -267,6 +241,7 @@ public final class Classes extends Stati
      * @return The class of the given object, or {@code null} if the given object was null.
      */
     @SuppressWarnings("unchecked")
+    @Workaround(library="JDK", version="1.7")
     public static <T> Class<? extends T> getClass(final T object) {
         return (object != null) ? (Class<? extends T>) object.getClass() : null;
     }
@@ -282,7 +257,7 @@ public final class Classes extends Stati
      * @param  objects The collection of objects.
      * @return The set of classes of all objects in the given collection.
      */
-    public static <T> Set<Class<? extends T>> getClasses(final Collection<? extends T> objects) {
+    private static <T> Set<Class<? extends T>> getClasses(final Iterable<? extends T> objects) {
         final Set<Class<? extends T>> types = new LinkedHashSet<Class<? extends T>>();
         for (final T object : objects) {
             types.add(getClass(object));
@@ -291,23 +266,49 @@ public final class Classes extends Stati
     }
 
     /**
-     * Returns the set of every interfaces implemented by the given class or interface. This is
-     * similar to {@link Class#getInterfaces()} except that this method searches recursively in
-     * the super-interfaces. For example if the given type is {@link java.util.ArrayList}, then
+     * Returns every interfaces implemented, directly or indirectly, by the given class or interface.
+     * This is similar to {@link Class#getInterfaces()} except that this method searches recursively
+     * in the super-interfaces. For example if the given type is {@link java.util.ArrayList}, then
      * the returned set will contains {@link java.util.List} (which is implemented directly)
      * together with its parent interfaces {@link Collection} and {@link Iterable}.
      *
+     * @param  <T>  The compile-time type of the {@code Class} argument.
+     * @param  type The class or interface for which to get all implemented interfaces.
+     * @return All implemented interfaces (not including the given {@code type} if it was an
+     *         interface), or an empty array if none.
+     *
+     * @see Class#getInterfaces()
+     */
+    @SuppressWarnings({"unchecked","rawtypes"}) // Generic array creation.
+    public static <T> Class<? super T>[] getAllInterfaces(final Class<T> type) {
+        final Set<Class<?>> interfaces = getInterfaceSet(type);
+        return (interfaces != null) ? interfaces.toArray(new Class[interfaces.size()]) : EMPTY_ARRAY;
+    }
+
+    /**
+     * Implementation of {@link #getAllInterfaces(Class)} returning a {@link Set}.
+     * The public API exposes the method returning an array instead than a set for
+     * the following reasons:
+     *
+     * <ul>
+     *   <li>Consistency with other methods ({@link #getLeafInterfaces(Class, Class)},
+     *       {@link Class#getInterfaces()}).</li>
+     *   <li>Because arrays in Java are covariant, while the {@code Set} are not.
+     *       Consequently callers can cast {@code Class<? super T>[]} to {@code Class<?>[]}
+     *       while they can not cast {@code Set<Class<? super T>>} to {@code Set<Class<?>>}.</li>
+     * </ul>
+     *
      * @param  type The class or interface for which to get all implemented interfaces.
      * @return All implemented interfaces (not including the given {@code type} if it was an
-     *         interface), or an empty set if none. Callers can freely modify the returned set.
+     *         interface), or {@code null} if none. Callers can freely modify the returned set.
      */
-    public static Set<Class<?>> getAllInterfaces(Class<?> type) {
+    static Set<Class<?>> getInterfaceSet(Class<?> type) {
         Set<Class<?>> interfaces = null;
         while (type != null) {
-            interfaces = getAllInterfaces(type, interfaces);
+            interfaces = getInterfaceSet(type, interfaces);
             type = type.getSuperclass();
         }
-        return (interfaces != null) ? interfaces : Collections.<Class<?>>emptySet();
+        return interfaces;
     }
 
     /**
@@ -318,15 +319,15 @@ public final class Classes extends Stati
      * @return The given set (may be {@code null}), or a new set if the given set was null
      *         and at least one interface has been found.
      */
-    private static Set<Class<?>> getAllInterfaces(final Class<?> type, Set<Class<?>> addTo) {
+    private static Set<Class<?>> getInterfaceSet(final Class<?> type, Set<Class<?>> addTo) {
         final Class<?>[] interfaces = type.getInterfaces();
         for (int i=0; i<interfaces.length; i++) {
             final Class<?> candidate = interfaces[i];
             if (addTo == null) {
-                addTo = new LinkedHashSet<Class<?>>(hashMapCapacity(interfaces.length - i));
+                addTo = new LinkedHashSet<Class<?>>(hashMapCapacity(interfaces.length));
             }
             if (addTo.add(candidate)) {
-                getAllInterfaces(candidate, addTo);
+                getInterfaceSet(candidate, addTo);
             }
         }
         return addTo;
@@ -396,7 +397,7 @@ next:       for (final Class<?> candidat
      * @return The most specialized class, or {@code null} if the given collection does not contain
      *         at least one non-null element.
      */
-    public static Class<?> findSpecializedClass(final Collection<?> objects) {
+    public static Class<?> findSpecializedClass(final Iterable<?> objects) {
         final Set<Class<?>> types = getClasses(objects);
         types.remove(null);
         /*
@@ -448,7 +449,7 @@ next:       for (final Class<?> candidat
      * @return The most specific class common to all supplied objects, or {@code null} if the
      *         given collection does not contain at least one non-null element.
      */
-    public static Class<?> findCommonClass(final Collection<?> objects) {
+    public static Class<?> findCommonClass(final Iterable<?> objects) {
         final Set<Class<?>> types = getClasses(objects);
         types.remove(null);
         return common(types);
@@ -494,13 +495,16 @@ next:       for (final Class<?> candidat
      *         Callers can freely modify the returned set.
      */
     public static Set<Class<?>> findCommonInterfaces(final Class<?> c1, final Class<?> c2) {
-        final Set<Class<?>> interfaces = getAllInterfaces(c1);
-        final Set<Class<?>> buffer     = getAllInterfaces(c2); // To be recycled.
+        final Set<Class<?>> interfaces = getInterfaceSet(c1);
+        final Set<Class<?>> buffer     = getInterfaceSet(c2); // To be recycled.
+        if (interfaces == null || buffer == null) {
+            return Collections.emptySet();
+        }
         interfaces.retainAll(buffer);
         for (Iterator<Class<?>> it=interfaces.iterator(); it.hasNext();) {
             final Class<?> candidate = it.next();
             buffer.clear(); // Safe because the buffer can not be Collections.EMPTY_SET at this point.
-            getAllInterfaces(candidate, buffer);
+            getInterfaceSet(candidate, buffer);
             if (interfaces.removeAll(buffer)) {
                 it = interfaces.iterator();
             }
@@ -578,11 +582,11 @@ cmp:    for (final Class<?> c : c1) {
         if (classe == null) {
             return "<*>";
         }
-        Class<?> enclosing = classe.getEnclosingClass();
         while (classe.isAnonymousClass()) {
             classe = classe.getSuperclass();
         }
         String name = classe.getSimpleName();
+        final Class<?> enclosing = classe.getEnclosingClass();
         if (enclosing != null) {
             name = getShortName(enclosing) + '.' + name;
         }
@@ -621,7 +625,7 @@ cmp:    for (final Class<?> c : c1) {
      * @param  allowedTypes The allowed types.
      * @return {@code true} if the given type is assignable to one of the allowed types.
      */
-    public static boolean isAssignableTo(final Class<?> type, final Class<?>... allowedTypes) {
+    public static boolean isAssignableToAny(final Class<?> type, final Class<?>... allowedTypes) {
         if (type != null) {
             if (allowedTypes == null) {
                 return true;

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Exceptions.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Exceptions.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Exceptions.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Exceptions.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -25,7 +25,7 @@ import org.apache.sis.internal.util.Loca
 import static org.apache.sis.util.CharSequences.trimWhitespaces;
 
 // Related to JDK7
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java?rev=1457601&r1=1457600&r2=1457601&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java [UTF-8] (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java [UTF-8] Sun Mar 17 23:53:53 2013
@@ -25,11 +25,11 @@ package org.apache.sis.util;
  *
  * {@section Conditions for equality}
  * <ul>
- *   <li>{@link org.apache.sis.metadata.iso.MetadataEntity} subclasses
+ *   <li>{@link org.apache.sis.metadata.iso.ISOMetadata} subclasses
  *     <ol>
  *       <li>{@link ComparisonMode#STRICT STRICT} – Objects must be of the same class
  *           and all attributes must be equal, including {@code xlink} and others
- *           {@linkplain org.apache.sis.metadata.iso.MetadataEntity#getIdentifiers() identifiers}.</li>
+ *           {@linkplain org.apache.sis.metadata.iso.ISOMetadata#getIdentifiers() identifiers}.</li>
  *       <li>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT} – The same attributes than the above
  *           {@code STRICT} mode must be equal, but the metadata object don't need to be implemented
  *           by the same class provided that they implement the same GeoAPI interface.</li>



Mime
View raw message