package geniusweb.protocol.session.mopac.phase; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import geniusweb.actions.Action; import geniusweb.actions.EndNegotiation; import geniusweb.actions.PartyId; import geniusweb.actions.Votes; import geniusweb.inform.Agreements; import geniusweb.inform.Inform; import geniusweb.inform.OptIn; import geniusweb.protocol.ProtocolException; import geniusweb.protocol.session.mopac.PartyStates; import geniusweb.voting.CollectedVotes; import geniusweb.voting.VotingEvaluator; public class OptInPhase extends DefaultPhase { /** * The votes received in the {@link VotingPhase} */ private final List votes; @JsonCreator protected OptInPhase(@JsonProperty("votes") List votes, @JsonProperty("partyStates") PartyStates partyStates, @JsonProperty("deadline") Long deadline, @JsonProperty("evaluator") VotingEvaluator evaluator) { super(partyStates, deadline, evaluator); this.votes = votes; if (votes == null) throw new IllegalArgumentException("votes must be not null"); } @Override public Inform getInform() { return new OptIn(votes); } @Override public Phase with(PartyId actor, Action action, long now) { try { checkAction(actor, action, now); if (action instanceof Votes) checkExtends((Votes) action); return new OptInPhase(votes, partyStates.with(action), deadline, evaluator); } catch (ProtocolException e) { return this.with(e); } } /** * Check that this action extends previous action. * * @param newvotes new {@link Votes} just received * @throws ProtocolException if this action does not correctly extend * previous vote. */ private void checkExtends(Votes newvotes) throws ProtocolException { PartyId actor = newvotes.getActor(); // this actor is active so he must have voted in previous round. Votes prevVotes = votes.stream().filter(v -> v.getActor().equals(actor)) .findFirst().get(); if (!(newvotes.isExtending(prevVotes))) throw new ProtocolException("New votes " + newvotes + " does not extend previous vote " + prevVotes, actor); } @Override public OptInPhase with(ProtocolException e) { return new OptInPhase(votes, partyStates.with(e), deadline, evaluator); } @Override public OptInPhase finish() { PartyStates states = partyStates.finish(); Map votesmap = states.getActions(Votes.class).stream() .collect(Collectors.toMap(votes -> votes.getActor(), v -> v)); CollectedVotes allvotes = new CollectedVotes(votesmap, states.getPowers()); Agreements newAgree = evaluator.create(allvotes).getAgreements(); if (!newAgree.getMap().isEmpty()) { System.out.println("detected new agreements"); } PartyStates finalStates = states.with(newAgree); return new OptInPhase(votes, finalStates, deadline, evaluator); } @Override public OfferPhase checkedNext(long newdeadline) { return new OfferPhase(partyStates.flush(), newdeadline, evaluator); } @Override public List> getAllowedActions() { return Arrays.asList(Votes.class, EndNegotiation.class); } public List getVotes() { return Collections.unmodifiableList(votes); } }