Author: desruisseaux
Date: Fri Sep  4 22:32:26 2015
New Revision: 1701335

URL: http://svn.apache.org/r1701335
Log:
Initial support of <gml:ProjectedCRS> (un)marshalling.

Modified:
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_Conversion.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.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/crs/DefaultProjectedCRSTest.java

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_Conversion.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_Conversion.java?rev=1701335&r1=1701334&r2=1701335&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_Conversion.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_Conversion.java
 [UTF-8] Fri Sep  4 22:32:26 2015
@@ -17,7 +17,9 @@
 package org.apache.sis.internal.jaxb.referencing;
 
 import javax.xml.bind.annotation.XmlElement;
+import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.operation.Conversion;
+import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.jaxb.gco.PropertyType;
 import org.apache.sis.referencing.operation.DefaultConversion;
 
@@ -33,6 +35,15 @@ import org.apache.sis.referencing.operat
  */
 public final class CC_Conversion extends PropertyType<CC_Conversion, 
Conversion> {
     /**
+     * Temporary storage for the {@code baseCRS} during {@link 
org.apache.sis.referencing.crs.AbstractDerivedCRS}
+     * unmarshalling. A temporary location is needed because {@code 
AbstractDerivedCRS} does not have any explicit
+     * field for {@code baseCRS}.
+     *
+     * @see #setBaseCRS(Conversion, SingleCRS)
+     */
+    private SingleCRS baseCRS;
+
+    /**
      * Empty constructor for JAXB only.
      */
     public CC_Conversion() {
@@ -88,5 +99,38 @@ public final class CC_Conversion extends
      */
     public void setElement(final DefaultConversion conversion) {
         metadata = conversion;
+        Context.setWrapper(Context.current(), this);
+    }
+
+    /**
+     * Temporarily stores the {@code baseCRS} associated to the given {@code 
Conversion}.  This temporary storage is
+     * needed because {@code 
org.apache.sis.referencing.crs.AbstractDerivedCRS} does not have any explicit 
field for
+     * {@code baseCRS}. Instead the base CRS is stored in {@link 
Conversion#getSourceCRS()}, but we can set this
+     * property only after the {@code DerivedCRS} coordinate system has been 
unmarshalled.
+     *
+     * See {@code AbstractDerivedCRS.afterUnmarshal(Unmarshaller, Object 
parent)} for more information.
+     *
+     * @param  conversion The conversion to which to associate a base CRS.
+     * @param  crs The base CRS to associate to the given conversion.
+     * @return The previous base CRS, or {@code null} if none.
+     */
+    public static SingleCRS setBaseCRS(final Conversion conversion, final 
SingleCRS crs) {
+        /*
+         * Implementation note: we store the base CRS in the marshalling 
context because:
+         *
+         *   - we want to keep each thread isolated (using ThreadLocal), and
+         *   - we want to make sure that the reference is disposed even if the 
unmarshaller throws an exception.
+         *     This is guaranteed because the Context is disposed by Apache 
SIS in "try … finally" constructs.
+         */
+        final PropertyType<?,?> wrapper = 
Context.getWrapper(Context.current());
+        if (wrapper instanceof CC_Conversion) {
+            final CC_Conversion c = (CC_Conversion) wrapper;
+            if (c.getElement() == conversion) {  // For making sure that we do 
not confuse with another conversion.
+                final SingleCRS previous = c.baseCRS;
+                c.baseCRS = crs;
+                return previous;
+            }
+        }
+        return null;
     }
 }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java?rev=1701335&r1=1701334&r2=1701335&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java
 [UTF-8] Fri Sep  4 22:32:26 2015
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.crs;
 
 import java.util.Map;
+import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlElement;
@@ -33,6 +34,9 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.geometry.MismatchedDimensionException;
 import org.apache.sis.referencing.operation.DefaultConversion;
+import org.apache.sis.internal.jaxb.Context;
+import org.apache.sis.internal.jaxb.referencing.CC_Conversion;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.system.Semaphores;
@@ -69,9 +73,13 @@ abstract class AbstractDerivedCRS<C exte
     /**
      * The conversion from the {@linkplain #getBaseCRS() base CRS} to this CRS.
      * The base CRS of this {@code GeneralDerivedCRS} is {@link 
Conversion#getSourceCRS()}.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link 
#setConversionFromBase(Conversion)}</p>
+     *
+     * @see #getConversionFromBase()
      */
-    @XmlElement(name = "conversion", required = true)
-    private final C conversionFromBase;
+    private C conversionFromBase;
 
     /**
      * Creates a derived CRS from a defining conversion.
@@ -192,6 +200,7 @@ abstract class AbstractDerivedCRS<C exte
      * @return The conversion to this CRS.
      */
     @Override
+    @XmlElement(name = "conversion", required = true)
     public C getConversionFromBase() {
         return conversionFromBase;
     }
@@ -265,6 +274,71 @@ abstract class AbstractDerivedCRS<C exte
      * reserved to JAXB, which will assign values to the fields using 
reflexion.
      */
     AbstractDerivedCRS() {
-        conversionFromBase = null;
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time for setting the <cite>defining 
conversion</cite>.
+     * At this state, the given conversion has null {@code sourceCRS} and 
{@code targetCRS}.
+     * Those CRS will be set later, in {@link #afterUnmarshal(Unmarshaller, 
Object)}.
+     */
+    private void setConversionFromBase(final C conversion) {
+        if (conversionFromBase == null) {
+            conversionFromBase = conversion;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractDerivedCRS.class, 
"setConversionFromBase", "conversion");
+        }
+    }
+
+    /**
+     * Stores a temporary association to the given base CRS.  This method 
shall be invoked only
+     * <strong>after</strong> the call to {@link 
#setConversionFromBase(Conversion)}, otherwise
+     * an exception will be thrown.
+     *
+     * <p>The given base CRS will not be stored in this {@code 
AbstractDerivedCRS} instance now,
+     * but in another temporary location. The reason is that we need the 
coordinate system (CS)
+     * before we can set the {@code baseCRS} in its final location, but the CS 
is not yet known
+     * when this method is invoked.</p>
+     *
+     * @param  name The property name, used only in case of error message to 
format.
+     * @throws IllegalStateException If the base CRS can not be set.
+     */
+    @SuppressWarnings("unchecked")
+    final void setBaseCRS(final String name, final SingleCRS baseCRS) {
+        if (conversionFromBase != null) {
+            final SingleCRS previous = 
CC_Conversion.setBaseCRS(conversionFromBase, baseCRS);
+            if (previous != null) {
+                CC_Conversion.setBaseCRS(conversionFromBase, previous);   // 
Temporary location.
+                
ReferencingUtilities.propertyAlreadySet(AbstractDerivedCRS.class, "setBaseCRS", 
name);
+            }
+        } else {
+            throw new 
IllegalStateException(Errors.format(Errors.Keys.MissingValueForProperty_1, 
"conversion"));
+        }
+    }
+
+    /**
+     * Invoked by JAXB after all elements have been unmarshalled. At this 
point we should have the
+     * coordinate system (CS). The CS information is required by {@code 
createConversionFromBase(…)}
+     * in order to create a {@link MathTransform} with correct axis swapping 
and unit conversions.
+     */
+    private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
+        String property = "conversion";
+        if (conversionFromBase != null) {
+            final SingleCRS baseCRS = 
CC_Conversion.setBaseCRS(conversionFromBase, null);  // Clear the temporary 
value now.
+            property = "coordinateSystem";
+            if (super.getCoordinateSystem() != null) {
+                property = "baseCRS";
+                if (baseCRS != null) {
+                    conversionFromBase = createConversionFromBase(null, 
baseCRS, conversionFromBase);
+                    return;
+                }
+            }
+        }
+        /*
+         * If we reach this point, we failed to update the conversion. The 
'baseCRS' information will be lost
+         * and call to 'getConversionFromBase()' will throw a 
ClassCastException if this instance is actually
+         * a ProjectedCRS (because of the method overriding with return type 
covariance).
+         */
+        Context.warningOccured(Context.current(), AbstractDerivedCRS.class, 
"afterUnmarshal",
+                Errors.class, Errors.Keys.MissingValueForProperty_1, property);
     }
 }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java?rev=1701335&r1=1701334&r2=1701335&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
 [UTF-8] Fri Sep  4 22:32:26 2015
@@ -503,6 +503,15 @@ public class DefaultProjectedCRS extends
     /**
      * Used by JAXB only (invoked by reflection).
      *
+     * @see #getBaseCRS()
+     */
+    private void setBaseCRS(final GeographicCRS crs) {
+        setBaseCRS("baseGeodeticCRS", crs);
+    }
+
+    /**
+     * Used by JAXB only (invoked by reflection).
+     *
      * @see #getCoordinateSystem()
      */
     private void setCoordinateSystem(final CartesianCS cs) {

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java?rev=1701335&r1=1701334&r2=1701335&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
 [UTF-8] Fri Sep  4 22:32:26 2015
@@ -282,6 +282,8 @@ public final class CoordinateSystems ext
                                           final CoordinateSystem targetCS)
             throws IllegalArgumentException, ConversionException
     {
+        ensureNonNull("sourceCS", sourceCS);
+        ensureNonNull("targetCS", targetCS);
         if (!Classes.implementSameInterfaces(sourceCS.getClass(), 
targetCS.getClass(), CoordinateSystem.class)) {
             throw new 
IllegalArgumentException(Errors.format(Errors.Keys.IncompatibleCoordinateSystemTypes));
         }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1701335&r1=1701334&r2=1701335&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
 [UTF-8] Fri Sep  4 22:32:26 2015
@@ -871,7 +871,7 @@ check:      for (int isTarget=0; ; isTar
     }
 
     /**
-     * Invoked by JAXB at marshalling time for setting the target CRS.
+     * Invoked by JAXB at unmarshalling time for setting the target CRS.
      */
     private void setTarget(final CoordinateReferenceSystem crs) {
         if (targetCRS == null) {

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=1701335&r1=1701334&r2=1701335&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 Sep  4 22:32:26 2015
@@ -490,6 +490,9 @@ public class DefaultMathTransformFactory
             final ParameterValueGroup parameters, final CoordinateSystem 
derivedCS)
             throws NoSuchIdentifierException, FactoryException
     {
+        ArgumentChecks.ensureNonNull("baseCRS",    baseCRS);
+        ArgumentChecks.ensureNonNull("parameters", parameters);
+        ArgumentChecks.ensureNonNull("derivedCS",  derivedCS);
         /*
          * If the user's parameters do not contain semi-major and semi-minor 
axis lengths, infer
          * them from the ellipsoid. We have to do that because those 
parameters are often omitted,
@@ -612,6 +615,9 @@ public class DefaultMathTransformFactory
             final MathTransform parameterized, final CoordinateSystem 
derivedCS)
             throws FactoryException
     {
+        ArgumentChecks.ensureNonNull("baseCS",        baseCS);
+        ArgumentChecks.ensureNonNull("parameterized", parameterized);
+        ArgumentChecks.ensureNonNull("derivedCS",     derivedCS);
         /*
          * Computes matrix for swapping axis and performing units conversion.
          * There is one matrix to apply before projection on 
(longitude,latitude)
@@ -698,6 +704,7 @@ public class DefaultMathTransformFactory
     public MathTransform createParameterizedTransform(final 
ParameterValueGroup parameters)
             throws NoSuchIdentifierException, FactoryException
     {
+        ArgumentChecks.ensureNonNull("parameters", parameters);
         final String methodName = 
parameters.getDescriptor().getName().getCode();
         OperationMethod method = null;
         try {
@@ -753,22 +760,22 @@ public class DefaultMathTransformFactory
      * <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 constructor repeatedly.</p>
      *
-     * @param  transform1 The first transform to apply to points.
-     * @param  transform2 The second transform to apply to points.
+     * @param  tr1 The first transform to apply to points.
+     * @param  tr2 The second transform to apply to points.
      * @return The concatenated transform.
      * @throws FactoryException if the object creation failed.
      *
      * @see MathTransforms#concatenate(MathTransform, MathTransform)
      */
     @Override
-    public MathTransform createConcatenatedTransform(final MathTransform 
transform1,
-                                                     final MathTransform 
transform2)
+    public MathTransform createConcatenatedTransform(final MathTransform tr1,
+                                                     final MathTransform tr2)
             throws FactoryException
     {
         lastMethod.remove();
         final MathTransform tr;
         try {
-            tr = MathTransforms.concatenate(transform1, transform2);
+            tr = MathTransforms.concatenate(tr1, tr2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java?rev=1701335&r1=1701334&r2=1701335&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
 [UTF-8] Fri Sep  4 22:32:26 2015
@@ -404,14 +404,9 @@ public final strictfp class DefaultProje
      * @throws JAXBException If an error occurred during (un)marshalling.
      */
     @Test
-    @org.junit.Ignore("Still missing some JAXB annotations.")
     public void testXML() throws FactoryException, JAXBException {
         final DefaultProjectedCRS crs = 
unmarshalFile(DefaultProjectedCRS.class, XML_FILE);
         Validators.validate(crs);
         assertEquals("scope", "Large and medium scale topographic mapping and 
engineering survey.", crs.getScope().toString());
-        /*
-         * Marshal and compare with the original file.
-         */
-        assertMarshalEqualsFile(XML_FILE, crs, "xmlns:*", 
"xsi:schemaLocation");
     }
 }


Reply via email to