sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1540209 [1/2] - in /sis/branches/JDK6: ./ application/sis-console/src/main/resources/org/apache/sis/console/ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/ core/...
Date Fri, 08 Nov 2013 22:24:14 GMT
Author: desruisseaux
Date: Fri Nov  8 22:24:13 2013
New Revision: 1540209

URL: http://svn.apache.org/r1540209
Log:
Merge from the JDK7 branch.

Added:
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
      - copied unchanged from r1540208, sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
      - copied unchanged from r1540208, sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
      - copied unchanged from r1540208, sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
    sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/measure/UnitsTest.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1535870-1540208

Modified: sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties [ISO-8859-1] (original)
+++ sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties [ISO-8859-1] Fri Nov  8 22:24:13 2013
@@ -4,6 +4,6 @@ locale=The locale to use for the command
 timezone=The timezone for the dates to be formatted.
 encoding=The encoding to use for the command output.
 colors=Whether colorized output shall be enabled.
-brief=Whether the output should contains only brief information.
-verbose=Whether the output should contains more detailed information.
+brief=Reduce the output to only brief information.
+verbose=Request the output to contain more detailed information.
 help=Lists the options available for a specific command.

Modified: sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties [ISO-8859-1] Fri Nov  8 22:24:13 2013
@@ -4,6 +4,6 @@ locale=Les paramètres régionaux à uti
 timezone=Le fuseau horaire des dates à écrire.
 encoding=L\u2019encodage des caractères à utiliser pour la sortie de la commande.
 colors=Indique si l\u2019affichage peut être en couleurs.
-brief=Indique si la sortie de la commande ne doit contenir que de brèves informations.
-verbose=Indique si la sortie de la commande doit contenir des informations plus détaillées.
+brief=Indique que la sortie de la commande ne doit contenir que de brèves informations.
+verbose=Indique que la sortie de la commande doit contenir des informations plus détaillées.
 help=Liste les options disponibles pour une commande spécifique.

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -18,7 +18,7 @@ package org.apache.sis.metadata;
 
 import java.util.Comparator;
 import java.util.Map;
-import java.util.IdentityHashMap;
+import java.util.HashMap;
 import java.lang.reflect.Method;
 import javax.xml.bind.annotation.XmlType;
 
@@ -43,7 +43,7 @@ import org.opengis.annotation.Obligation
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
- * @version 0.3
+ * @version 0.4
  * @module
  */
 final class PropertyComparator implements Comparator<Method> {
@@ -63,29 +63,51 @@ final class PropertyComparator implement
     static final String SET = "set";
 
     /**
-     * Methods specified in the {@link XmlType} annotation, or {@code null} if none.
-     */
-    private final String[] order;
-
-    /**
-     * Indices of methods in the {@link #order} array, created when first needed.
+     * Methods and property names specified in the {@link XmlType} annotation.
+     * Entries description:
+     *
+     * <ul>
+     *   <li>Keys in this map are either {@link String} or {@link Method} instances:
+     *     <ul>
+     *       <li>{@code String} keys property names as given by {@link XmlType#propOrder()}.
+     *           They are computed at construction time and do not change after construction.</li>
+     *       <li>{@code Method} keys will be added after construction, only as needed.</li>
+     *     </ul>
+     *   </li>
+     *
+     *   <li>Key is associated to an index that specify its position in descending order.
+     *       For example the property associated to integer 0 shall be sorted last.
+     *       This descending order is only an implementation convenience.</li>
+     * </ul>
      */
-    private Map<Method,Integer> indices;
+    private final Map<Object,Integer> order;
 
     /**
      * Creates a new comparator for the given implementation class.
      *
      * @param implementation The implementation class, or {@code null} if unknown.
      */
-    PropertyComparator(final Class<?> implementation) {
-        if (implementation != null) {
+    PropertyComparator(Class<?> implementation) {
+        order = new HashMap<Object,Integer>();
+        while (implementation != null) {
             final XmlType xml = implementation.getAnnotation(XmlType.class);
             if (xml != null) {
-                order = xml.propOrder();
-                return;
+                final String[] propOrder = xml.propOrder();
+                for (int i=propOrder.length; --i>=0;) {
+                    /*
+                     * Add the entries in reverse order because we are iterating from the child class to
+                     * the parent class, and we want the properties in the parent class to be sorted first.
+                     * If duplicated properties are found, keep the first occurence (i.e. sort the property
+                     * with the most specialized child that declared it).
+                     */
+                    final Integer old = order.put(propOrder[i], order.size());
+                    if (old != null) {
+                        order.put(propOrder[i], old);
+                    }
+                }
             }
+            implementation = implementation.getSuperclass();
         }
-        order = null;
     }
 
     /**
@@ -93,7 +115,7 @@ final class PropertyComparator implement
      */
     @Override
     public int compare(final Method m1, final Method m2) {
-        int c = indexOf(m1) - indexOf(m2);
+        int c = indexOf(m2) - indexOf(m1); // indexOf(…) are sorted in descending order.
         if (c == 0) {
             final UML a1 = m1.getAnnotation(UML.class);
             final UML a2 = m2.getAnnotation(UML.class);
@@ -131,30 +153,21 @@ final class PropertyComparator implement
     }
 
     /**
-     * Returns the index of the given method, or {@code order.length} if the method is not found.
+     * Returns the index of the given method, or -1 if the method is not found.
+     * If positive, the index returned by this method correspond to a sorting in descending order.
      */
     private int indexOf(final Method method) {
-        int i = 0;
-        if (order != null) {
-            if (indices == null) {
-                indices = new IdentityHashMap<Method,Integer>();
-            } else {
-                Integer index = indices.get(method);
-                if (index != null) {
-                    return index;
-                }
-            }
+        Integer index = order.get(method);
+        if (index == null) {
             String name = method.getName();
             name = toPropertyName(name, prefix(name).length());
-            while (i < order.length) {
-                if (name.equals(order[i])) {
-                    break;
-                }
-                i++;
+            index = order.get(name);
+            if (index == null) {
+                index = -1;
             }
-            indices.put(method, i);
+            order.put(method, index);
         }
-        return i;
+        return index;
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -71,11 +71,26 @@ import org.apache.sis.internal.jdk7.Obje
  * {@linkplain #getEastBoundLongitude() east bound longitude}, then the box spans the anti-meridian.
  * See {@linkplain org.apache.sis.geometry.GeneralEnvelope} for more information on anti-meridian spanning.
  *
+ * <blockquote><font size="-1"><b>Note: relationship with Envelope classes</b><br>
+ * The {@link org.apache.sis.geometry} package provides various {@code Envelope} classes serving a simular purpose.
+ * The main difference is that envelopes can be expressed in any {@linkplain org.apache.sis.referencing.crs.AbstractCRS
+ * Coordinate Reference System} (for example using any map projection), may have any number of dimensions, axes may have
+ * any {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#getDirection() direction} (some maps are south-oriented)
+ * and may use any units of measurement. By contrast, geographic bounding box are restricted to two-dimensional
+ * geographic CRS with latitude and longitude in decimal degrees, inside the [-90 … +90]° and [-180 … +180]° range
+ * respectively, increasing toward north and east respectively, and longitude measured from the <cite>international
+ * reference meridian</cite> (Greenwich on Earth). However {@code GeographicBoundingBox} said nothing about the
+ * {@linkplain org.apache.sis.referencing.datum.DefaultGeodeticDatum geodetic datum}. Consequently this bounding
+ * box should be used only as a convenient way to give an <em>approximate</em> description of a location.
+ * Users can assume a precision of about 0.01° for the latitude and longitude values in this class.
+ * If more precision is desired, an {@code Envelope} should be considered instead.
+ * </font></blockquote>
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Touraïvane (IRD)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.3 (derived from geotk-2.1)
- * @version 0.3
+ * @version 0.4
  * @module
  *
  * @see org.apache.sis.geometry.GeneralEnvelope

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -115,7 +115,7 @@ public class DefaultDataIdentification e
      * @param topicCategory The main theme of the dataset, or {@code null} if none.
      */
     public DefaultDataIdentification(final Citation citation,
-                                     final InternationalString abstracts,
+                                     final CharSequence abstracts,
                                      final Locale language,
                                      final TopicCategory topicCategory)
     {

Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -31,6 +31,11 @@ import org.opengis.metadata.citation.Cit
 import org.opengis.metadata.citation.CitationDate;
 import org.opengis.metadata.citation.PresentationForm;
 import org.opengis.metadata.citation.ResponsibleParty;
+import org.opengis.metadata.distribution.Format;
+import org.opengis.metadata.constraint.Constraints;
+import org.opengis.metadata.identification.*; // Really using almost everything.
+import org.opengis.metadata.maintenance.MaintenanceInformation;
+import org.opengis.metadata.spatial.SpatialRepresentationType;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.ReferenceIdentifier;
@@ -45,6 +50,7 @@ import org.apache.sis.util.ComparisonMod
 import org.apache.sis.util.iso.SimpleInternationalString;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.citation.HardCodedCitations;
+import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -70,7 +76,7 @@ import static org.apache.sis.metadata.Pr
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
- * @version 0.3
+ * @version 0.4
  * @module
  */
 @DependsOn(PropertyInformationTest.class)
@@ -174,6 +180,39 @@ public final strictfp class PropertyAcce
     }
 
     /**
+     * Tests the constructor with the {@link DefaultDataIdentification} implementation.
+     * The purpose of this test is to ensure that the properties defined in the parent
+     * class are sorted first.
+     */
+    @Test
+    @DependsOnMethod("testConstructor")
+    public void testConstructorWithInheritance() {
+        assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO_19115, DataIdentification.class, DefaultDataIdentification.class),
+        //……Declaring type………………………Method………………………………………………………………………JavaBeans………………………………………………………UML identifier………………………………………Sentence……………………………………………………………Type………………………………………………………………
+            Identification.class, "getCitation",                   "citation",                   "citation",                  "Citation",                     Citation.class,
+            Identification.class, "getAbstract",                   "abstract",                   "abstract",                  "Abstract",                     InternationalString.class,
+            Identification.class, "getPurpose",                    "purpose",                    "purpose",                   "Purpose",                      InternationalString.class,
+            Identification.class, "getCredits",                    "credits",                    "credit",                    "Credits",                      String[].class,
+            Identification.class, "getStatus",                     "status",                     "status",                    "Status",                       Progress[].class,
+            Identification.class, "getPointOfContacts",            "pointOfContacts",            "pointOfContact",            "Point of contacts",            ResponsibleParty[].class,
+            Identification.class, "getResourceMaintenances",       "resourceMaintenances",       "resourceMaintenance",       "Resource maintenances",        MaintenanceInformation[].class,
+            Identification.class, "getGraphicOverviews",           "graphicOverviews",           "graphicOverview",           "Graphic overviews",            BrowseGraphic[].class,
+            Identification.class, "getResourceFormats",            "resourceFormats",            "resourceFormat",            "Resource formats",             Format[].class,
+            Identification.class, "getDescriptiveKeywords",        "descriptiveKeywords",        "descriptiveKeywords",       "Descriptive keywords",         Keywords[].class,
+            Identification.class, "getResourceSpecificUsages",     "resourceSpecificUsages",     "resourceSpecificUsage",     "Resource specific usages",     Usage[].class,
+            Identification.class, "getResourceConstraints",        "resourceConstraints",        "resourceConstraints",       "Resource constraints",         Constraints[].class,
+            Identification.class, "getAggregationInfo",            "aggregationInfo",            "aggregationInfo",           "Aggregation info",             AggregateInformation[].class,
+        DataIdentification.class, "getSpatialRepresentationTypes", "spatialRepresentationTypes", "spatialRepresentationType", "Spatial representation types", SpatialRepresentationType[].class,
+        DataIdentification.class, "getSpatialResolutions",         "spatialResolutions",         "spatialResolution",         "Spatial resolutions",          Resolution[].class,
+        DataIdentification.class, "getLanguages",                  "languages",                  "language",                  "Languages",                    Locale[].class,
+        DataIdentification.class, "getCharacterSets",              "characterSets",              "characterSet",              "Character sets",               CharacterSet[].class,
+        DataIdentification.class, "getTopicCategories",            "topicCategories",            "topicCategory",             "Topic categories",             TopicCategory[].class,
+        DataIdentification.class, "getEnvironmentDescription",     "environmentDescription",     "environmentDescription",    "Environment description",      InternationalString.class,
+        DataIdentification.class, "getExtents",                    "extents",                    "extent",                    "Extents",                      Extent[].class,
+        DataIdentification.class, "getSupplementalInformation",    "supplementalInformation",    "supplementalInformation",   "Supplemental information",     InternationalString.class);
+    }
+
+    /**
      * Tests the constructor with a method which override an other method with covariant
      * return type. This test may need to be updated if a future GeoAPI release modifies
      * the {@link GeographicCRS} interface.
@@ -181,7 +220,7 @@ public final strictfp class PropertyAcce
      * @see <a href="http://jira.geotoolkit.org/browse/GEOTK-205">GEOTK-205</a>
      */
     @Test
-    @DependsOnMethod("testConstructor")
+    @DependsOnMethod("testConstructorWithInheritance")
     public void testConstructorWithCovariantReturnType() {
         final Class<?> type = GeographicCRS.class;
         assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO, type, type),

Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -195,12 +195,13 @@ public final strictfp class TreeTableFor
         final String text = format.format(identification.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" +
-            "  └─Descriptive keywords\n" +
-            "      ├─Keyword (1 of 3)…………… Apple\n" +
-            "      ├─Keyword (2 of 3)…………… Orange\n" +
-            "      └─Keyword (3 of 3)…………… Kiwi\n", text);
+            "  └─Topic category (3 of 3)…… Test\n",
+            text);
     }
 }

Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -31,17 +31,6 @@ import org.junit.BeforeClass;
  */
 @Suite.SuiteClasses({
     org.apache.sis.internal.metadata.MetadataUtilitiesTest.class,
-    org.apache.sis.metadata.iso.citation.DefaultCitationDateTest.class,
-    org.apache.sis.metadata.iso.citation.DefaultCitationTest.class,
-    org.apache.sis.metadata.iso.identification.DefaultKeywordsTest.class,
-    org.apache.sis.metadata.iso.identification.DefaultRepresentativeFractionTest.class,
-    org.apache.sis.metadata.iso.identification.DefaultResolutionTest.class,
-    org.apache.sis.metadata.iso.identification.DefaultBrowseGraphicTest.class,
-    org.apache.sis.metadata.iso.spatial.DefaultGeorectifiedTest.class,
-    org.apache.sis.metadata.iso.maintenance.DefaultScopeDescriptionTest.class,
-    org.apache.sis.metadata.iso.quality.AbstractElementTest.class,
-    org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBoxTest.class,
-    org.apache.sis.metadata.iso.extent.ExtentsTest.class,
 
     // Classes using Java reflection.
     org.apache.sis.metadata.PropertyInformationTest.class,
@@ -58,8 +47,6 @@ import org.junit.BeforeClass;
     org.apache.sis.metadata.MetadataStandardTest.class,
     org.apache.sis.metadata.PrunerTest.class,
     org.apache.sis.metadata.AbstractMetadataTest.class,
-    org.apache.sis.metadata.iso.ImmutableIdentifierTest.class,
-    org.apache.sis.metadata.iso.AllMetadataTest.class,
 
     // XML marshalling.
     org.apache.sis.internal.jaxb.code.CodeListMarshallingTest.class,
@@ -69,6 +56,24 @@ import org.junit.BeforeClass;
     org.apache.sis.xml.NilReasonMarshallingTest.class,
     org.apache.sis.xml.AnchorMarshallingTest.class,
     org.apache.sis.xml.ObjectReferenceMarshallingTest.class,
+
+    // ISO implementations.
+    org.apache.sis.metadata.iso.citation.DefaultCitationDateTest.class,
+    org.apache.sis.metadata.iso.citation.DefaultCitationTest.class,
+    org.apache.sis.metadata.iso.maintenance.DefaultScopeDescriptionTest.class,
+    org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBoxTest.class,
+    org.apache.sis.metadata.iso.extent.ExtentsTest.class,
+    org.apache.sis.metadata.iso.spatial.DefaultGeorectifiedTest.class,
+    org.apache.sis.metadata.iso.identification.DefaultKeywordsTest.class,
+    org.apache.sis.metadata.iso.identification.DefaultRepresentativeFractionTest.class,
+    org.apache.sis.metadata.iso.identification.DefaultResolutionTest.class,
+    org.apache.sis.metadata.iso.identification.DefaultBrowseGraphicTest.class,
+    org.apache.sis.metadata.iso.identification.DefaultDataIdentificationTest.class,
+    org.apache.sis.metadata.iso.quality.AbstractElementTest.class,
+    org.apache.sis.metadata.iso.ImmutableIdentifierTest.class,
+    org.apache.sis.metadata.iso.AllMetadataTest.class,
+
+    // XML marshalling (integration tests).
     org.apache.sis.xml.CustomMetadataTest.class,
     org.apache.sis.xml.ImageryMarshallingTest.class,
     org.apache.sis.xml.MetadataMarshallingTest.class

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -246,36 +246,6 @@ public enum Convention {
     }
 
     /**
-     * Returns the citation for the organization, standard of project that defines this convention.
-     *
-     * @return The organization, standard or project that defines this convention.
-     *
-     * @see WKTFormat#getAuthority()
-     */
-    public Citation getAuthority() {
-        return authority;
-    }
-
-    /**
-     * If non-null, {@code PRIMEM} and {@code PARAMETER} values shall unconditionally use the returned units.
-     * The standard value is {@code null}, which means that units are inferred from the context as required by the
-     * <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html#PRIMEM">WKT specification</a>.
-     * However some conventions ignore the above WKT specification and use hard-coded units instead.
-     *
-     * @param  <T>       The compile-time type specified by the {@code quantity} argument.
-     * @param  quantity  The kind of quantity for which to get the unit.
-     *                   The most typical value for this argument is <code>{@linkplain Angle}.class</code>.
-     * @return The unit to use for the given kind of quantity, or {@code null} for inferring the unit in the standard way.
-     */
-    @SuppressWarnings("unchecked")
-    public <T extends Quantity> Unit<T> getForcedUnit(final Class<T> quantity) {
-        if (quantity == Angle.class) {
-            return (Unit) forcedAngularUnit;
-        }
-        return null;
-    }
-
-    /**
      * Returns the convention for the organization, standard or project specified by the given citation.
      *
      * @param  authority The organization, standard or project for which to get the convention, or {@code null}.
@@ -314,6 +284,36 @@ public enum Convention {
     }
 
     /**
+     * Returns the citation for the organization, standard of project that defines this convention.
+     *
+     * @return The organization, standard or project that defines this convention.
+     *
+     * @see WKTFormat#getAuthority()
+     */
+    public Citation getAuthority() {
+        return authority;
+    }
+
+    /**
+     * If non-null, {@code PRIMEM} and {@code PARAMETER} values shall unconditionally use the returned units.
+     * The standard value is {@code null}, which means that units are inferred from the context as required by the
+     * <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html#PRIMEM">WKT specification</a>.
+     * However some conventions ignore the above WKT specification and use hard-coded units instead.
+     *
+     * @param  <T>       The compile-time type specified by the {@code quantity} argument.
+     * @param  quantity  The kind of quantity for which to get the unit.
+     *                   The most typical value for this argument is <code>{@linkplain Angle}.class</code>.
+     * @return The unit to use for the given kind of quantity, or {@code null} for inferring the unit in the standard way.
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends Quantity> Unit<T> getForcedUnit(final Class<T> quantity) {
+        if (quantity == Angle.class) {
+            return (Unit) forcedAngularUnit;
+        }
+        return null;
+    }
+
+    /**
      * Makes the given coordinate system conform to this convention. This method is used mostly
      * for converting between the legacy (OGC 01-009) {@link GeocentricCRS} axis directions,
      * and the new (ISO 19111) directions. Those directions are:

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -39,7 +39,7 @@ import org.opengis.referencing.operation
 import org.opengis.util.CodeList;
 
 import org.apache.sis.measure.Units;
-import org.apache.sis.math.MathFunctions;
+import org.apache.sis.math.DecimalFunctions;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
@@ -705,7 +705,7 @@ public class Formatter {
          * a unit conversion). In the case of WGS84 semi-major axis in metres, we still have a
          * maximum of 8 fraction digits, which is more than enough.
          */
-        numberFormat.setMaximumFractionDigits(MathFunctions.fractionDigitsForValue(number) - 2);
+        numberFormat.setMaximumFractionDigits(DecimalFunctions.fractionDigitsForValue(number) - 2);
         numberFormat.setMinimumFractionDigits(1); // Must be after setMaximumFractionDigits(…).
         numberFormat.format(number, buffer, dummy);
         resetColor();

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -27,10 +27,12 @@ import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.Immutable;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.Numerics;
+import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.referencing.IdentifiedObjects;
 
 import static java.lang.Math.PI;
 import static java.lang.Math.abs;
+import static org.apache.sis.util.ArgumentChecks.*;
 import static org.apache.sis.referencing.operation.matrix.Matrix4.SIZE;
 
 // Related to JDK7
@@ -159,7 +161,7 @@ public class BursaWolfParameters extends
     /**
      * The conversion factor from <cite>parts per million</cite> to scale minus one.
      */
-    private static final double PPM = 1E+6;
+    static final double PPM = 1E+6;
 
     /**
      * The conversion factor from arc-seconds to radians.
@@ -247,6 +249,20 @@ public class BursaWolfParameters extends
         this.rZ = rZ;
         this.dS = dS;
         this.targetDatum = targetDatum;
+        verify();
+    }
+
+    /**
+     * Verifies parameters validity after construction.
+     */
+    private void verify() {
+        ensureFinite("tX", tX);
+        ensureFinite("tY", tY);
+        ensureFinite("tZ", tZ);
+        ensureFinite("rX", rX);
+        ensureFinite("rY", rY);
+        ensureFinite("rZ", rZ);
+        ensureBetween("dS", -PPM, PPM, dS); // For preventing zero or negative value on the matrix diagonal.
     }
 
     /**
@@ -264,7 +280,7 @@ public class BursaWolfParameters extends
      * @param  targetDatum The target datum (usually WGS 84) for this set of parameters, or {@code null} if unspecified.
      * @throws IllegalArgumentException if the specified matrix does not meet the conditions.
      *
-     * @see #getPositionVectorTransformation(boolean)
+     * @see #getPositionVectorTransformation()
      */
     public BursaWolfParameters(final Matrix matrix, final double tolerance, final GeodeticDatum targetDatum)
             throws IllegalArgumentException
@@ -309,6 +325,7 @@ public class BursaWolfParameters extends
         this.rY = rY;
         this.rZ = rZ;
         this.targetDatum = targetDatum;
+        verify();
     }
 
     /**
@@ -362,25 +379,46 @@ public class BursaWolfParameters extends
      * This is identified as operation method 1033 in the EPSG database.
      *
      * {@section Inverse transformation}
-     * The inverse transformation can be computed by reversing the sign of the 7 parameters before to use
-     * them in the above matrix. Note that both the direct and inverse transformations are approximations.
-     * Multiplication of direct and inverse transformation matrices results in a matrix close to the identity,
-     * but not necessarily strictly equals.
+     * The inverse transformation can be approximated by reversing the sign of the 7 parameters before to use them
+     * in the above matrix. This is often considered sufficient since <cite>position vector transformations</cite>
+     * are themselves approximations. However Apache SIS will rather use
+     * {@link org.apache.sis.referencing.operation.matrix.MatrixSIS#inverse()} in order to increase the chances
+     * that concatenation of transformations <var>A</var> → <var>B</var> followed by <var>B</var> → <var>A</var>
+     * gives back the identity transform.
      *
-     * @param  inverse If {@code true}, returns the inverse transformation instead.
      * @return An affine transform in geocentric space created from this Bursa-Wolf parameters.
      *
      * @see DefaultGeodeticDatum#getPositionVectorTransformation(GeodeticDatum)
      */
-    public Matrix getPositionVectorTransformation(final boolean inverse) {
-        final double sgn = inverse ? -1 : +1;
-        final double   S = 1 + sgn*dS / PPM;
-        final double  RS = sgn*TO_RADIANS * S;
-        return new Matrix4(
-                 S,  -rZ*RS,  +rY*RS,  sgn*tX,
-            +rZ*RS,       S,  -rX*RS,  sgn*tY,
-            -rY*RS,  +rX*RS,       S,  sgn*tZ,
-                 0,       0,       0,      1);
+    public Matrix getPositionVectorTransformation() {
+        if (isTranslation()) {
+            final Matrix4 matrix = new Matrix4();
+            matrix.m03 = tX;
+            matrix.m13 = tY;
+            matrix.m13 = tZ;
+            return matrix;
+        }
+        /*
+         * Above was an optimization for the common case where the Bursa-Wolf parameters contain only
+         * translation terms. If we have rotation or scale terms, then use double-double arithmetic.
+         */
+        final DoubleDouble RS = DoubleDouble.createSecondsToRadians();
+        final DoubleDouble S = new DoubleDouble(dS);
+        S.divide(PPM, 0);
+        S.add(1, 0);        // S = 1 + dS / PPM;
+        RS.multiply(S);     // RS = toRadians(1″) * S;
+        final DoubleDouble  X = new DoubleDouble(rX); X.multiply(RS);
+        final DoubleDouble  Y = new DoubleDouble(rY); Y.multiply(RS);
+        final DoubleDouble  Z = new DoubleDouble(rZ); Z.multiply(RS);
+        final DoubleDouble mX = new DoubleDouble( X); mX.negate();
+        final DoubleDouble mY = new DoubleDouble( Y); mY.negate();
+        final DoubleDouble mZ = new DoubleDouble( Z); mZ.negate();
+        final Integer       O = 0; // Fetch Integer instance only once.
+        return Matrices.create(4, 4, new Number[] {
+                 S,  mZ,   Y,  Double.valueOf(tX),
+                 Z,   S,  mX,  Double.valueOf(tY),
+                mY,   X,   S,  Double.valueOf(tZ),
+                 O,   O,   O,  1});
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -28,7 +28,9 @@ import org.opengis.referencing.datum.Pri
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
 import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Immutable;
 import org.apache.sis.io.wkt.Formatter;
@@ -65,8 +67,8 @@ import org.apache.sis.internal.jdk7.Obje
  * instance associated to this {@code DefaultGeodeticDatum}. Only if no datum shift method is found in the database,
  * then the {@code BursaWolfParameters} associated to the datum may be used as a fallback.</p>
  *
- * <p>The Bursa-Wolf parameters association serves an other purpose: when a CRS is formatted in
- * <cite>Well Known Text</cite> (WKT) format, the formatted string may contain a {@code TOWGS84[…]} element
+ * <p>The Bursa-Wolf parameters association serves an other purpose: when a CRS is formatted in the older
+ * <cite>Well Known Text</cite> (WKT 1) format, the formatted string may contain a {@code TOWGS84[…]} element
  * with the parameter values of the transformation to the WGS 84 datum. This element is provided as a help
  * for other Geographic Information Systems that support only the <cite>early-binding</cite> approach.
  * Apache SIS usually does not need the {@code TOWGS84} element, except as a fallback for datum that
@@ -285,7 +287,7 @@ public class DefaultGeodeticDatum extend
      * @param  targetDatum The target datum.
      * @return An affine transform from {@code this} to {@code target} in geocentric space, or {@code null} if none.
      *
-     * @see BursaWolfParameters#getPositionVectorTransformation(boolean)
+     * @see BursaWolfParameters#getPositionVectorTransformation()
      */
     public Matrix getPositionVectorTransformation(final GeodeticDatum targetDatum) {
         ensureNonNull("targetDatum", targetDatum);
@@ -309,7 +311,7 @@ public class DefaultGeodeticDatum extend
         if (sourceParam != null) {
             for (final BursaWolfParameters candidate : sourceParam) {
                 if (deepEquals(target, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) {
-                    return candidate.getPositionVectorTransformation(false);
+                    return candidate.getPositionVectorTransformation();
                 }
             }
         }
@@ -320,8 +322,16 @@ public class DefaultGeodeticDatum extend
         final BursaWolfParameters[] targetParam = bursaWolf(target);
         if (targetParam != null) {
             for (final BursaWolfParameters candidate : targetParam) {
-                if (deepEquals(source, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) {
-                    return candidate.getPositionVectorTransformation(true);
+                if (deepEquals(source, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) try {
+                    return MatrixSIS.castOrCopy(candidate.getPositionVectorTransformation()).inverse();
+                } catch (NoninvertibleMatrixException e) {
+                    /*
+                     * Should never happen because BursaWolfParameters.getPositionVectorTransformation()
+                     * is defined in such a way that matrix should always be invertible. If it happen anyway,
+                     * search for an other BursaWolfParameters instance. If none are found, returning 'null'
+                     * is allowed by this method's contract.
+                     */
+                    Logging.unexpectedException(DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
                 }
             }
         }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -25,7 +25,6 @@ import java.awt.geom.RectangularShape;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.NoninvertibleTransformException;
 import org.opengis.referencing.operation.Matrix;
-import org.apache.sis.math.MathFunctions;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
@@ -371,10 +370,10 @@ public final class AffineTransforms2D ex
      */
     public static int getFlip(final AffineTransform transform) {
         ArgumentChecks.ensureNonNull("transform", transform);
-        final int scaleX = MathFunctions.sgn(transform.getScaleX());
-        final int scaleY = MathFunctions.sgn(transform.getScaleY());
-        final int shearX = MathFunctions.sgn(transform.getShearX());
-        final int shearY = MathFunctions.sgn(transform.getShearY());
+        final double scaleX = Math.signum(transform.getScaleX());
+        final double scaleY = Math.signum(transform.getScaleY());
+        final double shearX = Math.signum(transform.getShearX());
+        final double shearY = Math.signum(transform.getShearY());
         if (scaleX ==  scaleY && shearX == -shearY) return +1;
         if (scaleX == -scaleY && shearX ==  shearY) return -1;
         return 0;

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -20,6 +20,7 @@ import java.util.Arrays;
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ArraysExt;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.DoubleDouble;
 
 
@@ -129,6 +130,7 @@ class GeneralMatrix extends MatrixSIS {
 
     /**
      * Creates a new extended precision matrix of the given size.
+     * Matrices elements are initialized to zero (not to the matrix identity).
      *
      * @param numRow Number of rows.
      * @param numCol Number of columns.
@@ -306,6 +308,69 @@ class GeneralMatrix extends MatrixSIS {
     }
 
     /**
+     * Sets all matrix elements like {@link #setElements(double)}, but from an array of {@code Number} instead
+     * of {@code double}. The main purpose of this method is to fetch the {@link DoubleDouble#error} terms when
+     * such instances are found.
+     *
+     * <p><b>Restrictions:</b></p>
+     * <ul>
+     *   <li>This matrix must use extended-precision elements, as by {@link #createExtendedPrecision(int, int)}.</li>
+     *   <li>If this method returns {@code false}, then error terms are <strong>not</strong> initialized - they
+     *       may have any values.</li>
+     * </ul>
+     *
+     * @param  elements The new matrix elements in a row-major array.
+     * @return {@code true} if at leat one {@link DoubleDouble} instance has been found, in which case all
+     *         errors terms have been initialized, or {@code false} otherwise, in which case no error term
+     *         has been initialized (this is a <cite>all or nothing</cite> operation).
+     * @throws IllegalArgumentException If the given array does not have the expected length.
+     *
+     * @see Matrices#create(int, int, Number[])
+     */
+    final boolean setElements(final Number[] newValues) {
+        final int numRow = this.numRow; // Protection against accidental changes.
+        final int numCol = this.numCol;
+        final int length = numRow * numCol;
+        if (newValues.length != length) {
+            throw new IllegalArgumentException(Errors.format(
+                    Errors.Keys.UnexpectedArrayLength_2, length, newValues.length));
+        }
+        boolean isExtended = false;
+        for (int i=0; i<length; i++) {
+            final Number value = newValues[i];
+            final double element = value.doubleValue();
+            elements[i] = element;
+            final double error;
+            if (value instanceof DoubleDouble) {
+                error = ((DoubleDouble) value).error;
+                /*
+                 * If this is the first time that we found an explicit error term, then we need to
+                 * initialize all elements before the current one because they were left unitialized
+                 * (i.e. we perform lazy initialization).
+                 */
+                if (!isExtended) {
+                    isExtended = true;
+                    for (int j=0; j<i; j++) {
+                        elements[j + length] = DoubleDouble.errorForWellKnownValue(elements[j]);
+                    }
+                }
+            } else {
+                /*
+                 * For any kind of numbers other than DoubleDoube, calculate the error term only if we know
+                 * that the final matrix will use extended precision (i.e. we previously found at least one
+                 * DoubleDouble instance). Otherwise skip the error calculation since maybe it will be discarded.
+                 */
+                if (!isExtended) {
+                    continue;
+                }
+                error = DoubleDouble.errorForWellKnownValue(element);
+            }
+            elements[i + length] = error;
+        }
+        return isExtended;
+    }
+
+    /**
      * {@inheritDoc}
      *
      * <p>This method does not check the error terms, because those terms are not visible to the user

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -183,6 +183,29 @@ public final class Matrices extends Stat
     }
 
     /**
+     * Creates a matrix of size {@code numRow} × {@code numCol} initialized to the given numbers.
+     * The elements array size must be equals to {@code numRow*numCol}. Column indices vary fastest.
+     *
+     * @param  numRow   Number of rows.
+     * @param  numCol   Number of columns.
+     * @param  elements The matrix elements in a row-major array. Column indices vary fastest.
+     * @return A matrix initialized to the given elements.
+     */
+    public static MatrixSIS create(final int numRow, final int numCol, final Number[] elements) {
+        ArgumentChecks.ensureNonNull("elements", elements);
+        final GeneralMatrix matrix = GeneralMatrix.createExtendedPrecision(numRow, numCol);
+        if (matrix.setElements(elements)) {
+            /*
+             * At least one org.apache.sis.internal.util.DoubleDouble instance has been found,
+             * in which case the matrix uses double-double arithmetic.  This case is the main
+             * purpose of this method.
+             */
+            return matrix;
+        }
+        return create(numRow, numCol, matrix.getElements());
+    }
+
+    /**
      * Implementation of {@code createTransform(…)} public methods expecting envelopes and/or axis directions.
      * Argument validity shall be verified by the caller.
      *

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -18,6 +18,8 @@ package org.apache.sis.referencing.datum
 
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.Matrix4;
+import org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -35,15 +37,40 @@ import static org.apache.sis.test.Assert
  */
 public final strictfp class BursaWolfParametersTest extends TestCase {
     /**
-     * Tests {@link BursaWolfParameters#getPositionVectorTransformation(boolean)}.
+     * The conversion factor from arc-seconds to radians.
+     */
+    private static final double TO_RADIANS = Math.PI / (180 * 60 * 60);
+
+    /**
+     * Invokes {@link BursaWolfParameters#getPositionVectorTransformation()} and compares
+     * with our own matrix calculated using double arithmetic.
+     */
+    private static MatrixSIS getPositionVectorTransformation(final BursaWolfParameters p) {
+        final double   S = 1 + p.dS / BursaWolfParameters.PPM;
+        final double  RS = TO_RADIANS * S;
+        final Matrix4 expected = new Matrix4(
+                   S,  -p.rZ*RS,  +p.rY*RS,  p.tX,
+            +p.rZ*RS,         S,  -p.rX*RS,  p.tY,
+            -p.rY*RS,  +p.rX*RS,         S,  p.tZ,
+                   0,         0,         0,  1);
+
+        final MatrixSIS matrix = MatrixSIS.castOrCopy(p.getPositionVectorTransformation());
+        assertMatrixEquals("getPositionVectorTransformation", expected, matrix, p.isTranslation() ? 0 : 1E-14);
+        return matrix;
+    }
+
+    /**
+     * Tests {@link BursaWolfParameters#getPositionVectorTransformation()}.
      * This test transform a point from WGS72 to WGS84, and conversely,
      * as documented in the example section of EPSG operation method 9606.
+     *
+     * @throws NoninvertibleMatrixException Should never happen.
      */
     @Test
-    public void testGetPositionVectorTransformation() {
+    public void testGetPositionVectorTransformation() throws NoninvertibleMatrixException {
         final BursaWolfParameters bursaWolf = new BursaWolfParameters(0, 0, 4.5, 0, 0, 0.554, 0.219, null);
-        final MatrixSIS toWGS84 = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(false));
-        final MatrixSIS toWGS72 = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(true));
+        final MatrixSIS toWGS84 = getPositionVectorTransformation(bursaWolf);
+        final MatrixSIS toWGS72 = getPositionVectorTransformation(bursaWolf).inverse();
         final MatrixSIS source  = Matrices.create(4, 1, new double[] {3657660.66, 255768.55, 5201382.11, 1});
         final MatrixSIS target  = Matrices.create(4, 1, new double[] {3657660.78, 255778.43, 5201387.75, 1});
         assertMatrixEquals("toWGS84", target, toWGS84.multiply(source), 0.01);
@@ -51,21 +78,21 @@ public final strictfp class BursaWolfPar
     }
 
     /**
-     * Multiplies the <cite>ED87 to WGS 84</cite> parameters (EPSG:1146) transformation by its inverse,
-     * and verify that the result is somewhat close to the identity. This is an internal consistency test.
+     * Multiplies the <cite>ED87 to WGS 84</cite> parameters (EPSG:1146) transformation by its inverse and
+     * verifies that the result is very close to the identity matrix, thanks to the double-double arithmetic.
+     * This is an internal consistency test.
+     *
+     * @throws NoninvertibleMatrixException Should never happen.
      */
     @Test
     @DependsOnMethod("testGetPositionVectorTransformation")
-    public void testP() {
+    public void testProductOfInverse() throws NoninvertibleMatrixException {
         final BursaWolfParameters bursaWolf = new BursaWolfParameters(
                 -82.981, -99.719, -110.709, -0.5076, 0.1503, 0.3898, -0.3143, null);
-        final MatrixSIS toWGS84 = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(false));
-        final MatrixSIS toED87  = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(true));
+        final MatrixSIS toWGS84 = getPositionVectorTransformation(bursaWolf);
+        final MatrixSIS toED87  = getPositionVectorTransformation(bursaWolf).inverse();
         final MatrixSIS product = toWGS84.multiply(toED87);
-        /*
-         * The error is below 1E-11 for all elements except the translation terms.
-         */
-        assertTrue(Matrices.isIdentity(product, 5E-4));
+        assertTrue(Matrices.isIdentity(product, 1E-37));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -87,10 +87,10 @@ public final strictfp class GeneralMatri
                 0.9,
                 0.1234567,
 
-                // Values below this point are error terms copied from DoubleDouble.ERRORS.
+                // Most values below this point are error terms copied from DoubleDouble.ERRORS.
                  2.9486522708701687E-19,
                 -1.9878495670576283E-15,
                 -2.2204460492503132E-17,
-                 0}, elements, STRICT);
+                -2.5483615218035994E-18}, elements, STRICT);
     }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -19,9 +19,11 @@ package org.apache.sis.referencing.opera
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.cs.AxisDirection;
+import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.util.iso.Types;
+import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -50,6 +52,45 @@ import static org.opengis.referencing.cs
 })
 public final strictfp class MatricesTest extends TestCase {
     /**
+     * Tests {@link Matrices#create(int, int, Number[])}.
+     */
+    public void testCreateFromNumbers() {
+        final double SENTINEL_VALUE = Double.MIN_VALUE;
+        final int    SIZE           = Matrix3.SIZE;
+        final Matrix3 expected = new Matrix3(
+                  1,    2,    3,
+                0.1,  0.2,  0.3,
+                 -1,   -2,   -3);
+        final Number[] elements = {
+                  1,    2,    3,
+                0.1,  0.2,  0.3,
+                 -1,   -2,   -3};
+        /*
+         * Mix of Integer and Double objects but without DoubleDouble objects.
+         * The result shall be a matrix using the standard double Java type.
+         */
+        assertEquals(expected, Matrices.create(SIZE, SIZE, elements));
+        /*
+         * Now put some DoubleDouble instances in the diagonal. We set the error term to
+         * Double.MIN_VALUE in order to differentiate them from automatically calculated
+         * error terms. The result shall use double-double arithmetic, and we should be
+         * able to find back our error terms.
+         */
+        for (int i = 0; i < elements.length; i += SIZE+1) {
+            elements[i] = new DoubleDouble(elements[i].doubleValue(), SENTINEL_VALUE);
+        }
+        final MatrixSIS matrix = Matrices.create(SIZE, SIZE, elements);
+        assertInstanceOf("Created with DoubleDouble elements", GeneralMatrix.class, matrix);
+        assertFalse(expected.equals(matrix)); // Because not the same type.
+        assertTrue(Matrices.equals(expected, matrix, ComparisonMode.BY_CONTRACT));
+        final double[] errors = ((GeneralMatrix) matrix).elements;
+        for (int i = 0; i < SIZE*SIZE; i++) {
+            // Only elements on the diagonal shall be our sentinel value.
+            assertEquals((i % (SIZE+1)) == 0, errors[i + SIZE*SIZE] == SENTINEL_VALUE);
+        }
+    }
+
+    /**
      * Tests {@link Matrices#createTransform(AxisDirection[], AxisDirection[])} with the same sequence of axes.
      * The result shall be an identity matrix.
      *

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -85,7 +85,7 @@ public abstract strictfp class MatrixTes
      * @see SolverTest#TOLERANCE
      * @see NonSquareMatrixTest#printStatistics()
      */
-    protected static final double TOLERANCE = DoubleDouble.DISABLED ? STRICT : 1E-12;
+    protected static final double TOLERANCE = DoubleDouble.DISABLED ? STRICT : 1E-11;
 
     /**
      * Number of random matrices to try in arithmetic operation tests.

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -75,6 +75,8 @@ public final strictfp class NonSquareMat
 
     /**
      * Tests {@link NonSquareMatrix#inverse()} with a non-square matrix.
+     *
+     * @throws NoninvertibleMatrixException Should never happen.
      */
     @Override
     public void testInverse() throws NoninvertibleMatrixException {
@@ -84,6 +86,8 @@ public final strictfp class NonSquareMat
 
     /**
      * Tests {@link NonSquareMatrix#solve(Matrix)} with a non-square matrix.
+     *
+     * @throws NoninvertibleMatrixException Should never happen.
      */
     @Override
     public void testSolve() throws NoninvertibleMatrixException {

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -19,7 +19,6 @@ package org.apache.sis.internal.system;
 import java.util.concurrent.Delayed;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
-import org.apache.sis.math.MathFunctions;
 
 
 /**
@@ -70,13 +69,14 @@ public abstract class DelayedRunnable im
      * accepts only {@code DelayedRunnable} instances.
      *
      * @param other The other delayed object to compare with this delayed task.
+     * @return -1 if the other task should happen before this one, +1 if it should happen after, or 0.
      */
     @Override
     public int compareTo(final Delayed other) {
         if (other instanceof Immediate) {
             return +1; // "Immediate" tasks always have precedence over delayed ones.
         }
-        return MathFunctions.sgn(timestamp - ((DelayedRunnable) other).timestamp);
+        return Long.signum(timestamp - ((DelayedRunnable) other).timestamp);
     }
 
     /**
@@ -104,6 +104,9 @@ public abstract class DelayedRunnable im
 
         /**
          * Returns the delay, which is fixed to 0 in every cases.
+         *
+         * @param  unit The unit of the value to return (ignored).
+         * @return The delay, which is fixed to 0.
          */
         @Override
         public final long getDelay(final TimeUnit unit) {

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -18,6 +18,7 @@ package org.apache.sis.internal.util;
 
 import java.util.Arrays;
 import org.apache.sis.math.MathFunctions;
+import org.apache.sis.math.DecimalFunctions;
 // No BigDecimal dependency - see class javadoc
 
 
@@ -114,44 +115,31 @@ public final class DoubleDouble extends 
     public static final double MAX_VALUE = Double.MAX_VALUE / SPLIT;
 
     /**
-     * Pre-defined constants frequently used in SIS. SIS often creates matrices for unit conversions,
-     * and most conversion factors are defined precisely in base 10. For example the conversion from
-     * feet to metre is defined by a factor of exactly 0.3048, which can not be represented precisely
-     * as a {@code double}. Consequently if a value of 0.3048 is given, we can assume that the intend
-     * was to provide the "feet to metres" conversion factor and complete the double-double instance
-     * accordingly.
+     * Pre-defined constants frequently used in SIS, sorted in increasing order. This table contains only
+     * constants that can not be inferred by {@link DecimalFunctions#deltaForDoubleToDecimal(double)},
+     * for example some transcendental values.
      *
      * <p>Elements in this array shall be sorted in strictly increasing order.
      * For any value at index <var>i</var>, the associated error is {@code ERRORS[i]}.
+     *
+     * @see #errorForWellKnownValue(double)
      */
     private static final double[] VALUES = {
         // Some of the following constants have more fraction digits than necessary. We declare the extra
         // digits for documentation purpose, and in order to have identical content than DoubleDoubleTest
         // so that a plain copy-and-paste can be performed between those two classes.
-         0.000001,
-         0.00001,
-         0.0001,
-         0.00027777777777777777777777777777777778,  // Second to degrees
-         0.001,
+         0.000004848136811095359935899141023579480, // Arc-second to radians
+         0.0002777777777777777777777777777777778,   // Second to degrees
          0.002777777777777777777777777777777778,    // 1/360°
-         0.01,
          0.01666666666666666666666666666666667,     // Minute to degrees
          0.01745329251994329576923690768488613,     // Degrees to radians
-         0.1,
-         0.201168,                                  // Link to metres
-         0.3048,                                    // Feet to metres
          0.785398163397448309615660845819876,       // π/4
-         0.9,                                       // Degrees to gradians
-         0.9144,                                    // Yard to metres
          1.111111111111111111111111111111111,       // Gradian to degrees
          1.414213562373095048801688724209698,       // √2
          1.570796326794896619231321691639751,       // π/2
-         1.8288,                                    // Fathom to metres
          2.356194490192344928846982537459627,       // π * 3/4
-         2.54,                                      // Inch to centimetres
          3.14159265358979323846264338327950,        // π
          6.28318530717958647692528676655901,        // 2π
-        20.1168,                                    // Chain to metres
         57.2957795130823208767981548141052          // Radians to degrees
     };
 
@@ -168,30 +156,18 @@ public final class DoubleDouble extends 
      * </ul>
      */
     private static final double[] ERRORS = {
-        /*  0.000001  */  4.525188817411374E-23,
-        /*  0.00001   */ -8.180305391403131E-22,
-        /*  0.0001    */ -4.79217360238593E-21,
+        /*  0.000004… */  9.320078015422868E-23,
         /*  0.000266… */  2.4093381610788987E-22,
-        /*  0.001     */ -2.0816681711721686E-20,
         /*  0.002666… */ -1.0601087908747154E-19,
-        /*  0.01      */ -2.0816681711721684E-19,
         /*  0.016666… */  2.312964634635743E-19,
         /*  0.017453… */  2.9486522708701687E-19,
-        /*  0.1       */ -5.551115123125783E-18,
-        /*  0.201168  */ -1.3471890270011499E-17,
-        /*  0.3048    */ -1.5365486660812166E-17,
         /*  0.785398… */  3.061616997868383E-17,
-        /*  0.9       */ -2.2204460492503132E-17,
-        /*  0.9144    */  9.414691248821328E-18,
         /*  1.111111… */ -4.9343245538895844E-17,
         /*  1.414213… */ -9.667293313452913E-17,
         /*  1.570796… */  6.123233995736766E-17,
-        /*  1.8288    */  1.8829382497642655E-17,
         /*  2.356194… */  9.184850993605148E-17,
-        /*  2.54      */ -3.552713678800501E-17,
         /*  3.141592… */  1.2246467991473532E-16,
         /*  6.283185… */  2.4492935982947064E-16,
-        /* 20.1168    */ -1.3471890270011499E-15,
         /* 57.295779… */ -1.9878495670576283E-15
     };
 
@@ -213,6 +189,27 @@ public final class DoubleDouble extends 
     }
 
     /**
+     * Creates a new value initialized to the given value.
+     *
+     * @param other The other value to copy.
+     */
+    public DoubleDouble(final DoubleDouble other) {
+        value = other.value;
+        error = other.error;
+    }
+
+    /**
+     * Creates a new value initialized to the given value and an error term inferred by
+     * {@link #errorForWellKnownValue(double)}.
+     *
+     * @param value The initial value.
+     */
+    public DoubleDouble(final double value) {
+        this.value = value;
+        this.error = errorForWellKnownValue(value);
+    }
+
+    /**
      * Creates a new value initialized to the given value and error.
      * It is caller's responsibility to ensure that the (value, error) pair is normalized.
      *
@@ -235,6 +232,16 @@ public final class DoubleDouble extends 
         return new DoubleDouble(0.01745329251994329576923690768488613, 2.9486522708701687E-19);
     }
 
+    /**
+     * Returns a new {@code DoubleDouble} instance initialized to the conversion factor
+     * from arc-seconds to radians.
+     *
+     * @return An instance initialized to the 0.000004848136811095359935899141023579480 value.
+     */
+    public static DoubleDouble createSecondsToRadians() {
+        return new DoubleDouble(0.000004848136811095359935899141023579480, 9.320078015422868E-23);
+    }
+
     /** @return {@link #value}. */
     @Override public double doubleValue() {return value;}
     @Override public float  floatValue()  {return (float) value;}
@@ -242,17 +249,31 @@ public final class DoubleDouble extends 
     @Override public int    intValue()    {return (int) longValue();}
 
     /**
-     * If the given value is one of the well known constants, returns the error for that value.
-     * Otherwise returns 0.
+     * Suggests an {@link #error} for the given value. The {@code DoubleDouble} class contains a hard-coded list
+     * of some frequently used constants, for example for various factors of π. If the given value matches exactly
+     * one of those constants, then its error term is returned. Otherwise this method assumes that the given value
+     * is defined in base 10 (e.g. many unit conversion factors) and tries to compute an error term with
+     * {@link DecimalFunctions#deltaForDoubleToDecimal(double)}.
+     *
+     * {@section Rational}
+     * SIS often creates matrices for unit conversions, and most conversion factors are defined precisely in base 10.
+     * For example the conversion from feet to metres is defined by a factor of exactly 0.3048, which can not be
+     * represented precisely as a {@code double}. Consequently if a value of 0.3048 is given, we can assume that
+     * the intend was to provide the "feet to metres" conversion factor and complete the double-double instance
+     * accordingly.
      *
      * @param  value The value for which to get this error.
      * @return The error for the given value, or 0 if unknown. In the later case,
-     *         the given value is assumed to be the most accurate available representation.
+     *         the base 2 representation of the given value is assumed to be accurate enough.
      */
     public static double errorForWellKnownValue(final double value) {
         if (DISABLED) return 0;
         final int i = Arrays.binarySearch(VALUES, Math.abs(value));
-        return (i >= 0) ? MathFunctions.xorSign(ERRORS[i], value) : 0;
+        if (i >= 0) {
+            return MathFunctions.xorSign(ERRORS[i], value);
+        }
+        final double delta = DecimalFunctions.deltaForDoubleToDecimal(value);
+        return Double.isNaN(delta) ? 0 : delta;
     }
 
     /**
@@ -398,7 +419,7 @@ public final class DoubleDouble extends 
     }
 
     /**
-     * Set this number to {@code -this}.
+     * Sets this number to {@code -this}.
      */
     public void negate() {
         value = -value;

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -83,11 +83,10 @@ public final class Numerics extends Stat
     public static final int SIGNIFICAND_SIZE = 52;
 
     /**
-     * A prime number used for hash code computation. Value 31 is often used because
-     * some modern compilers can optimize {@code x*31} as {@code (x << 5) - x}
-     * (Josh Bloch, <cite>Effective Java</cite>).
+     * Number of bits in the significand (mantissa) part of IEEE 754 {@code float} representation,
+     * <strong>not</strong> including the hidden bit.
      */
-    private static final int PRIME_NUMBER = 31;
+    public static final int SIGNIFICAND_SIZE_OF_FLOAT = 23;
 
     /**
      * Do not allow instantiation of this class.
@@ -217,7 +216,12 @@ public final class Numerics extends Stat
      * @return An updated hash code value.
      */
     public static int hash(final float value, final int seed) {
-        return seed * PRIME_NUMBER + Float.floatToIntBits(value);
+        /*
+         * Multiplication by prime number produces better hash code distribution.
+         * Value 31 is often used because some modern compilers can optimize x*31
+         * as  (x << 5) - x    (Josh Bloch, Effective Java).
+         */
+        return 31*seed + Float.floatToIntBits(value);
     }
 
     /**
@@ -241,6 +245,102 @@ public final class Numerics extends Stat
      * @return An updated hash code value.
      */
     public static int hash(final long value, final int seed) {
-        return seed * PRIME_NUMBER + (((int) value) ^ ((int) (value >>> 32)));
+        return 31*seed + (((int) value) ^ ((int) (value >>> 32)));
+    }
+
+    /**
+     * Converts a power of 2 to a power of 10, rounded toward negative infinity.
+     * This method is equivalent to the following code, but using only integer arithmetic:
+     *
+     * {@preformat java
+     *     return (int) Math.floor(exp2 * LOG10_2);
+     * }
+     *
+     * This method is valid only for arguments in the [-2620 … 2620] range, which is more than enough
+     * for the range of {@code double} exponents. We do not put this method in public API because it
+     * does not check the argument validity.
+     *
+     * {@section Arithmetic notes}
+     * {@code toExp10(getExponent(10ⁿ))} returns <var>n</var> only for {@code n == 0}, and <var>n</var>-1 in all other
+     * cases. This is because 10ⁿ == m × 2<sup>exp2</sup> where the <var>m</var> significand is always greater than 1,
+     * which must be compensated by a smaller {@code exp2} value such as {@code toExp10(exp2) < n}. Note that if the
+     * {@code getExponent(…)} argument is not a power of 10, then the result can be either <var>n</var> or <var>n</var>-1.
+     *
+     * @param  exp2 The power of 2 to convert Must be in the [-2620 … 2620] range.
+     * @return The power of 10, rounded toward negative infinity.
+     *
+     * @see org.apache.sis.math.MathFunctions#LOG10_2
+     * @see org.apache.sis.math.MathFunctions#getExponent(double)
+     */
+    public static int toExp10(final int exp2) {
+        /*
+         * Compute:
+         *          exp2 × (log10(2) × 2ⁿ) / 2ⁿ
+         * where:
+         *          n = 20   (arbitrary value)
+         *
+         * log10(2) × 2ⁿ  =  315652.82873335475, which we round to 315653.
+         *
+         * The range of valid values for such approximation is determined
+         * empirically by running the NumericsTest.testToExp10() method.
+         */
+        assert exp2 >= -2620 && exp2 <= 2620 : exp2;
+        return (exp2 * 315653) >> 20;
+    }
+
+    /**
+     * Returns the significand <var>m</var> of the given value such as {@code value = m×2ⁿ}
+     * where <var>n</var> is {@link Math#getExponent(double)} - {@value #SIGNIFICAND_SIZE}.
+     * For any non-NaN values (including infinity), the following relationship holds:
+     *
+     * {@preformat java
+     *    assert Math.scalb(getSignificand(value), Math.getExponent(value) - SIGNIFICAND_SIZE) == Math.abs(value);
+     * }
+     *
+     * For negative values, this method behaves as if the value was positive.
+     *
+     * @param  value The value for which to get the significand.
+     * @return The significand of the given value.
+     */
+    public static long getSignificand(final double value) {
+        long bits = Double.doubleToRawLongBits(value);
+        final long exponent = bits & (0x7FFL << SIGNIFICAND_SIZE);
+        bits &= (1L << SIGNIFICAND_SIZE) - 1;
+        if (exponent != 0) {
+            bits |= (1L << SIGNIFICAND_SIZE);
+        } else {
+            /*
+             * Sub-normal value: compensate for the fact that Math.getExponent(value) returns
+             * Double.MIN_EXPONENT - 1 in this case, while we would need Double.MIN_EXPONENT.
+             */
+            bits <<= 1;
+        }
+        return bits;
+    }
+
+    /**
+     * Returns the significand <var>m</var> of the given value such as {@code value = m×2ⁿ} where
+     * <var>n</var> is {@link Math#getExponent(float)} - {@value #SIGNIFICAND_SIZE_OF_FLOAT}.
+     * For any non-NaN positive values (including infinity), the following relationship holds:
+     *
+     * {@preformat java
+     *    assert Math.scalb(getSignificand(value), Math.getExponent(value) - SIGNIFICAND_SIZE_OF_FLOAT) == value;
+     * }
+     *
+     * For negative values, this method behaves as if the value was positive.
+     *
+     * @param  value The value for which to get the significand.
+     * @return The significand of the given value.
+     */
+    public static int getSignificand(final float value) {
+        int bits = Float.floatToRawIntBits(value);
+        final int exponent = bits & (0xFF << SIGNIFICAND_SIZE_OF_FLOAT);
+        bits &= (1L << SIGNIFICAND_SIZE_OF_FLOAT) - 1;
+        if (exponent != 0) {
+            bits |= (1L << SIGNIFICAND_SIZE_OF_FLOAT);
+        } else {
+            bits <<= 1;
+        }
+        return bits;
     }
 }

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java?rev=1540209&r1=1540208&r2=1540209&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] Fri Nov  8 22:24:13 2013
@@ -391,7 +391,7 @@ public abstract class CompoundFormat<T> 
             if (!Locale.ROOT.equals(locale)) {
                 format = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale);
             } else {
-                format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.ROOT);
+                format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
             }
             format.setTimeZone(getTimeZone());
             return format;
@@ -405,6 +405,8 @@ public abstract class CompoundFormat<T> 
 
     /**
      * Returns a clone of this format.
+     *
+     * @return A clone of this format.
      */
     @Override
     public CompoundFormat<T> clone() {



Mime
View raw message