Search in sources :

Example 36 with GenericName

use of org.opengis.util.GenericName in project sis by apache.

the class AbstractFeature method propertyNotFound.

/**
 * Returns the exception message for a property not found. The message will differ depending
 * on whether the property is not found because ambiguous or because it does not exist.
 *
 * @param  feature   the name of the feature where a property where searched ({@link String} or {@link GenericName}).
 * @param  property  the name of the property which has not been found.
 */
static String propertyNotFound(final FeatureType type, final Object feature, final String property) {
    GenericName ambiguous = null;
    for (final AbstractIdentifiedType p : type.getProperties(true)) {
        final GenericName next = p.getName();
        GenericName name = next;
        do {
            if (property.equalsIgnoreCase(name.toString())) {
                if (ambiguous == null) {
                    ambiguous = next;
                } else {
                    return Errors.format(Errors.Keys.AmbiguousName_3, ambiguous, next, property);
                }
            }
        } while (name instanceof ScopedName && (name = ((ScopedName) name).tail()) != null);
    }
    return Resources.format(Resources.Keys.PropertyNotFound_2, feature, property);
}
Also used : GenericName(org.opengis.util.GenericName) ScopedName(org.opengis.util.ScopedName)

Example 37 with GenericName

use of org.opengis.util.GenericName in project sis by apache.

the class CharacteristicMap method verifyAttributeType.

/**
 * Ensures that the given attribute type is the instance that we expect at the given index.
 * If the given instance is not the expected one, then an {@link IllegalArgumentException}
 * will be thrown with an error message formatted using the name of expected and given types.
 *
 * @param  index  index of the expected attribute type.
 * @param  type   the actual attribute type.
 */
final void verifyAttributeType(final int index, final DefaultAttributeType<?> type) {
    final DefaultAttributeType<?> expected = types.characterizedBy[index];
    if (!expected.equals(type)) {
        final GenericName en = expected.getName();
        final GenericName an = type.getName();
        throw new IllegalArgumentException(String.valueOf(en).equals(String.valueOf(an)) ? Resources.format(Resources.Keys.MismatchedPropertyType_1, en) : Resources.format(Resources.Keys.CanNotSetCharacteristics_2, en.push(source.getName()), an));
    }
}
Also used : GenericName(org.opengis.util.GenericName)

Example 38 with GenericName

use of org.opengis.util.GenericName in project sis by apache.

the class DefaultAssociationRole method resolve.

/**
 * If the associated feature type is a placeholder for a {@code FeatureType} to be defined later,
 * replaces the placeholder by the actual instance if available. Otherwise do nothing.
 *
 * This method is needed only in case of cyclic graph, e.g. feature <var>A</var> has an association
 * to feature <var>B</var> which has an association back to <var>A</var>. It may also be <var>A</var>
 * having an association to itself, <i>etc.</i>
 *
 * @param  creating    the feature type in process of being constructed.
 * @param  properties  {@code creating.getProperties(false)} given as a direct reference to the internal field,
 *         without invoking {@code getProperties(…)}. We do that because {@code resolve(…)} is invoked while the
 *         given {@code DefaultFeatureType} is under creation. Since {@code getProperties(…)} can be overridden,
 *         invoking that method on {@code creating} may cause a failure with user code.
 * @return {@code true} if this association references a resolved feature type after this method call.
 */
final boolean resolve(final DefaultFeatureType creating, final Collection<AbstractIdentifiedType> properties) {
    final FeatureType type = valueType;
    if (type instanceof NamedFeatureType) {
        FeatureType resolved = ((NamedFeatureType) type).resolved;
        if (resolved == null) {
            final GenericName name = type.getName();
            if (name.equals(creating.getName())) {
                // This is the most common case.
                resolved = creating;
            } else {
                /*
                     * The feature that we need to resolve is not the one we just created. Maybe we can find
                     * this desired feature in an association of the 'creating' feature, instead than beeing
                     * the 'creating' feature itself. This is a little bit unusual, but not illegal.
                     */
                final List<DefaultFeatureType> deferred = new ArrayList<>();
                resolved = search(creating, properties, name, deferred);
                if (resolved == null) {
                    /*
                         * Did not found the desired FeatureType in the 'creating' instance.
                         * Try harder, by searching recursively in associations of associations.
                         */
                    if (deferred.isEmpty() || (resolved = deepSearch(deferred, name)) == null) {
                        return false;
                    }
                }
            }
            ((NamedFeatureType) type).resolved = resolved;
        }
        valueType = resolved;
    }
    return true;
}
Also used : GenericName(org.opengis.util.GenericName) ArrayList(java.util.ArrayList)

Example 39 with GenericName

use of org.opengis.util.GenericName in project sis by apache.

the class DefaultFeatureType method scanPropertiesFrom.

/**
 * Fills the {@link #byName} map using the non-transient information in the given {@code source}.
 * This method invokes itself recursively in order to use the information provided in super-types.
 * This method also performs an opportunist verification of argument validity.
 *
 * <p>{@code this} shall be the instance in process of being created, not any other instance
 * (i.e. recursive method invocations are performed on the same {@code this} instance).</p>
 *
 * <p>This method requires that the caller gives {@code source.getProperties(false)} himself for two reasons:</p>
 * <ul>
 *   <li>Avoid a call to the user-overrideable {@link #getProperties(boolean)} method
 *       while this {@code DefaultFeatureType} instance is still under constructor.</li>
 *   <li>Allow the {@code DefaultFeatureType(Map, boolean, FeatureType[], PropertyType[])} constructor
 *       to pass a temporary modifiable list that allow element removal.</li>
 * </ul>
 *
 * @param  source            the feature from which to get properties.
 * @param  sourceProperties  {@code source.getProperties(false)} (see above method javadoc).
 * @throws IllegalArgumentException if two properties have the same name.
 */
private void scanPropertiesFrom(final DefaultFeatureType source, final Collection<? extends AbstractIdentifiedType> sourceProperties) {
    for (final DefaultFeatureType parent : source.getSuperTypes()) {
        if (assignableTo.add(parent.getName())) {
            scanPropertiesFrom(parent, parent.getProperties(false));
        }
    }
    int index = -1;
    final Iterator<? extends AbstractIdentifiedType> it = sourceProperties.iterator();
    while (it.hasNext()) {
        final AbstractIdentifiedType property = it.next();
        final String name = toString(property.getName(), source, "properties", ++index);
        final AbstractIdentifiedType previous = byName.put(name, property);
        if (previous != null) {
            if (previous.equals(property)) {
                // Keep the instance declared in super-type.
                byName.put(name, previous);
                if (source == this) {
                    // Remove duplicated values in instance under construction.
                    it.remove();
                }
            } else if (!isAssignableIgnoreName(previous, property)) {
                final GenericName owner = ownerOf(this, sourceProperties, previous);
                throw new IllegalArgumentException(Resources.format(Resources.Keys.PropertyAlreadyExists_2, (owner != null) ? owner : "?", name));
            }
        }
    }
}
Also used : GenericName(org.opengis.util.GenericName) InternationalString(org.opengis.util.InternationalString)

Example 40 with GenericName

use of org.opengis.util.GenericName in project sis by apache.

the class NameToIdentifier method isHeuristicMatchForName.

/**
 * Returns {@code true} if the given {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName()
 * primary name} or one of the given aliases matches the given name. The comparison ignores case, some Latin
 * diacritical signs and any characters that are not letters or digits.
 *
 * @param  name        the name of the {@code IdentifiedObject} to check.
 * @param  aliases     the list of aliases in the {@code IdentifiedObject} (may be {@code null}).
 *                     This method will never modify that list, so the given list can be a direct
 *                     reference to an internal list.
 * @param  toSearch    the name for which to check for equality.
 * @param  simplifier  a function for simplifying the names before comparison.
 * @return {@code true} if the primary name or at least one alias matches the given {@code name}.
 */
public static boolean isHeuristicMatchForName(final Identifier name, final Collection<GenericName> aliases, CharSequence toSearch, final Simplifier simplifier) {
    if (toSearch != null) {
        CharSequence code = (name != null) ? name.getCode() : null;
        if (toSearch.equals(code)) {
            // Optimization for a common case.
            return true;
        }
        toSearch = simplifier.apply(toSearch);
        code = simplifier.apply(code);
        if (CharSequences.equalsFiltered(toSearch, code, LETTERS_AND_DIGITS, true)) {
            return true;
        }
        if (aliases != null) {
            for (final GenericName alias : aliases) {
                if (alias != null) {
                    // Paranoiac check.
                    final CharSequence tip = simplifier.apply(alias.tip().toString());
                    if (CharSequences.equalsFiltered(toSearch, tip, LETTERS_AND_DIGITS, true)) {
                        return true;
                    }
                /*
                         * Note: a previous version compared also the scoped names. We removed that part,
                         * because experience has shown that this method is used only for the "code" part
                         * of an object name. If we really want to compare scoped name, it would probably
                         * be better to take a GenericName argument instead than String.
                         */
                }
            }
        }
    }
    return false;
}
Also used : GenericName(org.opengis.util.GenericName)

Aggregations

GenericName (org.opengis.util.GenericName)46 Test (org.junit.Test)11 ReferenceIdentifier (org.opengis.referencing.ReferenceIdentifier)9 InternationalString (org.opengis.util.InternationalString)9 ArrayList (java.util.ArrayList)5 IdentifiedObject (org.opengis.referencing.IdentifiedObject)5 NameFactory (org.opengis.util.NameFactory)5 Identifier (org.opengis.metadata.Identifier)4 ScopedName (org.opengis.util.ScopedName)4 HashMap (java.util.HashMap)3 DependsOnMethod (org.apache.sis.test.DependsOnMethod)3 IOException (java.io.IOException)2 UncheckedIOException (java.io.UncheckedIOException)2 Collection (java.util.Collection)2 IdentityHashMap (java.util.IdentityHashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 AbstractIdentifiedType (org.apache.sis.feature.AbstractIdentifiedType)2 NameToIdentifier (org.apache.sis.internal.metadata.NameToIdentifier)2 TableAppender (org.apache.sis.io.TableAppender)2