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.


Reply via email to