/** * Copyright (C) 2013-2014 Olaf Lessenich * Copyright (C) 2014-2015 University of Passau, Germany * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA * * Contributors: * Olaf Lessenich <lessenic@fim.uni-passau.de> * Georg Seibt <seibt@fim.uni-passau.de> */ package de.fosd.jdime.matcher.cost_model; import java.util.Objects; import de.fosd.jdime.artifact.Artifact; /** * A pair of matching artifacts. This class is used instead of <code>Matching</code> because the * <code>CostModelMatcher</code> needs different semantics than the <code>Matching</code> provides. One difference is * that either one of the artifacts being matched may be <code>null</code> representing the no-match node. * This class also contains fields to store the exact and bounded costs for this matching. * * @param <T> * the type of the artifacts */ final class CMMatching<T extends Artifact<T>> { final T m; final T n; private float exactCost; private Bounds costBounds; /** * Constructs a new <code>CMMatching</code> between <code>m</code> and <code>n</code>. * * @param m * the left artifact * @param n * the right artifact */ CMMatching(T m, T n) { this.m = m; this.n = n; } /** * Returns whether this <code>CMMatching</code> represents a no-match. * * @return true iff one of the artifacts being matched is <code>null</code> */ public boolean isNoMatch() { return m == null || n == null; } /** * Returns whether one of the artifacts being matched is <code>t</code>. * * @param t * the artifact to test * @return true iff <code>m</code> or <code>n</code> is <code>t</code> */ public boolean contains(T t) { return m == t || n == t; } /** * If this <code>CMMatching</code> contains <code>t</code>, this method returns the artifact <code>t</code> is being * matched with. * * @param t * the <code>Artifact</code> to return the matching partner for * @return the <code>Artifact</code> <code>t</code> is being matched with * @throws IllegalArgumentException * if this <code>CMMatching</code> does not contain <code>t</code> */ public T other(T t) { if (m == t) { return n; } else if (n == t) { return m; } else { throw new IllegalArgumentException(t + " is not part of " + this); } } /** * Returns the exact cost of this matching. * * @return the exact cost */ public float getExactCost() { return exactCost; } /** * Sets the exact cost of this matching. * * @param exactCost * the new exact cost */ public void setExactCost(float exactCost) { this.exactCost = exactCost; } /** * Returns the bounded cost for this matching. * * @return the bounded cost */ public Bounds getCostBounds() { return costBounds; } /** * Sets the bounded cost for this matching. * * @param lower * the new lower bound * @param upper * the new upper bound */ public void setBounds(float lower, float upper) { if (costBounds == null) { setCostBounds(new Bounds(lower, upper)); } else { costBounds.setLower(lower); costBounds.setUpper(upper); } } /** * Sets the bounded cost for this matching * * @param costBounds * the new bounded costs */ public void setCostBounds(Bounds costBounds) { this.costBounds = costBounds; } @Override public String toString() { return String.format("{%s, %s, %f, %s}", m, n, exactCost, costBounds); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } CMMatching<?> that = (CMMatching<?>) o; return Objects.equals(m, that.m) && Objects.equals(n, that.n); } @Override public int hashCode() { return Objects.hash(m, n); } }