001package de.monochromata.anaphors.ast; 002 003import static java.util.Optional.empty; 004 005import java.util.Optional; 006import java.util.function.Supplier; 007 008import de.monochromata.anaphors.ast.relatedexp.RelatedExpression; 009 010/** 011 * A default implementation of an indirect anaphora relation. 012 * 013 * @param <N> The node type in the AST 014 * @param <E> The expression type 015 * @param <T> The type type 016 * @param <B> The binding type 017 * @param <TB> The type binding type 018 * @param <S> The scope type (optional) 019 * @param <I> The type used to represent identifiers 020 * @param <QI> The type used to represent qualified identifiers 021 * @param <R> The sub-type of related expression to use 022 * @param <A> The sub-type of AST-based anaphora to use 023 */ 024public class DefaultIndirectAnaphora<N, E, T, B, TB extends B, S, I, QI, R extends RelatedExpression<N, T, B, TB, S, QI, R>, A extends ASTBasedAnaphora<N, E, T, B, TB, S, I, QI, R, A>> 025 extends AbstractASTBasedAnaphora<N, E, T, B, TB, S, I, QI, R, A> 026 implements IndirectAnaphora<N, E, T, B, TB, S, I, QI, R, A> { 027 028 private final String underspecifiedRelation; 029 private final Optional<Supplier<String>> customReferenceDescriptionSupplier; 030 031 /** 032 * Used in contract testing. 033 */ 034 @SuppressWarnings("unused") 035 protected DefaultIndirectAnaphora() { 036 underspecifiedRelation = null; 037 customReferenceDescriptionSupplier = null; 038 } 039 040 public DefaultIndirectAnaphora(final RelatedExpressionPart<N, E, T, B, TB, S, I, QI, R> relatedExpressionPart, 041 final AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> anaphorPart, final String underspecifiedRelation, 042 final boolean isUnderspecified) { 043 this(relatedExpressionPart, anaphorPart, underspecifiedRelation, empty(), isUnderspecified); 044 } 045 046 public DefaultIndirectAnaphora(final RelatedExpressionPart<N, E, T, B, TB, S, I, QI, R> relatedExpressionPart, 047 final AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> anaphorPart, final String underspecifiedRelation, 048 final Supplier<String> customReferenceDescriptionSupplier, final boolean isUnderspecified) { 049 this(relatedExpressionPart, anaphorPart, underspecifiedRelation, 050 Optional.of(customReferenceDescriptionSupplier), isUnderspecified); 051 } 052 053 protected DefaultIndirectAnaphora(final RelatedExpressionPart<N, E, T, B, TB, S, I, QI, R> relatedExpressionPart, 054 final AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> anaphorPart, final String underspecifiedRelation, 055 final Optional<Supplier<String>> customReferenceDescriptionSupplier, final boolean isUnderspecified) { 056 super(relatedExpressionPart, anaphorPart, isUnderspecified); 057 this.underspecifiedRelation = underspecifiedRelation; 058 this.customReferenceDescriptionSupplier = customReferenceDescriptionSupplier; 059 } 060 061 /* 062 * (non-Javadoc) 063 * 064 * @see de.monochromata.anaphors.IndirectAnaphora#getUnderspecifiedRelation() 065 */ 066 @Override 067 public String getUnderspecifiedRelation() { 068 return underspecifiedRelation; 069 } 070 071 @Override 072 public String getReferenceDescription() { 073 return customReferenceDescriptionSupplier.map(Supplier::get).orElseGet(this::getDefaultReferenceDescription); 074 } 075 076 protected String getDefaultReferenceDescription() { 077 return getReferent().getDescription() + " of " + getRelatedExpression().getRelatedExpression() + " at " 078 + getRelatedExpression().getLine() + ":" + getRelatedExpression().getColumn() + " (" + getKind() + ")"; 079 } 080 081 @Override 082 public int hashCode() { 083 final int prime = 31; 084 int result = super.hashCode(); 085 result = prime * result + ((underspecifiedRelation == null) ? 0 : underspecifiedRelation.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 DefaultIndirectAnaphora other = (DefaultIndirectAnaphora) obj; 101 if (underspecifiedRelation == null) { 102 if (other.underspecifiedRelation != null) { 103 return false; 104 } 105 } else if (!underspecifiedRelation.equals(other.underspecifiedRelation)) { 106 return false; 107 } 108 return true; 109 } 110 111 @Override 112 public String toString() { 113 return getKind() + " [getUnderspecifiedRelation()=" + underspecifiedRelation + ", getRelatedExpression()=" 114 + getRelatedExpression() + ", getAnaphor()=" + getAnaphor() + ", getAnaphorExpression()=" 115 + getAnaphorExpression() + ", getReferent()=" + getReferent() + ", getRelatedExpressionStrategy()=" 116 + getRelatedExpressionStrategy() + ", getAnaphorResolutionStrategy()=" + getAnaphorResolutionStrategy() 117 + ", getReferentializationStrategy()=" + getReferentializationStrategy() + ", getBinding()=" 118 + getBinding() + ", isUnderspecified()=" + isUnderspecified() + ", isExplicated()=" + isExplicated() 119 + "]"; 120 } 121 122}