use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.
the class DefaultParameterDescriptorGroup method verifyNames.
/**
* Ensures that the given name array does not contain duplicate values.
*
* @param properties the properties given to the constructor, or {@code null} if unknown.
*/
private static void verifyNames(final Map<String, ?> properties, final GeneralParameterDescriptor[] parameters) {
for (int i = 0; i < parameters.length; i++) {
final GeneralParameterDescriptor parameter = parameters[i];
ArgumentChecks.ensureNonNullElement("parameters", i, parameter);
final String name = parameter.getName().getCode();
for (int j = 0; j < i; j++) {
if (IdentifiedObjects.isHeuristicMatchForName(parameters[j], name)) {
throw new InvalidParameterNameException(Resources.forProperties(properties).getString(Resources.Keys.DuplicatedParameterName_4, Verifier.getDisplayName(parameters[j]), j, name, i), name);
}
}
}
}
use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.
the class DefaultParameterValueGroup method parameterIfExist.
/**
* Returns the value in this group for the specified name if it exists, or {@code null} if none.
* This method does not create any new {@code ParameterValue} instance.
*
* @see #isKnownImplementation()
*/
@Override
ParameterValue<?> parameterIfExist(final String name) throws ParameterNotFoundException {
// Protect against accidental changes.
final ParameterValueList values = this.values;
/*
* Search for an exact match. By invoking 'descriptor(i)' instead of 'get(i)', we avoid the
* creation of mandatory ParameterValue which was deferred. If we find a matching name, the
* ParameterValue will be lazily created (if not already done) by the call to 'get(i)'.
*/
int index = -1;
int ambiguity = -1;
final int size = values.size();
for (int i = 0; i < size; i++) {
final GeneralParameterDescriptor descriptor = values.descriptor(i);
if (descriptor instanceof ParameterDescriptor<?>) {
if (IdentifiedObjects.isHeuristicMatchForName(descriptor, name)) {
if (index < 0) {
index = i;
} else {
ambiguity = i;
}
}
}
}
if (ambiguity < 0) {
// May lazily create a ParameterValue.
return (index >= 0) ? (ParameterValue<?>) values.get(index) : null;
}
final GeneralParameterDescriptor d1 = values.descriptor(index);
final GeneralParameterDescriptor d2 = values.descriptor(ambiguity);
final String message;
if (d1 == d2) {
message = Errors.format(Errors.Keys.MultiOccurenceValueAtIndices_3, name, index, ambiguity);
} else {
message = Errors.format(Errors.Keys.AmbiguousName_3, IdentifiedObjects.toString(d1.getName()), IdentifiedObjects.toString(d2.getName()), name);
}
throw new ParameterNotFoundException(message, name);
}
use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.
the class DefaultParameterValueGroup method parameter.
/**
* Returns the value in this group for the specified name.
* This method performs the first applicable action in the following choices:
*
* <ul>
* <li>If this group contains a parameter value of the given name, then that parameter is returned.</li>
* <li>Otherwise if a {@linkplain DefaultParameterDescriptorGroup#descriptor(String) descriptor} of the
* given name exists, then a new {@code ParameterValue} instance is
* {@linkplain DefaultParameterDescriptor#createValue() created}, added to this group and returned.</li>
* <li>Otherwise a {@code ParameterNotFoundException} is thrown.</li>
* </ul>
*
* This convenience method provides a way to get and set parameter values by name.
* For example the following idiom fetches a floating point value for the <cite>False easting</cite>
* and <cite>False northing</cite> parameters and set a new value for the <cite>False easting</cite> one:
*
* {@preformat java
* double easting = parameter("False easting" ).doubleValue();
* double northing = parameter("False northing").doubleValue();
* parameter("False easting").setValue(500000.0);
* }
*
* <div class="note"><b>API note:</b> there is no <code>parameter<b><u>s</u></b>(String)</code> method
* returning a list of parameter values because the ISO 19111 standard fixes the {@code ParameterValue}
* {@linkplain DefaultParameterDescriptor#getMaximumOccurs() maximum occurrence} to 1.</div>
*
* <div class="section">Parameters subgroups</div>
* This method does not search recursively in subgroups. This is because more than one subgroup
* may exist for the same {@linkplain ParameterDescriptorGroup descriptor}. The user have to
* {@linkplain #groups(String) query all subgroups} and select explicitly the appropriate one.
*
* @param name the name of the parameter to search for.
* @return the parameter value for the given name.
* @throws ParameterNotFoundException if there is no parameter value for the given name.
*
* @see #getValue(ParameterDescriptor)
*/
@Override
public ParameterValue<?> parameter(final String name) throws ParameterNotFoundException {
ArgumentChecks.ensureNonNull("name", name);
ParameterValue<?> value = parameterIfExist(name);
if (value == null) {
/*
* No existing parameter found. Maybe the parameter is optional and not yet created.
* Get the descriptor of that parameter. If the descriptor is not found, or is not
* a descriptor for a single parameter (not a group), or the parameter is disabled
* (maximum occurrence = 0), behaves as if the parameter was not found.
*/
final GeneralParameterDescriptor descriptor = values.descriptor.descriptor(name);
if (!(descriptor instanceof ParameterDescriptor<?>) || descriptor.getMaximumOccurs() == 0) {
throw new ParameterNotFoundException(Resources.format(Resources.Keys.ParameterNotFound_2, Verifier.getDisplayName(values.descriptor), name), name);
}
/*
* Create the optional parameter and add it to our internal list. Note that this is
* not the only place were a ParameterValue may be created, so do not extract just
* this call to 'createValue()' in a user-overrideable method.
*/
value = ((ParameterDescriptor<?>) descriptor).createValue();
values.addUnchecked(value);
}
return value;
}
use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.
the class SingleOperationMarshallingTest method verifyMethod.
/**
* Verifies the unmarshalled parameter descriptors.
*/
private static void verifyMethod(final OperationMethod method) {
assertIdentifierEquals("name", null, null, null, "Mercator (1SP)", method.getName());
assertEquals("formula", "See EPSG guide.", method.getFormula().getFormula().toString());
assertEquals("sourceDimensions", Integer.valueOf(2), method.getSourceDimensions());
assertEquals("targetDimensions", Integer.valueOf(2), method.getTargetDimensions());
final ParameterDescriptorGroup parameters = method.getParameters();
assertEquals("parameters.name", "Mercator (1SP)", parameters.getName().getCode());
final Iterator<GeneralParameterDescriptor> it = parameters.descriptors().iterator();
CC_OperationParameterGroupTest.verifyMethodParameter(Mercator1SP.LATITUDE_OF_ORIGIN, (ParameterDescriptor<?>) it.next());
CC_OperationParameterGroupTest.verifyMethodParameter(Mercator1SP.LONGITUDE_OF_ORIGIN, (ParameterDescriptor<?>) it.next());
assertFalse("Unexpected parameter.", it.hasNext());
}
use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.
the class CC_OperationParameterGroup method merge.
/**
* 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()]);
}
Aggregations