sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1724531 [4/13] - in /sis/trunk: ./ application/sis-console/src/main/artifact/bin/ application/sis-console/src/main/artifact/log/ application/sis-console/src/main/java/org/apache/sis/console/ core/sis-build-helper/src/main/java/org/apache/s...
Date Wed, 13 Jan 2016 23:59:41 GMT
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -328,11 +328,18 @@ public class GeodeticObjectFactory exten
      * An {@linkplain #createGeocentricCRS(Map, GeodeticDatum, SphericalCS) alternate method} allows creation of the
      * same kind of CRS with spherical coordinate system instead than a Cartesian one.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
-     *   <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
      *   <li>{@link #createCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
-     * </ul>
+     *   <li>One of:<ul>
+     *     <li>{@link #createEllipsoid(Map, double, double, Unit)}</li>
+     *     <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li>
+     *   </ul></li>
+     *   <li>{@link #createPrimeMeridian(Map, double, Unit)}</li>
+     *   <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultGeocentricCRS} instance.
      *
@@ -341,6 +348,7 @@ public class GeodeticObjectFactory exten
      * @param  cs         The three-dimensional Cartesian coordinate system for the created CRS.
      * @throws FactoryException if the object creation failed.
      *
+     * @see GeodeticAuthorityFactory#createGeocentricCRS(String)
      * @see DefaultGeocentricCRS#DefaultGeocentricCRS(Map, GeodeticDatum, CartesianCS)
      */
     @Override
@@ -351,7 +359,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultGeocentricCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createGeocentricCRS", crs);
     }
@@ -360,10 +368,11 @@ public class GeodeticObjectFactory exten
      * Creates a three-dimensional Cartesian coordinate system from the given set of axis.
      * This coordinate system can be used with geocentric, engineering and derived CRS.
      *
-     * <p>The components needed by this method can be created by the following method:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultCartesianCS} instance.
      *
@@ -374,6 +383,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultCartesianCS#DefaultCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createCartesianCS(String)
      */
     @Override
     public CartesianCS createCartesianCS(final Map<String,?> properties,
@@ -385,7 +395,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultCartesianCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createCartesianCS", cs);
     }
@@ -396,11 +406,18 @@ public class GeodeticObjectFactory exten
      * An {@linkplain #createGeocentricCRS(Map, GeodeticDatum, CartesianCS) alternate method} allows creation of the
      * same kind of CRS with Cartesian coordinate system instead than a spherical one.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
-     *   <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
      *   <li>{@link #createSphericalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
-     * </ul>
+     *   <li>One of:<ul>
+     *     <li>{@link #createEllipsoid(Map, double, double, Unit)}</li>
+     *     <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li>
+     *   </ul></li>
+     *   <li>{@link #createPrimeMeridian(Map, double, Unit)}</li>
+     *   <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultGeocentricCRS} instance.
      *
@@ -410,6 +427,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultGeocentricCRS#DefaultGeocentricCRS(Map, GeodeticDatum, SphericalCS)
+     * @see GeodeticAuthorityFactory#createGeocentricCRS(String)
      */
     @Override
     public GeocentricCRS createGeocentricCRS(final Map<String,?> properties,
@@ -419,7 +437,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultGeocentricCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createGeocentricCRS", crs);
     }
@@ -428,10 +446,11 @@ public class GeodeticObjectFactory exten
      * Creates a spherical coordinate system from the given set of axis.
      * This coordinate system can be used with geocentric, engineering and derived CRS.
      *
-     * <p>The components needed by this method can be created by the following method:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultSphericalCS} instance.
      *
@@ -442,6 +461,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultSphericalCS#DefaultSphericalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createSphericalCS(String)
      */
     @Override
     public SphericalCS createSphericalCS(final Map<String,?> properties,
@@ -453,7 +473,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultSphericalCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createSphericalCS", cs);
     }
@@ -462,11 +482,21 @@ public class GeodeticObjectFactory exten
      * Creates a geographic coordinate reference system. It can be (<var>latitude</var>, <var>longitude</var>)
      * or (<var>longitude</var>, <var>latitude</var>), optionally with an ellipsoidal height.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
+     *   <li>One of:<ul>
+     *     <li>{@link #createEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
+     *     <li>{@link #createEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
+     *   </ul></li>
+     *   <li>One of:<ul>
+     *     <li>{@link #createEllipsoid(Map, double, double, Unit)}</li>
+     *     <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li>
+     *   </ul></li>
+     *   <li>{@link #createPrimeMeridian(Map, double, Unit)}</li>
      *   <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li>
-     *   <li>{@link #createEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultGeographicCRS} instance.
      *
@@ -476,6 +506,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultGeographicCRS#DefaultGeographicCRS(Map, GeodeticDatum, EllipsoidalCS)
+     * @see GeodeticAuthorityFactory#createGeographicCRS(String)
      */
     @Override
     public GeographicCRS createGeographicCRS(final Map<String,?> properties,
@@ -485,7 +516,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultGeographicCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createGeographicCRS", crs);
     }
@@ -495,11 +526,15 @@ public class GeodeticObjectFactory exten
      * Geodetic datum defines the location and orientation of an ellipsoid that approximates the shape of the earth.
      * This datum can be used with geographic, geocentric and engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
-     *   <li>{@link #createEllipsoid(Map, double, double, Unit)} or {@link #createFlattenedSphere(Map, double, double, Unit)}</li>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>One of:<ul>
+     *     <li>{@link #createEllipsoid(Map, double, double, Unit)}</li>
+     *     <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li>
+     *   </ul></li>
      *   <li>{@link #createPrimeMeridian(Map, double, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultGeodeticDatum} instance.
      *
@@ -509,6 +544,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultGeodeticDatum#DefaultGeodeticDatum(Map, Ellipsoid, PrimeMeridian)
+     * @see GeodeticAuthorityFactory#createGeodeticDatum(String)
      */
     @Override
     public GeodeticDatum createGeodeticDatum(final Map<String,?> properties,
@@ -518,7 +554,7 @@ public class GeodeticObjectFactory exten
         try {
             datum = new DefaultGeodeticDatum(complete(properties), ellipsoid, primeMeridian);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createGeodeticDatum", datum);
     }
@@ -535,6 +571,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultPrimeMeridian#DefaultPrimeMeridian(Map, double, Unit)
+     * @see GeodeticAuthorityFactory#createPrimeMeridian(String)
      */
     @Override
     public PrimeMeridian createPrimeMeridian(final Map<String,?> properties,
@@ -544,7 +581,7 @@ public class GeodeticObjectFactory exten
         try {
             meridian = new DefaultPrimeMeridian(complete(properties), longitude, angularUnit);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createPrimeMeridian", meridian);
     }
@@ -553,10 +590,11 @@ public class GeodeticObjectFactory exten
      * Creates an ellipsoidal coordinate system without ellipsoidal height.
      * It can be (<var>latitude</var>, <var>longitude</var>) or (<var>longitude</var>, <var>latitude</var>).
      *
-     * <p>The components needed by this method can be created by the following method:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultEllipsoidalCS} instance.
      *
@@ -566,6 +604,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultEllipsoidalCS#DefaultEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createEllipsoidalCS(String)
      */
     @Override
     public EllipsoidalCS createEllipsoidalCS(final Map<String,?> properties,
@@ -576,7 +615,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultEllipsoidalCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createEllipsoidalCS", cs);
     }
@@ -586,10 +625,11 @@ public class GeodeticObjectFactory exten
      * It can be (<var>latitude</var>, <var>longitude</var>, <var>height</var>)
      * or (<var>longitude</var>, <var>latitude</var>, <var>height</var>).
      *
-     * <p>The components needed by this method can be created by the following method:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultEllipsoidalCS} instance.
      *
@@ -600,6 +640,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultEllipsoidalCS#DefaultEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createEllipsoidalCS(String)
      */
     @Override
     public EllipsoidalCS createEllipsoidalCS(final Map<String,?> properties,
@@ -611,7 +652,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultEllipsoidalCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createEllipsoidalCS", cs);
     }
@@ -627,6 +668,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultEllipsoid#createEllipsoid(Map, double, double, Unit)
+     * @see GeodeticAuthorityFactory#createEllipsoid(String)
      */
     @Override
     public Ellipsoid createEllipsoid(final Map<String,?> properties,
@@ -637,7 +679,7 @@ public class GeodeticObjectFactory exten
         try {
             ellipsoid = DefaultEllipsoid.createEllipsoid(complete(properties), semiMajorAxis, semiMinorAxis, unit);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createEllipsoid", ellipsoid);
     }
@@ -653,6 +695,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultEllipsoid#createFlattenedSphere(Map, double, double, Unit)
+     * @see GeodeticAuthorityFactory#createEllipsoid(String)
      */
     @Override
     public Ellipsoid createFlattenedSphere(final Map<String,?> properties,
@@ -663,7 +706,7 @@ public class GeodeticObjectFactory exten
         try {
             ellipsoid = DefaultEllipsoid.createFlattenedSphere(complete(properties), semiMajorAxis, inverseFlattening, unit);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createFlattenedSphere", ellipsoid);
     }
@@ -673,12 +716,21 @@ public class GeodeticObjectFactory exten
      * Projected CRS are used to approximate the shape of the earth on a planar surface in such a way
      * that the distortion that is inherent to the approximation is controlled and known.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
+     *   <li>{@link #createCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
+     *   <li>{@link #createEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
+     *   <li>One of:<ul>
+     *     <li>{@link #createEllipsoid(Map, double, double, Unit)}</li>
+     *     <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li>
+     *   </ul></li>
+     *   <li>{@link #createPrimeMeridian(Map, double, Unit)}</li>
+     *   <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li>
      *   <li>{@link #createGeographicCRS(Map, GeodeticDatum, EllipsoidalCS)}</li>
      *   <li>{@link org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory#createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}</li>
-     *   <li>{@link #createCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The supplied {@code conversion} argument shall <strong>not</strong> includes the operation steps
      * for performing {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes unit
@@ -694,6 +746,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultProjectedCRS#DefaultProjectedCRS(Map, GeographicCRS, Conversion, CartesianCS)
+     * @see GeodeticAuthorityFactory#createProjectedCRS(String)
      */
     @Override
     public ProjectedCRS createProjectedCRS(final Map<String,?> properties,
@@ -704,7 +757,11 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultProjectedCRS(complete(properties), baseCRS, conversion, derivedCS);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            final Throwable cause = exception.getCause();
+            if (cause instanceof FactoryException) {
+                throw (FactoryException) cause;         // Must be propagated for allowing caller to catch NoSuchIdentifierException.
+            }
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createProjectedCRS", crs);
     }
@@ -713,10 +770,11 @@ public class GeodeticObjectFactory exten
      * Creates a two-dimensional Cartesian coordinate system from the given pair of axis.
      * This coordinate system can be used with projected, engineering and derived CRS.
      *
-     * <p>The components needed by this method can be created by the following method:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultCartesianCS} instance.
      *
@@ -726,6 +784,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultCartesianCS#DefaultCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createCartesianCS(String)
      */
     @Override
     public CartesianCS createCartesianCS(final Map<String,?> properties,
@@ -736,7 +795,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultCartesianCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createCartesianCS", cs);
     }
@@ -747,12 +806,14 @@ public class GeodeticObjectFactory exten
      * {@link TemporalCRS} or {@link EngineeringCRS} interface depending on the type of the base CRS and the
      * coordinate system.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
+     *   <li>A {@code createFooCS(…)} method for Cartesian, spherical, ellipsoidal, vertical, temporal, linear, affine, polar, cylindrical or user-defined CS.</li>
      *   <li>An other {@code createFooCRS(…)} method for geocentric, geographic, vertical, temporal or engineering CRS.</li>
      *   <li>{@link org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory#createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}</li>
-     *   <li>A {@code createFooCS(…)} method for Cartesian, spherical, ellipsoidal, vertical, temporal, linear, affine, polar, cylindrical or user-defined CS.</li>
-     * </ul>
+     * </ol></div>
      *
      * The supplied {@code conversion} argument shall <strong>not</strong> includes the operation steps
      * for performing {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes unit
@@ -768,6 +829,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultDerivedCRS#create(Map, SingleCRS, Conversion, CoordinateSystem)
+     * @see GeodeticAuthorityFactory#createDerivedCRS(String)
      */
     @Override
     public DerivedCRS createDerivedCRS(final Map<String,?> properties,
@@ -779,7 +841,11 @@ public class GeodeticObjectFactory exten
         try {
             crs = DefaultDerivedCRS.create(complete(properties), (SingleCRS) baseCRS, conversion, derivedCS);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            final Throwable cause = exception.getCause();
+            if (cause instanceof FactoryException) {
+                throw (FactoryException) cause;         // Must be propagated for allowing caller to catch NoSuchIdentifierException.
+            }
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createDerivedCRS", crs);
     }
@@ -789,11 +855,13 @@ public class GeodeticObjectFactory exten
      * Vertical CRSs make use of the direction of gravity to define the concept of height or depth,
      * but the relationship with gravity may not be straightforward.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
-     *   <li>{@link #createVerticalDatum(Map, VerticalDatumType)}</li>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
      *   <li>{@link #createVerticalCS(Map, CoordinateSystemAxis)}</li>
-     * </ul>
+     *   <li>{@link #createVerticalDatum(Map, VerticalDatumType)}</li>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultVerticalCRS} instance.
      *
@@ -803,6 +871,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultVerticalCRS#DefaultVerticalCRS(Map, VerticalDatum, VerticalCS)
+     * @see GeodeticAuthorityFactory#createVerticalCRS(String)
      */
     @Override
     public VerticalCRS createVerticalCRS(final Map<String,?> properties,
@@ -812,7 +881,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultVerticalCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createVerticalCRS", crs);
     }
@@ -826,6 +895,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultVerticalDatum#DefaultVerticalDatum(Map, VerticalDatumType)
+     * @see GeodeticAuthorityFactory#createVerticalDatum(String)
      */
     @Override
     public VerticalDatum createVerticalDatum(final Map<String,?> properties,
@@ -835,7 +905,7 @@ public class GeodeticObjectFactory exten
         try {
             datum = new DefaultVerticalDatum(complete(properties), type);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createVerticalDatum", datum);
     }
@@ -844,10 +914,11 @@ public class GeodeticObjectFactory exten
      * Creates a vertical coordinate system.
      * This coordinate system can be used with vertical and derived CRS.
      *
-     * <p>The components needed by this method can be created by the following method:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultVerticalCS} instance.
      *
@@ -856,6 +927,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultVerticalCS#DefaultVerticalCS(Map, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createVerticalCS(String)
      */
     @Override
     public VerticalCS createVerticalCS(final Map<String,?> properties,
@@ -865,7 +937,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultVerticalCS(complete(properties), axis);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createVerticalCS", cs);
     }
@@ -873,11 +945,13 @@ public class GeodeticObjectFactory exten
     /**
      * Creates a temporal coordinate reference system.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
-     *   <li>{@link #createTemporalDatum(Map, Date)}</li>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
      *   <li>{@link #createTimeCS(Map, CoordinateSystemAxis)}</li>
-     * </ul>
+     *   <li>{@link #createTemporalDatum(Map, Date)}</li>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultTemporalCRS} instance.
      *
@@ -887,6 +961,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultTemporalCRS#DefaultTemporalCRS(Map, TemporalDatum, TimeCS)
+     * @see GeodeticAuthorityFactory#createTemporalCRS(String)
      */
     @Override
     public TemporalCRS createTemporalCRS(final Map<String,?> properties,
@@ -896,7 +971,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultTemporalCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createTemporalCRS", crs);
     }
@@ -910,6 +985,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultTemporalDatum#DefaultTemporalDatum(Map, Date)
+     * @see GeodeticAuthorityFactory#createTemporalDatum(String)
      */
     @Override
     public TemporalDatum createTemporalDatum(final Map<String,?> properties,
@@ -919,7 +995,7 @@ public class GeodeticObjectFactory exten
         try {
             datum = new DefaultTemporalDatum(complete(properties), origin);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createTemporalDatum", datum);
     }
@@ -928,10 +1004,11 @@ public class GeodeticObjectFactory exten
      * Creates a temporal coordinate system.
      * This coordinate system can be used with temporal and derived CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultTimeCS} instance.
      *
@@ -940,6 +1017,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultTimeCS#DefaultTimeCS(Map, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createTimeCS(String)
      */
     @Override
     public TimeCS createTimeCS(final Map<String,?> properties,
@@ -949,7 +1027,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultTimeCS(complete(properties), axis);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createTimeCS", cs);
     }
@@ -959,11 +1037,11 @@ public class GeodeticObjectFactory exten
      * Apache SIS puts no restriction on the components that can be used in a compound CRS.
      * However for better inter-operability, users are encouraged to follow the order mandated by ISO 19162:
      *
-     * <ul>
+     * <ol>
      *   <li>A mandatory horizontal CRS (only one of two-dimensional {@code GeographicCRS} or {@code ProjectedCRS} or {@code EngineeringCRS}).</li>
      *   <li>Optionally followed by a {@code VerticalCRS} or a {@code ParametricCRS} (but not both).</li>
      *   <li>Optionally followed by a {@code TemporalCRS}.</li>
-     * </ul>
+     * </ol>
      *
      * The default implementation creates a {@link DefaultCompoundCRS} instance.
      *
@@ -972,6 +1050,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultCompoundCRS#DefaultCompoundCRS(Map, CoordinateReferenceSystem...)
+     * @see GeodeticAuthorityFactory#createCompoundCRS(String)
      */
     @Override
     public CompoundCRS createCompoundCRS(final Map<String,?> properties,
@@ -981,7 +1060,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultCompoundCRS(complete(properties), elements);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createCompoundCRS", crs);
     }
@@ -996,6 +1075,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultImageCRS#DefaultImageCRS(Map, ImageDatum, AffineCS)
+     * @see GeodeticAuthorityFactory#createImageCRS(String)
      */
     @Override
     public ImageCRS createImageCRS(final Map<String,?> properties,
@@ -1005,7 +1085,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultImageCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createImageCRS", crs);
     }
@@ -1019,6 +1099,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultImageDatum#DefaultImageDatum(Map, PixelInCell)
+     * @see GeodeticAuthorityFactory#createImageDatum(String)
      */
     @Override
     public ImageDatum createImageDatum(final Map<String,?> properties,
@@ -1028,7 +1109,7 @@ public class GeodeticObjectFactory exten
         try {
             datum = new DefaultImageDatum(complete(properties), pixelInCell);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createImageDatum", datum);
     }
@@ -1037,10 +1118,11 @@ public class GeodeticObjectFactory exten
      * Creates a two-dimensional affine coordinate system from the given pair of axis.
      * This coordinate system can be used with image and engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultAffineCS} instance.
      *
@@ -1060,7 +1142,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultAffineCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createAffineCS", cs);
     }
@@ -1074,11 +1156,13 @@ public class GeodeticObjectFactory exten
      *   <li>CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft.</li>
      * </ul>
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
-     *   <li>{@link #createEngineeringDatum(Map)}</li>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
+     *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
      *   <li>A {@code createFooCS(…)} method for Cartesian, spherical, linear, affine, polar, cylindrical or user-defined CS.</li>
-     * </ul>
+     *   <li>{@link #createEngineeringDatum(Map)}</li>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultEngineeringCRS} instance.
      *
@@ -1088,6 +1172,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultEngineeringCRS#DefaultEngineeringCRS(Map, EngineeringDatum, CoordinateSystem)
+     * @see GeodeticAuthorityFactory#createEngineeringCRS(String)
      */
     @Override
     public EngineeringCRS createEngineeringCRS(final Map<String,?> properties,
@@ -1097,7 +1182,7 @@ public class GeodeticObjectFactory exten
         try {
             crs = new DefaultEngineeringCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createEngineeringCRS", crs);
     }
@@ -1110,6 +1195,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultEngineeringDatum#DefaultEngineeringDatum(Map)
+     * @see GeodeticAuthorityFactory#createEngineeringDatum(String)
      */
     @Override
     public EngineeringDatum createEngineeringDatum(final Map<String,?> properties)
@@ -1119,7 +1205,7 @@ public class GeodeticObjectFactory exten
         try {
             datum = new DefaultEngineeringDatum(complete(properties));
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createEngineeringDatum", datum);
     }
@@ -1128,10 +1214,11 @@ public class GeodeticObjectFactory exten
      * Creates a three-dimensional affine coordinate system from the given set of axis.
      * This coordinate system can be used with engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultAffineCS} instance.
      *
@@ -1141,7 +1228,7 @@ public class GeodeticObjectFactory exten
      * @param  axis2 The third  axis.
      * @throws FactoryException if the object creation failed.
      *
-     * @see DefaultAffineCS#DefaultAffineCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see DefaultAffineCS#DefaultAffineCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)
      */
     @Override
     public AffineCS createAffineCS(final Map<String,?> properties,
@@ -1153,7 +1240,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultAffineCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createAffineCS", cs);
     }
@@ -1162,10 +1249,11 @@ public class GeodeticObjectFactory exten
      * Creates a cylindrical coordinate system from the given set of axis.
      * This coordinate system can be used with engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultCylindricalCS} instance.
      *
@@ -1176,6 +1264,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultCylindricalCS#DefaultCylindricalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createCylindricalCS(String)
      */
     @Override
     public CylindricalCS createCylindricalCS(final Map<String,?> properties,
@@ -1187,7 +1276,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultCylindricalCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createCylindricalCS", cs);
     }
@@ -1196,10 +1285,11 @@ public class GeodeticObjectFactory exten
      * Creates a polar coordinate system from the given pair of axis.
      * This coordinate system can be used with engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultPolarCS} instance.
      *
@@ -1209,6 +1299,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultPolarCS#DefaultPolarCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)
+     * @see GeodeticAuthorityFactory#createPolarCS(String)
      */
     @Override
     public PolarCS createPolarCS(final Map<String,?> properties,
@@ -1219,7 +1310,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultPolarCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createPolarCS", cs);
     }
@@ -1228,10 +1319,11 @@ public class GeodeticObjectFactory exten
      * Creates a linear coordinate system.
      * This coordinate system can be used with engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultLinearCS} instance.
      *
@@ -1249,7 +1341,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultLinearCS(complete(properties), axis);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createLinearCS", cs);
     }
@@ -1258,10 +1350,11 @@ public class GeodeticObjectFactory exten
      * Creates a two-dimensional user defined coordinate system from the given pair of axis.
      * This coordinate system can be used with engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultUserDefinedCS} instance.
      *
@@ -1281,7 +1374,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultUserDefinedCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createUserDefinedCS", cs);
     }
@@ -1290,10 +1383,11 @@ public class GeodeticObjectFactory exten
      * Creates a three-dimensional user defined coordinate system from the given set of axis.
      * This coordinate system can be used with engineering CRS.
      *
-     * <p>The components needed by this method can be created by the following methods:</p>
-     * <ul>
+     * <div class="note"><b>Dependencies:</b>
+     * the components needed by this method can be created by the following methods:
+     * <ol>
      *   <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li>
-     * </ul>
+     * </ol></div>
      *
      * The default implementation creates a {@link DefaultUserDefinedCS} instance.
      *
@@ -1315,7 +1409,7 @@ public class GeodeticObjectFactory exten
         try {
             cs = new DefaultUserDefinedCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createUserDefinedCS", cs);
     }
@@ -1334,6 +1428,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see DefaultCoordinateSystemAxis#DefaultCoordinateSystemAxis(Map, String, AxisDirection, Unit)
+     * @see GeodeticAuthorityFactory#createCoordinateSystemAxis(String)
      */
     @Override
     public CoordinateSystemAxis createCoordinateSystemAxis(final Map<String,?> properties,
@@ -1344,7 +1439,7 @@ public class GeodeticObjectFactory exten
         try {
             axis = new DefaultCoordinateSystemAxis(complete(properties), abbreviation, direction, unit);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception);
         }
         return unique("createCoordinateSystemAxis", axis);
     }
@@ -1358,6 +1453,8 @@ public class GeodeticObjectFactory exten
      *
      * @param  xml Coordinate reference system encoded in XML format.
      * @throws FactoryException if the object creation failed.
+     *
+     * @see XML#unmarshal(String)
      */
     @Override
     public CoordinateReferenceSystem createFromXML(final String xml) throws FactoryException {
@@ -1365,7 +1462,7 @@ public class GeodeticObjectFactory exten
         try {
             object = XML.unmarshal(xml);
         } catch (JAXBException e) {
-            throw new FactoryException(e);
+            throw new FactoryException(e.getLocalizedMessage(), e);
         }
         if (object instanceof CoordinateReferenceSystem) {
             return (CoordinateReferenceSystem) object;
@@ -1415,6 +1512,7 @@ public class GeodeticObjectFactory exten
      * @throws FactoryException if the object creation failed.
      *
      * @see org.apache.sis.io.wkt
+     * @see org.apache.sis.referencing.CRS#fromWKT(String)
      * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
      * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy WKT 1</a>
      */

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -44,8 +44,11 @@ import org.apache.sis.util.ComparisonMod
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.UnsupportedImplementationException;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.parameter.Parameterized;
+import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.transform.PassThroughTransform;
 import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
@@ -54,6 +57,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.internal.system.Semaphores;
+import org.apache.sis.internal.system.Loggers;
 
 import static org.apache.sis.util.Utilities.deepEquals;
 
@@ -718,7 +722,7 @@ check:      for (int isTarget=0; ; isTar
      * @return {@code true} if both objects are equal for the given comparison mode.
      */
     @Override
-    public boolean equals(final Object object, final ComparisonMode mode) {
+    public boolean equals(final Object object, ComparisonMode mode) {
         if (super.equals(object, mode)) {
             if (mode == ComparisonMode.STRICT) {
                 final AbstractCoordinateOperation that = (AbstractCoordinateOperation) object;
@@ -730,34 +734,76 @@ check:      for (int isTarget=0; ; isTar
                     Objects.equals(coordinateOperationAccuracy, that.coordinateOperationAccuracy))
                 {
                     // Check against never-ending recursivity with DerivedCRS.
-                    if (Semaphores.queryAndSet(Semaphores.COMPARING)) {
+                    if (Semaphores.queryAndSet(Semaphores.CONVERSION_AND_CRS)) {
                         return true;
                     } else try {
                         return Objects.equals(targetCRS, that.targetCRS);
                     } finally {
-                        Semaphores.clear(Semaphores.COMPARING);
+                        Semaphores.clear(Semaphores.CONVERSION_AND_CRS);
                     }
                 }
             } else {
+                /*
+                 * This block is for all ComparisonModes other than STRICT. At this point we know that the metadata
+                 * properties (class, name, identifiers, etc.) match the criterion of the given comparison mode.
+                 * Before to continue perform the following checks:
+                 *
+                 *   - Scope, domain and accuracy properties only if NOT in "ignore metadata" mode.
+                 *   - Interpolation CRS in all cases (regardless if ignoring metadata or not).
+                 */
                 final CoordinateOperation that = (CoordinateOperation) object;
-                if (mode == ComparisonMode.BY_CONTRACT) {
-                    if (!deepEquals(getScope(),                       that.getScope(), mode) ||
-                        !deepEquals(getDomainOfValidity(),            that.getDomainOfValidity(), mode) ||
-                        !deepEquals(getCoordinateOperationAccuracy(), that.getCoordinateOperationAccuracy(), mode))
-                    {
-                        return false;
-                    }
-                }
-                if (deepEquals(getMathTransform(),    that.getMathTransform(),   mode) &&
-                    deepEquals(getSourceCRS(),        that.getSourceCRS(),       mode) &&
-                    deepEquals(getInterpolationCRS(), getInterpolationCRS(that), mode))
+                if ((mode.isIgnoringMetadata() ||
+                    (deepEquals(getScope(),                       that.getScope(), mode) &&
+                     deepEquals(getDomainOfValidity(),            that.getDomainOfValidity(), mode) &&
+                     deepEquals(getCoordinateOperationAccuracy(), that.getCoordinateOperationAccuracy(), mode))) &&
+                     deepEquals(getInterpolationCRS(),            getInterpolationCRS(that), mode))
                 {
-                    if (Semaphores.queryAndSet(Semaphores.COMPARING)) {
-                        return true;
+                    /*
+                     * At this point all metdata match or can be ignored. First, compare the targetCRS.
+                     * We need to perform this comparison only if this 'equals(…)' method is not invoked
+                     * from AbstractDerivedCRS, otherwise we would fall in an infinite recursive loop
+                     * (because targetCRS is the DerivedCRS, which in turn wants to compare this operation).
+                     *
+                     * We also opportunistically use this "anti-recursivity" check for another purpose.
+                     * The Semaphores.COMPARING flag should be set only when AbstractDerivedCRS is comparing
+                     * its "from base" conversion. The flag should never be set in any other circumstance,
+                     * since this is an internal Apache SIS mechanism. If we know that we are comparing the
+                     * AbstractDerivedCRS.fromBase conversion, then (in the way Apache SIS is implemented)
+                     * this.sourceCRS == AbstractDerivedCRS.baseCRS. Consequently we can relax the check
+                     * sourceCRS axis order if the mode is ComparisonMode.IGNORE_METADATA.
+                     */
+                    if (Semaphores.queryAndSet(Semaphores.CONVERSION_AND_CRS)) {
+                        if (mode.isIgnoringMetadata()) {
+                            mode = ComparisonMode.ALLOW_VARIANT;
+                        }
                     } else try {
-                        return deepEquals(getTargetCRS(), that.getTargetCRS(), mode);
+                        if (!deepEquals(getTargetCRS(), that.getTargetCRS(), mode)) {
+                            return false;
+                        }
                     } finally {
-                        Semaphores.clear(Semaphores.COMPARING);
+                        Semaphores.clear(Semaphores.CONVERSION_AND_CRS);
+                    }
+                    /*
+                     * Now compare the sourceCRS, potentially with a relaxed ComparisonMode (see above comment).
+                     * If the comparison mode allows the two CRS to have different axis order and units, then we
+                     * need to take in account those difference before to compare the MathTransform. We proceed
+                     * by modifying 'tr2' as if it was a MathTransform with crs1 as the source instead of crs2.
+                     */
+                    final CoordinateReferenceSystem crs1 = this.getSourceCRS();
+                    final CoordinateReferenceSystem crs2 = that.getSourceCRS();
+                    if (deepEquals(crs1, crs2, mode)) {
+                        MathTransform tr1 = this.getMathTransform();
+                        MathTransform tr2 = that.getMathTransform();
+                        if (mode == ComparisonMode.ALLOW_VARIANT) try {
+                            final MathTransform swap = MathTransforms.linear(
+                                    CoordinateSystems.swapAndScaleAxes(crs1.getCoordinateSystem(),
+                                                                       crs2.getCoordinateSystem()));
+                            tr2 = MathTransforms.concatenate(swap, tr2);
+                        } catch (Exception e) {    // (ConversionException | RuntimeException) on the JDK7 branch.
+                            Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
+                                    AbstractCoordinateOperation.class, "equals", e);
+                        }
+                        return deepEquals(tr1, tr2, mode);
                     }
                 }
             }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -93,7 +93,7 @@ class AbstractSingleOperation extends Ab
      * The operation method.
      *
      * <p><b>Consider this field as final!</b>
-     * This field is modified only at unmarshalling time by {@link #setMethod(OperationMethod)}</p>
+     * This field is modified only at unmarshalling time by {@link #setMethod(OperationMethod)}.</p>
      *
      * @see #getMethod()
      */
@@ -104,7 +104,7 @@ class AbstractSingleOperation extends Ab
      *
      * <p><b>Consider this field as final!</b>
      * This field is non-final only for the convenience of constructors and for initialization
-     * at XML unmarshalling time by {@link #setParameters(GeneralParameterValue[])}</p>
+     * at XML unmarshalling time by {@link #setParameters(GeneralParameterValue[])}.</p>
      */
     ParameterValueGroup parameters;
 
@@ -128,8 +128,7 @@ class AbstractSingleOperation extends Ab
          * However there is a few cases, for example the Molodenski transform, where we can not infer the
          * parameters easily because the operation is implemented by a concatenation of math transforms.
          */
-        parameters = Containers.property(properties, ReferencingServices.PARAMETERS_KEY, ParameterValueGroup.class);
-        // No clone since this is a SIS internal property and SIS does not modify those values after construction.
+        parameters = Parameters.unmodifiable(Containers.property(properties, ReferencingServices.PARAMETERS_KEY, ParameterValueGroup.class));
     }
 
     /**
@@ -164,7 +163,7 @@ class AbstractSingleOperation extends Ab
     protected AbstractSingleOperation(final SingleOperation operation) {
         super(operation);
         method = operation.getMethod();
-        parameters = getParameterValues(operation);
+        parameters = Parameters.unmodifiable(operation.getParameterValues());
     }
 
     /**
@@ -314,9 +313,8 @@ class AbstractSingleOperation extends Ab
      * Returns the parameter values. The default implementation performs the following choice:
      *
      * <ul>
-     *   <li>If parameter values were specified explicitely at construction time, then a
-     *       {@linkplain org.apache.sis.parameter.DefaultParameterValueGroup#clone() clone}
-     *       of those parameters is returned.</li>
+     *   <li>If parameter values were specified explicitely at construction time, then they are returned as an
+     *       {@linkplain Parameters#unmodifiable(ParameterValueGroup) unmodifiable parameter group}.</li>
      *   <li>Otherwise if this method can infer the parameter values from the
      *       {@linkplain #getMathTransform() math transform}, then those parameters are returned.</li>
      *   <li>Otherwise throw {@link org.apache.sis.util.UnsupportedImplementationException}.</li>
@@ -330,18 +328,7 @@ class AbstractSingleOperation extends Ab
      */
     @Override
     public ParameterValueGroup getParameterValues() {
-        return (parameters != null) ? parameters.clone() : super.getParameterValues();
-    }
-
-    /**
-     * Gets the parameter values of the given operation without computing and without cloning them (if possible).
-     * If the parameters are automatically inferred from the math transform, do not compute them and instead return
-     * {@code null} (in conformance with {@link #parameters} contract).
-     */
-    private static ParameterValueGroup getParameterValues(final SingleOperation operation) {
-        return (operation instanceof AbstractSingleOperation)
-               ? ((AbstractSingleOperation) operation).parameters   // Null if inferred from MathTransform
-               : operation.getParameterValues();
+        return (parameters != null) ? parameters : super.getParameterValues();
     }
 
     /**
@@ -508,6 +495,7 @@ class AbstractSingleOperation extends Ab
              */
             parameters = new DefaultParameterValueGroup(method.getParameters());
             CC_OperationMethod.store(values, parameters.values(), replacements);
+            parameters = Parameters.unmodifiable(parameters);
         } else {
             ReferencingUtilities.propertyAlreadySet(AbstractSingleOperation.class, "setParameters", "parameterValue");
         }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -74,13 +74,15 @@ final class DefaultConicProjection exten
      * @param sourceCRS  The source CRS.
      * @param targetCRS  The target CRS.
      * @param factory    The factory to use for creating a transform from the parameters or for performing axis changes.
+     * @param actual     An array of length 1 where to store the actual operation method used by the math transform factory.
      */
     DefaultConicProjection(final Conversion definition,
                            final CoordinateReferenceSystem sourceCRS,
                            final CoordinateReferenceSystem targetCRS,
-                           final MathTransformFactory factory) throws FactoryException
+                           final MathTransformFactory factory,
+                           final OperationMethod[] actual) throws FactoryException
     {
-        super(definition, sourceCRS, targetCRS, factory);
+        super(definition, sourceCRS, targetCRS, factory, actual);
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -30,12 +30,12 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.GeneralDerivedCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.datum.Datum;
 import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
@@ -63,9 +63,8 @@ import org.apache.sis.util.Utilities;
  * MathTransform, ParameterValueGroup) constructor} for such defining conversions.
  *
  * <p>After the source and target CRS become known, we can invoke the {@link #specialize specialize(…)} method for
- * {@linkplain DefaultMathTransformFactory#createBaseToDerived(CoordinateReferenceSystem, ParameterValueGroup,
- * CoordinateSystem) creating a math transform from the parameters}, instantiate a new {@code Conversion} of a
- * more specific type
+ * {@linkplain DefaultMathTransformFactory#createParameterizedTransform creating a math transform from the parameters},
+ * instantiate a new {@code Conversion} of a more specific type
  * ({@link org.opengis.referencing.operation.ConicProjection},
  *  {@link org.opengis.referencing.operation.CylindricalProjection} or
  *  {@link org.opengis.referencing.operation.PlanarProjection}) if possible,
@@ -198,7 +197,7 @@ public class DefaultConversion extends A
      * @param transform  Transform from positions in the source CRS to positions in the target CRS, or {@code null}.
      * @param parameters The {@code transform} parameter values, or {@code null}.
      *
-     * @see DefaultMathTransformFactory#createBaseToDerived(CoordinateSystem, MathTransform, CoordinateSystem)
+     * @see DefaultMathTransformFactory#swapAndScaleAxes(MathTransform, DefaultMathTransformFactory.Context)
      */
     public DefaultConversion(final Map<String,?>       properties,
                              final OperationMethod     method,
@@ -214,7 +213,7 @@ public class DefaultConversion extends A
                     .getString(Errors.Keys.UnspecifiedParameterValues));
         }
         if (parameters != null) {
-            this.parameters = parameters.clone();
+            this.parameters = Parameters.unmodifiable(parameters);
         }
         checkDimensions(properties);
     }
@@ -228,27 +227,51 @@ public class DefaultConversion extends A
      * @param source     The new source CRS.
      * @param target     The new target CRS.
      * @param factory    The factory to use for creating a transform from the parameters or for performing axis changes.
+     * @param actual     An array of length 1 where to store the actual operation method used by the math transform factory.
      */
     DefaultConversion(final Conversion definition,
                       final CoordinateReferenceSystem source,
                       final CoordinateReferenceSystem target,
-                      final MathTransformFactory factory) throws FactoryException
+                      final MathTransformFactory factory,
+                      final OperationMethod[] actual) throws FactoryException
     {
         super(definition);
         int interpDim = ReferencingUtilities.getDimension(super.getInterpolationCRS());
         if (transform == null) {
             /*
-             * If the user did not specified explicitely a MathTransform, we will need to create it
-             * from the parameters. This case happen often when creating a ProjectedCRS, because the
-             * user often did not have all needed information when he created the defining conversion:
-             * the length of semi-major and semi-minor axes were often missing. But now we know those
-             * lengths thanks to the 'sourceCRS' argument given to this method. So we can complete the
-             * parameters. This is the job of MathTransformFactory.createBaseToDerived(…).
+             * If the user did not specified explicitely a MathTransform, we will need to create it from the parameters.
+             * This case happen when creating a ProjectedCRS because the length of semi-major and semi-minor axes are
+             * often missing at defining conversion creation time. Since this constructor know those semi-axis lengths
+             * thanks to the 'sourceCRS' argument, we can complete the parameters.
              */
             if (parameters == null) {
                 throw new IllegalArgumentException(Errors.format(Errors.Keys.UnspecifiedParameterValues));
             }
-            transform = factory.createBaseToDerived(source, parameters, target.getCoordinateSystem());
+            if (factory instanceof DefaultMathTransformFactory) {
+                /*
+                 * Apache SIS specific API (not yet defined in GeoAPI, but could be proposed).
+                 * Note that setTarget(…) intentionally uses only the CoordinateSystem instead than the full
+                 * CoordinateReferenceSystem because the targetCRS is typically under construction when this
+                 * method in invoked, and attempts to use it can cause NullPointerException.
+                 */
+                final DefaultMathTransformFactory.Context context = new DefaultMathTransformFactory.Context();
+                context.setSource(source);
+                if (target instanceof GeneralDerivedCRS) {
+                    context.setTarget(target.getCoordinateSystem());    // Using 'target' would be unsafe here.
+                } else {
+                    context.setTarget(target);
+                }
+                transform = ((DefaultMathTransformFactory) factory).createParameterizedTransform(parameters, context);
+                parameters = Parameters.unmodifiable(context.getCompletedParameters());
+            } else {
+                /*
+                 * Fallback for non-SIS implementation. Equivalent to the above code, except that we can
+                 * not get the parameters completed with semi-major and semi-minor axis lengths. Most of
+                 * the code should work anyway.
+                 */
+                transform = factory.createBaseToDerived(source, parameters, target.getCoordinateSystem());
+            }
+            actual[0] = factory.getLastMethodUsed();
         } else {
             /*
              * If the user specified explicitely a MathTransform, we may still need to swap or scale axes.
@@ -256,12 +279,11 @@ public class DefaultConversion extends A
              * ProjectedCRS), then DefaultMathTransformFactory has a specialized createBaseToDerived(…)
              * method for this job.
              */
-            final CoordinateReferenceSystem sourceCRS = super.getSourceCRS();
-            final CoordinateReferenceSystem targetCRS = super.getTargetCRS();
             if (sourceCRS == null && targetCRS == null && factory instanceof DefaultMathTransformFactory) {
-                transform = ((DefaultMathTransformFactory) factory).createBaseToDerived(
-                        source.getCoordinateSystem(), transform,
-                        target.getCoordinateSystem());
+                final DefaultMathTransformFactory.Context context = new DefaultMathTransformFactory.Context();
+                context.setSource(source.getCoordinateSystem());
+                context.setTarget(target.getCoordinateSystem());    // See comment on the other setTarget(…) call.
+                transform = ((DefaultMathTransformFactory) factory).swapAndScaleAxes(transform, context);
             } else {
                 /*
                  * If we can not use our SIS factory implementation, or if this conversion is not a defining
@@ -373,7 +395,7 @@ public class DefaultConversion extends A
      *         parameter values}, or a {@linkplain CoordinateSystems#swapAndScaleAxes change of axis order or units}
      *         failed.
      *
-     * @see DefaultMathTransformFactory#createBaseToDerived(CoordinateReferenceSystem, ParameterValueGroup, CoordinateSystem)
+     * @see DefaultMathTransformFactory#createParameterizedTransform(ParameterValueGroup, DefaultMathTransformFactory.Context)
      */
     public <T extends Conversion> T specialize(final Class<T> baseType,
             final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS,

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -33,6 +33,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.Utilities;
+import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import org.apache.sis.util.collection.WeakHashSet;
 import org.apache.sis.util.collection.Containers;
@@ -244,7 +245,7 @@ public class DefaultCoordinateOperationF
         try {
             method = new DefaultOperationMethod(properties, sourceDimensions, targetDimensions, parameters);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception.getLocalizedMessage(), exception);
         }
         return pool.unique(method);
     }
@@ -304,7 +305,7 @@ public class DefaultCoordinateOperationF
         try {
             conversion = new DefaultConversion(properties, method, null, parameters);
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception.getLocalizedMessage(), exception);
         }
         // We do no invoke unique(conversion) because defining conversions are usually short-lived objects.
         return conversion;
@@ -519,7 +520,7 @@ public class DefaultCoordinateOperationF
         try {
             op = new DefaultConcatenatedOperation(properties, operations, getMathTransformFactory());
         } catch (IllegalArgumentException exception) {
-            throw new FactoryException(exception);
+            throw new InvalidGeodeticParameterException(exception.getLocalizedMessage(), exception);
         }
         return pool.unique(op);
     }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -74,13 +74,15 @@ final class DefaultCylindricalProjection
      * @param sourceCRS  The source CRS.
      * @param targetCRS  The target CRS.
      * @param factory    The factory to use for creating a transform from the parameters or for performing axis changes.
+     * @param actual     An array of length 1 where to store the actual operation method used by the math transform factory.
      */
     DefaultCylindricalProjection(final Conversion definition,
                                  final CoordinateReferenceSystem sourceCRS,
                                  final CoordinateReferenceSystem targetCRS,
-                                 final MathTransformFactory factory) throws FactoryException
+                                 final MathTransformFactory factory,
+                                 final OperationMethod[] actual) throws FactoryException
     {
-        super(definition, sourceCRS, targetCRS, factory);
+        super(definition, sourceCRS, targetCRS, factory, actual);
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -74,13 +74,15 @@ final class DefaultPlanarProjection exte
      * @param sourceCRS  The source CRS.
      * @param targetCRS  The target CRS.
      * @param factory    The factory to use for creating a transform from the parameters or for performing axis changes.
+     * @param actual     An array of length 1 where to store the actual operation method used by the math transform factory.
      */
     DefaultPlanarProjection(final Conversion definition,
                             final CoordinateReferenceSystem sourceCRS,
                             final CoordinateReferenceSystem targetCRS,
-                            final MathTransformFactory factory) throws FactoryException
+                            final MathTransformFactory factory,
+                            final OperationMethod[] actual) throws FactoryException
     {
-        super(definition, sourceCRS, targetCRS, factory);
+        super(definition, sourceCRS, targetCRS, factory, actual);
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -87,13 +87,15 @@ class DefaultProjection extends DefaultC
      * @param sourceCRS  The source CRS.
      * @param targetCRS  The target CRS.
      * @param factory    The factory to use for creating a transform from the parameters or for performing axis changes.
+     * @param actual     An array of length 1 where to store the actual operation method used by the math transform factory.
      */
     DefaultProjection(final Conversion definition,
                       final CoordinateReferenceSystem sourceCRS,
                       final CoordinateReferenceSystem targetCRS,
-                      final MathTransformFactory factory) throws FactoryException
+                      final MathTransformFactory factory,
+                      final OperationMethod[] actual) throws FactoryException
     {
-        super(definition, sourceCRS, targetCRS, factory);
+        super(definition, sourceCRS, targetCRS, factory, actual);
         ArgumentChecks.ensureCanCast("sourceCRS", GeographicCRS.class, sourceCRS);
         ArgumentChecks.ensureCanCast("targetCRS", ProjectedCRS .class, targetCRS);
     }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubTypes.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubTypes.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubTypes.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubTypes.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -36,7 +36,7 @@ import org.apache.sis.referencing.Abstra
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  */
 final class SubTypes {
@@ -126,7 +126,7 @@ final class SubTypes {
      *         the defining {@linkplain DefaultConversion#getInterface() conversion type} and
      *         the {@linkplain DefaultOperationMethod#getOperationType() method operation type}.
      */
-    static <T extends Conversion> T create(final Class<T> baseType, final Conversion definition,
+    static <T extends Conversion> T create(final Class<T> baseType, Conversion definition,
             final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS,
             final MathTransformFactory factory) throws FactoryException
     {
@@ -144,23 +144,44 @@ final class SubTypes {
                 type = c.asSubclass(type);
             }
         }
-        final Conversion conversion;
+        Conversion conversion;
         if (type.isInstance(definition)
                 && definition.getSourceCRS() == sourceCRS
                 && definition.getTargetCRS() == targetCRS
                 && definition.getMathTransform() != null)
         {
             conversion = definition;
-        } else if (CylindricalProjection.class.isAssignableFrom(type)) {
-            conversion = new DefaultCylindricalProjection(definition, sourceCRS, targetCRS, factory);
-        } else if (ConicProjection.class.isAssignableFrom(type)) {
-            conversion = new DefaultConicProjection(definition, sourceCRS, targetCRS, factory);
-        } else if (PlanarProjection.class.isAssignableFrom(type)) {
-            conversion = new DefaultPlanarProjection(definition, sourceCRS, targetCRS, factory);
-        } else if (Projection.class.isAssignableFrom(type)) {
-            conversion = new DefaultProjection(definition, sourceCRS, targetCRS, factory);
         } else {
-            conversion = new DefaultConversion(definition, sourceCRS, targetCRS, factory);
+            final OperationMethod[] actual = new OperationMethod[1];
+            boolean tryAgain;
+            do {
+                tryAgain = false;
+                if (CylindricalProjection.class.isAssignableFrom(type)) {
+                    conversion = new DefaultCylindricalProjection(definition, sourceCRS, targetCRS, factory, actual);
+                } else if (ConicProjection.class.isAssignableFrom(type)) {
+                    conversion = new DefaultConicProjection(definition, sourceCRS, targetCRS, factory, actual);
+                } else if (PlanarProjection.class.isAssignableFrom(type)) {
+                    conversion = new DefaultPlanarProjection(definition, sourceCRS, targetCRS, factory, actual);
+                } else if (Projection.class.isAssignableFrom(type)) {
+                    conversion = new DefaultProjection(definition, sourceCRS, targetCRS, factory, actual);
+                } else {
+                    conversion = new DefaultConversion(definition, sourceCRS, targetCRS, factory, actual);
+                }
+                /*
+                 * The DefaultConversion constructor may have used by MathTransformFactory for creating the actual
+                 * MathTransform object. In such case, we can use the knownledge that the factory has about the
+                 * coordinate operation for refining again the type of the object to be returned.
+                 */
+                final OperationMethod m = actual[0];
+                if (m instanceof DefaultOperationMethod) {
+                    final Class<?> t = ((DefaultOperationMethod) m).getOperationType();
+                    if (t != null && t != type && type.isAssignableFrom(t)) {
+                        type = t.asSubclass(type);
+                        definition = conversion;
+                        tryAgain = true;
+                    }
+                }
+            } while (tryAgain);
         }
         return type.cast(conversion);
     }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java?rev=1724531&r1=1724530&r2=1724531&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java [UTF-8] Wed Jan 13 23:59:38 2016
@@ -65,7 +65,7 @@ public final class AffineTransforms2D ex
         if (matrix == null || matrix instanceof AffineTransform) {
             return (AffineTransform) matrix;
         }
-        MatrixSIS.ensureSizeMatch(3, matrix);
+        MatrixSIS.ensureSizeMatch(3, 3, matrix);
         if (!Matrices.isAffine(matrix)) {
             throw new IllegalStateException(Errors.format(Errors.Keys.NotAnAffineTransform));
         }



Mime
View raw message