You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/09/06 21:10:31 UTC
svn commit: r1701516 [2/6] - in /sis/branches/JDK7: ./
core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/
core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/
core/sis-metadata/src/test/java/org/apache/sis/metadata/ cor...
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -16,10 +16,18 @@
*/
package org.apache.sis.internal.jaxb.referencing;
+import java.util.Map;
+import java.util.List;
+import java.util.LinkedHashMap;
import javax.xml.bind.annotation.XmlElement;
+import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.GeneralParameterDescriptor;
import org.apache.sis.internal.jaxb.gco.PropertyType;
import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
+import org.apache.sis.util.CorruptedObjectException;
+import org.apache.sis.util.collection.Containers;
+import org.apache.sis.util.resources.Errors;
/**
@@ -89,4 +97,125 @@ public final class CC_OperationParameter
public void setElement(final DefaultParameterDescriptorGroup parameter) {
metadata = parameter;
}
+
+ /**
+ * Invoked by {@link DefaultParameterDescriptorGroup#setDescriptors(GeneralParameterDescriptor[])}
+ * for merging into a single set the descriptors which are repeated twice in a GML document.
+ *
+ * <p>The {@code descriptors} argument gives the descriptors listed explicitely inside a
+ * {@code <gml:OperationParameterGroup>} or {@code <gml:OperationMethod>} element. Those
+ * descriptors are said "incomplete" (from SIS point of view) because they are missing the
+ * {@link ParameterDescriptor#getValueClass()} property, which does not exist in GML but
+ * is mandatory for us. However an exception to this "incompleteness" happen when SIS has
+ * been able to match the {@code <gml:OperationMethod>} parent to one of the pre-defined
+ * operations in the {@link org.apache.sis.internal.referencing.provider} package.</p>
+ *
+ * <p>The {@code fromValues} argument gives the descriptors declared in each {@code <gml:ParameterValue>}
+ * instances of a {@code <gml:ParameterValueGroup>} or {@code <gml:AbstractSingleOperation>} element.
+ * Contrarily to the {@code descriptors} argument, the {@code fromValues} instances should have non-null
+ * {@link ParameterDescriptor#getValueClass()} property inferred by SIS from the parameter value.</p>
+ *
+ * <p>So the preferred descriptors from more complete to less complete are:</p>
+ * <ol>
+ * <li>{@code descriptors} if and only if they contain pre-defined parameters inferred by SIS from the {@code <gml:OperationMethod>} name.</li>
+ * <li>{@code fromValues}, which contain the descriptors declared in the {@code <gml:ParameterValue>} instances.</li>
+ * <li>{@code descriptors}, which contain the descriptor listed in {@code <gml:OperationParameterGroup>} or {@code <gml:OperationMethod>}.</li>
+ * </ol>
+ *
+ * <div class="note"><b>Note:</b>
+ * this code is defined in this {@code CC_OperationParameterGroup} class instead than in the
+ * {@link DefaultParameterDescriptorGroup} class in the hope to reduce the amount of code
+ * processed by the JVM in the common case where JAXB (un)marshalling is not needed.</div>
+ *
+ * @param descriptors The descriptors declared in the {@code ParameterDescriptorGroup}.
+ * @param fromValues The descriptors declared in the {@code ParameterValue} instances.
+ * They are said "valid" because they contain the mandatory {@code valueClass} property.
+ * @param replacements An {@code IdentityHashMap} where to store the replacements that the caller needs
+ * to apply in the {@code GeneralParameterValue} instances.
+ * @return A sequence containing the merged set of parameter descriptors.
+ *
+ * @see <a href="http://issues.apache.org/jira/browse/SIS-290">SIS-290</a>
+ */
+ public static GeneralParameterDescriptor[] merge(
+ final List<GeneralParameterDescriptor> descriptors,
+ final GeneralParameterDescriptor[] fromValues,
+ final Map<GeneralParameterDescriptor,GeneralParameterDescriptor> replacements)
+ {
+ if (descriptors.isEmpty()) {
+ return fromValues;
+ }
+ final Map<String,GeneralParameterDescriptor> union =
+ new LinkedHashMap<>(Containers.hashMapCapacity(descriptors.size()));
+ /*
+ * Collect the descriptors declared explicitely in the ParameterDescriptorGroup. We should never have
+ * two descriptors of the same name since the DefaultParameterDescriptorGroup constructor checked for
+ * name ambiguity. If a name collision is nevertheless detected, this would mean that a descriptor's
+ * name mutated.
+ */
+ for (final GeneralParameterDescriptor p : descriptors) {
+ final String name = p.getName().getCode();
+ if (union.put(name, p) != null) {
+ throw new CorruptedObjectException(name);
+ }
+ }
+ /*
+ * Verify if any descriptors found in the ParameterValue instances could replace the descriptors in the group.
+ * We give precedence to the descriptors having a non-null 'valueClass' property, which normally appear in the
+ * 'fromValues' array.
+ */
+ for (final GeneralParameterDescriptor valueDescriptor : fromValues) {
+ final String name = valueDescriptor.getName().getCode();
+ GeneralParameterDescriptor complete = valueDescriptor;
+ GeneralParameterDescriptor previous = union.put(name, complete);
+ if (previous != null) {
+ if (previous instanceof ParameterDescriptor<?>) {
+ verifyEquivalence(name, complete instanceof ParameterDescriptor<?>);
+ final Class<?> valueClass = ((ParameterDescriptor<?>) previous).getValueClass();
+ if (valueClass != null) {
+ /*
+ * This may happen if the 'descriptors' argument contain the parameters of a pre-defined
+ * method from the 'org.apache.sis.internal.referencing.provider' package instead than a
+ * descriptor from the GML file. In such case, presume that 'previous' is actually more
+ * complete than 'complete'.
+ *
+ * Note that 'r' should never be null unless JAXB unmarshalled the elements in reverse
+ * order (e.g. <gml:ParameterValue> before <gml:OperationMethod>). Since this behavior
+ * may depend on JAXB implementation, we are better to check for such case.
+ */
+ final Class<?> r = ((ParameterDescriptor<?>) complete).getValueClass();
+ if (r != null) {
+ verifyEquivalence(name, valueClass == r);
+ }
+ // Restore the previous value in the map and swap 'previous' with 'replacement'.
+ previous = union.put(name, complete = previous);
+ }
+ } else if (previous instanceof ParameterDescriptorGroup) {
+ verifyEquivalence(name, complete instanceof ParameterDescriptorGroup);
+ }
+ /*
+ * Verify that the replacement contains at least all the information provided by the previous
+ * descriptor. The replacement is allowed to contain more information however.
+ */
+ final GeneralParameterDescriptor replacement = CC_GeneralOperationParameter.merge(previous, complete);
+ if (replacement != valueDescriptor) {
+ union.put(name, replacement);
+ if (replacements.put(valueDescriptor, replacement) != null) {
+ // Should never happen, unless the parameter name changed during execution of this loop.
+ throw new CorruptedObjectException(name);
+ }
+ }
+ }
+ }
+ return union.values().toArray(new GeneralParameterDescriptor[union.size()]);
+ }
+
+ /**
+ * Throws an exception for mismatched descriptor if a condition is false.
+ * This is used for verifying that a descriptors has the expected properties.
+ */
+ private static void verifyEquivalence(final String name, final boolean condition) {
+ if (!condition) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedParameterDescriptor_1, name));
+ }
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -27,6 +27,7 @@ import org.opengis.referencing.datum.Ell
import org.opengis.referencing.datum.PrimeMeridian;
import org.apache.sis.util.Static;
import org.apache.sis.util.Utilities;
+import org.apache.sis.util.CharSequences;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.jaxb.Context;
import org.apache.sis.referencing.CommonCRS;
@@ -224,6 +225,41 @@ public final class ReferencingUtilities
}
/**
+ * Returns the XML property name of the given interface.
+ *
+ * For {@link CoordinateSystem} base type, the returned value shall be one of
+ * {@code affineCS}, {@code cartesianCS}, {@code cylindricalCS}, {@code ellipsoidalCS}, {@code linearCS},
+ * {@code parametricCS}, {@code polarCS}, {@code sphericalCS}, {@code timeCS} or {@code verticalCS}.
+ *
+ * @param base The abstract base interface.
+ * @param type The interface or classes for which to get the XML property name.
+ * @return The XML property name for the given class or interface, or {@code null} if none.
+ *
+ * @since 0.6
+ */
+ public static StringBuilder toPropertyName(final Class<?> base, final Class<?> type) {
+ final UML uml = type.getAnnotation(UML.class);
+ if (uml != null && uml.specification() == Specification.ISO_19111) {
+ final String name = uml.identifier();
+ final int length = name.length();
+ final StringBuilder buffer = new StringBuilder(length).append(name, name.indexOf('_') + 1, length);
+ if (buffer.length() != 0) {
+ buffer.setCharAt(0, Character.toLowerCase(buffer.charAt(0)));
+ return buffer;
+ }
+ }
+ for (final Class<?> c : type.getInterfaces()) {
+ if (base.isAssignableFrom(c)) {
+ final StringBuilder name = toPropertyName(base, c);
+ if (name != null) {
+ return name;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns the WKT type of the given interface.
*
* For {@link CoordinateSystem} base type, the returned value shall be one of
@@ -236,28 +272,18 @@ public final class ReferencingUtilities
*/
public static String toWKTType(final Class<?> base, final Class<?> type) {
if (type != base) {
- final UML uml = type.getAnnotation(UML.class);
- if (uml != null && uml.specification() == Specification.ISO_19111) {
- String name = uml.identifier();
- final int length = name.length() - 5; // Length without "CS_" and "CS".
- if (length >= 1 && name.startsWith("CS_") && name.endsWith("CS")) {
- final StringBuilder buffer = new StringBuilder(length).append(name, 3, 3 + length);
- if (!name.regionMatches(3, "Cartesian", 0, 9)) {
- buffer.setCharAt(0, Character.toLowerCase(buffer.charAt(0)));
+ final StringBuilder name = toPropertyName(base, type);
+ if (name != null) {
+ int end = name.length() - 2;
+ if (CharSequences.regionMatches(name, end, "CS")) {
+ name.setLength(end);
+ if ("time".contentEquals(name)) {
+ return "temporal";
}
- name = buffer.toString();
- if (name.equals("time")) {
- name = "temporal";
- }
- return name;
- }
- }
- for (final Class<?> c : type.getInterfaces()) {
- if (base.isAssignableFrom(c)) {
- final String name = toWKTType(base, c);
- if (name != null) {
- return name;
+ if (CharSequences.regionMatches(name, 0, "cartesian")) {
+ name.setCharAt(0, 'C'); // "Cartesian"
}
+ return name.toString();
}
}
}
@@ -265,9 +291,9 @@ public final class ReferencingUtilities
}
/**
- * Ensures that the given argument value is {@code false}. This method is invoked by private setter methods,
- * which are themselves invoked by JAXB at unmarshalling time. Invoking this method from those setter methods
- * serves three purposes:
+ * Invoked by private setter methods (themselves invoked by JAXB at unmarshalling time)
+ * when an element is already set. Invoking this method from those setter methods serves
+ * three purposes:
*
* <ul>
* <li>Make sure that a singleton property is not defined twice in the XML document.</li>
@@ -277,23 +303,17 @@ public final class ReferencingUtilities
* warning or error messages in future SIS versions.</li>
* </ul>
*
- * @param classe The caller class, used only in case of warning message to log.
- * @param method The caller method, used only in case of warning message to log.
- * @param name The property name, used only in case of error message to format.
- * @param isDefined Whether the property in the caller object is current defined.
- * @return {@code true} if the caller can set the property.
+ * @param classe The caller class, used only in case of warning message to log.
+ * @param method The caller method, used only in case of warning message to log.
+ * @param name The property name, used only in case of error message to format.
* @throws IllegalStateException If {@code isDefined} is {@code true} and we are not unmarshalling an object.
*/
- public static boolean canSetProperty(final Class<?> classe, final String method,
- final String name, final boolean isDefined) throws IllegalStateException
+ public static void propertyAlreadySet(final Class<?> classe, final String method, final String name)
+ throws IllegalStateException
{
- if (!isDefined) {
- return true;
- }
final Context context = Context.current();
if (context != null) {
Context.warningOccured(context, classe, method, Errors.class, Errors.Keys.ElementAlreadyPresent_1, name);
- return false;
} else {
throw new IllegalStateException(Errors.format(Errors.Keys.ElementAlreadyPresent_1, name));
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -114,12 +114,13 @@ abstract class AbstractProvider extends
}
/**
- * Creates a descriptor for a constant value in degrees.
+ * Creates a descriptor for a 0 constant value in degrees.
*
* @see MapProjection#validate(ParameterDescriptor, double)
*/
- static ParameterDescriptor<Double> createConstant(final ParameterBuilder builder, final Double constant) {
- return builder.createBounded(MeasurementRange.create(constant, true, constant, true, NonSI.DEGREE_ANGLE), constant);
+ static ParameterDescriptor<Double> createZeroConstant(final ParameterBuilder builder) {
+ final Double zero = +0.0;
+ return builder.createBounded(MeasurementRange.create(-0.0, true, zero, true, NonSI.DEGREE_ANGLE), zero);
}
/**
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -163,7 +163,7 @@ public final class Equirectangular exten
* still see it in use sometime. However, taking inspiration from the practice done in "Mercator (1SP)"
* projection, we require that the parameter value must be zero.
*/
- LATITUDE_OF_ORIGIN = createConstant(builder // Was used by EPSG:9823 (also EPSG:9842).
+ LATITUDE_OF_ORIGIN = createZeroConstant(builder // Was used by EPSG:9823 (also EPSG:9842).
.addIdentifier("8801")
.addName("Latitude of natural origin")
.addName(Citations.OGC, "latitude_of_origin")
@@ -172,7 +172,7 @@ public final class Equirectangular exten
.addName(Citations.GEOTIFF, "ProjCenterLat")
.addName(Citations.PROJ4, "lat_0")
.setRemarks(Messages.formatInternational(Messages.Keys.ConstantProjParameterValue_1, 0))
- .setRequired(false), 0.0);
+ .setRequired(false));
// Do not declare the ESRI "Equidistant_Cylindrical" projection name below,
// for avoiding confusion with EPSG "Equidistant Cylindrical" ellipsoidal projection.
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -47,7 +47,6 @@ import org.apache.sis.util.resources.Mes
import static org.opengis.metadata.Identifier.AUTHORITY_KEY;
// Branch-dependent imports
-import java.util.Objects;
/**
@@ -133,7 +132,7 @@ public abstract class MapProjection exte
* @param value The parameter value in the units given by the descriptor.
* @throws IllegalArgumentException if the given value is out of bounds.
*
- * @see #createConstant(ParameterBuilder, Double)
+ * @see #createZeroConstant(ParameterBuilder)
*/
public static void validate(final ParameterDescriptor<? extends Number> descriptor, final double value)
throws IllegalArgumentException
@@ -144,7 +143,9 @@ public abstract class MapProjection exte
}
final Comparable<? extends Number> min = descriptor.getMinimumValue();
final Comparable<? extends Number> max = descriptor.getMaximumValue();
- if (!Objects.equals(min, max)) {
+ final double minValue = (min instanceof Number) ? ((Number) min).doubleValue() : Double.NaN;
+ final double maxValue = (max instanceof Number) ? ((Number) max).doubleValue() : Double.NaN;
+ if (value < minValue || value > maxValue) {
/*
* RATIONAL: why we do not check the bounds if (min == max):
* The only case when our descriptor have (min == max) is when a parameter can only be zero,
@@ -152,11 +153,9 @@ public abstract class MapProjection exte
* But in some cases, it would be possible to deal with non-zero values, even if in principle
* we should not. In such case we let the caller decides.
*
- * Above check should be revisited if createConstant(ParameterBuilder, Double) is modified.
+ * Above check should be revisited if createZeroConstant(ParameterBuilder) is modified.
*/
- if ((min instanceof Number && !(value >= ((Number) min).doubleValue())) ||
- (max instanceof Number && !(value <= ((Number) max).doubleValue())))
- {
+ if (minValue != maxValue) { // Compare as 'double' because we want (-0 == +0) to be true.
throw new IllegalArgumentException(Errors.format(Errors.Keys.ValueOutOfRange_4,
descriptor.getName(), min, max, value));
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator1SP.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator1SP.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator1SP.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator1SP.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -66,9 +66,9 @@ public final class Mercator1SP extends A
static final ParameterDescriptorGroup PARAMETERS;
static {
final ParameterBuilder builder = builder();
- LATITUDE_OF_ORIGIN = createConstant(builder.addNamesAndIdentifiers(Equirectangular.LATITUDE_OF_ORIGIN)
+ LATITUDE_OF_ORIGIN = createZeroConstant(builder.addNamesAndIdentifiers(Equirectangular.LATITUDE_OF_ORIGIN)
.rename(Citations.GEOTIFF, "NatOriginLat")
- .setRemarks(Equirectangular.LATITUDE_OF_ORIGIN.getRemarks()), 0.0);
+ .setRemarks(Equirectangular.LATITUDE_OF_ORIGIN.getRemarks()));
LONGITUDE_OF_ORIGIN = createLongitude(builder.addNamesAndIdentifiers(Equirectangular.LONGITUDE_OF_ORIGIN)
.rename(Citations.GEOTIFF, "NatOriginLong"));
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -77,9 +77,9 @@ public final class Mercator2SP extends A
*/
builder.setRequired(false); // Will apply to all remaining parameters.
final InternationalString remarks = notFormalParameter("Mercator (variant A)");
- final ParameterDescriptor<Double> latitudeOfOrigin = createConstant(builder
+ final ParameterDescriptor<Double> latitudeOfOrigin = createZeroConstant(builder
.addNamesAndIdentifiers(Mercator1SP.LATITUDE_OF_ORIGIN)
- .setRemarks(remarks), 0.0);
+ .setRemarks(remarks));
/*
* Remove the EPSG name and identifier at least for the scale factor, because its meaning does not fit well
* in this context. The EPSG name is "Scale factor at natural origin" while actually the scale factor applied
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -34,6 +34,7 @@ import org.apache.sis.util.ComparisonMod
import org.apache.sis.util.Debug;
import static org.apache.sis.util.Utilities.deepEquals;
+import static org.apache.sis.internal.jaxb.referencing.CC_GeneralOperationParameter.DEFAULT_OCCURRENCE;
// Branch-dependent imports
import java.util.Objects;
@@ -134,17 +135,6 @@ public abstract class AbstractParameterD
private short maximumOccurs;
/**
- * 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.
- */
- AbstractParameterDescriptor() {
- super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
- minimumOccurs = 1; // Default value is XML element is omitted.
- maximumOccurs = 1;
- }
-
- /**
* Constructs a parameter descriptor from a set of 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:
@@ -368,7 +358,30 @@ public abstract class AbstractParameterD
return WKTKeywords.Parameter;
}
- // ---- XML SUPPORT ----------------------------------------------------
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ //////// ////////
+ //////// 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.
+ */
+ AbstractParameterDescriptor() {
+ super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
+ minimumOccurs = DEFAULT_OCCURRENCE; // Default value if XML element is omitted.
+ maximumOccurs = DEFAULT_OCCURRENCE;
+ }
/**
* Invoked by JAXB for marshalling the {@link #minimumOccurs} value. Omit marshalling of this
@@ -378,7 +391,7 @@ public abstract class AbstractParameterD
@XmlSchemaType(name = "nonNegativeInteger")
private Integer getNonDefaultMinimumOccurs() {
final int n = getMinimumOccurs();
- return (n != 1) ? n : null;
+ return (n != DEFAULT_OCCURRENCE) ? n : null;
}
/**
@@ -395,20 +408,20 @@ public abstract class AbstractParameterD
@XmlSchemaType(name = "nonNegativeInteger")
private Integer getNonDefaultMaximumOccurs() {
final int n = getMaximumOccurs();
- return (n != 1) ? n : null;
+ return (n != DEFAULT_OCCURRENCE) ? n : null;
}
/**
* Invoked by JAXB for unmarshalling the {@link #minimumOccurs} value.
*/
private void setNonDefaultMinimumOccurs(final Integer n) {
- minimumOccurs = (n != null) ? crop(n) : 1;
+ minimumOccurs = (n != null) ? crop(n) : DEFAULT_OCCURRENCE;
}
/**
* Invoked by JAXB for unmarshalling the {@link #maximumOccurs} value.
*/
private void setNonDefaultMaximumOccurs(final Integer n) {
- maximumOccurs = (n != null) ? crop(n) : 1;
+ maximumOccurs = (n != null) ? crop(n) : DEFAULT_OCCURRENCE;
}
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptor.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -121,37 +121,6 @@ public class DefaultParameterDescriptor<
private final T defaultValue;
/**
- * 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.
- *
- * <p>This constructor fetches the value class and the unit of measurement from the enclosing
- * {@link DefaultParameterValue}, if presents, because those information are not presents in GML.
- * They are GeoAPI additions.</p>
- */
- @SuppressWarnings("unchecked")
- private DefaultParameterDescriptor() {
- final PropertyType<?,?> wrapper = Context.getWrapper(Context.current());
- if (wrapper instanceof CC_OperationParameter) {
- final CC_OperationParameter param = (CC_OperationParameter) wrapper;
- /*
- * This unsafe cast would be forbidden if this constructor was public or used in any context where the
- * user can choose the value of <T>. But this constructor should be invoked only during unmarshalling,
- * after the creation of the ParameterValue (this is the reverse creation order than what we normally
- * do through the public API). The 'valueClass' should be compatible with DefaultParameterValue.value,
- * and the parameterized type visible to the user should be only <?>.
- */
- valueClass = (Class) param.valueClass;
- valueDomain = param.valueDomain;
- } else {
- valueClass = null;
- valueDomain = null;
- }
- validValues = null;
- defaultValue = null;
- }
-
- /**
* Constructs a descriptor from the given properties. The properties map is given unchanged to the
* {@linkplain AbstractParameterDescriptor#AbstractParameterDescriptor(Map, int, int) super-class constructor}.
* The following table is a reminder of main (not all) properties:
@@ -537,4 +506,50 @@ public class DefaultParameterDescriptor<
protected long computeHashCode() {
return Arrays.deepHashCode(new Object[] {valueClass, valueDomain, defaultValue}) + super.computeHashCode();
}
+
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ //////// ////////
+ //////// 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.
+ *
+ * <p>This constructor fetches the value class and the unit of measurement from the enclosing
+ * {@link DefaultParameterValue}, if presents, because those information are not presents in GML.
+ * They are GeoAPI additions.</p>
+ */
+ @SuppressWarnings("unchecked")
+ private DefaultParameterDescriptor() {
+ final PropertyType<?,?> wrapper = Context.getWrapper(Context.current());
+ if (wrapper instanceof CC_OperationParameter) {
+ final CC_OperationParameter param = (CC_OperationParameter) wrapper;
+ /*
+ * This unsafe cast would be forbidden if this constructor was public or used in any context where the
+ * user can choose the value of <T>. But this constructor should be invoked only during unmarshalling,
+ * after the creation of the ParameterValue (this is the reverse creation order than what we normally
+ * do through the public API). The 'valueClass' should be compatible with DefaultParameterValue.value,
+ * and the parameterized type visible to the user should be only <?>.
+ */
+ valueClass = (Class) param.valueClass;
+ valueDomain = param.valueDomain;
+ } else {
+ valueClass = null;
+ valueDomain = null;
+ }
+ validValues = null;
+ defaultValue = null;
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -21,7 +21,6 @@ import java.util.Set;
import java.util.List;
import java.util.HashSet;
import java.util.Collections;
-import java.util.LinkedHashMap;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@@ -31,9 +30,10 @@ import org.opengis.parameter.ParameterDe
import org.opengis.parameter.GeneralParameterDescriptor;
import org.opengis.parameter.ParameterNotFoundException;
import org.opengis.parameter.InvalidParameterNameException;
+import org.apache.sis.internal.jaxb.referencing.CC_OperationParameterGroup;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.referencing.IdentifiedObjects;
import org.apache.sis.internal.util.UnmodifiableArrayList;
-import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;
@@ -110,15 +110,6 @@ public class DefaultParameterDescriptorG
private List<GeneralParameterDescriptor> descriptors;
/**
- * Constructs a new object in which every attributes are set to a null value or an empty list.
- * <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 DefaultParameterDescriptorGroup() {
- descriptors = Collections.emptyList();
- }
-
- /**
* Constructs a parameter group from a set of properties. The properties map is given unchanged to the
* {@linkplain AbstractParameterDescriptor#AbstractParameterDescriptor(Map, int, int) super-class constructor}.
* The following table is a reminder of main (not all) properties:
@@ -419,7 +410,30 @@ public class DefaultParameterDescriptorG
return super.computeHashCode() + descriptors.hashCode();
}
- // ---- XML SUPPORT ----------------------------------------------------
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ //////// ////////
+ //////// 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 or an empty list.
+ * <strong>This is not a valid object.</strong> This constructor is strictly reserved to JAXB
+ * and to {@link DefaultParameterValueGroup}, which will assign values later.
+ *
+ * @see #setDescriptors(GeneralParameterDescriptor[])
+ */
+ DefaultParameterDescriptorGroup() {
+ descriptors = Collections.emptyList();
+ }
/**
* Invoked by JAXB for getting the parameters to marshal.
@@ -431,35 +445,39 @@ public class DefaultParameterDescriptorG
}
/**
- * Invoked by JAXB or by {@link DefaultParameterValueGroup} for setting the unmarshalled parameters.
- * If parameters already exist, them this method computes the union of the two parameter collections
- * with the new parameters having precedence over the old ones.
+ * Invoked by JAXB for setting the unmarshalled parameter descriptors.
+ */
+ private void setDescriptors(final GeneralParameterDescriptor[] parameters) {
+ if (descriptors.isEmpty()) {
+ verifyNames(null, parameters);
+ descriptors = asList(parameters);
+ } else {
+ ReferencingUtilities.propertyAlreadySet(DefaultParameterValue.class, "setDescriptors", "parameter");
+ }
+ }
+
+ /**
+ * Merges the given parameter descriptors with the descriptors currently in this group.
+ * The descriptors are set twice during {@link DefaultParameterValueGroup} unmarshalling:
*
- * <div class="note"><b>Rational:</b>
- * this method is invoked twice during {@link DefaultParameterValueGroup} unmarshalling:
* <ol>
- * <li>First, this method is invoked during unmarshalling of this {@code DefaultParameterDescriptorGroup}.
+ * <li>First, the descriptors are set during unmarshalling of this {@code DefaultParameterDescriptorGroup}.
* But the value class of {@code ParameterDescriptor} components are unknown because this information
* is not part of GML.</li>
* <li>Next, this method is invoked during unmarshalling of the {@code DefaultParameterValueGroup} enclosing
* element with the descriptors found inside the {@code ParameterValue} components. The later do have the
* {@code valueClass} information, so we want to use them in replacement of descriptors of step 1.</li>
* </ol>
- * </div>
+ *
+ * @param fromValues Descriptors declared in the {@code ParameterValue} instances of a {@code ParameterValueGroup}.
+ * @param replacements An {@code IdentityHashMap} where to store the replacements that the caller needs
+ * to apply in the {@code GeneralParameterValue} instances.
*/
- final void setDescriptors(GeneralParameterDescriptor[] parameters) {
- verifyNames(null, parameters);
- if (!descriptors.isEmpty()) {
- final Map<String,GeneralParameterDescriptor> union =
- new LinkedHashMap<>(Containers.hashMapCapacity(descriptors.size()));
- for (final GeneralParameterDescriptor p : descriptors) {
- union.put(p.getName().getCode(), p);
- }
- for (final GeneralParameterDescriptor p : parameters) {
- union.put(p.getName().getCode(), p);
- }
- parameters = union.values().toArray(new GeneralParameterDescriptor[union.size()]);
- }
- descriptors = asList(parameters);
+ final void merge(GeneralParameterDescriptor[] fromValues,
+ final Map<GeneralParameterDescriptor,GeneralParameterDescriptor> replacements)
+ {
+ fromValues = CC_OperationParameterGroup.merge(descriptors, fromValues, replacements);
+ verifyNames(null, fromValues);
+ descriptors = asList(fromValues);
}
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -161,13 +161,6 @@ public class DefaultParameterValue<T> ex
private Unit<?> unit;
/**
- * Default constructor for JAXB only. The descriptor is initialized to {@code null},
- * but will be assigned a value after XML unmarshalling.
- */
- private DefaultParameterValue() {
- }
-
- /**
* Creates a parameter value from the specified descriptor.
* The value will be initialized to the default value, if any.
*
@@ -1002,7 +995,38 @@ public class DefaultParameterValue<T> ex
formatter.hasContextualUnit(2); // In WKT2
}
- // ---- XML SUPPORT ----------------------------------------------------
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ //////// ////////
+ //////// 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. ////////
+ //////// ////////
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Default constructor for JAXB only. The descriptor is initialized to {@code null},
+ * but will be assigned a value after XML unmarshalling.
+ */
+ private DefaultParameterValue() {
+ }
+
+ /**
+ * Invoked by JAXB at unmarshalling time.
+ * May also be invoked by {@link DefaultParameterValueGroup} if the descriptor as been completed
+ * with additional information provided in the {@code <gml:group>} element of a descriptor group.
+ *
+ * @see #getDescriptor()
+ */
+ final void setDescriptor(final ParameterDescriptor<T> descriptor) {
+ this.descriptor = descriptor;
+ assert (value == null) || descriptor.getValueClass().isInstance(value) : this;
+ }
/**
* Invoked by JAXB for obtaining the object to marshal.
@@ -1052,9 +1076,7 @@ public class DefaultParameterValue<T> ex
*/
@SuppressWarnings("unchecked")
private void setXmlValue(Object xmlValue) {
- if (ReferencingUtilities.canSetProperty(DefaultParameterValue.class,
- "setXmlValue", "value", value != null || unit != null))
- {
+ if (value == null && unit == null) {
if (xmlValue instanceof Measure) {
final Measure measure = (Measure) xmlValue;
xmlValue = measure.value;
@@ -1085,16 +1107,8 @@ public class DefaultParameterValue<T> ex
*/
value = (T) xmlValue;
}
+ } else {
+ ReferencingUtilities.propertyAlreadySet(DefaultParameterValue.class, "setXmlValue", "value");
}
}
-
- /**
- * Invoked by JAXB at unmarshalling time.
- *
- * @see #getDescriptor()
- */
- private void setDescriptor(final ParameterDescriptor<T> descriptor) {
- this.descriptor = descriptor;
- assert (value == null) || descriptor.getValueClass().isInstance(value) : this;
- }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -18,7 +18,8 @@ package org.apache.sis.parameter;
import java.util.List;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Map;
+import java.util.IdentityHashMap;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
@@ -132,13 +133,6 @@ public class DefaultParameterValueGroup
private ParameterValueList values;
/**
- * Default constructor for JAXB only. The values list is initialized to {@code null},
- * but will be assigned a value after XML unmarshalling.
- */
- private DefaultParameterValueGroup() {
- }
-
- /**
* Creates a parameter group from the specified descriptor.
*
* <p><b>Usage note:</b> {@code ParameterValueGroup} are usually not instantiated directly. Instead, consider
@@ -504,7 +498,42 @@ public class DefaultParameterValueGroup
ParameterFormat.print(this);
}
- // ---- XML SUPPORT ----------------------------------------------------
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ //////// ////////
+ //////// 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. ////////
+ //////// ////////
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Default constructor for JAXB only. The values list is initialized to {@code null},
+ * but will be assigned a value after XML unmarshalling.
+ */
+ private DefaultParameterValueGroup() {
+ }
+
+ /**
+ * Invoked by JAXB for setting the group parameter descriptor. Those parameter are redundant with
+ * the parameters associated to the values given to {@link #setValues(GeneralParameterValue[])},
+ * except the the group identification (name, <i>etc.</i>) and for any optional parameters which
+ * were not present in the above {@code GeneralParameterValue} array.
+ *
+ * @see #getDescriptor()
+ */
+ private void setDescriptor(final ParameterDescriptorGroup descriptor) {
+ if (values == null) {
+ values = new ParameterValueList(descriptor);
+ } else {
+ ReferencingUtilities.propertyAlreadySet(DefaultParameterValue.class, "setDescriptor", "group");
+ }
+ }
/**
* Invoked by JAXB for getting the parameters to marshal.
@@ -519,38 +548,56 @@ public class DefaultParameterValueGroup
* Invoked by JAXB for setting the unmarshalled parameters. This method should be invoked last
* (after {@link #setDescriptor(ParameterDescriptorGroup)}) even if the {@code parameterValue}
* elements were first in the XML document. This is the case at least with the JAXB reference
- * implementation.
+ * implementation, because the property type is an array (it would not work with a list).
+ *
+ * <p><b>Maintenance note:</b> the {@code "setValues"} method name is also hard-coded in
+ * {@link org.apache.sis.internal.jaxb.referencing.CC_GeneralOperationParameter} for logging purpose.</p>
*/
private void setValues(final GeneralParameterValue[] parameters) {
- final GeneralParameterDescriptor[] descriptors = new GeneralParameterDescriptor[parameters.length];
- for (int i=0; i<descriptors.length; i++) {
- descriptors[i] = parameters[i].getDescriptor();
- }
- if (values == null) {
+ ParameterValueList addTo = values;
+ if (addTo == null) {
// Should never happen, unless the XML document is invalid and does not have a 'group' element.
-
- } else {
- // We known that the descriptor is an instance of our DefaultParameterDescriptorGroup
- // implementation because this is what we declare to the JAXBContext and in adapters.
- ((DefaultParameterDescriptorGroup) values.descriptor).setDescriptors(descriptors);
- values.clear(); // Because references to parameter descriptors have changed.
+ addTo = new ParameterValueList(new DefaultParameterDescriptorGroup());
}
- values.addAll(Arrays.asList(parameters));
+ /*
+ * Merge the descriptors declared in the <gml:group> element with the descriptors given in each
+ * <gml:parameterValue> element. The implementation is known to be DefaultParameterDescriptorGroup
+ * because this is the type declared in the JAXBContext and in adapters.
+ */
+ final Map<GeneralParameterDescriptor,GeneralParameterDescriptor> replacements = new IdentityHashMap<>(4);
+ ((DefaultParameterDescriptorGroup) addTo.descriptor).merge(getDescriptors(parameters), replacements);
+ addTo.clear(); // Because references to parameter descriptors have changed.
+ setValues(parameters, replacements, addTo);
}
/**
- * Invoked by JAXB for setting the group parameter descriptor. Those parameter are redundant with
- * the parameters associated to the values given to {@link #setValues(GeneralParameterValue[])},
- * except the the group identification (name, <i>etc.</i>) and for any optional parameters which
- * were not present in the above {@code GeneralParameterValue} array.
+ * Appends all parameter values. In this process, we may need to update the descriptor of some values
+ * if those descriptors changed as a result of the above merge process.
*
- * @see #getDescriptor()
+ * @param parameters The parameters to add, or {@code null} for {@link #values}.
+ * @param replacements The replacements to apply in the {@code GeneralParameterValue} instances.
+ * @param addTo Where to store the new values.
*/
- private void setDescriptor(final ParameterDescriptorGroup descriptor) {
- if (ReferencingUtilities.canSetProperty(DefaultParameterValue.class,
- "setDescriptor", "group", values != null))
- {
- values = new ParameterValueList(descriptor);
+ @SuppressWarnings({"unchecked", "AssignmentToCollectionOrArrayFieldFromParameter"})
+ private void setValues(GeneralParameterValue[] parameters,
+ final Map<GeneralParameterDescriptor,GeneralParameterDescriptor> replacements,
+ final ParameterValueList addTo)
+ {
+ if (parameters == null) {
+ parameters = values.toArray();
+ }
+ for (final GeneralParameterValue p : parameters) {
+ final GeneralParameterDescriptor replacement = replacements.get(p.getDescriptor());
+ if (replacement != null) {
+ if (p instanceof DefaultParameterValue<?>) {
+ ((DefaultParameterValue<?>) p).setDescriptor((ParameterDescriptor) replacement);
+ } else if (p instanceof DefaultParameterValueGroup) {
+ ((DefaultParameterValueGroup) p).setValues(null, replacements,
+ new ParameterValueList((ParameterDescriptorGroup) replacement));
+ }
+ }
+ addTo.add(p);
}
+ values = addTo;
}
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -34,6 +34,7 @@ import org.opengis.metadata.Identifier;
import org.apache.sis.util.ArraysExt;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
+import org.apache.sis.referencing.IdentifiedObjects;
/**
@@ -238,14 +239,15 @@ final class ParameterValueList extends A
* parameter name was not found, or the parameter descriptor does not matches.
*/
final Identifier name = desc.getName();
+ final String code = name.getCode();
for (final GeneralParameterDescriptor descriptor : descriptors) {
- if (name.equals(descriptor.getName())) {
+ if (IdentifiedObjects.isHeuristicMatchForName(descriptor, code)) {
throw new IllegalArgumentException(Errors.format(
Errors.Keys.MismatchedParameterDescriptor_1, name));
}
}
throw new InvalidParameterNameException(Errors.format(Errors.Keys.ParameterNotFound_2,
- Verifier.getDisplayName(descriptor), name), name.getCode());
+ Verifier.getDisplayName(descriptor), name), code);
}
}
@@ -310,6 +312,14 @@ final class ParameterValueList extends A
}
/**
+ * Returns the parameters in an array.
+ */
+ @Override
+ public GeneralParameterValue[] toArray() {
+ return Arrays.copyOf(values, size);
+ }
+
+ /**
* Returns a string representation of this list.
*/
@Override
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -220,6 +220,35 @@ public abstract class Parameters impleme
}
/**
+ * Returns the descriptors of the given parameters, in the same order.
+ * Special cases:
+ *
+ * <ul>
+ * <li>If the given array is {@code null}, then this method returns {@code null}.
+ * <li>If an element of the given array is {@code null}, then the corresponding
+ * element of the returned array is also {@code null}.</li>
+ * </ul>
+ *
+ * @param parameters The parameter values from which to get the descriptors, or {@code null}.
+ * @return The descriptors of the given parameter values, or {@code null} if the {@code parameters} argument was null.
+ *
+ * @since 0.6
+ */
+ public static GeneralParameterDescriptor[] getDescriptors(final GeneralParameterValue... parameters) {
+ if (parameters == null) {
+ return null;
+ }
+ final GeneralParameterDescriptor[] descriptors = new GeneralParameterDescriptor[parameters.length];
+ for (int i=0; i<parameters.length; i++) {
+ final GeneralParameterValue p = parameters[i];
+ if (p != null) {
+ descriptors[i] = p.getDescriptor();
+ }
+ }
+ return descriptors;
+ }
+
+ /**
* Gets the parameter name as an instance of {@code MemberName}.
* This method performs the following checks:
*
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -29,6 +29,7 @@ import javax.xml.bind.annotation.XmlType
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import org.opengis.util.GenericName;
@@ -223,16 +224,6 @@ public class AbstractIdentifiedObject ex
private transient int hashCode;
/**
- * 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.
- */
- AbstractIdentifiedObject() {
- remarks = null;
- deprecated = false;
- }
-
- /**
* Constructs an object from the given properties. Keys are strings from the table below.
* The map given in argument shall contain an entry at least for the
* {@value org.opengis.referencing.IdentifiedObject#NAME_KEY} or
@@ -500,6 +491,7 @@ public class AbstractIdentifiedObject ex
* since it may depends on the marshalling context.</p>
*/
@XmlID
+ @XmlSchemaType(name = "ID")
@XmlAttribute(name = "id", namespace = Namespaces.GML, required = true)
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
final String getID() {
@@ -532,144 +524,6 @@ public class AbstractIdentifiedObject ex
}
/**
- * Returns a single element from the {@code Set<Identifier>} collection, or {@code null} if none.
- * We have to define this method because ISO 19111 defines the {@code identifiers} property as a collection
- * while GML 3.2 defines it as a singleton.
- *
- * <p>This method searches for the following identifiers, in preference order:</p>
- * <ul>
- * <li>The first identifier having a code that begin with {@code "urn:"}.</li>
- * <li>The first identifier having a code that begin with {@code "http:"}.</li>
- * <li>The first identifier, converted to the {@code "urn:} syntax if possible.</li>
- * </ul>
- */
- @XmlElement(name = "identifier")
- final Code getIdentifier() {
- return Code.forIdentifiedObject(getClass(), identifiers);
- }
-
- /**
- * Invoked by JAXB at unmarshalling time for setting the identifier.
- */
- private void setIdentifier(final Code identifier) {
- if (identifier != null) {
- final Identifier id = identifier.getIdentifier();
- if (id != null && ReferencingUtilities.canSetProperty(AbstractIdentifiedObject.class,
- "setIdentifier", "identifier", identifiers != null))
- {
- identifiers = Collections.singleton(id);
- }
- }
- }
-
- /**
- * A writable view over the {@linkplain AbstractIdentifiedObject#getName() name} of the enclosing object followed
- * by all {@linkplain AbstractIdentifiedObject#getAlias() aliases} which are instance of {@link Identifier}.
- * Used by JAXB only at (un)marshalling time because GML merges the name and aliases in a single {@code <gml:name>}
- * property.
- */
- private final class Names extends AbstractCollection<Identifier> {
- /**
- * Invoked by JAXB before to write in the collection at unmarshalling time.
- * Do nothing since our object is already empty.
- */
- @Override
- public void clear() {
- }
-
- /**
- * Returns the number of name and aliases that are instance of {@link Identifier}.
- */
- @Override
- public int size() {
- return NameIterator.count(AbstractIdentifiedObject.this);
- }
-
- /**
- * Returns an iterator over the name and aliases that are instance of {@link Identifier}.
- */
- @Override
- public Iterator<Identifier> iterator() {
- return new NameIterator(AbstractIdentifiedObject.this);
- }
-
- /**
- * Invoked by JAXB at unmarshalling time for each identifier. The first identifier will be taken
- * as the name and all other identifiers (if any) as aliases.
- *
- * <p>Some (but not all) JAXB implementations never invoke setter method for collections.
- * Instead they invoke {@link AbstractIdentifiedObject#getNames()} and add directly the identifiers
- * in the returned collection. Consequently this method must writes directly in the enclosing object.
- * See <a href="https://java.net/jira/browse/JAXB-488">JAXB-488</a> for more information.</p>
- */
- @Override
- public boolean add(final Identifier id) {
- addName(id);
- return true;
- }
- }
-
- /**
- * Implementation of {@link Names#add(Identifier)}, defined in the enclosing class
- * for access to private fields without compiler-generated bridge methods.
- */
- final void addName(final Identifier id) {
- if (name == NilReferencingObject.UNNAMED) {
- name = id;
- } else {
- /*
- * Our Code and RS_Identifier implementations should always create NamedIdentifier instance,
- * so the 'instanceof' check should not be necessary. But we do a paranoiac check anyway.
- */
- final GenericName n = id instanceof GenericName ? (GenericName) id : new NamedIdentifier(id);
- if (alias == null) {
- alias = Collections.singleton(n);
- } else {
- /*
- * This implementation is inefficient since each addition copies the array, but we rarely
- * have more than two aliases. This implementation is okay for a small number of aliases
- * and ensures that the enclosing AbstractIdentifiedObject is unmodifiable except by this
- * add(…) method.
- *
- * Note about alternative approaches
- * ---------------------------------
- * An alternative approach could be to use an ArrayList and replace it by an unmodifiable
- * list only after unmarshalling (using an afterUnmarshal(Unmarshaller, Object) method),
- * but we want to avoid Unmarshaller dependency (for reducing classes loading for users
- * who are not interrested in XML) and it may actually be less efficient for the vast
- * majority of cases where there is less than 3 aliases.
- */
- final int size = alias.size();
- final GenericName[] names = alias.toArray(new GenericName[size + 1]);
- names[size] = n;
- alias = UnmodifiableArrayList.wrap(names);
- }
- }
- }
-
- /**
- * Returns the {@link #name} and all aliases which are also instance of {@link Identifier}.
- * The later happen often in SIS implementation since many aliases are instance of {@link NamedIdentifier}.
- *
- * <p>The returned collection is <cite>live</cite>: adding elements in that collection will modify this
- * {@code AbstractIdentifiedObject} instance. This is needed for unmarshalling with JAXB and should not
- * be used in other context.</p>
- *
- * <div class="section">Why there is no <code>setNames(…)</code> method</div>
- * Some JAXB implementations never invoke setter method for collections. Instead they invoke the getter and
- * add directly the identifiers in the returned collection. Whether JAXB will perform or not a final call to
- * {@code setNames(…)} is JAXB-implementation dependent (JDK7 does but JDK6 and JDK8 early access do not).
- * It seems a more portable approach (at least for JAXB reference implementations) to design our class
- * without setter method, in order to have the same behavior on all supported JDK versions.
- *
- * @see <a href="https://java.net/jira/browse/JAXB-488">JAXB-488</a>
- */
- @XmlElement(name = "name", required = true)
- final Collection<Identifier> getNames() {
- return new Names();
- }
-
- /**
* Returns the primary name by which this object is identified.
*
* @return The primary name.
@@ -1066,4 +920,168 @@ public class AbstractIdentifiedObject ex
WKTUtilities.appendName(this, formatter, ElementKind.forType(getClass()));
return null;
}
+
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ //////// ////////
+ //////// 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.
+ */
+ AbstractIdentifiedObject() {
+ remarks = null;
+ deprecated = false;
+ }
+
+ /**
+ * Returns a single element from the {@code Set<Identifier>} collection, or {@code null} if none.
+ * We have to define this method because ISO 19111 defines the {@code identifiers} property as a collection
+ * while GML 3.2 defines it as a singleton.
+ *
+ * <p>This method searches for the following identifiers, in preference order:</p>
+ * <ul>
+ * <li>The first identifier having a code that begin with {@code "urn:"}.</li>
+ * <li>The first identifier having a code that begin with {@code "http:"}.</li>
+ * <li>The first identifier, converted to the {@code "urn:} syntax if possible.</li>
+ * </ul>
+ */
+ @XmlElement(name = "identifier")
+ final Code getIdentifier() {
+ return Code.forIdentifiedObject(getClass(), identifiers);
+ }
+
+ /**
+ * Invoked by JAXB at unmarshalling time for setting the identifier.
+ */
+ private void setIdentifier(final Code identifier) {
+ if (identifiers == null) {
+ if (identifier != null) {
+ final Identifier id = identifier.getIdentifier();
+ if (id != null) {
+ identifiers = Collections.singleton(id);
+ }
+ }
+ } else {
+ ReferencingUtilities.propertyAlreadySet(AbstractIdentifiedObject.class, "setIdentifier", "identifier");
+ }
+ }
+
+ /**
+ * Returns the {@link #name} and all aliases which are also instance of {@link Identifier}.
+ * The later happen often in SIS implementation since many aliases are instance of {@link NamedIdentifier}.
+ *
+ * <p>The returned collection is <cite>live</cite>: adding elements in that collection will modify this
+ * {@code AbstractIdentifiedObject} instance. This is needed for unmarshalling with JAXB and should not
+ * be used in other context.</p>
+ *
+ * <div class="section">Why there is no <code>setNames(…)</code> method</div>
+ * Some JAXB implementations never invoke setter method for collections. Instead they invoke the getter and
+ * add directly the identifiers in the returned collection. Whether JAXB will perform or not a final call to
+ * {@code setNames(…)} is JAXB-implementation dependent (JDK7 does but JDK6 and JDK8 early access do not).
+ * It seems a more portable approach (at least for JAXB reference implementations) to design our class
+ * without setter method, in order to have the same behavior on all supported JDK versions.
+ *
+ * @see <a href="https://java.net/jira/browse/JAXB-488">JAXB-488</a>
+ */
+ @XmlElement(name = "name", required = true)
+ final Collection<Identifier> getNames() {
+ return new Names();
+ }
+
+ /**
+ * A writable view over the {@linkplain AbstractIdentifiedObject#getName() name} of the enclosing object followed
+ * by all {@linkplain AbstractIdentifiedObject#getAlias() aliases} which are instance of {@link Identifier}.
+ * Used by JAXB only at (un)marshalling time because GML merges the name and aliases in a single {@code <gml:name>}
+ * property.
+ */
+ private final class Names extends AbstractCollection<Identifier> {
+ /**
+ * Invoked by JAXB before to write in the collection at unmarshalling time.
+ * Do nothing since our object is already empty.
+ */
+ @Override
+ public void clear() {
+ }
+
+ /**
+ * Returns the number of name and aliases that are instance of {@link Identifier}.
+ */
+ @Override
+ public int size() {
+ return NameIterator.count(AbstractIdentifiedObject.this);
+ }
+
+ /**
+ * Returns an iterator over the name and aliases that are instance of {@link Identifier}.
+ */
+ @Override
+ public Iterator<Identifier> iterator() {
+ return new NameIterator(AbstractIdentifiedObject.this);
+ }
+
+ /**
+ * Invoked by JAXB at unmarshalling time for each identifier. The first identifier will be taken
+ * as the name and all other identifiers (if any) as aliases.
+ *
+ * <p>Some (but not all) JAXB implementations never invoke setter method for collections.
+ * Instead they invoke {@link AbstractIdentifiedObject#getNames()} and add directly the identifiers
+ * in the returned collection. Consequently this method must writes directly in the enclosing object.
+ * See <a href="https://java.net/jira/browse/JAXB-488">JAXB-488</a> for more information.</p>
+ */
+ @Override
+ public boolean add(final Identifier id) {
+ addName(id);
+ return true;
+ }
+ }
+
+ /**
+ * Implementation of {@link Names#add(Identifier)}, defined in the enclosing class
+ * for access to private fields without compiler-generated bridge methods.
+ */
+ final void addName(final Identifier id) {
+ if (name == NilReferencingObject.UNNAMED) {
+ name = id;
+ } else {
+ /*
+ * Our Code and RS_Identifier implementations should always create NamedIdentifier instance,
+ * so the 'instanceof' check should not be necessary. But we do a paranoiac check anyway.
+ */
+ final GenericName n = id instanceof GenericName ? (GenericName) id : new NamedIdentifier(id);
+ if (alias == null) {
+ alias = Collections.singleton(n);
+ } else {
+ /*
+ * This implementation is inefficient since each addition copies the array, but we rarely
+ * have more than two aliases. This implementation is okay for a small number of aliases
+ * and ensures that the enclosing AbstractIdentifiedObject is unmodifiable except by this
+ * add(…) method.
+ *
+ * Note about alternative approaches
+ * ---------------------------------
+ * An alternative approach could be to use an ArrayList and replace it by an unmodifiable
+ * list only after unmarshalling (using an afterUnmarshal(Unmarshaller, Object) method),
+ * but we want to avoid Unmarshaller dependency (for reducing classes loading for users
+ * who are not interrested in XML) and it may actually be less efficient for the vast
+ * majority of cases where there is less than 3 aliases.
+ */
+ final int size = alias.size();
+ final GenericName[] names = alias.toArray(new GenericName[size + 1]);
+ names[size] = n;
+ alias = UnmodifiableArrayList.wrap(names);
+ }
+ }
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -89,16 +89,6 @@ public class AbstractReferenceSystem ext
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.
- */
- AbstractReferenceSystem() {
- domainOfValidity = null;
- scope = null;
- }
-
- /**
* Constructs a reference system from the given properties.
* The properties given in argument follow the same rules than for the
* {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
@@ -252,4 +242,28 @@ public class AbstractReferenceSystem ext
protected long computeHashCode() {
return super.computeHashCode() + Objects.hash(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.
+ */
+ AbstractReferenceSystem() {
+ domainOfValidity = null;
+ scope = null;
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1701516&r1=1701515&r2=1701516&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Sun Sep 6 19:10:30 2015
@@ -122,15 +122,6 @@ public class AbstractCRS extends Abstrac
private transient Map<AxesConvention,AbstractCRS> forConvention;
/**
- * 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.
- */
- AbstractCRS() {
- super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
- }
-
- /**
* Creates a coordinate reference system from the given properties and coordinate system.
* The properties given in argument follow the same rules than for the
* {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
@@ -290,47 +281,6 @@ public class AbstractCRS extends Abstrac
}
/**
- * Sets the coordinate system to the given value. This method is invoked only by JAXB at
- * unmarshalling time and can be invoked only if the coordinate system has never been set.
- *
- * <div class="note"><b>Implementation note:</b>
- * It was easy to put JAXB annotations directly on datum fields in subclasses because each CRS type
- * can be associated to only one datum type. But we do not have this convenience for coordinate systems,
- * where the same CRS may accept different kinds of CS. In GML, the different kinds of CS are marshalled
- * as different XML elements. The usual way to handle such {@code <xs:choice>} with JAXB is to annotate
- * a single method like below:
- *
- * {@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 have not been conclusive.
- * For an unknown reason, the unmarshalled CS object was empty.</div>
- *
- * @param name The property name, used only in case of error message to format.
- * @throws IllegalStateException If the coordinate system has already been set.
- */
- final void setCoordinateSystem(final String name, final CoordinateSystem cs) {
- if (cs != null && ReferencingUtilities.canSetProperty(AbstractCRS.class,
- "setCoordinateSystem", name, coordinateSystem != null))
- {
- coordinateSystem = cs;
- }
- }
-
- /**
* Returns the existing CRS for the given convention, or {@code null} if none.
*/
final AbstractCRS getCached(final AxesConvention convention) {
@@ -537,4 +487,45 @@ public class AbstractCRS extends Abstrac
formatter.restoreContextualUnit(unit, oldUnit);
formatter.newLine(); // For writing the ID[…] element on its own line.
}
+
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ //////// ////////
+ //////// 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.
+ */
+ AbstractCRS() {
+ super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
+ }
+
+ /**
+ * Sets the coordinate system to the given value.
+ * This method is indirectly invoked by JAXB at unmarshalling time.
+ *
+ * @param name The property name, used only in case of error message to format. Can be null for auto-detect.
+ * @throws IllegalStateException If the coordinate system has already been set.
+ */
+ final void setCoordinateSystem(String name, final CoordinateSystem cs) {
+ if (coordinateSystem == null) {
+ coordinateSystem = cs;
+ } else {
+ if (name == null) {
+ name = String.valueOf(ReferencingUtilities.toPropertyName(CoordinateSystem.class, cs.getClass()));
+ }
+ ReferencingUtilities.propertyAlreadySet(AbstractCRS.class, "setCoordinateSystem", name);
+ }
+ }
}