sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1659712 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/referencing/operation/ sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ sis-referencing/src/test/java/org/apache/sis/referencin...
Date Fri, 13 Feb 2015 23:30:23 GMT
Author: desruisseaux
Date: Fri Feb 13 23:30:22 2015
New Revision: 1659712

URL: http://svn.apache.org/r1659712
Log:
Change in the contract of DefaultOperationMethod.redimension(...).
The javadoc tries to explain better its purpose, with "Affine" and "Molodensky" methods as
examples.
This is an incompatible change compared to Apache SIS 0.5 release, but this class was the
very last
one added before the release (maybe too late) and we hope that since it will not be used before
SIS
0.6, few users would be affected.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultOperationMethodTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java?rev=1659712&r1=1659711&r2=1659712&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
[UTF-8] Fri Feb 13 23:30:22 2015
@@ -98,7 +98,7 @@ import java.util.Objects;
  * {@link org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory}.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.5
+ * @version 0.6
  * @since   0.5
  * @module
  *
@@ -106,10 +106,16 @@ import java.util.Objects;
  * @see org.apache.sis.referencing.operation.transform.MathTransformProvider
  */
 public class DefaultOperationMethod extends AbstractIdentifiedObject implements OperationMethod
{
+    /*
+     * NOTE FOR JAVADOC WRITER:
+     * The "method" word is ambiguous here, because it can be "Java method" or "coordinate
operation method".
+     * In this class, we reserve the "method" word for "coordinate operation method" as much
as possible.
+     */
+
     /**
      * Serial number for inter-operability with different versions.
      */
-    private static final long serialVersionUID = -8181774670648793964L;
+    private static final long serialVersionUID = 2870579345991143357L;
 
     /**
      * Formula(s) or procedure used by this operation method. This may be a reference to
a publication.
@@ -123,14 +129,14 @@ public class DefaultOperationMethod exte
      * May be {@code null} if this method can work with any number of
      * source dimensions (e.g. <cite>Affine Transform</cite>).
      */
-    private final Integer sourceDimension;
+    private final Integer sourceDimensions;
 
     /**
      * Number of dimensions in the target CRS of this operation method.
      * May be {@code null} if this method can work with any number of
      * target dimensions (e.g. <cite>Affine Transform</cite>).
      */
-    private final Integer targetDimension;
+    private final Integer targetDimensions;
 
     /**
      * The set of parameters, or {@code null} if none.
@@ -183,19 +189,19 @@ public class DefaultOperationMethod exte
      * The source and target dimensions may be {@code null} if this method can work
      * with any number of dimensions (e.g. <cite>Affine Transform</cite>).
      *
-     * @param properties      Set of properties. Shall contain at least {@code "name"}.
-     * @param sourceDimension Number of dimensions in the source CRS of this operation method,
or {@code null}.
-     * @param targetDimension Number of dimensions in the target CRS of this operation method,
or {@code null}.
-     * @param parameters      Description of parameters expected by this operation.
+     * @param properties       Set of properties. Shall contain at least {@code "name"}.
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method,
or {@code null}.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method,
or {@code null}.
+     * @param parameters       Description of parameters expected by this operation.
      */
     public DefaultOperationMethod(final Map<String,?> properties,
-                                  final Integer sourceDimension,
-                                  final Integer targetDimension,
+                                  final Integer sourceDimensions,
+                                  final Integer targetDimensions,
                                   final ParameterDescriptorGroup parameters)
     {
         super(properties);
-        if (sourceDimension != null) ensurePositive("sourceDimension", sourceDimension);
-        if (targetDimension != null) ensurePositive("targetDimension", targetDimension);
+        if (sourceDimensions != null) ensurePositive("sourceDimensions", sourceDimensions);
+        if (targetDimensions != null) ensurePositive("targetDimensions", targetDimensions);
         ensureNonNull("parameters", parameters);
 
         Object value = properties.get(FORMULA_KEY);
@@ -209,9 +215,9 @@ public class DefaultOperationMethod exte
             throw new IllegalArgumentException(Errors.getResources(properties)
                     .getString(Errors.Keys.IllegalPropertyClass_2, FORMULA_KEY, value.getClass()));
         }
-        this.parameters      = parameters;
-        this.sourceDimension = sourceDimension;
-        this.targetDimension = targetDimension;
+        this.parameters       = parameters;
+        this.sourceDimensions = sourceDimensions;
+        this.targetDimensions = targetDimensions;
     }
 
     /**
@@ -223,8 +229,8 @@ public class DefaultOperationMethod exte
      */
     public DefaultOperationMethod(final MathTransform transform) {
         super(getProperties(transform));
-        sourceDimension = transform.getSourceDimensions();
-        targetDimension = transform.getTargetDimensions();
+        sourceDimensions = transform.getSourceDimensions();
+        targetDimensions = transform.getTargetDimensions();
         if (transform instanceof Parameterized) {
             parameters = ((Parameterized) transform).getParameterDescriptors();
         } else {
@@ -288,15 +294,15 @@ public class DefaultOperationMethod exte
      */
     protected DefaultOperationMethod(final OperationMethod method) {
         super(method);
-        formula         = method.getFormula();
-        parameters      = method.getParameters();
-        sourceDimension = method.getSourceDimensions();
-        targetDimension = method.getTargetDimensions();
+        formula          = method.getFormula();
+        parameters       = method.getParameters();
+        sourceDimensions = method.getSourceDimensions();
+        targetDimensions = method.getTargetDimensions();
     }
 
     /**
      * Returns a SIS operation method implementation with the same values than the given
arbitrary implementation.
-     * If the given object is {@code null}, then this method returns {@code null}.
+     * If the given object is {@code null}, then {@code null} is returned.
      * Otherwise if the given object is already a SIS implementation, then the given object
is returned unchanged.
      * Otherwise a new SIS implementation is created and initialized to the attribute values
of the given object.
      *
@@ -314,52 +320,140 @@ public class DefaultOperationMethod exte
      * The source and target dimensions may be {@code null} if this method can work with
any number of dimensions
      * (e.g. <cite>Affine Transform</cite>).
      *
-     * @param method The operation method to copy.
-     * @param sourceDimension Number of dimensions in the source CRS of this operation method.
-     * @param targetDimension Number of dimensions in the target CRS of this operation method.
+     * @param method           The operation method to copy.
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
      */
     private DefaultOperationMethod(final OperationMethod method,
-                                   final Integer sourceDimension,
-                                   final Integer targetDimension)
+                                   final Integer sourceDimensions,
+                                   final Integer targetDimensions)
     {
         super(method);
         this.formula    = method.getFormula();
         this.parameters = method.getParameters();
-        this.sourceDimension = sourceDimension;
-        this.targetDimension = targetDimension;
+        this.sourceDimensions = sourceDimensions;
+        this.targetDimensions = targetDimensions;
     }
 
     /**
-     * Returns an operation method with the same values than the specified one except the
dimensions.
-     * The source and target dimensions may be {@code null} if this method can work with
any number of dimensions
-     * (e.g. <cite>Affine Transform</cite>).
+     * Returns an operation method with different dimensions, if we are allowed to change
dimensionality.
+     * This method accepts to change a dimension only if the value specified by the original
method
+     * is {@code null}. Otherwise an {@link IllegalArgumentException} is thrown.
+     *
+     * @param method           The operation method to redimension.
+     * @param sourceDimensions The desired new source dimensions.
+     * @param methodSource     The current number of source dimensions (may be {@code null}).
+     * @param targetDimensions The desired new target dimensions.
+     * @param methodTarget     The current number of target dimensions (may be {@code null}).
+     * @throws IllegalArgumentException if the given dimensions are illegal for this operation
method.
+     */
+    private static OperationMethod redimension(final OperationMethod method,
+            final int sourceDimensions, final Integer methodSource,
+            final int targetDimensions, final Integer methodTarget)
+    {
+        boolean sourceValids = (methodSource != null) && (methodSource == sourceDimensions);
+        boolean targetValids = (methodTarget != null) && (methodTarget == targetDimensions);
+        if (sourceValids && targetValids) {
+            return method;
+        }
+        sourceValids |= (methodSource == null);
+        targetValids |= (methodTarget == null);
+        ensurePositive("sourceDimensions", sourceDimensions);
+        ensurePositive("targetDimensions", targetDimensions);
+        if (!sourceValids || !targetValids) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalOperationDimension_3,
+                    method.getName().getCode(), sourceDimensions, targetDimensions));
+        }
+        return new DefaultOperationMethod(method, sourceDimensions, targetDimensions);
+    }
+
+    /**
+     * Returns an operation method with different dimensions, if we are allowed to change
dimensionality.
+     * The need to change an {@code OperationMethod} dimensionality may occur in two contexts:
+     *
+     * <ul>
+     *   <li><p>When the original method can work with any number of dimensions.
Those methods do not know
+     *     in advance the number of dimensions, which is fixed only after the actual {@link
MathTransform}
+     *     instance has been created.
+     *     Example: <cite>Affine</cite> conversion.</p></li>
+     *   <li><p>When a three-dimensional method can also be used in the two-dimensional
case, typically by
+     *     assuming that the ellipsoidal height is zero everywhere.
+     *     Example: <cite>Molodensky</cite> transform.</p></li>
+     * </ul>
      *
-     * @param  method The operation method to redimension, or {@code null}.
-     * @param  sourceDimension Number of dimensions in the source CRS of this operation method.
-     * @param  targetDimension Number of dimensions in the target CRS of this operation method.
-     * @return The redimensioned operation method, or {@code method} if the given method
was {@code null}
-     *         or already had th given dimensions.
+     * This {@code redimension(…)} implementation performs the following choice:
+     *
+     * <ul>
+     *   <li><p>If the given method is an instance of {@code DefaultOperationMethod},
then delegate to
+     *     {@link #redimension(int, int)} in order to allow subclasses to defines their own
policy.
+     *     For example the <cite>Molodensky</cite> method needs to override.</p></li>
+     *   <li>Otherwise for each dimension (<var>source</var> and <var>target</var>):
+     *     <ul>
+     *       <li>If the corresponding dimension of the given method is {@code null},
then
+     *         set that dimension to the given value in a new {@code OperationMethod}.</li>
+     *       <li>Otherwise if the given value is not equal to the corresponding dimension
+     *         in the given method, throw an {@link IllegalArgumentException}.</li>
+     *     </ul>
+     *   </li>
+     * </ul>
+     *
+     * @param  method           The operation method to redimension, or {@code null}.
+     * @param  sourceDimensions The desired number of input dimensions.
+     * @param  targetDimensions The desired number of output dimensions.
+     * @return The redimensioned operation method, or {@code null} if the given method was
null,
+     *         or {@code method} if no change is needed.
+     * @throws IllegalArgumentException if the given dimensions are illegal for the given
operation method.
      */
     public static OperationMethod redimension(OperationMethod method,
-                                        final Integer sourceDimension,
-                                        final Integer targetDimension)
+            final int sourceDimensions, final int targetDimensions)
     {
-        if (sourceDimension != null) ensurePositive("sourceDimension", sourceDimension);
-        if (targetDimension != null) ensurePositive("targetDimension", targetDimension);
-        if (method != null && !(Objects.equals(sourceDimension, method.getSourceDimensions())
-                             && Objects.equals(targetDimension, method.getTargetDimensions())))
-        {
-            method = new DefaultOperationMethod(method, sourceDimension, targetDimension);
+        if (method != null) {
+            if (method instanceof DefaultOperationMethod) {
+                return ((DefaultOperationMethod) method).redimension(sourceDimensions, targetDimensions);
+            } else {
+                method = redimension(method, sourceDimensions, method.getSourceDimensions(),
+                                             targetDimensions, method.getTargetDimensions());
+            }
         }
         return method;
     }
 
     /**
+     * Returns this operation method with different dimensions, if we are allowed to change
dimensionality.
+     * See {@link #redimension(OperationMethod, int, int)} for more information.
+     *
+     * <p>The default implementation performs the following choice:
+     * for each dimension (<var>source</var> and <var>target</var>):</p>
+     * <ul>
+     *   <li>If the corresponding dimension of the given method is {@code null}, then
+     *       set that dimension to the given value in a new {@code OperationMethod}.</li>
+     *   <li>Otherwise if the given value is not equal to the corresponding dimension
+     *       in the given method, throw an {@link IllegalArgumentException}.</li>
+     * </ul>
+     *
+     * Subclasses should override this method if they can work with different number of dimensions.
+     * For example a <cite>Molodensky</cite> transform usually works in a three-dimensional
space,
+     * but can also work in a two-dimensional space by assuming that the ellipsoidal height
is zero
+     * everywhere.
+     *
+     * @param  sourceDimensions The desired number of input dimensions.
+     * @param  targetDimensions The desired number of output dimensions.
+     * @return The redimensioned operation method, or {@code this} if no change is needed.
+     * @throws IllegalArgumentException if the given dimensions are illegal for this operation
method.
+     *
+     * @since 0.6
+     */
+    public OperationMethod redimension(final int sourceDimensions, final int targetDimensions)
{
+        return redimension(this, sourceDimensions, this.sourceDimensions,
+                                 targetDimensions, this.targetDimensions);
+    }
+
+    /**
      * Returns the GeoAPI interface implemented by this class.
      * The SIS implementation returns {@code OperationMethod.class}.
      *
      * <div class="note"><b>Note for implementors:</b>
-     * Subclasses usually do not need to override this method since GeoAPI does not define
{@code OperationMethod}
+     * Subclasses usually do not need to override this information since GeoAPI does not
define {@code OperationMethod}
      * sub-interface. Overriding possibility is left mostly for implementors who wish to
extend GeoAPI with their
      * own set of interfaces.</div>
      *
@@ -390,7 +484,7 @@ public class DefaultOperationMethod exte
      *     {@link org.opengis.referencing.operation.PlanarProjection} subtypes.</p></li>
      * </ul>
      *
-     * In case of doubt, this method can conservatively return the base type.
+     * In case of doubt, {@code getOperationType()} can conservatively return the base type.
      * The default implementation returns {@code SingleOperation.class},
      * which is the most conservative return value.
      *
@@ -430,7 +524,7 @@ public class DefaultOperationMethod exte
      */
     @Override
     public Integer getSourceDimensions() {
-        return sourceDimension;
+        return sourceDimensions;
     }
 
     /**
@@ -443,7 +537,7 @@ public class DefaultOperationMethod exte
      */
     @Override
     public Integer getTargetDimensions() {
-        return targetDimension;
+        return targetDimensions;
     }
 
     /**
@@ -482,10 +576,10 @@ public class DefaultOperationMethod exte
                 case STRICT: {
                     // Name and identifiers have been compared by super.equals(object, mode).
                     final DefaultOperationMethod that = (DefaultOperationMethod) object;
-                    return Objects.equals(this.formula,         that.formula) &&
-                           Objects.equals(this.sourceDimension, that.sourceDimension) &&
-                           Objects.equals(this.targetDimension, that.targetDimension) &&
-                           Objects.equals(this.parameters,      that.parameters);
+                    return Objects.equals(this.formula,          that.formula) &&
+                           Objects.equals(this.sourceDimensions, that.sourceDimensions) &&
+                           Objects.equals(this.targetDimensions, that.targetDimensions) &&
+                           Objects.equals(this.parameters,       that.parameters);
                 }
                 case BY_CONTRACT: {
                     // Name and identifiers have been compared by super.equals(object, mode).
@@ -534,7 +628,7 @@ public class DefaultOperationMethod exte
      */
     @Override
     protected long computeHashCode() {
-        return super.computeHashCode() + Objects.hash(sourceDimension, targetDimension, parameters);
+        return super.computeHashCode() + Objects.hash(sourceDimensions, targetDimensions,
parameters);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1659712&r1=1659711&r2=1659712&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
[UTF-8] Fri Feb 13 23:30:22 2015
@@ -93,6 +93,13 @@ import org.apache.sis.util.resources.Mes
  * @module
  */
 public class DefaultMathTransformFactory extends AbstractFactory implements MathTransformFactory
{
+    /*
+     * NOTE FOR JAVADOC WRITER:
+     * The "method" word is ambiguous here, because it can be "Java method" or "coordinate
operation method".
+     * In this class, we reserve the "method" word for "coordinate operation method" as much
as possible.
+     * For Java methods, we rather use "constructor" or "function".
+     */
+
     /**
      * The separator character between an identifier and its namespace in the argument given
to
      * {@link #getOperationMethod(String)}. For example this is the separator in {@code "EPSG:9807"}.
@@ -136,7 +143,7 @@ public class DefaultMathTransformFactory
     private final Map<Class<?>, OperationMethodSet> methodsByType;
 
     /**
-     * The last method used by a {@code create(…)} method.
+     * The last coordinate operation method used by a {@code create(…)} constructor.
      */
     private final ThreadLocal<OperationMethod> lastMethod;
 
@@ -213,8 +220,8 @@ public class DefaultMathTransformFactory
      *   <li>{@link SingleOperation} for all coordinate operations.</li>
      * </ul>
      *
-     * This method may conservatively return more {@code OperationMethod} elements than requested
-     * if it does not support filtering by the given type.
+     * The returned set may conservatively contain more {@code OperationMethod} elements
than requested
+     * if this {@code MathTransformFactory} does not support filtering by the given type.
      *
      * @param  type <code>{@linkplain SingleOperation}.class</code> for fetching
all operation methods,
      *         <code>{@linkplain org.opengis.referencing.operation.Projection}.class</code>
for fetching
@@ -264,7 +271,7 @@ public class DefaultMathTransformFactory
      * methods are deprecated, the first one is returned.</p>
      *
      * @param  identifier The name or identifier of the operation method to search.
-     * @return The operation method for the given name or identifier.
+     * @return The coordinate operation method for the given name or identifier.
      * @throws NoSuchIdentifierException if there is no operation method registered for the
specified identifier.
      */
     public OperationMethod getOperationMethod(String identifier) throws NoSuchIdentifierException
{
@@ -304,9 +311,9 @@ public class DefaultMathTransformFactory
     /**
      * Returns {@code true} if the name or an identifier of the given method matches the
given {@code identifier}.
      *
-     * This method is private and static for now, but we may consider to make it a protected
member in a future
-     * SIS version in order to give users a chance to override the matching criterion. We
don't do that yet
-     * because we would like to have at least one use case before doing so.
+     * This function is private and static for now, but we may consider to make it a protected
member
+     * in a future SIS version in order to give users a chance to override the matching criterion.
+     * We don't do that yet because we would like to have at least one use case before doing
so.
      *
      * @param  method     The method to test for a match.
      * @param  identifier The name or identifier of the operation method to search.
@@ -331,15 +338,17 @@ public class DefaultMathTransformFactory
     }
 
     /**
-     * Returns the default parameter values for a math transform using the given method.
-     * The method argument is the name of any operation method returned by the {@link #getAvailableMethods(Class)}
method.
+     * Returns the default parameter values for a math transform using the given operation
method.
+     * The {@code method} argument is the name of any {@code OperationMethod} instance returned
by
+     * <code>{@link #getAvailableMethods(Class) getAvailableMethods}({@linkplain SingleOperation}.class)</code>.
      * A typical example is
      * "<a href="http://www.remotesensing.org/geotiff/proj_list/transverse_mercator.html">Transverse
Mercator</a>").
      *
-     * <p>This method creates new parameter instances at every call. The returned object
is intended to be modified
-     * by the user before to be passed to {@link #createParameterizedTransform(ParameterValueGroup)}.</p>
+     * <p>This function creates new parameter instances at every call.
+     * Parameters are intended to be modified by the user before to be given to the
+     * {@link #createParameterizedTransform createParameterizedTransform(…)} constructor.</p>
      *
-     * @param  method The name or identifier of the operation method to search.
+     * @param  method The case insensitive name of the coordinate operation method to search
for.
      * @return A new group of parameter values for the {@code OperationMethod} identified
by the given name.
      * @throws NoSuchIdentifierException if there is no method registered for the given name
or identifier.
      *
@@ -355,7 +364,7 @@ public class DefaultMathTransformFactory
     /**
      * Returns the value of the given parameter in the given unit, or {@code NaN} if the
parameter is not set.
      *
-     * <p><b>NOTE:</b> Do not merge this method with {@code ensureSet(…)}.
We keep those two methods
+     * <p><b>NOTE:</b> Do not merge this function with {@code ensureSet(…)}.
We keep those two methods
      * separated in order to give to {@code createBaseToDerived(…)} a "all or nothing"
behavior.</p>
      */
     private static double getValue(final ParameterValue<?> parameter, final Unit<Length>
unit) {
@@ -392,7 +401,7 @@ public class DefaultMathTransformFactory
 
     /**
      * Creates a transform from a base CRS to a derived CS using the given parameters.
-     * This convenience method:
+     * This convenience constructor:
      *
      * <ol>
      *   <li>Infers the {@code "semi_major"} and {@code "semi_minor"} parameters values
from the
@@ -404,7 +413,7 @@ public class DefaultMathTransformFactory
      *       with any other transform required for performing units changes and ordinates
swapping.</li>
      * </ol>
      *
-     * The {@code OperationMethod} instance used by this method can be obtained by a call
to
+     * The {@code OperationMethod} instance used by this constructor can be obtained by a
call to
      * {@link #getLastMethodUsed()}.
      *
      * @param  baseCRS    The source coordinate reference system.
@@ -412,7 +421,7 @@ public class DefaultMathTransformFactory
      * @param  derivedCS  The target coordinate system.
      * @return The parameterized transform from {@code baseCRS} to {@code derivedCS},
      *         including unit conversions and axis swapping.
-     * @throws NoSuchIdentifierException if there is no transform registered for the method.
+     * @throws NoSuchIdentifierException if there is no transform registered for the coordinate
operation method.
      * @throws FactoryException if the object creation failed. This exception is thrown
      *         if some required parameter has not been supplied, or has illegal value.
      */
@@ -491,7 +500,7 @@ public class DefaultMathTransformFactory
 
     /**
      * Creates a transform from a base to a derived CS using an existing parameterized transform.
-     * This convenience method {@linkplain #createConcatenatedTransform concatenates} the
given parameterized
+     * This convenience constructor {@linkplain #createConcatenatedTransform concatenates}
the given parameterized
      * transform with any other transform required for performing units changes and ordinates
swapping.
      *
      * <p>The given {@code parameterized} transform shall expect
@@ -590,7 +599,7 @@ public class DefaultMathTransformFactory
      *
      * @param  parameters The parameter values.
      * @return The parameterized transform.
-     * @throws NoSuchIdentifierException if there is no transform registered for the method.
+     * @throws NoSuchIdentifierException if there is no transform registered for the coordinate
operation method.
      * @throws FactoryException if the object creation failed. This exception is thrown
      *         if some required parameter has not been supplied, or has illegal value.
      *
@@ -671,7 +680,7 @@ public class DefaultMathTransformFactory
      * A concatenated transform acts in the same way as applying two transforms, one after
the other.
      *
      * <p>The dimension of the output space of the first transform must match the dimension
of the input space
-     * in the second transform. In order to concatenate more than two transforms, use this
method repeatedly.</p>
+     * in the second transform. In order to concatenate more than two transforms, use this
constructor repeatedly.</p>
      *
      * @param  transform1 The first transform to apply to points.
      * @param  transform2 The second transform to apply to points.
@@ -738,7 +747,7 @@ public class DefaultMathTransformFactory
 
     /**
      * Creates a math transform object from a XML string. The default implementation
-     * always throws an exception, since this method is not yet implemented.
+     * always throws an exception, since this constructor is not yet implemented.
      *
      * @param  xml Math transform encoded in XML format.
      * @throws FactoryException if the object creation failed.
@@ -766,10 +775,15 @@ public class DefaultMathTransformFactory
     }
 
     /**
-     * Returns the operation method used by the latest call to a {@code create} method in
the currently running thread.
-     * Returns {@code null} if not applicable.
+     * Returns the operation method used by the latest call to a {@code create(…)} constructor
+     * in the currently running thread. Returns {@code null} if not applicable.
+     *
+     * <p>Invoking {@code getLastMethodUsed()} can be useful after a call to
+     * {@link #createParameterizedTransform createParameterizedTransform(…)}, or after
a call to another
+     * constructor that delegates its work to {@code createParameterizedTransform(…)},
for example
+     * {@link #createBaseToDerived createBaseToDerived(…)}.</p>
      *
-     * @return The last method used, or {@code null} if unknown of unsupported.
+     * @return The last method used by a {@code create(…)} constructor, or {@code null}
if unknown of unsupported.
      *
      * @see #createParameterizedTransform(ParameterValueGroup)
      */

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultOperationMethodTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultOperationMethodTest.java?rev=1659712&r1=1659711&r2=1659712&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultOperationMethodTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultOperationMethodTest.java
[UTF-8] Fri Feb 13 23:30:22 2015
@@ -41,7 +41,7 @@ import static org.apache.sis.test.TestUt
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.5
- * @since   0.5
+ * @since   0.6
  * @module
  */
 @DependsOn({
@@ -55,9 +55,12 @@ public final strictfp class DefaultOpera
      * @param  method     The operation name (example: "Mercator (variant A)").
      * @param  identifier The EPSG numeric identifier (example: "9804").
      * @param  formula    Formula citation (example: "EPSG guidance note #7-2").
+     * @param  dimension  The number of input and output dimension.
      * @return The operation method.
      */
-    private static DefaultOperationMethod create(final String method, final String identifier,
final String formula) {
+    private static DefaultOperationMethod create(final String method, final String identifier,
final String formula,
+            final Integer dimension)
+    {
         final Map<String,Object> properties = new HashMap<>(8);
         assertNull(properties.put(OperationMethod.NAME_KEY, method));
         assertNull(properties.put(Identifier.CODESPACE_KEY, "EPSG"));
@@ -74,7 +77,7 @@ public final strictfp class DefaultOpera
         assertNotNull(properties.put(OperationMethod.NAME_KEY, parameters.getName()));
         assertNull(properties.put(OperationMethod.IDENTIFIERS_KEY, new ImmutableIdentifier(HardCodedCitations.OGP,
"EPSG", identifier)));
         assertNull(properties.put(OperationMethod.FORMULA_KEY, new DefaultCitation(formula)));
-        return new DefaultOperationMethod(properties, 2, 2, parameters);
+        return new DefaultOperationMethod(properties, dimension, dimension, parameters);
     }
 
     /**
@@ -82,7 +85,7 @@ public final strictfp class DefaultOpera
      */
     @Test
     public void testConstruction() {
-        final OperationMethod method = create("Mercator (variant A)", "9804", "EPSG guidance
note #7-2");
+        final OperationMethod method = create("Mercator (variant A)", "9804", "EPSG guidance
note #7-2", 2);
         assertEpsgIdentifierEquals("Mercator (variant A)", method.getName());
         assertEpsgIdentifierEquals("9804", getSingleton(method.getIdentifiers()));
         assertEquals("formula", "EPSG guidance note #7-2", method.getFormula().getCitation().getTitle().toString());
@@ -95,15 +98,16 @@ public final strictfp class DefaultOpera
      */
     @Test
     public void testEquals() {
-        final DefaultOperationMethod m1 = create("Mercator (variant A)", "9804", "EPSG guidance
note #7-2");
-        final DefaultOperationMethod m2 = create("Mercator (variant A)", "9804", "E = FE
+ a*ko(lon - lonO)");
+        final Integer dim = 2;
+        final DefaultOperationMethod m1 = create("Mercator (variant A)", "9804", "EPSG guidance
note #7-2",   dim);
+        final DefaultOperationMethod m2 = create("Mercator (variant A)", "9804", "E = FE
+ a*ko(lon - lonO)", dim);
         assertFalse ("STRICT",          m1.equals(m2, ComparisonMode.STRICT));
         assertFalse ("BY_CONTRACT",     m1.equals(m2, ComparisonMode.BY_CONTRACT));
         assertTrue  ("IGNORE_METADATA", m1.equals(m2, ComparisonMode.IGNORE_METADATA));
         assertEquals("Hash code should ignore metadata.", m1.hashCode(), m2.hashCode());
 
-        final DefaultOperationMethod m3 = create("Mercator (variant B)", "9805", "EPSG guidance
note #7-2");
-        final DefaultOperationMethod m4 = create("mercator (variant b)", "9805", "EPSG guidance
note #7-2");
+        final DefaultOperationMethod m3 = create("Mercator (variant B)", "9805", "EPSG guidance
note #7-2", dim);
+        final DefaultOperationMethod m4 = create("mercator (variant b)", "9805", "EPSG guidance
note #7-2", dim);
         assertFalse("IGNORE_METADATA", m1.equals(m3, ComparisonMode.IGNORE_METADATA));
         assertTrue ("IGNORE_METADATA", m3.equals(m4, ComparisonMode.IGNORE_METADATA));
         assertFalse("BY_CONTRACT",     m3.equals(m4, ComparisonMode.BY_CONTRACT));
@@ -114,25 +118,36 @@ public final strictfp class DefaultOpera
      */
     @Test
     @DependsOnMethod({"testConstruction", "testEquals"})
-    public void testResize() {
-        final OperationMethod method = create("Affine geometric transformation", "9623",
"EPSG guidance note #7-2");
+    public void testRedimension() {
+        final OperationMethod method = create("Affine geometric transformation", "9623",
"EPSG guidance note #7-2", null);
         OperationMethod other = DefaultOperationMethod.redimension(method, 2, 2);
-        assertSame(method, other);
-        assertTrue(method.equals(other));
+        assertSame(other, DefaultOperationMethod.redimension(other, 2, 2));
+        assertNotSame(method, other);
+        assertFalse(method.equals(other));
         assertEquals("sourceDimensions", Integer.valueOf(2), other.getSourceDimensions());
         assertEquals("targetDimensions", Integer.valueOf(2), other.getTargetDimensions());
 
         other = DefaultOperationMethod.redimension(method, 2, 3);
+        assertSame(other, DefaultOperationMethod.redimension(other, 2, 3));
         assertNotSame(method, other);
         assertFalse(method.equals(other));
         assertEquals("sourceDimensions", Integer.valueOf(2), other.getSourceDimensions());
         assertEquals("targetDimensions", Integer.valueOf(3), other.getTargetDimensions());
 
         other = DefaultOperationMethod.redimension(method, 3, 2);
+        assertSame(other, DefaultOperationMethod.redimension(other, 3, 2));
         assertNotSame(method, other);
         assertFalse(method.equals(other));
         assertEquals("sourceDimensions", Integer.valueOf(3), other.getSourceDimensions());
         assertEquals("targetDimensions", Integer.valueOf(2), other.getTargetDimensions());
+
+        try {
+            DefaultOperationMethod.redimension(other, 3, 3);
+            fail("Should not have accepted to change non-null dimensions.");
+        } catch (IllegalArgumentException e) {
+            final String message = e.getLocalizedMessage();
+            assertTrue(message, message.contains("Affine geometric transformation"));
+        }
     }
 
     /**
@@ -141,7 +156,7 @@ public final strictfp class DefaultOpera
     @Test
     @DependsOnMethod("testConstruction")
     public void testWKT() {
-        final OperationMethod method = create("Mercator (variant A)", "9804", "EPSG guidance
note #7-2");
+        final OperationMethod method = create("Mercator (variant A)", "9804", "EPSG guidance
note #7-2", 2);
         assertWktEquals("Method[“Mercator (variant A)”, Id[“EPSG”, 9804, Citation[“OGP”],
URI[“urn:ogc:def:method:EPSG::9804”]]]", method);
         assertWktEquals(Convention.WKT1, "PROJECTION[“Mercator (variant A)”, AUTHORITY[“EPSG”,
“9804”]]", method);
     }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1659712&r1=1659711&r2=1659712&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] Fri Feb 13 23:30:22 2015
@@ -333,6 +333,11 @@ public final class Errors extends Indexe
         public static final short IllegalMemberType_2 = 37;
 
         /**
+         * Dimensions of “{0}” operation can not be ({1}, {2}).
+         */
+        public static final short IllegalOperationDimension_3 = 180;
+
+        /**
          * This operation can not be applied to values of class ‘{0}’.
          */
         public static final short IllegalOperationForValueClass_1 = 141;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1659712&r1=1659711&r2=1659712&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] Fri Feb 13 23:30:22 2015
@@ -76,6 +76,7 @@ IllegalClass_2                    = Clas
 IllegalFormatPatternForClass_2    = The \u201c{1}\u201d pattern can not be applied to formating
of objects of type \u2018{0}\u2019.
 IllegalLanguageCode_1             = The \u201c{0}\u201d language is not recognized.
 IllegalMemberType_2               = Member \u201c{0}\u201d can not be associated to type
\u201c{1}\u201d.
+IllegalOperationDimension_3       = Dimensions of \u201c{0}\u201d operation can not be ({1},
{2}).
 IllegalOperationForValueClass_1   = This operation can not be applied to values of class
\u2018{0}\u2019.
 IllegalOptionValue_2              = Option \u2018{0}\u2019 can not take the \u201c{1}\u201d
value.
 IllegalOrdinateRange_3            = The [{0} \u2026 {1}] range of ordinate values is not
valid for the \u201c{2}\u201d axis.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1659712&r1=1659711&r2=1659712&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] Fri Feb 13 23:30:22 2015
@@ -66,6 +66,7 @@ IllegalClass_2                    = La c
 IllegalFormatPatternForClass_2    = Le mod\u00e8le \u00ab\u202f{1}\u202f\u00bb ne peut pas
\u00eatre appliqu\u00e9 au formatage d\u2019objets de type \u2018{0}\u2019.
 IllegalLanguageCode_1             = Le code de langue \u00ab\u202f{0}\u202f\u00bb n\u2019est
pas reconnu.
 IllegalMemberType_2               = Le membre \u00ab\u202f{0}\u202f\u00bb ne peut pas \u00eatre
associ\u00e9 au type \u00ab\u202f{1}\u202f\u00bb.
+IllegalOperationDimension_3       = Les dimensions de l\u2019op\u00e9ration \u00ab\u202f{0}\u202f\u00bb
ne peuvent pas \u00eatre ({1}, {2}).
 IllegalOperationForValueClass_1   = Cette op\u00e9ration ne peut pas s\u2019appliquer aux
valeurs de classe \u2018{0}\u2019.
 IllegalOptionValue_2              = L\u2019option \u2018{0}\u2019 n\u2019accepte pas la valeur
\u00ab\u202f{1}\u202f\u00bb.
 IllegalOrdinateRange_3            = La plage de valeurs de coordonn\u00e9es [{0} \u2026 {1}]
n\u2019est pas valide pour l\u2019axe \u00ab\u202f{2}\u202f\u00bb.



Mime
View raw message