package geniusweb.protocol.session.mopac2.phase;
import geniusweb.actions.Action;
import geniusweb.actions.PartyId;
import geniusweb.protocol.ProtocolException;
import geniusweb.protocol.session.mopac2.PartyStates;
import geniusweb.voting.VotingEvaluator;
import geniusweb.voting.VotingEvaluatorWithValue;
public abstract class DefaultPhase implements Phase {
// deadline for this phase, ms since 1970
protected final Long deadline;
protected final PartyStates partyStates;
protected final VotingEvaluatorWithValue evaluator;
/**
* @param partyStates the {@link PartyStates}
* @param deadline deadline for this phase, ms since 1970
* @param evaluator the {@link VotingEvaluator} to be used
*/
public DefaultPhase(PartyStates partyStates, Long deadline,
VotingEvaluatorWithValue evaluator) {
this.partyStates = partyStates;
this.deadline = deadline;
this.evaluator = evaluator;
}
@Override
public boolean isFinal(long now) {
return now >= deadline || partyStates.getNotYetActed().isEmpty();
}
@Override
public long getDeadline() {
return deadline;
}
/**
* Check if actor can do given action. Basic checks:
*
* - real actor does not match action's actor
*
- deadline for this phase has passed
*
- action is not allowed in this phase
*
- actor already acted in this phase
*
*
* @param actor the actor that really acted
* @param action the action that was done
* @param now current time
* @throws ProtocolException if the action violates the protocol
*/
protected void checkAction(PartyId actor, Action action, long now)
throws ProtocolException {
if (action == null)
throw new ProtocolException("Action=null", actor);
if (!(actor.equals(action.getActor())))
throw new ProtocolException(
"Incorrect actor info in action:" + action.getActor(),
actor);
if (isFinal(now))
throw new ProtocolException("passed deadline", actor);
if (!(getAllowedActions().contains(action.getClass())))
throw new ProtocolException("Action not allowed in "
+ this.getClass().getSimpleName() + ": " + action, actor);
if (!partyStates.getNotYetActed().contains(actor))
throw new ProtocolException("Actor can not act anymore", actor);
return;
}
/**
* @return current PartyStates
*/
@Override
public PartyStates getPartyStates() {
return partyStates;
}
@Override
public VotingEvaluatorWithValue getEvaluator() {
return evaluator;
}
@Override
public Phase next(long now, long duration) {
if (duration < PHASE_MINTIME || duration > PHASE_MAXTIME)
throw new IllegalArgumentException("Bug, illegal duration");
if (!isFinal(now))
throw new IllegalStateException("phase is not final");
return checkedNext(now + duration);
}
/**
* As {@link #next(long, long)} but DefaultPhase already checked that 1.
* there is enough time for a next phase 2. current state is final 3.
*
* @param dl the deadline for the next phase (ms since 1970).
* @return the next phase
*/
protected abstract Phase checkedNext(long dl);
@Override
public String toString() {
return getClass().getSimpleName() + "[" + partyStates + "," + deadline
+ "," + evaluator + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((deadline == null) ? 0 : deadline.hashCode());
result = prime * result
+ ((evaluator == null) ? 0 : evaluator.hashCode());
result = prime * result
+ ((partyStates == null) ? 0 : partyStates.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;
DefaultPhase other = (DefaultPhase) obj;
if (deadline == null) {
if (other.deadline != null)
return false;
} else if (!deadline.equals(other.deadline))
return false;
if (evaluator == null) {
if (other.evaluator != null)
return false;
} else if (!evaluator.equals(other.evaluator))
return false;
if (partyStates == null) {
if (other.partyStates != null)
return false;
} else if (!partyStates.equals(other.partyStates))
return false;
return true;
}
}