Author: desruisseaux
Date: Mon Aug 31 17:52:00 2015
New Revision: 1700283
URL: http://svn.apache.org/r1700283
Log:
Consolidation of JAXB annotations on DefaultOperationMethod and parameters:
- Delegate more works to JAXB adapter classes.
- More effort for merging information provided by duplicated parameter
descriptors.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_GeneralOperationParameter.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/OperationMarshallingTest.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_GeneralOperationParameter.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_GeneralOperationParameter.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_GeneralOperationParameter.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_GeneralOperationParameter.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -16,20 +16,40 @@
*/
package org.apache.sis.internal.jaxb.referencing;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
import javax.xml.bind.annotation.XmlElementRef;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.ParameterNotFoundException;
import org.apache.sis.parameter.AbstractParameterDescriptor;
import org.apache.sis.parameter.DefaultParameterDescriptor;
import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
+import org.apache.sis.parameter.Parameters;
+import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.jaxb.gco.PropertyType;
+import org.apache.sis.internal.jaxb.Context;
/**
* JAXB adapter mapping implementing class to the GeoAPI interface. See
* package documentation for more information about JAXB and interface.
*
+ * <p>This class provides an additional {@link
#replacement(GeneralParameterDescriptor, GeneralParameterDescriptor)}
+ * method building a unique descriptor instance when the same descriptor is
declared in more than one place in the
+ * GML document. Some examples of duplications are:</p>
+ *
+ * <ul>
+ * <li>The descriptors listed under the {@code <gml:group>} element, which
duplicate the descriptors listed
+ * under each {@code <gml:parameterValue>} element.</li>
+ * <li>The descriptors declared in each parameter value of a {@code
SingleOperation}, which duplicate the
+ * descriptors declared in the associated {@code OperationMethod}.</li>
+ * </ul>
+ *
* @author Martin Desruisseaux (Geomatys)
* @since 0.6
* @version 0.6
@@ -37,6 +57,31 @@ import org.apache.sis.internal.jaxb.gco.
*/
public final class CC_GeneralOperationParameter extends
PropertyType<CC_GeneralOperationParameter, GeneralParameterDescriptor> {
/**
+ * The default value of {@code minimumOccurs} and {@code maximumOccurs} if
the XML element is not provided.
+ */
+ public static final short DEFAULT_OCCURRENCE = 1;
+
+ /**
+ * The properties to ignore in the descriptor parsed from GML when this
descriptor is merged with a
+ * pre-defined descriptor. Remarks:
+ *
+ * <ul>
+ * <li>We ignore the name because the comparisons shall be performed by
the caller with
+ * {@link IdentifiedObjects#isHeuristicMatchForName} or something
equivalent.</li>
+ * <li>We ignore aliases and identifiers for now for avoiding the
additional complexity
+ * of dealing with collections, and because the Apache SIS
pre-defined descriptors
+ * will be more complete in a majority of case.
+ *
+ * <b>TODO - </b> this may be revised in any future SIS version.</li>
+ * </ul>
+ */
+ private static final String[] IGNORE_DURING_MERGE = {
+ GeneralParameterDescriptor.NAME_KEY,
+ GeneralParameterDescriptor.ALIAS_KEY,
+ GeneralParameterDescriptor.IDENTIFIERS_KEY
+ };
+
+ /**
* Empty constructor for JAXB only.
*/
public CC_GeneralOperationParameter() {
@@ -105,4 +150,167 @@ public final class CC_GeneralOperationPa
public void setElement(final AbstractParameterDescriptor parameter) {
metadata = parameter;
}
+
+ /**
+ * Returns a descriptor with the same properties than the {@code provided}
one, but completed with information
+ * not found in GML. Those missing information are given by the {@code
complete} descriptor, which may come from
+ * two sources:
+ *
+ * <ul>
+ * <li>The descriptor for a {@code <gml:ParameterValue>} element. Those
descriptors are more complete than the
+ * ones provided by {@code <gml:OperationParameter>} elements alone
because the parameter value allows SIS
+ * to infer the {@code valueClass}.</li>
+ * <li>A pre-defined parameter descriptor from the {@link
org.apache.sis.internal.referencing.provider} package.</li>
+ * </ul>
+ *
+ * @param provided The descriptor unmarshalled from the GML document.
+ * @param complete The descriptor to use for completing missing
information.
+ * @return The descriptor to use. May be one of the arguments given to
this method, or a new instance.
+ */
+ public static GeneralParameterDescriptor replacement(final
GeneralParameterDescriptor provided,
+ final
GeneralParameterDescriptor complete)
+ {
+ if (provided == complete) {
+ return complete;
+ }
+ final boolean isGroup;
+ if (provided instanceof ParameterDescriptor<?> && complete instanceof
ParameterDescriptor<?>) {
+ isGroup = false; // This is by far the most usual case.
+ } else if (provided instanceof ParameterDescriptorGroup && complete
instanceof ParameterDescriptorGroup) {
+ isGroup = true;
+ } else {
+ /*
+ * Mismatched or unknown type. It should not happen with
descriptors parsed by JAXB and with
+ * pre-defined descriptors provided by SIS. But it could happen
with a pre-defined descriptor
+ * found in a user-provided OperationMethod with malformed
parameters.
+ * Return the descriptor found in the GML document as-is.
+ */
+ return provided;
+ }
+ final int minimumOccurs = provided.getMinimumOccurs();
+ final int maximumOccurs = provided.getMaximumOccurs();
+ final Map<String,?> expected =
IdentifiedObjects.getProperties(complete);
+ final Map<String,?> actual =
IdentifiedObjects.getProperties(provided, IGNORE_DURING_MERGE);
+ final boolean canSubstitute = complete.getMinimumOccurs() ==
minimumOccurs
+ && complete.getMaximumOccurs() ==
maximumOccurs
+ &&
expected.entrySet().containsAll(actual.entrySet());
+ if (canSubstitute && !isGroup) {
+ /*
+ * The pre-defined or ParameterValue descriptor contains at least
all the information found
+ * in the descriptor parsed from the GML document, ignoring
IGNORE_DURING_MERGE properties.
+ * So we can use the existing instance directly, assuming that the
additional properties and
+ * the difference in ignored properties are acceptable.
+ */
+ return complete;
+ }
+ /*
+ * Collect the properties specified in the GML document and complete
with the properties provided
+ * by the 'complete' descriptor. If the descriptor is a group, then
this 'replacement' method will
+ * be invoked recursively for each parameter in the group.
+ */
+ final Map<String,Object> merged = new HashMap<>(expected);
+ merged.putAll(actual); // May overwrite pre-defined properties.
+ if (isGroup) {
+ final List<GeneralParameterDescriptor> descriptors =
((ParameterDescriptorGroup) provided).descriptors();
+ return merge(actual, merged, minimumOccurs, maximumOccurs,
+ descriptors.toArray(new
GeneralParameterDescriptor[descriptors.size()]),
+ (ParameterDescriptorGroup) complete, canSubstitute);
+ } else {
+ return merge(merged, (ParameterDescriptor<?>) provided,
(ParameterDescriptor<?>) complete);
+ }
+ }
+
+ /**
+ * Returns a descriptor with the given properties, completed with
information not found in GML.
+ * Those extra information are given by the {@code complete} descriptor.
+ *
+ * @param properties Properties as declared in the GML document, to be
used if {@code complete} is incompatible.
+ * @param merged More complete properties, to be used if {@code
complete} is compatible.
+ * @param minimumOccurs Value to assign to {@link
DefaultParameterDescriptorGroup#getMinimumOccurs()}.
+ * @param maximumOccurs Value to assign to {@link
DefaultParameterDescriptorGroup#getMaximumOccurs()}.
+ * @param provided Parameter descriptors declared in the GML
document. This array will be overwritten.
+ * @param complete More complete parameter descriptors.
+ * @param canSubstitute {@code true} if this method is allowed to return
{@code complete}.
+ * @return The parameter descriptor group to use (may be the {@code
complete} instance).
+ */
+ static ParameterDescriptorGroup merge(final Map<String,?>
properties,
+ final Map<String,?>
merged,
+ final int
minimumOccurs,
+ final int
maximumOccurs,
+ final GeneralParameterDescriptor[]
provided,
+ final ParameterDescriptorGroup
complete,
+ boolean
canSubstitute)
+ {
+ boolean isCompatible = true;
+ final Map<GeneralParameterDescriptor,Boolean> included = new
IdentityHashMap<>(provided.length);
+ for (int i=0; i<provided.length; i++) {
+ final GeneralParameterDescriptor p = provided[i];
+ try {
+ /*
+ * Replace the descriptors provided in the GML document by
descriptors from the 'complete' instance,
+ * if possible. Keep trace of the complete descriptors that we
found in this process.
+ */
+ GeneralParameterDescriptor predefined =
complete.descriptor(p.getName().getCode());
+ if (predefined != null) { // Safety in case 'complete' is a
user's implementation.
+ canSubstitute &= (provided[i] = replacement(p,
predefined)) == predefined;
+ included.put(predefined, Boolean.TRUE);
+ continue;
+ }
+ } catch (ParameterNotFoundException e) {
+ Context.warningOccured(Context.current(),
CC_GeneralOperationParameter.class, "replacement", e, canSubstitute);
+ }
+ /*
+ * If a parameter was not found in the 'complete' descriptor, we
will not be able to use that descriptor.
+ * But we may still be able to use its properties (name, alias,
identifier) provided that the parameter
+ * not found was optional.
+ */
+ isCompatible &= p.getMinimumOccurs() == 0;
+ canSubstitute = false;
+ }
+ if (isCompatible) {
+ /*
+ * At this point, we determined that all mandatory parameters in
the GML document exist in the 'complete'
+ * descriptor. However the converse is not necessarily true.
Verify that all parameters missing in the GML
+ * document were optional.
+ */
+ for (final GeneralParameterDescriptor descriptor :
complete.descriptors()) {
+ if (!included.containsKey(descriptor) &&
descriptor.getMinimumOccurs() != 0
+ && !CC_OperationMethod.isImplicitParameter(descriptor))
+ {
+ canSubstitute = false;
+ isCompatible = false;
+ break;
+ }
+ }
+ }
+ if (canSubstitute) {
+ return complete;
+ } else {
+ return new DefaultParameterDescriptorGroup(isCompatible ? merged :
properties,
+ minimumOccurs, maximumOccurs, provided);
+ }
+ }
+
+ /**
+ * Creates a new descriptor with the same properties than the {@code
provided} one, but completed with
+ * information not found in GML. Those extra information are given by the
{@code complete} descriptor.
+ *
+ * <p>It is the caller's responsibility to construct the {@code
properties} map as a merge
+ * of the properties of the two given descriptors.</p>
+ */
+ private static <T> ParameterDescriptor<T> merge(final Map<String,?>
merged,
+ final
ParameterDescriptor<?> provided,
+ final
ParameterDescriptor<T> complete)
+ {
+ final Class<T> valueClass = complete.getValueClass();
+ return new DefaultParameterDescriptor<>(merged,
+ provided.getMinimumOccurs(),
+ provided.getMaximumOccurs(),
+ // Values below this point are not provided in GML documents,
+ // so they must be inferred from the pre-defined descriptor.
+ valueClass,
+ Parameters.getValueDomain(complete),
+ CollectionsExt.toArray(complete.getValidValues(), valueClass),
+ complete.getDefaultValue());
+ }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -16,10 +16,24 @@
*/
package org.apache.sis.internal.jaxb.referencing;
+import java.util.Map;
+import java.util.Collections;
import javax.xml.bind.annotation.XmlElement;
+import org.opengis.util.FactoryException;
+import org.opengis.metadata.Identifier;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.CoordinateOperationFactory;
+import org.apache.sis.internal.jaxb.Context;
import org.apache.sis.internal.jaxb.gco.PropertyType;
+import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.referencing.provider.MapProjection;
+import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
import org.apache.sis.referencing.operation.DefaultOperationMethod;
+import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.util.ArraysExt;
/**
@@ -89,4 +103,87 @@ public final class CC_OperationMethod ex
public void setElement(final DefaultOperationMethod method) {
metadata = method;
}
+
+ /**
+ * Returns the given descriptors, excluding the implicit {@link
MapProjection} parameters.
+ *
+ * @param array The parameters to filter.
+ * @return The filtered parameters.
+ */
+ public static GeneralParameterValue[] filterImplicit(final
GeneralParameterValue[] array) {
+ int n = 0;
+ for (final GeneralParameterValue value : array) {
+ if
(!CC_OperationMethod.isImplicitParameter(value.getDescriptor())) {
+ array[n++] = value;
+ }
+ }
+ return ArraysExt.resize(array, n);
+ }
+
+ /**
+ * Returns the given descriptors, excluding the implicit {@link
MapProjection} parameters.
+ *
+ * @param array The parameters to filter.
+ * @return The filtered parameters.
+ */
+ public static GeneralParameterDescriptor[] filterImplicit(final
GeneralParameterDescriptor[] array) {
+ int n = 0;
+ for (final GeneralParameterDescriptor descriptor : array) {
+ if (!CC_OperationMethod.isImplicitParameter(descriptor)) {
+ array[n++] = descriptor;
+ }
+ }
+ return ArraysExt.resize(array, n);
+ }
+
+ /**
+ * Returns {@code true} if the given descriptor is for an implicit
parameter which should be excluded from GML.
+ *
+ * @param descriptor The parameter descriptor to test.
+ * @return {@code true} if the given parameter should be omitted in the
GML document.
+ */
+ static boolean isImplicitParameter(final GeneralParameterDescriptor
descriptor) {
+ return descriptor == MapProjection.SEMI_MAJOR
+ || descriptor == MapProjection.SEMI_MINOR;
+ }
+
+ /**
+ * Wraps the given descriptors in a descriptor group of the given name. If
the given name can be matched
+ * to the name of one of the predefined operation method, then the
predefined parameters will be used.
+ *
+ * <p>We try to use predefined parameters if possible because they contain
information, especially the
+ * {@link org.opengis.parameter.ParameterDescriptor#getValueClass()}
property, which are not available
+ * in the GML document.</p>
+ *
+ * <div class="note"><b>Note:</b>
+ * this code is defined in this {@code CC_OperationMethod} class instead
than in the
+ * {@link DefaultOperationMethod} 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 name The operation method name, to be also given to the
descriptor group.
+ * @param descriptors The parameter descriptors to wrap in a group. This
array will be modified in-place.
+ * @return A parameter group containing at least the given descriptors, or
equivalent descriptors.
+ */
+ public static ParameterDescriptorGroup group(final Identifier name, final
GeneralParameterDescriptor[] descriptors) {
+ final CoordinateOperationFactory factory =
DefaultFactories.forClass(CoordinateOperationFactory.class);
+ OperationMethod method = null;
+ if (factory != null) try {
+ method = factory.getOperationMethod(name.getCode());
+ } catch (FactoryException e) {
+ Context.warningOccured(Context.current(),
DefaultOperationMethod.class, "setDescriptors", e, true);
+ }
+ final Map<String,?> properties =
Collections.singletonMap(ParameterDescriptorGroup.NAME_KEY, name);
+ if (method != null) {
+ /*
+ * Verify that the pre-defined operation method contains at least
all the parameters specified by
+ * the 'descriptors' array. If this is the case, then the
pre-defined parameters will be used in
+ * replacement of the given ones.
+ */
+ final ParameterDescriptorGroup parameters = method.getParameters();
+ return CC_GeneralOperationParameter.merge(properties,
+ IdentifiedObjects.getProperties(parameters),
+ 1, 1, descriptors, parameters, true);
+ }
+ return new DefaultParameterDescriptorGroup(properties, 1, 1,
descriptors);
+ }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationParameterGroup.java
[UTF-8] Mon Aug 31 17:52:00 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 java.util.ConcurrentModificationException;
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.collection.Containers;
+import org.apache.sis.util.resources.Errors;
/**
@@ -89,4 +97,105 @@ 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.
+ * The descriptors are:
+ *
+ * <ol>
+ * <li>The descriptors declared explicitely in the descriptor group.</li>
+ * <li>The descriptors declared in the parameter values.</li>
+ * </ol>
+ *
+ * The later are more complete than the former, because they allow us to
infer the {@code valueClass} property.
+ *
+ * <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 parameters The descriptors declared in the {@code
ParameterValue}.
+ * @return A single set containing the two given set of parameters.
+ */
+ public static GeneralParameterDescriptor[] merge(final
List<GeneralParameterDescriptor> descriptors,
+ final GeneralParameterDescriptor[] parameters)
+ {
+ if (descriptors.isEmpty()) {
+ return parameters;
+ }
+ 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
ConcurrentModificationException(Errors.format(Errors.Keys.UnexpectedChange_1,
name));
+ }
+ }
+ /*
+ * Verify if any descriptors found in the ParameterValue instances
could replace the current descriptors.
+ * We give precedence to the descriptors having a non-null
'valueClass' property, which normally are the
+ * descriptors from the 'parameters' array.
+ */
+ for (GeneralParameterDescriptor replacement : parameters) {
+ final String name = replacement.getName().getCode();
+ GeneralParameterDescriptor previous = union.put(name, replacement);
+ if (previous != null) {
+ if (previous instanceof ParameterDescriptor<?>) {
+ verifyEquivalence(name, replacement instanceof
ParameterDescriptor<?>);
+ final Class<?> valueClass = ((ParameterDescriptor<?>)
previous).getValueClass();
+ if (valueClass != null) {
+ final Class<?> r = ((ParameterDescriptor<?>)
replacement).getValueClass();
+ if (r != null) {
+ /*
+ * Should never happen unless the same (according
its name) ParameterValue appears
+ * more than once in the 'parameters' array, or
unless this method is invoked more
+ * often than expected.
+ */
+ verifyEquivalence(name, valueClass == r);
+ } else {
+ /*
+ * Should never happen unless JAXB unmarshalled
the elements in reverse order
+ * (i.e. ParameterValue before
ParameterDescriptorGroup). Since this behavior
+ * may depend on JAXB implementation, we are
better to check for such case.
+ * Restore the previous value in the map and swap
'previous' with 'replacement'.
+ */
+ previous = union.put(name, replacement = previous);
+ }
+ }
+ } else if (previous instanceof ParameterDescriptorGroup) {
+ verifyEquivalence(name, replacement 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 r =
CC_GeneralOperationParameter.replacement(previous, replacement);
+ if (r != replacement) {
+ union.put(name, r);
+
+ // TODO: We should instead update DefaultParameterValue
descriptor here.
+ verifyEquivalence(name, false);
+ }
+ }
+ }
+ 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
[UTF-8] Mon Aug 31 17:52:00 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;
@@ -140,8 +141,8 @@ public abstract class AbstractParameterD
*/
AbstractParameterDescriptor() {
super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
- minimumOccurs = 1; // Default value is XML element is omitted.
- maximumOccurs = 1;
+ minimumOccurs = DEFAULT_OCCURRENCE; // Default value if XML element
is omitted.
+ maximumOccurs = DEFAULT_OCCURRENCE;
}
/**
@@ -378,7 +379,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 +396,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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java
[UTF-8] Mon Aug 31 17:52:00 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,9 @@ 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.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;
@@ -111,10 +110,12 @@ public class DefaultParameterDescriptorG
/**
* 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.
+ * <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[])
*/
- private DefaultParameterDescriptorGroup() {
+ DefaultParameterDescriptorGroup() {
descriptors = Collections.emptyList();
}
@@ -432,7 +433,7 @@ 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
+ * If parameters already exist, then this method computes the union of the
two parameter collections
* with the new parameters having precedence over the old ones.
*
* <div class="note"><b>Rational:</b>
@@ -448,18 +449,8 @@ public class DefaultParameterDescriptorG
* </div>
*/
final void setDescriptors(GeneralParameterDescriptor[] parameters) {
+ parameters = CC_OperationParameterGroup.merge(descriptors, 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);
}
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -519,7 +519,7 @@ 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).
*/
private void setValues(final GeneralParameterValue[] parameters) {
final GeneralParameterDescriptor[] descriptors = new
GeneralParameterDescriptor[parameters.length];
@@ -528,13 +528,12 @@ public class DefaultParameterValueGroup
}
if (values == 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.
+ values = new ParameterValueList(new
DefaultParameterDescriptorGroup());
}
+ // 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.
values.addAll(Arrays.asList(parameters));
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -17,21 +17,26 @@
package org.apache.sis.referencing.operation;
import java.util.Map;
+import java.util.List;
+import java.util.Arrays;
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.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptorGroup;
+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.crs.CoordinateReferenceSystem;
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_OperationMethod;
import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.util.Constants;
@@ -57,7 +62,7 @@ import java.util.Objects;
*/
@XmlType(name="AbstractSingleOperationType", propOrder = {
"method",
-// "parameters"
+ "parameters"
})
@XmlRootElement(name = "AbstractSingleOperation")
@XmlSeeAlso({
@@ -77,8 +82,11 @@ class AbstractSingleOperation extends Ab
/**
* 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;
+ private ParameterValueGroup parameters;
/**
* Constructs a new object in which every attributes are set to a null
value.
@@ -87,7 +95,6 @@ class AbstractSingleOperation extends Ab
*/
AbstractSingleOperation() {
method = null;
- parameters = null;
}
/**
@@ -406,4 +413,49 @@ class AbstractSingleOperation extends Ab
*/
return true;
}
+
+ // ---- XML SUPPORT ----------------------------------------------------
+
+ /**
+ * 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 (ReferencingUtilities.canSetProperty(DefaultOperationMethod.class,
+ "setParameters", "parameterValue", parameters != null))
+ {
+ ParameterDescriptorGroup descriptor = method.getParameters();
+ parameters = new DefaultParameterValueGroup(descriptor);
+ parameters.values().addAll(Arrays.asList(values));
+ if (method instanceof DefaultOperationMethod) {
+ ((DefaultOperationMethod)
method).setParameters(parameters.getDescriptor());
+ }
+ }
+ }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -43,6 +43,7 @@ import org.apache.sis.util.iso.SimpleInt
import org.apache.sis.internal.util.Citations;
import org.apache.sis.internal.metadata.WKTKeywords;
import org.apache.sis.internal.jaxb.gco.StringAdapter;
+import org.apache.sis.internal.jaxb.referencing.CC_OperationMethod;
import org.apache.sis.internal.referencing.NilReferencingObject;
import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
@@ -590,7 +591,8 @@ public class DefaultOperationMethod exte
*
* <div class="note"><b>Departure from the ISO 19111 standard:</b>
* this property is mandatory according ISO 19111, but may be null in
Apache SIS if the
- * {@link #DefaultOperationMethod(MathTransform)} constructor has been
unable to infer it.</div>
+ * {@link #DefaultOperationMethod(MathTransform)} constructor has been
unable to infer it
+ * or if this {@code OperationMethod} has been read from an incomplete GML
document.</div>
*
* @return The parameters, or {@code null} if unknown.
*
@@ -783,13 +785,17 @@ public class DefaultOperationMethod exte
*
* But we would need to make sure that {@link
AbstractSingleOperation#getParameters()} is consistent
* with the decision taken by this method.</div>
+ *
+ * @see #getParameters()
+ * @see AbstractSingleOperation#getParameters()
*/
@XmlElement(name = "parameter")
private GeneralParameterDescriptor[] getDescriptors() {
if (parameters != null) {
final List<GeneralParameterDescriptor> descriptors =
parameters.descriptors();
if (descriptors != null) { // Paranoiac check (should not be
allowed).
- return descriptors.toArray(new
GeneralParameterDescriptor[descriptors.size()]);
+ return CC_OperationMethod.filterImplicit(descriptors.toArray(
+ new GeneralParameterDescriptor[descriptors.size()]));
}
}
return null;
@@ -797,22 +803,29 @@ public class DefaultOperationMethod exte
/**
* Invoked by JAXB for setting the unmarshalled parameters.
- * This method wraps the given descriptors in an {@link
DefaultParameterDescriptorGroup},
- * unless the given descriptors was already a {@code
ParameterDescriptorGroup}.
+ * This method wraps the given descriptors in a {@link
DefaultParameterDescriptorGroup}.
+ *
+ * <p>The parameter descriptors created by this method are incomplete
since we can not
+ * provide a non-null value for {@link
ParameterDescriptor#getValueClass()}. The value
+ * class will be provided either by replacing this {@code OperationMethod}
by one of the
+ * pre-defined methods, or by unmarshalling the enclosing {@link
AbstractSingleOperation}.</p>
*
- * <p>The parameter descriptors created by this method are incomplete,
since they can not
- * provide a non-null value for {@link
ParameterDescriptor#getValueClass()}.</p>
+ * @see AbstractSingleOperation#setParameters
*/
private void setDescriptors(final GeneralParameterDescriptor[]
descriptors) {
if (ReferencingUtilities.canSetProperty(DefaultOperationMethod.class,
"setDescriptors", "parameter", parameters != null))
{
- if (descriptors.length == 1 && descriptors[0] instanceof
ParameterDescriptorGroup) {
- parameters = (ParameterDescriptorGroup) descriptors[0];
- } else {
- parameters = new DefaultParameterDescriptorGroup(
- Collections.singletonMap(NAME_KEY, super.getName()),
1, 1, descriptors);
- }
+ parameters = CC_OperationMethod.group(super.getName(),
descriptors);
}
}
+
+ /**
+ * Invoked by {@link AbstractSingleOperation} for completing the parameter
descriptor.
+ *
+ * @see #getParameters()
+ */
+ final void setParameters(final ParameterDescriptorGroup descriptor) {
+ parameters = descriptor;
+ }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -68,6 +68,7 @@
@XmlJavaTypeAdapter(CI_Citation.class),
@XmlJavaTypeAdapter(DQ_PositionalAccuracy.class),
@XmlJavaTypeAdapter(CC_OperationMethod.class),
+ @XmlJavaTypeAdapter(CC_GeneralParameterValue.class),
@XmlJavaTypeAdapter(CC_GeneralOperationParameter.class),
@XmlJavaTypeAdapter(InternationalStringConverter.class)
})
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -33,6 +33,7 @@ import org.opengis.parameter.ParameterDe
* @version 0.4
* @module
*/
+@SuppressWarnings("CloneInNonCloneableClass")
final class ParameterValueGroupWrapper implements ParameterValueGroup {
/**
* The implementation to hide.
@@ -46,10 +47,11 @@ final class ParameterValueGroupWrapper i
this.impl = impl;
}
+ @SuppressWarnings("CloneDoesntCallSuperClone")
+ @Override public ParameterValueGroup clone()
{return impl.clone();}
@Override public ParameterDescriptorGroup getDescriptor()
{return impl.getDescriptor();}
@Override public List<GeneralParameterValue> values()
{return impl.values();}
@Override public ParameterValue<?> parameter(String name)
{return impl.parameter(name);}
@Override public List<ParameterValueGroup> groups(String name)
{return impl.groups(name);}
@Override public ParameterValueGroup addGroup(String name)
{return impl.addGroup(name);}
- @Override public ParameterValueGroup clone()
{return impl.clone();}
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/OperationMarshallingTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/OperationMarshallingTest.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/OperationMarshallingTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/OperationMarshallingTest.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -19,11 +19,11 @@ package org.apache.sis.referencing.opera
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
-import org.opengis.parameter.GeneralParameterDescriptor;
import javax.xml.bind.JAXBException;
import javax.measure.unit.NonSI;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.GeneralParameterDescriptor;
import org.apache.sis.parameter.ParameterBuilder;
import org.apache.sis.xml.Namespaces;
import org.apache.sis.xml.XML;
@@ -55,8 +55,8 @@ public final strictfp class OperationMar
final ParameterBuilder builder = new ParameterBuilder();
builder.setCodeSpace(EPSG, "EPSG").setRequired(true);
ParameterDescriptor<?>[] parameters = {
- builder.addName("Latitude of natural origin" ).create(0,
NonSI.DEGREE_ANGLE),
- builder.addName("Longitude of natural origin").create(0,
NonSI.DEGREE_ANGLE)
+ builder.addIdentifier("8801").addName("Latitude of natural origin"
).create(0, NonSI.DEGREE_ANGLE),
+ builder.addIdentifier("8802").addName("Longitude of natural
origin").create(0, NonSI.DEGREE_ANGLE)
// There is more parameters for a Mercator projection, but 2 is
enough for this test.
};
builder.addName(null, "Mercator");
@@ -81,12 +81,14 @@ public final strictfp class OperationMar
+ " <gml:sourceDimensions>2</gml:sourceDimensions>\n"
+ " <gml:targetDimensions>2</gml:targetDimensions>\n"
+ " <gml:parameter>\n"
- + " <gml:OperationParameter
gml:id=\"LatitudeOfNaturalOrigin\">\n"
+ + " <gml:OperationParameter
gml:id=\"epsg-parameter-8801\">\n"
+ + " <gml:identifier
codeSpace=\"IOGP\">urn:ogc:def:parameter:EPSG::8801</gml:identifier>\n"
+ " <gml:name codeSpace=\"EPSG\">Latitude of
natural origin</gml:name>\n"
+ " </gml:OperationParameter>\n"
+ " </gml:parameter>\n"
+ " <gml:parameter>\n"
- + " <gml:OperationParameter
gml:id=\"LongitudeOfNaturalOrigin\">\n"
+ + " <gml:OperationParameter
gml:id=\"epsg-parameter-8802\">\n"
+ + " <gml:identifier
codeSpace=\"IOGP\">urn:ogc:def:parameter:EPSG::8802</gml:identifier>\n"
+ " <gml:name codeSpace=\"EPSG\">Longitude of
natural origin</gml:name>\n"
+ " </gml:OperationParameter>\n"
+ " </gml:parameter>\n"
@@ -104,7 +106,7 @@ public final strictfp class OperationMar
assertEquals("sourceDimensions", Integer.valueOf(2),
method.getSourceDimensions());
assertEquals("targetDimensions", Integer.valueOf(2),
method.getTargetDimensions());
final ParameterDescriptorGroup parameters = method.getParameters();
- assertEquals("parameters.name", method.getName(),
parameters.getName());
+ assertEquals("parameters.name", "Mercator",
parameters.getName().getCode());
final Iterator<GeneralParameterDescriptor> it =
parameters.descriptors().iterator();
verifyIncompleteDescriptor("Latitude of natural origin", it.next());
verifyIncompleteDescriptor("Longitude of natural origin", it.next());
@@ -122,6 +124,5 @@ public final strictfp class OperationMar
private static void verifyIncompleteDescriptor(final String name, final
GeneralParameterDescriptor descriptor) {
assertIdentifierEquals("name", "##unrestricted", "EPSG", null, name,
descriptor.getName());
assertEquals("maximumOccurs", 1, descriptor.getMaximumOccurs());
- assertEquals("minimumOccurs", 1, descriptor.getMinimumOccurs());
}
}
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -46,7 +46,7 @@ import org.apache.sis.xml.ReferenceResol
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.5
+ * @version 0.6
* @module
*/
public final class Context extends MarshalContext {
@@ -530,16 +530,16 @@ public final class Context extends Marsh
* Convenience method for sending a warning for the given exception.
* The logger will be {@code "org.apache.sis.xml"}.
*
- * @param context The current context, or {@code null} if none.
- * @param classe The class to declare as the warning source.
- * @param method The name of the method to declare as the warning source.
- * @param cause The exception which occurred.
- * @param warning {@code true} for {@link Level#WARNING}, or {@code false}
for {@link Level#FINE}.
+ * @param context The current context, or {@code null} if none.
+ * @param classe The class to declare as the warning source.
+ * @param method The name of the method to declare as the warning
source.
+ * @param cause The exception which occurred.
+ * @param isWarning {@code true} for {@link Level#WARNING}, or {@code
false} for {@link Level#FINE}.
*/
public static void warningOccured(final Context context, final Class<?>
classe,
- final String method, final Exception cause, final boolean warning)
+ final String method, final Exception cause, final boolean
isWarning)
{
- warningOccured(context, warning ? Level.WARNING : Level.FINE, classe,
method, cause,
+ warningOccured(context, isWarning ? Level.WARNING : Level.FINE,
classe, method, cause,
null, (short) 0, (Object[]) null);
}
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -20,6 +20,7 @@ import java.util.*;
import java.lang.reflect.Array;
import org.opengis.util.CodeList;
import org.apache.sis.util.Static;
+import org.apache.sis.util.Numbers;
import org.apache.sis.util.collection.CodeListSet;
import org.apache.sis.util.resources.Errors;
import org.opengis.parameter.InvalidParameterCardinalityException;
@@ -588,6 +589,27 @@ public final class CollectionsExt extend
}
/**
+ * Returns the elements of the given collection as an array. This method
can be used when the {@code valueClass}
+ * argument is not known at compile-time. If the {@code valueClass} is
known at compile-time, then callers should
+ * use {@link Collection#toArray(T[])} instead.
+ *
+ * @param <T> The compile-time value of {@code valueClass}.
+ * @param collection The collection from which to get the elements.
+ * @param valueClass The runtime type of collection elements.
+ * @return The collection elements as an array, or {@code null} if {@code
collection} is null.
+ *
+ * @since 0.6
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] toArray(final Collection<T> collection, final
Class<T> valueClass) {
+ assert Numbers.primitiveToWrapper(valueClass) == valueClass :
valueClass;
+ if (collection != null) {
+ return collection.toArray((T[]) Array.newInstance(valueClass,
collection.size()));
+ }
+ return null;
+ }
+
+ /**
* Adds a value in a pseudo multi-values map. The multi-values map is
simulated by a map of lists.
* The map can be initially empty - lists will be created as needed.
*
Modified:
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java?rev=1700283&r1=1700282&r2=1700283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java
[UTF-8] Mon Aug 31 17:52:00 2015
@@ -44,7 +44,7 @@ import java.util.function.Function;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.5
+ * @version 0.6
* @module
*/
public final strictfp class CollectionsExtTest extends TestCase {
@@ -153,4 +153,16 @@ public final strictfp class CollectionsE
assertFalse(CollectionsExt.identityEquals(c2.iterator(),
c1.iterator()));
assertTrue(CollectionsExt.identityEquals(c1.iterator(),
Arrays.asList("A", "B", "C").iterator()));
}
+
+ /**
+ * Tests {@link CollectionsExt#toArray(Collection, Class)}.
+ *
+ * @since 0.6
+ */
+ @Test
+ public void testToArray() {
+ final String[] expected = new String[] {"One", "Two", "Three"};
+ final String[] actual =
CollectionsExt.toArray(Arrays.asList(expected), String.class);
+ assertArrayEquals(expected, actual);
+ }
}