package geniusweb.issuevalue; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; /** * Contains a (possibly partial) bid. Basically a map. immutable, thread safe. */ @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) public class Bid { // not immutable and explicit HashMap for better serializability, must be // kept immutable. private final HashMap issuevalues; /** * * @param issuevalues a map of issue, Value pairs. The String is the issue * name. */ @JsonCreator public Bid(@JsonProperty("issuevalues") Map issuevalues) { if (issuevalues == null) { throw new NullPointerException("issuevalues=null"); } for (String issue : issuevalues.keySet()) { if (issuevalues.get(issue) == null) { throw new IllegalArgumentException( "value of issue " + issue + " can not be null"); } } this.issuevalues = new HashMap(issuevalues); } /** * Makes partial bid with just 1 issue and value. * * @param issue the issue name * @param value the {@link Value} */ public Bid(String issue, Value value) { if (issue == null || value == null) { throw new NullPointerException("issue and value must be not =null"); } issuevalues = new HashMap<>(); issuevalues.put(issue, value); } /** * @param issue name of the issue * @return the value for the given issue, or null if there is no value for * the given issue. */ public Value getValue(String issue) { return issuevalues.get(issue); } /** * @param issue name of the issue * @return true iff the bid contains a value for the given issue. */ public boolean containsIssue(String issue) { return issuevalues.containsKey(issue); } public Set getIssues() { return Collections.unmodifiableSet(issuevalues.keySet()); } /** * Merges this partial bid with another partial bid. * * @param otherbid another partial bid. * @return a bid with the combined values of both partial bids. * @throws IllegalArgumentException if issues overlap. */ public Bid merge(Bid otherbid) { Set ourissues = new HashSet<>(issuevalues.keySet()); ourissues.retainAll(otherbid.getIssues()); if (!ourissues.isEmpty()) { throw new IllegalArgumentException( "Otherbid contains issues that are already set:" + ourissues); } HashMap newvalues = new HashMap<>(issuevalues); newvalues.putAll(otherbid.issuevalues); return new Bid(newvalues); } /** * * @return (unmodifyable) map with all issues and values in the bid. */ public Map getIssueValues() { return Collections.unmodifiableMap(issuevalues); } @Override public String toString() { return "Bid" + issuevalues; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((issuevalues == null) ? 0 : issuevalues.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Bid other = (Bid) obj; if (issuevalues == null) { if (other.issuevalues != null) return false; } else if (!issuevalues.equals(other.issuevalues)) return false; return true; } }