Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -56,14 +56,6 @@ public class DefaultUserDefinedCS extend private static final long serialVersionUID = -4904091898305706316L; /** - * Constructs a new coordinate system in which every attributes are set to a null or empty value. - * <strong>This is not a valid object.</strong> This constructor is strictly reserved to JAXB, - * which will assign values to the fields using reflexion. - */ - private DefaultUserDefinedCS() { - } - - /** * Creates a new coordinate system from an arbitrary number of axes. This constructor is for * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only, * because it does not verify the number of axes. @@ -203,4 +195,26 @@ public class DefaultUserDefinedCS extend default: throw unexpectedDimension(properties, axes, 2); } } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new coordinate system in which every attributes are set to a null or empty value. + * <strong>This is not a valid object.</strong> This constructor is strictly reserved to JAXB, + * which will assign values to the fields using reflexion. + */ + private DefaultUserDefinedCS() { + } }
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -74,14 +74,6 @@ public class DefaultVerticalCS extends A private static final long serialVersionUID = 1201155778896630499L; /** - * Constructs a new coordinate system in which every attributes are set to a null or empty value. - * <strong>This is not a valid object.</strong> This constructor is strictly reserved to JAXB, - * which will assign values to the fields using reflexion. - */ - private DefaultVerticalCS() { - } - - /** * Creates a new coordinate system from an arbitrary number of axes. This constructor is for * implementations of the {@link #createForAxes(Map, CoordinateSystemAxis[])} method only, * because it does not verify the number of axes. @@ -220,4 +212,26 @@ public class DefaultVerticalCS extends A default: throw unexpectedDimension(properties, axes, 1); } } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new coordinate system in which every attributes are set to a null or empty value. + * <strong>This is not a valid object.</strong> This constructor is strictly reserved to JAXB, + * which will assign values to the fields using reflexion. + */ + private DefaultVerticalCS() { + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -33,10 +33,10 @@ import org.apache.sis.util.iso.Types; import org.apache.sis.util.ComparisonMode; import org.apache.sis.internal.util.Citations; import org.apache.sis.internal.metadata.MetadataUtilities; +import org.apache.sis.internal.referencing.ReferencingUtilities; import static org.apache.sis.util.Utilities.deepEquals; import static org.apache.sis.util.collection.Containers.property; -import static org.apache.sis.internal.referencing.ReferencingUtilities.canSetProperty; // Branch-dependent imports import java.util.Objects; @@ -122,19 +122,6 @@ public class AbstractDatum extends Abstr private final InternationalString scope; /** - * Constructs a new object in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - AbstractDatum() { - super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); - anchorDefinition = null; - realizationEpoch = Long.MIN_VALUE; - domainOfValidity = null; - scope = null; - } - - /** * Creates a datum from the given properties. * The properties given in argument follow the same rules than for the * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}. @@ -303,17 +290,6 @@ public class AbstractDatum extends Abstr } /** - * Invoked by JAXB only at unmarshalling time. - */ - private void setRealizationEpoch(final Date value) { - if (value != null && canSetProperty(AbstractDatum.class, - "setRealizationEpoch", "realizationEpoch", realizationEpoch != Long.MIN_VALUE)) - { - realizationEpoch = value.getTime(); - } - } - - /** * Returns the region or timeframe in which this datum is valid, or {@code null} if unspecified. * * @return Area or region or timeframe in which this datum is valid, or {@code null}. @@ -434,4 +410,42 @@ public class AbstractDatum extends Abstr protected long computeHashCode() { return super.computeHashCode() + Objects.hash(anchorDefinition, realizationEpoch, domainOfValidity, scope); } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new object in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + AbstractDatum() { + super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); + anchorDefinition = null; + realizationEpoch = Long.MIN_VALUE; + domainOfValidity = null; + scope = null; + } + + /** + * Invoked by JAXB only at unmarshalling time. + */ + private void setRealizationEpoch(final Date value) { + if (realizationEpoch == Long.MIN_VALUE) { + realizationEpoch = value.getTime(); + } else { + ReferencingUtilities.propertyAlreadySet(AbstractDatum.class, "setRealizationEpoch", "realizationEpoch"); + } + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -21,6 +21,7 @@ import javax.measure.unit.SI; import javax.measure.unit.Unit; import javax.measure.quantity.Length; import javax.measure.converter.UnitConverter; +import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @@ -182,17 +183,6 @@ public class DefaultEllipsoid extends Ab private Unit<Length> unit; /** - * Constructs a new object in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultEllipsoid() { - super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); - // We need to let the DefaultEllipsoid fields unitialized - // because afterUnmarshal(…) will check for zero values. - } - - /** * Creates a new ellipsoid using the specified axis length. * The properties map is given unchanged to the * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}. @@ -348,30 +338,6 @@ public class DefaultEllipsoid extends Ab } /** - * After the unmarshalling process, only one value between {@link #semiMinorAxis} and - * {@link #inverseFlattening} has been defined. Since the {@link #semiMajorAxis} has - * been defined, it is now possible to calculate the value of the missing parameter - * using the values of those that are set. - * - * @see #setSemiMajorAxisMeasure(Measure) - * @see #setSecondDefiningParameter(SecondDefiningParameter) - */ - private void afterUnmarshal() { - if (ivfDefinitive) { - if (semiMinorAxis == 0) { - semiMinorAxis = Formulas.getSemiMinor(semiMajorAxis, inverseFlattening); - } - } else { - if (inverseFlattening == 0) { - inverseFlattening = Formulas.getInverseFlattening(semiMajorAxis, semiMinorAxis); - } - } - if (unit == null) { - Measure.missingUOM(DefaultEllipsoid.class, "semiMajorAxis"); - } - } - - /** * Returns the GeoAPI interface implemented by this class. * The SIS implementation returns {@code Ellipsoid.class}. * @@ -410,36 +376,6 @@ public class DefaultEllipsoid extends Ab } /** - * Returns the semi-major axis value as a measurement. - * This method is invoked by JAXB for XML marshalling. - */ - @XmlElement(name = "semiMajorAxis", required = true) - final Measure getSemiMajorAxisMeasure() { - return new Measure(semiMajorAxis, unit); - } - - /** - * Sets the semi-major axis value. - * This method is invoked by JAXB at unmarshalling time only. - * - * @see #setSecondDefiningParameter(SecondDefiningParameter) - * @see #afterUnmarshal() - */ - private void setSemiMajorAxisMeasure(final Measure measure) { - if (semiMajorAxis != 0) { - warnDuplicated("semiMajorAxis"); - } else { - final Unit<Length> uom = unit; // In case semi-minor were defined before semi-major. - ensureStrictlyPositive("semiMajorAxis", semiMajorAxis = measure.value); - unit = measure.getUnit(Length.class); - harmonizeAxisUnits(uom); - if ((ivfDefinitive ? inverseFlattening : semiMinorAxis) != 0) { - afterUnmarshal(); - } - } - } - - /** * Length of the semi-minor axis of the ellipsoid. This is the * polar radius in {@linkplain #getAxisUnit() axis linear unit}. * @@ -508,75 +444,6 @@ public class DefaultEllipsoid extends Ab } /** - * Returns the object to be marshalled as the {@code SecondDefiningParameter} XML element. The - * returned object contains the values for {@link #semiMinorAxis} or {@link #inverseFlattening}, - * according to the {@link #isIvfDefinitive()} value. This method is for JAXB marshalling only. - */ - @XmlElement(name = "secondDefiningParameter") - final SecondDefiningParameter getSecondDefiningParameter() { - return new SecondDefiningParameter(this, true); - } - - /** - * Sets the second defining parameter value, either the inverse of the flattening - * value or the semi minor axis value, according to what have been defined in the - * second defining parameter given. This is for JAXB unmarshalling process only. - * - * @see #setSemiMajorAxisMeasure(Measure) - * @see #afterUnmarshal() - */ - private void setSecondDefiningParameter(SecondDefiningParameter second) { - while (second.secondDefiningParameter != null) { - second = second.secondDefiningParameter; - } - final Measure measure = second.measure; - if (measure != null) { - final boolean isIvfDefinitive = second.isIvfDefinitive(); - if ((isIvfDefinitive ? inverseFlattening : semiMinorAxis) != 0) { - warnDuplicated("secondDefiningParameter"); - } else { - ivfDefinitive = isIvfDefinitive; - double value = measure.value; - if (isIvfDefinitive) { - if (value == 0) { - value = Double.POSITIVE_INFINITY; - } - ensureStrictlyPositive("inverseFlattening", inverseFlattening = value); - } else if (semiMinorAxis == 0) { - ensureStrictlyPositive("semiMinorAxis", semiMinorAxis = value); - harmonizeAxisUnits(measure.getUnit(Length.class)); - } - if (semiMajorAxis != 0) { - afterUnmarshal(); - } - } - } - } - - /** - * Ensures that the semi-minor axis uses the same unit than the semi-major one. - * The {@link #unit} field shall be set to the semi-major axis unit before this method call. - * - * @param uom The semi-minor axis unit. - */ - private void harmonizeAxisUnits(final Unit<Length> uom) { - if (unit == null) { - unit = uom; - } else if (uom != null && uom != unit) { - semiMinorAxis = uom.getConverterTo(unit).convert(semiMinorAxis); - } - } - - /** - * Emits a warning telling that the given element is repeated twice. - */ - private static void warnDuplicated(final String element) { - // We cheat a bit for the "unmarshal" method name since there is not such method... - Context.warningOccured(Context.current(), DefaultEllipsoid.class, "unmarshal", - Errors.class, Errors.Keys.DuplicatedElement_1, element); - } - - /** * {@code true} if the ellipsoid is degenerate and is actually a sphere. * The sphere is completely defined by the {@linkplain #getSemiMajorAxis() semi-major axis}, * which is the radius of the sphere. @@ -809,4 +676,146 @@ public class DefaultEllipsoid extends Ab } return WKTKeywords.Ellipsoid; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new object in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultEllipsoid() { + super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); + // We need to let the DefaultEllipsoid fields unitialized + // because afterUnmarshal(…) will check for zero values. + } + + /** + * After the unmarshalling process, only one value between {@link #semiMinorAxis} and + * {@link #inverseFlattening} has been defined. Since the {@link #semiMajorAxis} has + * been defined, it is now possible to calculate the value of the missing parameter + * using the values of those that are set. + * + * @see #setSemiMajorAxisMeasure(Measure) + * @see #setSecondDefiningParameter(SecondDefiningParameter) + */ + private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) { + if (ivfDefinitive) { + if (semiMinorAxis == 0) { + semiMinorAxis = Formulas.getSemiMinor(semiMajorAxis, inverseFlattening); + } + } else { + if (inverseFlattening == 0) { + inverseFlattening = Formulas.getInverseFlattening(semiMajorAxis, semiMinorAxis); + } + } + if (unit == null) { + Measure.missingUOM(DefaultEllipsoid.class, "semiMajorAxis"); + } + } + + /** + * Returns the semi-major axis value as a measurement. + * This method is invoked by JAXB for XML marshalling. + */ + @XmlElement(name = "semiMajorAxis", required = true) + private Measure getSemiMajorAxisMeasure() { + return new Measure(semiMajorAxis, unit); + } + + /** + * Sets the semi-major axis value. + * This method is invoked by JAXB at unmarshalling time only. + * + * @see #setSecondDefiningParameter(SecondDefiningParameter) + * @see #afterUnmarshal(Unmarshaller, Object) + */ + private void setSemiMajorAxisMeasure(final Measure measure) { + if (semiMajorAxis != 0) { + warnDuplicated("semiMajorAxis"); + } else { + final Unit<Length> uom = unit; // In case semi-minor were defined before semi-major. + ensureStrictlyPositive("semiMajorAxis", semiMajorAxis = measure.value); + unit = measure.getUnit(Length.class); + harmonizeAxisUnits(uom); + } + } + + /** + * Returns the object to be marshalled as the {@code SecondDefiningParameter} XML element. The + * returned object contains the values for {@link #semiMinorAxis} or {@link #inverseFlattening}, + * according to the {@link #isIvfDefinitive()} value. This method is for JAXB marshalling only. + */ + @XmlElement(name = "secondDefiningParameter") + private SecondDefiningParameter getSecondDefiningParameter() { + return new SecondDefiningParameter(this, true); + } + + /** + * Sets the second defining parameter value, either the inverse of the flattening + * value or the semi minor axis value, according to what have been defined in the + * second defining parameter given. This is for JAXB unmarshalling process only. + * + * @see #setSemiMajorAxisMeasure(Measure) + * @see #afterUnmarshal(Unmarshaller, Object) + */ + private void setSecondDefiningParameter(SecondDefiningParameter second) { + while (second.secondDefiningParameter != null) { + second = second.secondDefiningParameter; + } + final Measure measure = second.measure; + if (measure != null) { + final boolean isIvfDefinitive = second.isIvfDefinitive(); + if ((isIvfDefinitive ? inverseFlattening : semiMinorAxis) != 0) { + warnDuplicated("secondDefiningParameter"); + } else { + ivfDefinitive = isIvfDefinitive; + double value = measure.value; + if (isIvfDefinitive) { + if (value == 0) { + value = Double.POSITIVE_INFINITY; + } + ensureStrictlyPositive("inverseFlattening", inverseFlattening = value); + } else if (semiMinorAxis == 0) { + ensureStrictlyPositive("semiMinorAxis", semiMinorAxis = value); + harmonizeAxisUnits(measure.getUnit(Length.class)); + } + } + } + } + + /** + * Ensures that the semi-minor axis uses the same unit than the semi-major one. + * The {@link #unit} field shall be set to the semi-major axis unit before this method call. + * + * @param uom The semi-minor axis unit. + */ + private void harmonizeAxisUnits(final Unit<Length> uom) { + if (unit == null) { + unit = uom; + } else if (uom != null && uom != unit) { + semiMinorAxis = uom.getConverterTo(unit).convert(semiMinorAxis); + } + } + + /** + * Emits a warning telling that the given element is repeated twice. + */ + private static void warnDuplicated(final String element) { + // We cheat a bit for the "unmarshal" method name since there is not such method... + Context.warningOccured(Context.current(), DefaultEllipsoid.class, "unmarshal", + Errors.class, Errors.Keys.DuplicatedElement_1, element); + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -52,14 +52,6 @@ public class DefaultEngineeringDatum ext private static final long serialVersionUID = 1498304918725248637L; /** - * Constructs a new datum in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultEngineeringDatum() { - } - - /** * Creates an engineering datum from the given properties. The properties map is given * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}. * The following table is a reminder of main (not all) properties: @@ -187,4 +179,26 @@ public class DefaultEngineeringDatum ext } return WKTKeywords.EngineeringDatum; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new datum in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultEngineeringDatum() { + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -169,17 +169,6 @@ public class DefaultGeodeticDatum extend private final BursaWolfParameters[] bursaWolf; /** - * Constructs a new datum in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultGeodeticDatum() { - ellipsoid = null; - primeMeridian = null; - bursaWolf = null; - } - - /** * Creates a geodetic datum from the given properties. The properties map is given * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}. * In addition to the properties documented in the parent constructor, @@ -344,6 +333,7 @@ public class DefaultGeodeticDatum extend * * @return The Bursa-Wolf parameters, or an empty array if none. */ + @SuppressWarnings("ReturnOfCollectionOrArrayField") public BursaWolfParameters[] getBursaWolfParameters() { if (bursaWolf == null) { return EMPTY_ARRAY; @@ -579,4 +569,29 @@ public class DefaultGeodeticDatum extend } return WKTKeywords.Datum; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new datum in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultGeodeticDatum() { + ellipsoid = null; + primeMeridian = null; + bursaWolf = null; + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -66,15 +66,6 @@ public class DefaultImageDatum extends A private final PixelInCell pixelInCell; /** - * Constructs a new datum in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultImageDatum() { - pixelInCell = null; - } - - /** * Creates an image datum from the given properties. The properties map is given * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}. * The following table is a reminder of main (not all) properties: @@ -254,4 +245,27 @@ public class DefaultImageDatum extends A } return WKTKeywords.ImageDatum; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new datum in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultImageDatum() { + pixelInCell = null; + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -114,15 +114,6 @@ public class DefaultPrimeMeridian extend private Unit<Angle> angularUnit; /** - * Constructs a new object in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultPrimeMeridian() { - super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); - } - - /** * Creates a prime meridian from the given properties. The properties map is given unchanged to the * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}. * The following table is a reminder of main (not all) properties: @@ -255,38 +246,6 @@ public class DefaultPrimeMeridian extend } /** - * Invoked by JAXB for obtaining the Greenwich longitude to marshall together with its {@code "uom"} attribute. - */ - @XmlElement(name = "greenwichLongitude", required = true) - private Measure getGreenwichMeasure() { - return new Measure(greenwichLongitude, angularUnit); - } - - /** - * Invoked by JAXB for setting the Greenwich longitude and its unit of measurement. - */ - private void setGreenwichMeasure(final Measure measure) { - if (measure != null && ReferencingUtilities.canSetProperty(DefaultPrimeMeridian.class, - "setGreenwichMeasure", "greenwichLongitude", greenwichLongitude != 0 || angularUnit != null)) - { - greenwichLongitude = measure.value; - angularUnit = measure.getUnit(Angle.class); - if (angularUnit == null) { - /* - * Missing unit: if the Greenwich longitude is zero, any angular unit gives the same result - * (assuming that the missing unit was not applying an offset), so we can select a default. - * If the Greenwich longitude is not zero, we can not guess. Our object will be invalid. - */ - if (greenwichLongitude == 0) { - angularUnit = NonSI.DEGREE_ANGLE; - } else { - Measure.missingUOM(DefaultPrimeMeridian.class, "setGreenwichMeasure"); - } - } - } - } - - /** * Compares this prime meridian with the specified object for equality. * * @param object The object to compare to {@code this}. @@ -425,4 +384,59 @@ public class DefaultPrimeMeridian extend } return WKTKeywords.PrimeMeridian; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new object in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultPrimeMeridian() { + super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); + } + + /** + * Invoked by JAXB for obtaining the Greenwich longitude to marshall together with its {@code "uom"} attribute. + */ + @XmlElement(name = "greenwichLongitude", required = true) + private Measure getGreenwichMeasure() { + return new Measure(greenwichLongitude, angularUnit); + } + + /** + * Invoked by JAXB for setting the Greenwich longitude and its unit of measurement. + */ + private void setGreenwichMeasure(final Measure measure) { + if (greenwichLongitude == 0 && angularUnit == null) { + greenwichLongitude = measure.value; + angularUnit = measure.getUnit(Angle.class); + if (angularUnit == null) { + /* + * Missing unit: if the Greenwich longitude is zero, any angular unit gives the same result + * (assuming that the missing unit was not applying an offset), so we can select a default. + * If the Greenwich longitude is not zero, we can not guess. Our object will be invalid. + */ + if (greenwichLongitude == 0) { + angularUnit = NonSI.DEGREE_ANGLE; + } else { + Measure.missingUOM(DefaultPrimeMeridian.class, "setGreenwichMeasure"); + } + } + } else { + ReferencingUtilities.propertyAlreadySet(DefaultPrimeMeridian.class, "setGreenwichMeasure", "greenwichLongitude"); + } + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -29,12 +29,12 @@ import org.opengis.referencing.datum.Tem import org.apache.sis.internal.metadata.WKTKeywords; import org.apache.sis.internal.jaxb.gml.UniversalTimeAdapter; import org.apache.sis.internal.metadata.MetadataUtilities; +import org.apache.sis.internal.referencing.ReferencingUtilities; import org.apache.sis.util.ComparisonMode; import org.apache.sis.io.wkt.Formatter; import org.apache.sis.io.wkt.FormattableObject; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; -import static org.apache.sis.internal.referencing.ReferencingUtilities.canSetProperty; // Branch-dependent imports import java.util.Objects; @@ -99,15 +99,6 @@ public class DefaultTemporalDatum extend private long origin; /** - * Constructs a new datum in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultTemporalDatum() { - origin = Long.MIN_VALUE; - } - - /** * Creates a temporal datum from the given properties. The properties map is given * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}. * The following table is a reminder of main (not all) properties: @@ -230,17 +221,6 @@ public class DefaultTemporalDatum extend } /** - * Invoked by JAXB only at unmarshalling time. - */ - private void setOrigin(final Date value) { - if (value != null && canSetProperty(DefaultTemporalDatum.class, - "setOrigin", "origin", origin != Long.MIN_VALUE)) - { - origin = value.getTime(); - } - } - - /** * Compares this temporal datum with the specified object for equality. * * @param object The object to compare to {@code this}. @@ -318,4 +298,40 @@ public class DefaultTemporalDatum extend return WKTKeywords.TimeOrigin; } } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new datum in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultTemporalDatum() { + origin = Long.MIN_VALUE; + } + + /** + * Invoked by JAXB only at unmarshalling time. + * + * @see #getOrigin() + */ + private void setOrigin(final Date value) { + if (origin == Long.MIN_VALUE) { + origin = value.getTime(); + } else { + ReferencingUtilities.propertyAlreadySet(DefaultTemporalDatum.class, "setOrigin", "origin"); + } + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -31,9 +31,9 @@ import org.apache.sis.internal.jaxb.Cont import org.apache.sis.internal.jaxb.LegacyNamespaces; import org.apache.sis.internal.metadata.WKTKeywords; import org.apache.sis.internal.metadata.VerticalDatumTypes; +import org.apache.sis.internal.referencing.ReferencingUtilities; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; -import static org.apache.sis.internal.referencing.ReferencingUtilities.canSetProperty; // Branch-dependent imports import java.util.Objects; @@ -100,14 +100,6 @@ public class DefaultVerticalDatum extend private VerticalDatumType type; /** - * Constructs a new datum in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultVerticalDatum() { - } - - /** * Creates a vertical datum from the given properties. The properties map is given * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}. * The following table is a reminder of main (not all) properties: @@ -251,26 +243,6 @@ public class DefaultVerticalDatum extend } /** - * Returns the type to be marshalled to XML. - * This element was present in GML 3.0 and 3.1, but has been removed from GML 3.2. - * - * @see <a href="http://issues.apache.org/jira/browse/SIS-160">SIS-160: Need XSLT between GML 3.1 and 3.2</a> - */ - @XmlElement(name = "verticalDatumType") - private VerticalDatumType getTypeElement() { - return Context.isGMLVersion(Context.current(), LegacyNamespaces.VERSION_3_2) ? null : getVerticalDatumType(); - } - - /** - * Invoked by JAXB only. The vertical datum type is set only if it has not already been specified. - */ - private void setTypeElement(final VerticalDatumType t) { - if (t != null && canSetProperty(DefaultVerticalDatum.class, "setTypeElement", "verticalDatumType", type != null)) { - type = t; - } - } - - /** * Compare this vertical datum with the specified object for equality. * * @param object The object to compare to {@code this}. @@ -331,4 +303,48 @@ public class DefaultVerticalDatum extend } return WKTKeywords.VerticalDatum; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new datum in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultVerticalDatum() { + } + + /** + * Returns the type to be marshalled to XML. + * This element was present in GML 3.0 and 3.1, but has been removed from GML 3.2. + * + * @see <a href="http://issues.apache.org/jira/browse/SIS-160">SIS-160: Need XSLT between GML 3.1 and 3.2</a> + */ + @XmlElement(name = "verticalDatumType") + private VerticalDatumType getTypeElement() { + return Context.isGMLVersion(Context.current(), LegacyNamespaces.VERSION_3_2) ? null : getVerticalDatumType(); + } + + /** + * Invoked by JAXB only. The vertical datum type is set only if it has not already been specified. + */ + private void setTypeElement(final VerticalDatumType t) { + if (type == null) { + type = t; + } else { + ReferencingUtilities.propertyAlreadySet(DefaultVerticalDatum.class, "setTypeElement", "verticalDatumType"); + } + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -19,19 +19,20 @@ package org.apache.sis.referencing.opera import java.util.Map; import java.util.Collection; import java.util.Collections; +import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.opengis.util.InternationalString; +import org.opengis.metadata.Identifier; import org.opengis.metadata.extent.Extent; import org.opengis.metadata.quality.PositionalAccuracy; +import org.opengis.referencing.crs.GeneralDerivedCRS; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.CoordinateOperation; import org.opengis.referencing.operation.OperationMethod; import org.opengis.referencing.operation.MathTransform; -import org.opengis.metadata.Identifier; -import org.apache.sis.parameter.Parameterized; import org.opengis.parameter.GeneralParameterValue; import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.parameter.ParameterValueGroup; @@ -43,6 +44,7 @@ import org.apache.sis.util.ComparisonMod import org.apache.sis.util.resources.Errors; import org.apache.sis.util.collection.Containers; import org.apache.sis.util.UnsupportedImplementationException; +import org.apache.sis.parameter.Parameterized; import org.apache.sis.referencing.AbstractIdentifiedObject; import org.apache.sis.referencing.operation.transform.PassThroughTransform; import org.apache.sis.internal.referencing.PositionalAccuracyConstant; @@ -95,8 +97,8 @@ import java.util.Objects; "scope", "operationVersion", "coordinateOperationAccuracy", -// "sourceCRS", // TODO -// "targetCRS" + "source", + "target" }) @XmlRootElement(name = "AbstractCoordinateOperation") @XmlSeeAlso({ @@ -111,18 +113,22 @@ public class AbstractCoordinateOperation /** * The source CRS, or {@code null} if not available. * + * <p><b>Consider this field as final!</b> + * This field is modified only at unmarshalling time by {@link #setSource(CoordinateReferenceSystem)}</p> + * * @see #getSourceCRS() */ -// @XmlElement - private final CoordinateReferenceSystem sourceCRS; + private CoordinateReferenceSystem sourceCRS; /** * The target CRS, or {@code null} if not available. * + * <p><b>Consider this field as final!</b> + * This field is modified only at unmarshalling time by {@link #setTarget(CoordinateReferenceSystem)}</p> + * * @see #getTargetCRS() */ -// @XmlElement - private final CoordinateReferenceSystem targetCRS; + private CoordinateReferenceSystem targetCRS; /** * The CRS which is neither the {@linkplain #getSourceCRS() source CRS} or @@ -160,25 +166,11 @@ public class AbstractCoordinateOperation /** * Transform from positions in the {@linkplain #getSourceCRS source coordinate reference system} * to positions in the {@linkplain #getTargetCRS target coordinate reference system}. + * + * <p><b>Consider this field as final!</b> + * This field is modified only at unmarshalling time by {@link #afterUnmarshal(Unmarshaller, Object)}</p> */ - private final MathTransform transform; - - /** - * Creates a new object in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - AbstractCoordinateOperation() { - super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); - sourceCRS = null; - targetCRS = null; - interpolationCRS = null; - operationVersion = null; - coordinateOperationAccuracy = null; - domainOfValidity = null; - scope = null; - transform = null; - } + private MathTransform transform; /** * Creates a new coordinate operation with the same values than the specified defining conversion, @@ -321,6 +313,7 @@ public class AbstractCoordinateOperation * are consistent with {@link #transform} input and output dimensions. */ private void checkDimensions(final Map<String,?> properties) { + final MathTransform transform = this.transform; // Protect from changes. if (transform != null) { final int interpDim = ReferencingUtilities.getDimension(interpolationCRS); check: for (int isTarget=0; ; isTarget++) { // 0 == source check; 1 == target check. @@ -419,6 +412,36 @@ check: for (int isTarget=0; ; isTar } /** + * Returns {@code true} if this coordinate operation is for the definition of a + * {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS derived} or + * {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS projected CRS}. + * The standard (ISO 19111) approach constructs <cite>defining conversion</cite> + * as an operation of type {@link org.opengis.referencing.operation.Conversion} + * with null {@linkplain #getSourceCRS() source} and {@linkplain #getTargetCRS() target CRS}. + * But SIS supports also defining conversions with non-null CRS provided that: + * + * <ul> + * <li>{@link GeneralDerivedCRS#getBaseCRS()} is the {@linkplain #getSourceCRS() source CRS} of this operation, and</li> + * <li>{@link GeneralDerivedCRS#getConversionFromBase()} is this operation instance.</li> + * </ul> + * + * When this method returns {@code true}, the source and target CRS are not marshalled in XML documents. + * + * @return {@code true} if this coordinate operation is for the definition of a derived or projected CRS. + */ + public boolean isDefiningConversion() { + /* + * Trick: we do not need to verify if (this instanceof Conversion) because: + * - Only DefaultConversion constructor accepts null source and target CRS. + * - GeneralDerivedCRS.getConversionFromBase() return type is Conversion. + */ + return (sourceCRS == null && targetCRS == null) + || ((targetCRS instanceof GeneralDerivedCRS) + && ((GeneralDerivedCRS) targetCRS).getBaseCRS() == sourceCRS + && ((GeneralDerivedCRS) targetCRS).getConversionFromBase() == this); + } + + /** * Returns the source CRS, or {@code null} if unspecified. * The source CRS is mandatory for {@linkplain DefaultTransformation transformations} only. * This information is optional for {@linkplain DefaultConversion conversions} according @@ -791,4 +814,98 @@ check: for (int isTarget=0; ; isTar }); } } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Creates a new object in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + AbstractCoordinateOperation() { + super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE); + interpolationCRS = null; + operationVersion = null; + coordinateOperationAccuracy = null; + domainOfValidity = null; + scope = null; + } + + /** + * Invoked by JAXB for getting the source CRS to marshal. + */ + @XmlElement(name = "sourceCRS") + private CoordinateReferenceSystem getSource() { + return isDefiningConversion() ? null : getSourceCRS(); + } + + /** + * Invoked by JAXB at marshalling time for setting the source CRS. + */ + private void setSource(final CoordinateReferenceSystem crs) { + if (sourceCRS == null) { + sourceCRS = crs; + } else { + ReferencingUtilities.propertyAlreadySet(AbstractCoordinateOperation.class, "setSource", "sourceCRS"); + } + } + + /** + * Invoked by JAXB for getting the target CRS to marshal. + */ + @XmlElement(name = "targetCRS") + private CoordinateReferenceSystem getTarget() { + return isDefiningConversion() ? null : getTargetCRS(); + } + + /** + * Invoked by JAXB at unmarshalling time for setting the target CRS. + */ + private void setTarget(final CoordinateReferenceSystem crs) { + if (targetCRS == null) { + targetCRS = crs; + } else { + ReferencingUtilities.propertyAlreadySet(AbstractCoordinateOperation.class, "setTarget", "targetCRS"); + } + } + + /** + * Invoked by JAXB after unmarshalling. This method needs information provided by: + * + * <ul> + * <li>{@link #setSource(CoordinateReferenceSystem)}</li> + * <li>{@link #setTarget(CoordinateReferenceSystem)}</li> + * <li>{@link AbstractSingleOperation#setParameters(GeneralParameterValue[])}</li> + * </ul> + * + * Note that the later method is defined in a subclass, but experience suggests that it still works + * at least with the JAXB implementation provided in JDK. + */ + private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) { + if (transform == null && sourceCRS != null && targetCRS != null) { + transform = createMathTransform(); + } + } + + /** + * Implemented by subclasses at unmarshalling time for creating the math transform from available information. + * Can return {@code null} if there is not enough information. + * + * @see <a href="http://issues.apache.org/jira/browse/SIS-291">SIS-291</a> + */ + MathTransform createMathTransform() { + return null; + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -17,22 +17,35 @@ package org.apache.sis.referencing.operation; import java.util.Map; +import java.util.List; +import java.util.IdentityHashMap; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import org.opengis.util.FactoryException; import org.opengis.parameter.ParameterValueGroup; import org.opengis.parameter.ParameterDescriptorGroup; +import org.opengis.parameter.GeneralParameterDescriptor; +import org.opengis.parameter.GeneralParameterValue; import org.opengis.referencing.operation.Matrix; import org.opengis.referencing.operation.SingleOperation; import org.opengis.referencing.operation.OperationMethod; import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.apache.sis.parameter.Parameters; import org.apache.sis.parameter.Parameterized; +import org.apache.sis.parameter.DefaultParameterValueGroup; import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.referencing.operation.transform.MathTransforms; import org.apache.sis.referencing.operation.transform.PassThroughTransform; +import org.apache.sis.internal.jaxb.referencing.CC_OperationParameterGroup; +import org.apache.sis.internal.jaxb.referencing.CC_OperationMethod; +import org.apache.sis.internal.jaxb.Context; 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.util.Constants; import org.apache.sis.util.collection.Containers; import org.apache.sis.util.resources.Errors; @@ -55,12 +68,13 @@ import java.util.Objects; * @module */ @XmlType(name="AbstractSingleOperationType", propOrder = { -// "method", // TODO -// "parameters" + "method", + "parameters" }) @XmlRootElement(name = "AbstractSingleOperation") @XmlSeeAlso({ - DefaultConversion.class + DefaultConversion.class, + DefaultTransformation.class }) class AbstractSingleOperation extends AbstractCoordinateOperation implements SingleOperation, Parameterized { /** @@ -71,22 +85,16 @@ class AbstractSingleOperation extends Ab /** * The operation method. */ + @XmlElement private final OperationMethod method; /** * The parameter values, or {@code null} for inferring it from the math transform. + * + * <p><b>Consider this field as final!</b> + * This field is modified only at unmarshalling time by {@link #setParameters(GeneralParameterValue[])}</p> */ - private final ParameterValueGroup parameters; - - /** - * Constructs a new object in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - AbstractSingleOperation() { - method = null; - parameters = null; - } + private ParameterValueGroup parameters; /** * Creates a coordinate operation from the given properties. @@ -404,4 +412,115 @@ class AbstractSingleOperation extends Ab */ return true; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new object in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + AbstractSingleOperation() { + method = null; + } + + /** + * Invoked by JAXB for getting the parameters to marshal. This method usually marshals the sequence + * of parameters without their {@link ParameterValueGroup} wrapper, because GML is defined that way. + * The {@code ParameterValueGroup} wrapper is a GeoAPI addition done for allowing usage of its + * methods as a convenience (e.g. {@link ParameterValueGroup#parameter(String)}). + * + * <p>However it could happen that the user really wanted to specify a {@code ParameterValueGroup} as the + * sole {@code <gml:parameterValue>} element. We currently have no easy way to distinguish those cases. + * See {@link DefaultOperationMethod#getDescriptors()} for more discussion.</p> + * + * @see DefaultOperationMethod#getDescriptors() + */ + @XmlElement(name = "parameterValue") + private GeneralParameterValue[] getParameters() { + if (parameters != null) { + final List<GeneralParameterValue> values = parameters.values(); + if (values != null) { // Paranoiac check (should not be allowed). + return CC_OperationMethod.filterImplicit(values.toArray(new GeneralParameterValue[values.size()])); + } + } + return null; + } + + /** + * Invoked by JAXB for setting the unmarshalled parameters. + * This method wraps the given parameters in a {@link ParameterValueGroup}, + * unless the given descriptors was already a {@code ParameterValueGroup}. + * + * @see DefaultOperationMethod#setDescriptors + */ + private void setParameters(final GeneralParameterValue[] values) { + if (parameters == null) { + if (!(method instanceof DefaultOperationMethod)) { // May be a non-null proxy if defined only by xlink:href. + throw new IllegalStateException(Errors.format(Errors.Keys.MissingValueForProperty_1, "method")); + } + /* + * The descriptors in the <gml:method> element do not know the class of parameter value + * (String, Integer, Double, double[], etc.) because this information is not part of GML. + * But this information is available to descriptors in the <gml:parameterValue> elements + * because Apache SIS infers the type from the actual parameter value. The 'merge' method + * below puts those information together. + */ + final Map<GeneralParameterDescriptor,GeneralParameterDescriptor> replacements = new IdentityHashMap<>(4); + final GeneralParameterDescriptor[] merged = CC_OperationParameterGroup.merge( + method.getParameters().descriptors(), + Parameters.getDescriptors(values), + replacements); + /* + * Sometime Apache SIS recognizes the OperationMethod as one of its build-in methods and use the + * build-in parameters. In such cases the unmarshalled ParameterDescriptorGroup can be used as-in. + * But if the above 'merge' method has changed any parameter descriptor, then we will need to create + * a new ParameterDescriptorGroup with the new descriptors. + */ + for (int i=0; i<merged.length; i++) { + if (merged[i] != values[i].getDescriptor()) { + ((DefaultOperationMethod) method).updateDescriptors(merged); + // At this point, method.getParameters() may have changed. + break; + } + } + /* + * Sometime the descriptors associated to ParameterValues need to be updated, for example because + * the descriptors in OperationMethod contain more information (remarks, etc.). Those updates, if + * needed, are applied on-the-fly by the copy operation below, using the information provided by + * the 'replacements' map. + */ + parameters = new DefaultParameterValueGroup(method.getParameters()); + CC_OperationMethod.store(values, parameters.values(), replacements); + } else { + ReferencingUtilities.propertyAlreadySet(AbstractSingleOperation.class, "setParameters", "parameterValue"); + } + } + + /** + * Invoked at unmarshalling time for creating the math transform from available information. + * Can return {@code null} if there is not enough information. + */ + @Override + final MathTransform createMathTransform() { + if (parameters != null) try { + return DefaultFactories.forBuildin(MathTransformFactory.class).createBaseToDerived( + super.getSourceCRS(), parameters, super.getTargetCRS().getCoordinateSystem()); + } catch (FactoryException e) { + Context.warningOccured(Context.current(), AbstractCoordinateOperation.class, "createMathTransform", e, true); + } + return super.createMathTransform(); + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -55,6 +55,7 @@ import java.util.Objects; * @version 0.6 * @module */ +// Missing JAXB annotation. See http://issues.apache.org/jira/browse/SIS-292 final class DefaultConcatenatedOperation extends AbstractCoordinateOperation implements ConcatenatedOperation { /** * Serial number for inter-operability with different versions. Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -95,14 +95,6 @@ public class DefaultConversion extends A private static final long serialVersionUID = -2148164324805562793L; /** - * Constructs a new object in which every attributes are set to a null value. - * <strong>This is not a valid object.</strong> This constructor is strictly - * reserved to JAXB, which will assign values to the fields using reflexion. - */ - private DefaultConversion() { - } - - /** * Creates a coordinate conversion from the given properties. * The properties given in argument follow the same rules than for the * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem, @@ -494,4 +486,26 @@ public class DefaultConversion extends A } return transform; } + + + + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //////// //////// + //////// XML support with JAXB //////// + //////// //////// + //////// The following methods are invoked by JAXB using reflection (even if //////// + //////// they are private) or are helpers for other methods invoked by JAXB. //////// + //////// Those methods can be safely removed if Geographic Markup Language //////// + //////// (GML) support is not needed. //////// + //////// //////// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructs a new object in which every attributes are set to a null value. + * <strong>This is not a valid object.</strong> This constructor is strictly + * reserved to JAXB, which will assign values to the fields using reflexion. + */ + private DefaultConversion() { + } } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultFormula.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultFormula.java?rev=1701516&r1=1701515&r2=1701516&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultFormula.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultFormula.java [UTF-8] Sun Sep 6 19:10:30 2015 @@ -67,6 +67,16 @@ public class DefaultFormula extends Form private final Citation citation; /** + * Creates a new formula. This constructor is not public because of {@code Formula} object should not have + * both the formula literal and the citation. But we use this constructor an unmarshalling time if the XML + * document have both. Having both is not valid GML, but SIS is tolerant to this situation. + */ + DefaultFormula(final InternationalString formula, final Citation citation) { + this.formula = formula; + this.citation = citation; + } + + /** * Creates a new formula from the given string. * * @param formula The formula.
