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);
}
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));
}
}
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;
}
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));
}
}
}
}
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;
}
Aggregations