001package de.monochromata.anaphors.ast;
002
003import de.monochromata.anaphors.ast.reference.Referent;
004import de.monochromata.anaphors.ast.reference.strategy.ReferentializationStrategy;
005import de.monochromata.anaphors.ast.relatedexp.RelatedExpression;
006import de.monochromata.anaphors.ast.strategy.AnaphorResolutionStrategy;
007
008/**
009 * An default implementation of the {@link AnaphorPart} interface.
010 *
011 * @param <N>  The node type in the AST
012 * @param <E>  The expression type
013 * @param <T>  The type type
014 * @param <B>  The binding type
015 * @param <TB> The type binding type
016 * @param <S>  The scope type (optional)
017 * @param <I>  The type used to represent identifiers
018 * @param <QI> The type used to represent qualified identifiers
019 * @param <R>  The sub-type of related expression to use
020 * @param <A>  The sub-type of AST-based anaphora to use
021 */
022public class DefaultAnaphorPart<N, E, T, B, VB extends 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>>
023        implements AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> {
024
025    private final String anaphor;
026    private final E anaphorExpression;
027    private final Referent<TB, S, I, QI> referent;
028    private final AnaphorResolutionStrategy<N, E, T, B, TB, S, I, QI, R, A> anaphorResolutionStrategy;
029    private final ReferentializationStrategy<E, TB, S, I, QI> referentializationStrategy;
030    private final B binding;
031
032    /**
033     * Used in contract testing.
034     */
035    @SuppressWarnings("unused")
036    protected DefaultAnaphorPart() {
037        this(null, null, null, null, null, null);
038    }
039
040    public DefaultAnaphorPart(final String anaphor, final E anaphorExpression, final Referent<TB, S, I, QI> referent,
041            final AnaphorResolutionStrategy<N, E, T, B, TB, S, I, QI, R, A> anaphorResolutionStrategy,
042            final ReferentializationStrategy<E, TB, S, I, QI> referentializationStrategy, final B binding) {
043        this.anaphor = anaphor;
044        this.anaphorExpression = anaphorExpression;
045        this.referent = referent;
046        this.anaphorResolutionStrategy = anaphorResolutionStrategy;
047        this.referentializationStrategy = referentializationStrategy;
048        this.binding = binding;
049    }
050
051    @Override
052    public String getAnaphor() {
053        return anaphor;
054    }
055
056    @Override
057    public E getAnaphorExpression() {
058        return this.anaphorExpression;
059    }
060
061    @Override
062    public Referent<TB, S, I, QI> getReferent() {
063        return this.referent;
064    }
065
066    @Override
067    public AnaphorResolutionStrategy<N, E, T, B, TB, S, I, QI, R, A> getAnaphorResolutionStrategy() {
068        return this.anaphorResolutionStrategy;
069    }
070
071    @Override
072    public ReferentializationStrategy<E, TB, S, I, QI> getReferentializationStrategy() {
073        return this.referentializationStrategy;
074    }
075
076    @Override
077    public B getBinding() {
078        return this.binding;
079    }
080
081    @Override
082    public TB resolveType(final S scope) {
083        return this.referent.resolveType(scope);
084    }
085
086    @Override
087    public int hashCode() {
088        final int prime = 31;
089        int result = 1;
090        result = prime * result + ((anaphor == null) ? 0 : anaphor.hashCode());
091        result = prime * result + ((anaphorExpression == null) ? 0 : anaphorExpression.hashCode());
092        result = prime * result + ((anaphorResolutionStrategy == null) ? 0 : anaphorResolutionStrategy.hashCode());
093        result = prime * result + ((binding == null) ? 0 : binding.hashCode());
094        result = prime * result + ((referent == null) ? 0 : referent.hashCode());
095        result = prime * result + ((referentializationStrategy == null) ? 0 : referentializationStrategy.hashCode());
096        return result;
097    }
098
099    @Override
100    public boolean equals(final Object obj) {
101        if (this == obj) {
102            return true;
103        }
104        if (obj == null) {
105            return false;
106        }
107        if (getClass() != obj.getClass()) {
108            return false;
109        }
110        final DefaultAnaphorPart other = (DefaultAnaphorPart) obj;
111        if (anaphor == null) {
112            if (other.anaphor != null) {
113                return false;
114            }
115        } else if (!anaphor.equals(other.anaphor)) {
116            return false;
117        }
118        if (anaphorExpression == null) {
119            if (other.anaphorExpression != null) {
120                return false;
121            }
122        } else if (!anaphorExpression.equals(other.anaphorExpression)) {
123            return false;
124        }
125        if (anaphorResolutionStrategy == null) {
126            if (other.anaphorResolutionStrategy != null) {
127                return false;
128            }
129        } else if (!anaphorResolutionStrategy.equals(other.anaphorResolutionStrategy)) {
130            return false;
131        }
132        if (binding == null) {
133            if (other.binding != null) {
134                return false;
135            }
136        } else if (!binding.equals(other.binding)) {
137            return false;
138        }
139        if (referent == null) {
140            if (other.referent != null) {
141                return false;
142            }
143        } else if (!referent.equals(other.referent)) {
144            return false;
145        }
146        if (referentializationStrategy == null) {
147            if (other.referentializationStrategy != null) {
148                return false;
149            }
150        } else if (!referentializationStrategy.equals(other.referentializationStrategy)) {
151            return false;
152        }
153        return true;
154    }
155
156    @Override
157    public String toString() {
158        // The binding is not output because it can be quite long.
159        return "DefaultAnaphorPart [anaphor=" + anaphor + ", anaphorExpression=" + anaphorExpression + ", referent="
160                + referent + ", anaphorResolutionStrategy=" + anaphorResolutionStrategy
161                + ", referentializationStrategy=" + referentializationStrategy + "]";
162    }
163
164}