This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 5c80ea7d23 Revert https://issues.apache.org/jira/browse/SIS-166 for `DefaultEngineeringCRS`. That class appears to have the same problem than coordinate system in other CRS: the array of axes is empty for an unknown reason. 5c80ea7d23 is described below commit 5c80ea7d230b30f005cfafe721193e0e437781b8 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Thu Aug 11 17:36:08 2022 +0200 Revert https://issues.apache.org/jira/browse/SIS-166 for `DefaultEngineeringCRS`. That class appears to have the same problem than coordinate system in other CRS: the array of axes is empty for an unknown reason. The tests for GML parsing of EngineeringCRS were wrong. Maybe it is the reason why this bug was unnoticed. --- .../apache/sis/metadata/iso/DefaultMetadata.java | 5 +- .../apache/sis/referencing/crs/AbstractCRS.java | 2 +- .../sis/referencing/crs/DefaultEngineeringCRS.java | 107 ++++++++++++++++----- .../sis/referencing/crs/DefaultGeodeticCRS.java | 6 +- .../sis/referencing/crs/DefaultImageCRS.java | 5 +- .../org/apache/sis/referencing/cs/AbstractCS.java | 1 + .../referencing/crs/DefaultEngineeringCRSTest.java | 100 ++++++++++--------- 7 files changed, 142 insertions(+), 84 deletions(-) diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java index 158a87169d..b9539f8e6b 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java @@ -144,6 +144,7 @@ import org.apache.sis.math.FunctionProperty; * @since 0.3 * @module */ +@SuppressWarnings("serial") // Fields are not statically typed as Serializable. @XmlType(name = "MD_Metadata_Type", propOrder = { // Attributes new in ISO 19115:2014 "metadataIdentifier", @@ -1630,8 +1631,8 @@ public class DefaultMetadata extends ISOMetadata implements Metadata { } /** - * Invoked by JAXB {@link javax.xml.bind.Marshaller} after this object has been marshalled to - * XML. This method restores the locale to be used for XML marshalling to its previous value. + * Invoked by JAXB {@link javax.xml.bind.Marshaller} after this object has been marshalled to XML. + * This method restores the locale to be used for XML marshalling to its previous value. */ @SuppressWarnings("unused") private void afterMarshal(final Marshaller marshaller) { diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java index 2f51bc3b8e..078bcf316e 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java @@ -282,7 +282,7 @@ public class AbstractCRS extends AbstractReferenceSystem implements CoordinateRe final <T extends CoordinateSystem> T getCoordinateSystem(final Class<T> type) { final CoordinateSystem cs = coordinateSystem; if (type.isInstance(cs)) { - // Special case for AfficeCS: must ensure that the cs is not the CartesianCS subtype. + // Special case for AffineCS: must ensure that the cs is not the CartesianCS subtype. if (type != AffineCS.class || !(cs instanceof CartesianCS)) { return (T) cs; } diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java index 624d907d80..35eb3b4092 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java @@ -19,15 +19,16 @@ package org.apache.sis.referencing.crs; import java.util.Map; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlRootElement; -import org.opengis.referencing.cs.CoordinateSystem; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.opengis.referencing.cs.*; import org.opengis.referencing.crs.EngineeringCRS; import org.opengis.referencing.datum.EngineeringDatum; import org.apache.sis.referencing.cs.*; import org.apache.sis.referencing.AbstractReferenceSystem; import org.apache.sis.internal.metadata.MetadataUtilities; import org.apache.sis.internal.referencing.WKTKeywords; +import org.apache.sis.internal.jaxb.referencing.CS_CoordinateSystem; import org.apache.sis.io.wkt.Formatter; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; @@ -69,7 +70,14 @@ import static org.apache.sis.util.ArgumentChecks.ensureNonNull; * @module */ @XmlType(name = "EngineeringCRSType", propOrder = { - "coordinateSystem", + "abstractCS", + "affineCS", + "cartesianCS", + "cylindricalCS", + "linearCS", + "polarCS", + "sphericalCS", + "userDefinedCS", "datum" }) @XmlRootElement(name = "EngineeringCRS") @@ -208,26 +216,6 @@ public class DefaultEngineeringCRS extends AbstractCRS implements EngineeringCRS return datum; } - /** - * Returns the coordinate system. - * - * @return the coordinate system. - */ - @Override - @XmlElements({ - @XmlElement(name = "cartesianCS", type = DefaultCartesianCS.class), - @XmlElement(name = "affineCS", type = DefaultAffineCS.class), - @XmlElement(name = "cylindricalCS", type = DefaultCylindricalCS.class), - @XmlElement(name = "linearCS", type = DefaultLinearCS.class), - @XmlElement(name = "polarCS", type = DefaultPolarCS.class), - @XmlElement(name = "sphericalCS", type = DefaultSphericalCS.class), - @XmlElement(name = "userDefinedCS", type = DefaultUserDefinedCS.class), - @XmlElement(name = "coordinateSystem", type = AbstractCS.class) - }) - public CoordinateSystem getCoordinateSystem() { - return super.getCoordinateSystem(); - } - /** * {@inheritDoc} * @@ -304,10 +292,77 @@ public class DefaultEngineeringCRS extends AbstractCRS implements EngineeringCRS /** * Used by JAXB only (invoked by reflection). + * Only one of {@code getFooCS()} methods can return a non-null value. + * + * <div class="note"><b>Implementation note:</b> + * The usual way to handle {@code <xs:choice>} with JAXB is to annotate a single method like below: * - * @see #getCoordinateSystem() + * {@preformat java + * @Override + * @XmlElements({ + * @XmlElement(name = "cartesianCS", type = DefaultCartesianCS.class), + * @XmlElement(name = "affineCS", type = DefaultAffineCS.class), + * @XmlElement(name = "cylindricalCS", type = DefaultCylindricalCS.class), + * @XmlElement(name = "linearCS", type = DefaultLinearCS.class), + * @XmlElement(name = "polarCS", type = DefaultPolarCS.class), + * @XmlElement(name = "sphericalCS", type = DefaultSphericalCS.class), + * @XmlElement(name = "userDefinedCS", type = DefaultUserDefinedCS.class) + * }) + * public CoordinateSystem getCoordinateSystem() { + * return super.getCoordinateSystem(); + * } + * } + * + * However our attempts to apply this approach worked for {@code DefaultParameterValue} but not for this class: + * for an unknown reason, the unmarshalled CS object is empty.</div> + * + * @see <a href="http://issues.apache.org/jira/browse/SIS-166">SIS-166</a> + */ + @XmlElement(name="affineCS") private AffineCS getAffineCS() {return getCoordinateSystem(AffineCS .class);} + @XmlElement(name="cartesianCS") private CartesianCS getCartesianCS() {return getCoordinateSystem(CartesianCS .class);} + @XmlElement(name="cylindricalCS") private CylindricalCS getCylindricalCS() {return getCoordinateSystem(CylindricalCS.class);} + @XmlElement(name="linearCS") private LinearCS getLinearCS() {return getCoordinateSystem(LinearCS .class);} + @XmlElement(name="polarCS") private PolarCS getPolarCS() {return getCoordinateSystem(PolarCS .class);} + @XmlElement(name="sphericalCS") private SphericalCS getSphericalCS() {return getCoordinateSystem(SphericalCS .class);} + @XmlElement(name="userDefinedCS") private UserDefinedCS getUserDefinedCS() {return getCoordinateSystem(UserDefinedCS.class);} + + /** + * Invoked by JAXB at unmarshalling time. + */ + private void setAffineCS (final AffineCS cs) {super.setCoordinateSystem("affineCS", cs);} + private void setCartesianCS (final CartesianCS cs) {super.setCoordinateSystem("cartesianCS", cs);} + private void setCylindricalCS(final CylindricalCS cs) {super.setCoordinateSystem("cylindricalCS", cs);} + private void setLinearCS (final LinearCS cs) {super.setCoordinateSystem("linearCS", cs);} + private void setPolarCS (final PolarCS cs) {super.setCoordinateSystem("polarCS", cs);} + private void setSphericalCS (final SphericalCS cs) {super.setCoordinateSystem("sphericalCS", cs);} + private void setUserDefinedCS(final UserDefinedCS cs) {super.setCoordinateSystem("userDefinedCS", cs);} + + /** + * The types for which a specialized method exists. + * Not including {@link CartesianCS}, because this case is already covered by {@link AffineCS}. + */ + private static final Class<?>[] SPECIALIZED_TYPES = { + AffineCS.class, SphericalCS.class, CylindricalCS.class, PolarCS.class, LinearCS.class, UserDefinedCS.class + }; + + /** + * Returns the coordinate system if it is not an instance of any of the types handled by specialized methods. + * It is the case of {@link EllipsoidalCS}, {@link VerticalCS}, {@link TimeCS} and {@link ParametricCS}. + */ + @XmlElement(name = "coordinateSystem", required = true) + @XmlJavaTypeAdapter(CS_CoordinateSystem.class) + private CoordinateSystem getAbstractCS() { + final CoordinateSystem cs = getCoordinateSystem(); + for (final Class<?> t : SPECIALIZED_TYPES) { + if (t.isInstance(cs)) return null; + } + return cs; + } + + /** + * Used by JAXB only (invoked by reflection). */ - private void setCoordinateSystem(final CoordinateSystem cs) { - setCoordinateSystem(null, cs); // 'null' here means to infer the XML property name from the cs type. + private void setAbstractCS(final CoordinateSystem cs) { + setCoordinateSystem(null, cs); // `null` here means to infer the XML property name from the cs type. } } diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java index a36bc1ab9a..9aaa2c994e 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java @@ -324,10 +324,8 @@ class DefaultGeodeticCRS extends AbstractCRS implements GeodeticCRS { // If made * } * } * - * However our attempts to apply this approach worked for {@link DefaultEngineeringCRS} but not for this class: - * for an unknown reason, the unmarshalled CS object is empty. Maybe this is because the covariant return type - * in the {@link DefaultGeographicCRS} ({@code EllipsoidCS} instead of {@code CoordinateSystem} in above code) - * is causing confusion.</div> + * However our attempts to apply this approach worked for {@code DefaultParameterValue} but not for this class: + * for an unknown reason, the unmarshalled CS object is empty.</div> * * @see <a href="http://issues.apache.org/jira/browse/SIS-166">SIS-166</a> */ diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java index d3075566b7..265e9ea5ec 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java @@ -306,9 +306,8 @@ public class DefaultImageCRS extends AbstractCRS implements ImageCRS { * } * } * - * However our attempts to apply this approach worked for {@link DefaultEngineeringCRS} but not for this class: - * for an unknown reason, the unmarshalled CS object is empty. Maybe this is because the covariant return type - * ({@code AffineCS} instead of {@code CoordinateSystem} in above code) is causing confusion.</div> + * However our attempts to apply this approach worked for {@code DefaultParameterValue} but not for this class: + * for an unknown reason, the unmarshalled CS object is empty.</div> * * @see <a href="http://issues.apache.org/jira/browse/SIS-166">SIS-166</a> */ diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java index cd5fef4ddb..31c2c7ec55 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java @@ -117,6 +117,7 @@ public class AbstractCS extends AbstractIdentifiedObject implements CoordinateSy * * @see #getAxis(int) */ + @SuppressWarnings("serial") // Not statically typed as Serializable. private CoordinateSystemAxis[] axes; /** diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultEngineeringCRSTest.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultEngineeringCRSTest.java index e130975688..0748ff2472 100644 --- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultEngineeringCRSTest.java +++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultEngineeringCRSTest.java @@ -36,7 +36,7 @@ import static org.apache.sis.test.ReferencingAssert.*; * Tests {@link DefaultEngineeringCRS}. * * @author Martin Desruisseaux (Geomatys) - * @version 1.0 + * @version 1.3 * @since 0.6 * @module */ @@ -117,22 +117,24 @@ public final strictfp class DefaultEngineeringCRSTest extends TestCase { assertXmlEquals( "<gml:EngineeringCRS xmlns:gml=\"" + Namespaces.GML + "\">\n" + " <gml:name>A construction site CRS</gml:name>\n" + - " <gml:cartesianCS gml:id=\"Cartesian2D\">\n" + - " <gml:name>Cartesian 2D</gml:name>\n" + - " <gml:axis>\n" + - " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"x\">\n" + - " <gml:name>x</gml:name>\n" + - " <gml:axisAbbrev>x</gml:axisAbbrev>\n" + - " <gml:axisDirection codeSpace=\"EPSG\">east</gml:axisDirection>\n" + - " </gml:CoordinateSystemAxis>\n" + - " </gml:axis>\n" + - " <gml:axis>\n" + - " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"y\">\n" + - " <gml:name>y</gml:name>\n" + - " <gml:axisAbbrev>y</gml:axisAbbrev>\n" + - " <gml:axisDirection codeSpace=\"EPSG\">north</gml:axisDirection>\n" + - " </gml:CoordinateSystemAxis>\n" + - " </gml:axis>\n" + + " <gml:cartesianCS>\n" + + " <gml:CartesianCS gml:id=\"Cartesian2D\">\n" + + " <gml:name>Cartesian 2D</gml:name>\n" + + " <gml:axis>\n" + + " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"x\">\n" + + " <gml:name>x</gml:name>\n" + + " <gml:axisAbbrev>x</gml:axisAbbrev>\n" + + " <gml:axisDirection codeSpace=\"EPSG\">east</gml:axisDirection>\n" + + " </gml:CoordinateSystemAxis>\n" + + " </gml:axis>\n" + + " <gml:axis>\n" + + " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"y\">\n" + + " <gml:name>y</gml:name>\n" + + " <gml:axisAbbrev>y</gml:axisAbbrev>\n" + + " <gml:axisDirection codeSpace=\"EPSG\">north</gml:axisDirection>\n" + + " </gml:CoordinateSystemAxis>\n" + + " </gml:axis>\n" + + " </gml:CartesianCS>\n" + " </gml:cartesianCS>\n" + " <gml:engineeringDatum>\n" + " <gml:EngineeringDatum gml:id=\"P1\">\n" + @@ -167,37 +169,39 @@ public final strictfp class DefaultEngineeringCRSTest extends TestCase { assertXmlEquals( "<gml:EngineeringCRS xmlns:gml=\"" + Namespaces.GML + "\">\n" + " <gml:name>A spherical CRS</gml:name>\n" + - " <gml:sphericalCS gml:id=\"Spherical\">\n" + - " <gml:name>Spherical</gml:name>\n" + - " <gml:axis>\n" + - " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9122\" gml:id=\"SphericalLatitude\">\n" + - " <gml:name>Spherical latitude</gml:name>\n" + - " <gml:axisAbbrev>Ω</gml:axisAbbrev>\n" + - " <gml:axisDirection codeSpace=\"EPSG\">north</gml:axisDirection>\n" + - " <gml:minimumValue>-90.0</gml:minimumValue>\n" + - " <gml:maximumValue>90.0</gml:maximumValue>\n" + - " <gml:rangeMeaning codeSpace=\"EPSG\">exact</gml:rangeMeaning>\n" + - " </gml:CoordinateSystemAxis>\n" + - " </gml:axis>\n" + - " <gml:axis>\n" + - " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9122\" gml:id=\"SphericalLongitude\">\n" + - " <gml:name>Spherical longitude</gml:name>\n" + - " <gml:axisAbbrev>θ</gml:axisAbbrev>\n" + - " <gml:axisDirection codeSpace=\"EPSG\">east</gml:axisDirection>\n" + - " <gml:minimumValue>-180.0</gml:minimumValue>\n" + - " <gml:maximumValue>180.0</gml:maximumValue>\n" + - " <gml:rangeMeaning codeSpace=\"EPSG\">wraparound</gml:rangeMeaning>\n" + - " </gml:CoordinateSystemAxis>\n" + - " </gml:axis>\n" + - " <gml:axis>\n" + - " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"GeocentricRadius\">\n" + - " <gml:name>Geocentric radius</gml:name>\n" + - " <gml:axisAbbrev>r</gml:axisAbbrev>\n" + - " <gml:axisDirection codeSpace=\"EPSG\">up</gml:axisDirection>\n" + - " <gml:minimumValue>0.0</gml:minimumValue>\n" + - " <gml:rangeMeaning codeSpace=\"EPSG\">exact</gml:rangeMeaning>\n" + - " </gml:CoordinateSystemAxis>\n" + - " </gml:axis>\n" + + " <gml:sphericalCS>\n" + + " <gml:SphericalCS gml:id=\"Spherical\">\n" + + " <gml:name>Spherical</gml:name>\n" + + " <gml:axis>\n" + + " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9122\" gml:id=\"SphericalLatitude\">\n" + + " <gml:name>Spherical latitude</gml:name>\n" + + " <gml:axisAbbrev>Ω</gml:axisAbbrev>\n" + + " <gml:axisDirection codeSpace=\"EPSG\">north</gml:axisDirection>\n" + + " <gml:minimumValue>-90.0</gml:minimumValue>\n" + + " <gml:maximumValue>90.0</gml:maximumValue>\n" + + " <gml:rangeMeaning codeSpace=\"EPSG\">exact</gml:rangeMeaning>\n" + + " </gml:CoordinateSystemAxis>\n" + + " </gml:axis>\n" + + " <gml:axis>\n" + + " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9122\" gml:id=\"SphericalLongitude\">\n" + + " <gml:name>Spherical longitude</gml:name>\n" + + " <gml:axisAbbrev>θ</gml:axisAbbrev>\n" + + " <gml:axisDirection codeSpace=\"EPSG\">east</gml:axisDirection>\n" + + " <gml:minimumValue>-180.0</gml:minimumValue>\n" + + " <gml:maximumValue>180.0</gml:maximumValue>\n" + + " <gml:rangeMeaning codeSpace=\"EPSG\">wraparound</gml:rangeMeaning>\n" + + " </gml:CoordinateSystemAxis>\n" + + " </gml:axis>\n" + + " <gml:axis>\n" + + " <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"GeocentricRadius\">\n" + + " <gml:name>Geocentric radius</gml:name>\n" + + " <gml:axisAbbrev>r</gml:axisAbbrev>\n" + + " <gml:axisDirection codeSpace=\"EPSG\">up</gml:axisDirection>\n" + + " <gml:minimumValue>0.0</gml:minimumValue>\n" + + " <gml:rangeMeaning codeSpace=\"EPSG\">exact</gml:rangeMeaning>\n" + + " </gml:CoordinateSystemAxis>\n" + + " </gml:axis>\n" + + " </gml:SphericalCS>\n" + " </gml:sphericalCS>\n" + " <gml:engineeringDatum>\n" + " <gml:EngineeringDatum gml:id=\"Centre\">\n" +