Search in sources :

Example 11 with GeneralParameterDescriptor

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);
            }
        }
    }
}
Also used : GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) InvalidParameterNameException(org.opengis.parameter.InvalidParameterNameException)

Example 12 with GeneralParameterDescriptor

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);
}
Also used : GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterDescriptor(org.opengis.parameter.ParameterDescriptor) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException)

Example 13 with GeneralParameterDescriptor

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;
}
Also used : GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException)

Example 14 with GeneralParameterDescriptor

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());
}
Also used : ParameterDescriptorGroup(org.opengis.parameter.ParameterDescriptorGroup) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor)

Example 15 with GeneralParameterDescriptor

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()]);
}
Also used : GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterDescriptor(org.opengis.parameter.ParameterDescriptor) DefaultParameterDescriptorGroup(org.apache.sis.parameter.DefaultParameterDescriptorGroup) ParameterDescriptorGroup(org.opengis.parameter.ParameterDescriptorGroup) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) CorruptedObjectException(org.apache.sis.util.CorruptedObjectException) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

GeneralParameterDescriptor (org.opengis.parameter.GeneralParameterDescriptor)30 ParameterDescriptorGroup (org.opengis.parameter.ParameterDescriptorGroup)12 Test (org.junit.Test)10 DefaultParameterDescriptorGroup (org.apache.sis.parameter.DefaultParameterDescriptorGroup)8 DependsOnMethod (org.apache.sis.test.DependsOnMethod)8 ParameterNotFoundException (org.opengis.parameter.ParameterNotFoundException)6 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)6 HashMap (java.util.HashMap)5 Identifier (org.opengis.metadata.Identifier)5 GeneralParameterValue (org.opengis.parameter.GeneralParameterValue)5 ParameterDescriptor (org.opengis.parameter.ParameterDescriptor)4 IdentityHashMap (java.util.IdentityHashMap)3 OperationMethod (org.opengis.referencing.operation.OperationMethod)3 ArrayList (java.util.ArrayList)2 DefaultParameterValueGroup (org.apache.sis.parameter.DefaultParameterValueGroup)2 CorruptedObjectException (org.apache.sis.util.CorruptedObjectException)2 InvalidParameterNameException (org.opengis.parameter.InvalidParameterNameException)2 ParameterValue (org.opengis.parameter.ParameterValue)2 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1