private static boolean isAssignableIgnoreName()

in endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/DefaultFeatureType.java [704:806]


    private static boolean isAssignableIgnoreName(final AbstractIdentifiedType base, final AbstractIdentifiedType other) {
        if (base != other) {
            /*
             * If the base property is an attribute, then the overriding property shall be either an attribute
             * or a parameterless operation producing an attribute.  The parameterless operation is considered
             * has having a [1…1] multiplicity.
             *
             * Note: other SIS branches use AttributeType and FeatureAssociationRole
             *       instead than DefaultAttributeType and DefaultAssociationRole.
             */
            if (base instanceof DefaultAttributeType<?>) {
                final DefaultAttributeType<?> p0 = (DefaultAttributeType<?>) base;
                final DefaultAttributeType<?> p1;
                if (other instanceof DefaultAttributeType<?>) {
                    p1 = (DefaultAttributeType<?>) other;
                } else if (isParameterlessOperation(other)) {
                    final AbstractIdentifiedType result = ((AbstractOperation) other).getResult();
                    if (result instanceof DefaultAttributeType<?>) {
                        p1 = (DefaultAttributeType<?>) result;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
                final int minOccurs, maxOccurs;
                if (!p0.getValueClass().isAssignableFrom(p1.getValueClass())    ||
                    (minOccurs = p0.getMinimumOccurs()) > p1.getMinimumOccurs() ||
                    (maxOccurs = p0.getMaximumOccurs()) < p1.getMaximumOccurs() ||
                    (p1 != other && (minOccurs > 1 || maxOccurs < 1)))             // [1…1] multiplicity for operations.
                {
                    return false;
                }
            }
            /*
             * Unconditionally test for associations even if we executed the previous block for attributes,
             * because an implementation could implement both AttributeType and AssociationRole interfaces.
             * This is not recommended, but if it happen we want a behavior as consistent as possible.
             */
            if (base instanceof DefaultAssociationRole) {
                final DefaultAssociationRole p0 = (DefaultAssociationRole) base;
                final DefaultAssociationRole p1;
                if (other instanceof DefaultAssociationRole) {
                    p1 = (DefaultAssociationRole) other;
                } else if (isParameterlessOperation(other)) {
                    final AbstractIdentifiedType result = ((AbstractOperation) other).getResult();
                    if (result instanceof DefaultAssociationRole) {
                        p1 = (DefaultAssociationRole) result;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
                final int minOccurs, maxOccurs;
                if ((minOccurs = p0.getMinimumOccurs()) > p1.getMinimumOccurs() ||
                    (maxOccurs = p0.getMaximumOccurs()) < p1.getMaximumOccurs() ||
                    (p1 != other && (minOccurs > 1 || maxOccurs < 1)))             // [1…1] multiplicity for operations.
                {
                    return false;
                }
                final DefaultFeatureType f0 = p0.getValueType();
                final DefaultFeatureType f1 = p1.getValueType();
                if (f0 != f1 && !f0.isAssignableFrom(f1)) {
                    return false;
                }
            }
            /*
             * Operations can be overridden by other operations having the same parameters.
             * In the special case of parameterless operations, can also be overridden by
             * AttributeType or FeatureAssociationRole.
             */
            if (base instanceof AbstractOperation) {
                final AbstractOperation p0 = (AbstractOperation) base;
                final AbstractIdentifiedType r1;
                if (other instanceof AbstractOperation) {
                    final AbstractOperation p1 = (AbstractOperation) other;
                    if (!Objects.equals(p0.getParameters(), p1.getParameters())) {
                        return false;
                    }
                    r1 = p1.getResult();
                } else if (isParameterlessOperation(base)) {
                    r1 = other;
                } else {
                    return false;
                }
                final AbstractIdentifiedType r0 = p0.getResult();
                if (r0 != r1) {
                    if (r0 instanceof DefaultFeatureType) {
                        if (!(r1 instanceof DefaultFeatureType) || !((FeatureType) r0).isAssignableFrom((DefaultFeatureType) r1)) {
                            return false;
                        }
                    } else if (r0 != null) {
                        if (r1 == null || !isAssignableIgnoreName(r0, r1)) {
                            return false;
                        }
                    }
                    // No need for explicit AttributeType or Operation checks because they are PropertyType.
                }
            }
        }
        return true;
    }