001package de.monochromata.anaphors.ast.reference.strategy.feature; 002 003import de.monochromata.anaphors.ast.feature.FeatureContainer; 004import de.monochromata.anaphors.ast.reference.Referent; 005import de.monochromata.anaphors.ast.reference.strategy.AbstractReferentializationStrategy; 006import de.monochromata.anaphors.ast.reference.strategy.concept.ConceptReferentializationStrategy; 007import de.monochromata.anaphors.ast.spi.AnaphorsSpi; 008 009/** 010 * Referentialization based on feature recurrence (i.e. matching referents whose 011 * type is equal to a suffix of the simple name that acts as definite expression 012 * and that declare a feature in the constructor invocation that recurs in the 013 * non-empty prefix to the suffix of the simple name). 014 * 015 * <p> 016 * Note 017 * </p> 018 * 019 * TODO: Ensure non-empty prefix to the type name in the simple name 020 * 021 * TODO: Make sure all features from the simple name are found in the referent 022 * 023 * TODO: Collect features not only from the constructor, but also from other 024 * downstream accesses 025 * 026 * TODO: Implement matching of multiple features and flexible length of type 027 * names ... 028 * 029 * @param <N> The node type in the AST 030 * @param <E> The expression type 031 * @param <CI> The class instance creation expression node type 032 * @param <B> The binding type 033 * @param <TB> The type binding type 034 * @param <S> The scope type (optional) 035 * @param <I> The type used to represent identifiers 036 * @param <QI> The type used to represent qualified identifiers 037 * @param <EV> The type of the event contained in the condition that is 038 * evaluated to check when the perspectivations shall be applied. 039 * @param <PP> The type used for positions that carry perspectivations 040 */ 041public class FeatureRecurrence<N, E, CI extends N, B, TB extends B, S, I, QI, EV, PP> 042 extends AbstractReferentializationStrategy<N, E, TB, S, I, QI, EV, PP> 043 implements FeatureReferentializationStrategy<E, TB, S, I, QI> { 044 045 public static final String Rf_KIND_PREFIX = "Rf"; 046 private final ConceptReferentializationStrategy<E, TB, S, I, QI> delegate; 047 048 /** 049 * Used in contract testing. 050 */ 051 @SuppressWarnings("unused") 052 protected FeatureRecurrence() { 053 delegate = null; 054 } 055 056 public FeatureRecurrence(final ConceptReferentializationStrategy<E, TB, S, I, QI> delegate, 057 final AnaphorsSpi<N, E, TB, S, I, QI, EV, PP> anaphorsSpi) { 058 super(anaphorsSpi); 059 this.delegate = delegate; 060 } 061 062 @Override 063 public boolean canReferTo(final I idFromDefiniteExpression, final Referent<TB, S, I, QI> potentialReferent, 064 final S scope) { 065 final FeatureContainer<QI> featuresInIdentifier = delegate 066 .getFeaturesRemainingInIdentifierIfItCanReferUsingConceptualType(idFromDefiniteExpression, 067 potentialReferent, scope); 068 return featuresInIdentifier != null && potentialReferent.containsFeaturesOf(featuresInIdentifier); 069 } 070 071 @Override 072 public ConceptReferentializationStrategy<E, TB, S, I, QI> getDelegate() { 073 return delegate; 074 } 075 076 @Override 077 public String getKind() { 078 return Rf_KIND_PREFIX + delegate.getKind(); 079 } 080 081 @Override 082 public int hashCode() { 083 final int prime = 31; 084 int result = super.hashCode(); 085 result = prime * result + ((delegate == null) ? 0 : delegate.hashCode()); 086 return result; 087 } 088 089 @Override 090 public boolean equals(final Object obj) { 091 if (this == obj) { 092 return true; 093 } 094 if (!super.equals(obj)) { 095 return false; 096 } 097 if (getClass() != obj.getClass()) { 098 return false; 099 } 100 final FeatureRecurrence other = (FeatureRecurrence) obj; 101 if (delegate == null) { 102 if (other.delegate != null) { 103 return false; 104 } 105 } else if (!delegate.equals(other.delegate)) { 106 return false; 107 } 108 return true; 109 } 110 111}