package geniusweb.protocol.session.learn; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import geniusweb.actions.Action; import geniusweb.actions.LearningDone; import geniusweb.actions.PartyId; import geniusweb.inform.Agreements; import geniusweb.progress.Progress; import geniusweb.protocol.ProtocolException; import geniusweb.protocol.session.DefaultSessionState; import geniusweb.protocol.session.SessionResult; import geniusweb.references.PartyWithProfile; /** * Stores the state for Learn protocol. Immutable. */ public class LearnState extends DefaultSessionState { /** * * @param actions the actions done by the parties * @param conns the existing party connections. we assume ownership * of this so it should not be modified although * connections may of course break. If null, default * empty list is used. Can be less than 2 parties in * the first phases of the setup. * @param progress the {@link Progress} line. can be null * @param settings the {@link LearnSettings} * @param partyprofiles map with the {@link PartyWithProfile} for connected * parties. null is equivalent to an empty map. * @param e the {@link ProtocolException}, or null if none * occurred. */ public LearnState(List actions, List conns, Progress progress, LearnSettings settings, Map partyprofiles, ProtocolException e) { super(actions, conns, progress, settings, partyprofiles, e); } /** * Creates the initial state from the given settings and progress=null * * @param settings the {@link LearnSettings} */ public LearnState(LearnSettings settings) { this(Collections.emptyList(), Collections.emptyList(), null, settings, null, null); } @Override public LearnState with(List actions, List conns, Progress progr, LearnSettings settings, Map partyprofiles, ProtocolException e) { return new LearnState(actions, conns, progr, settings, partyprofiles, e); } @Override public Agreements getAgreements() { return new Agreements(); } @Override public List getResults() { return Arrays.asList(new SessionResult(getPartyProfiles(), getAgreements(), Collections.emptyMap(), null)); } @Override public boolean isFinal(long currentTimeMs) { Set done = getDoneLearning(); // if done is empty we're probably still starting up. return super.isFinal(currentTimeMs) || (!done.isEmpty() && done.containsAll(getConnections())); } /** * * @param e the error that occured * @return a new state with the error set. */ @Override public LearnState with(ProtocolException e) { return new LearnState(getActions(), getConnections(), getProgress(), getSettings(), getPartyProfiles(), e); } @Override public LearnSettings getSettings() { return super.getSettings(); } /** * * @param actor the known real actor that did this action * @param action an {@link Action} * @return null if action seems ok, or message explaining why not. */ @Override public String checkAction(PartyId actor, Action action) { String msg = super.checkAction(actor, action); if (msg != null) return msg; if (getDoneLearning().contains(actor)) return "actor already was done learning"; if (!(action instanceof LearningDone)) return "Action " + action + " is not allowed"; return null; } /** * * @return set of parties that reported they are done with learning. */ private Set getDoneLearning() { return getActions().stream().map(party -> party.getActor()) .collect(Collectors.toSet()); } }