diff --git a/voting-booth/src/main/java/meerkat/voting/controller/SystemMessages.java b/voting-booth/src/main/java/meerkat/voting/controller/SystemMessages.java new file mode 100644 index 0000000..ee6b506 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/controller/SystemMessages.java @@ -0,0 +1,84 @@ +package meerkat.voting.controller; + +import com.google.protobuf.ByteString; +import meerkat.protobuf.Voting.*; + +/** + * Created by hai on 18/05/16. + */ +final public class SystemMessages { + + private SystemMessages() { + // This is a static class. No instantiation of this is needed. + } + + public static UIElement getWaitForCommitMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Please wait while committing to ballot")) + .build(); + } + + public static UIElement getWaitForAuditMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Please wait while auditing your ballot")) + .build(); + } + + public static UIElement getWaitForCastMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Please wait while finalizing your ballot for voting")) + .build(); + } + + public static UIElement getFatalForceRestartMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Fatal error: Internal controller queue received unrecognized command. Force restarting the voting process.")) + .build(); + } + + public static UIElement getRestartVotingButton() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Restart voting")) + .build(); + } + + public static UIElement getUnrecognizedFinalizeResponseMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Could not understand response for Cast or Audit. Force restarting.")) + .build(); + } + + public static UIElement getUnsuccessfulChannelChoiceMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Choice of channel was unsuccessful. Force restarting.")) + .build(); + } + + public static UIElement getOutputDeviceFailureMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Ballot output device failure. Force restarting.")) + .build(); + } + + public static UIElement getUnsuccessfulVotingMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Voting was unsuccessful. Force restarting.")) + .build(); + } + + public static UIElement getSomethingWrongMessage() { + return UIElement.newBuilder() + .setType(UIElementDataType.TEXT) + .setData(ByteString.copyFromUtf8("Something was terribly wrong. Force restarting.")) + .build(); + } +} diff --git a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java index ee51f78..057f13d 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java @@ -8,12 +8,13 @@ import meerkat.voting.output.BallotOutputDevice; import meerkat.voting.storage.StorageManager; import java.util.ArrayList; +import java.util.List; /** * An interface for the controller component of the voting booth */ -public interface VotingBoothController { +public interface VotingBoothController extends Runnable{ /** * initialize by setting all the different components of the Voting Booth to be recognized by this controller @@ -31,8 +32,7 @@ public interface VotingBoothController { * set the voting questions * @param questions */ - public void setBallotChannelChoiceQuestions(BallotQuestion[] questions); - public void setBallotChannelChoiceQuestions(ArrayList questions); + public void setBallotChannelChoiceQuestions(List questions); /** * Set the channel question-selector (the component which matches the ballot questions to each user) @@ -44,18 +44,12 @@ public interface VotingBoothController { * set the voting race questions * @param questions */ - public void setBallotRaceQuestions(BallotQuestion[] questions); - public void setBallotRaceQuestions(ArrayList questions); - - /** - * a synchronous function. Starts running the controller component, and basically run the whole system for voting - */ - public void run (); + public void setBallotRaceQuestions(List questions); /** * an asynchronous call from Admin Console (If there is such one implemented) to shut down the system */ - public void shutDown(); + public void callShutDown(); } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java index fd67cac..cd53f65 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java @@ -12,20 +12,20 @@ import meerkat.voting.ui.VotingBoothUI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; /** * Created by hai on 28/03/16. */ -public class VotingBoothImpl implements VotingBoothController, Runnable { +public class VotingBoothImpl implements VotingBoothController { private BallotOutputDevice outputDevice; private VotingBoothEncryptor encryptor; private VotingBoothUI ui; private StorageManager storageManager; - private BallotQuestion[] questionsForChoosingChannel; - private BallotQuestion[] questions; + private List questionsForChoosingChannel; + private List questions; private QuestionSelector questionSelector; private LinkedBlockingQueue queue; @@ -33,38 +33,18 @@ public class VotingBoothImpl implements VotingBoothController, Runnable { private Logger logger; private ControllerState state; - private boolean shutDownHasBeenCalled; + private volatile boolean shutDownHasBeenCalled; protected final int MAX_REQUEST_IDENTIFIER = 100000; private static int requestCounter = 0; - private UIElement waitForCommitMessage; - private UIElement waitForAuditMessage; - private UIElement waitForCastMessage; - - public VotingBoothImpl () { logger = LoggerFactory.getLogger(VotingBoothImpl.class); logger.info("A VotingBoothImpl is constructed"); shutDownHasBeenCalled = false; queue = new LinkedBlockingQueue<>(); - - waitForCommitMessage = UIElement.newBuilder() - .setType(UIElementDataType.TEXT) - .setData(ByteString.copyFromUtf8("Please wait while committing to ballot")) - .build(); - waitForAuditMessage = UIElement.newBuilder() - .setType(UIElementDataType.TEXT) - .setData(ByteString.copyFromUtf8("Please wait while auditing your ballot")) - .build(); - waitForCastMessage = UIElement.newBuilder() - .setType(UIElementDataType.TEXT) - .setData(ByteString.copyFromUtf8("Please wait while finalizing your ballot for voting")) - .build(); - - state = new VotingBoothImpl.ControllerState(); - + state = new ControllerState(); } @Override @@ -80,42 +60,22 @@ public class VotingBoothImpl implements VotingBoothController, Runnable { } @Override - public void setBallotChannelChoiceQuestions(BallotQuestion[] questions) { + public void setBallotChannelChoiceQuestions(List questions) { logger.info("setting questions"); this.questionsForChoosingChannel = questions; } - @Override - public void setBallotChannelChoiceQuestions(ArrayList questions) { - BallotQuestion[] bqArr = new BallotQuestion[questions.size()]; - for (int i = 0; i < bqArr.length; ++i) { - bqArr[i] = questions.get(i); - } - setBallotChannelChoiceQuestions(bqArr); - } - @Override public void setChannelQuestionSelector(QuestionSelector selector) { this.questionSelector = selector; } @Override - public void setBallotRaceQuestions(BallotQuestion[] questions) { + public void setBallotRaceQuestions(List questions) { logger.info("setting questions"); this.questions = questions; } - @Override - public void setBallotRaceQuestions(ArrayList questions) { - // TODO: why does the toArray method not work?? - //BallotQuestion[] bqArr = (BallotQuestion[])(questions.toArray()); - BallotQuestion[] bqArr = new BallotQuestion[questions.size()]; - for (int i = 0; i < bqArr.length; ++i) { - bqArr[i] = questions.get(i); - } - setBallotRaceQuestions(bqArr); - } - @Override public void run() { logger.info("run command has been called"); @@ -124,17 +84,6 @@ public class VotingBoothImpl implements VotingBoothController, Runnable { } - @Override - public void shutDown() { - logger.info("shutDown command has been called"); - synchronized (this) { - shutDownHasBeenCalled = true; - } - - } - - - private void runVotingFlow () { logger.info("entered the voting flow"); @@ -151,64 +100,70 @@ public class VotingBoothImpl implements VotingBoothController, Runnable { } } - private void doShutDown () { - logger.info("running shutDown"); + @Override + public void callShutDown() { + logger.info("callShutDown command has been called"); + shutDownHasBeenCalled = true; + queue.clear(); + queue.add(new ShutDownCommand()); } private void handleSingleTask (ControllerCommand task) { - if (task instanceof RestartVotingCommand) { - doRestartVoting (); - return; - } - if (task.getBallotSerialNumber() != state.currentBallotSerialNumber) { + if (task.getBallotSerialNumber() != state.currentBallotSerialNumber && !(task instanceof RestartVotingCommand)) { + // probably an old command relating to some old ballot serial number. Simply log it and ignore it. String errorMessage = "handleSingleTask: received a task too old. " + task.getBallotSerialNumber() + " " + state.currentBallotSerialNumber; - logger.warn (errorMessage); + logger.debug(errorMessage); return; } - if (task instanceof CastCommand) { - doCast(); - return; + if (task instanceof RestartVotingCommand) { + doRestartVoting (); + } + else if (task instanceof CastCommand) { + doFinalize(false); } else if (task instanceof AuditCommand) { - doAudit(); - return; + doFinalize(true); } else if (task instanceof ChannelChoiceCommand) { doChooseChannel(); - return; } else if (task instanceof ChannelDeterminedCommand) { doSetChannelAndAskQuestions ((ChannelDeterminedCommand)task); - return; } else if (task instanceof EncryptAndCommitBallotCommand) { doCommit ((EncryptAndCommitBallotCommand)task); - return; + } + else if (task instanceof ReportErrorCommand) { + doReportErrorAndForceRestart((ReportErrorCommand)task); + } + else if (task instanceof ShutDownCommand) { + // wasShutDownCalled is now true. Do nothing. + // The program will not access the command queue anymore, and will exit normally + if (!wasShutDownCalled()) { + logger.warn("Received a ShutDownCommand command. At this point shutDownHasBeenCalled flag should have been True, but it's not..."); + shutDownHasBeenCalled = true; + } } else { - String errorMessage = "handleSingleTask: unknown type of ControllerCommand received: " + - task.getClass().getName(); - logger.error(errorMessage); - throw new RuntimeException(errorMessage); + logger.error("handleSingleTask: unknown type of ControllerCommand received: " + task.getClass().getName()); + doReportErrorAndForceRestart(SystemMessages.getSomethingWrongMessage()); } } - /* - Map taskHandlers = new Map<>() { -CaskTask.getClass().getName() : doCast(), -ChannelChoiceCommand.getClass().getName() : doChooseChannel(), -} - - - - */ - - private synchronized boolean wasShutDownCalled () { + private boolean wasShutDownCalled () { return shutDownHasBeenCalled; } + private void doShutDown () { + logger.info("running callShutDown"); + state.clearPlaintext(); + state.clearCiphertext(); + state.stateIdentifier = VBState.SHUT_DOWN; + //TODO: add commands to actually shut down the machine + } + private void doRestartVoting () { queue.clear(); state.clearPlaintext(); @@ -216,7 +171,22 @@ ChannelChoiceCommand.getClass().getName() : doChooseChannel(), state.stateIdentifier = VBState.NEW_VOTER; state.currentBallotSerialNumber += 1; - ui.startNewVoterSession(new NewVoterCallback(generateRequestIdentifier(), state.currentBallotSerialNumber , this.queue)); + ui.startNewVoterSession(new NewVoterCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + } + + private void doReportErrorAndForceRestart(ReportErrorCommand task) { + doReportErrorAndForceRestart(task.getErrorMessage()); + } + + private void doReportErrorAndForceRestart(UIElement errorMessage) { + queue.clear(); + state.clearPlaintext(); + state.clearCiphertext(); + state.stateIdentifier = VBState.FATAL_ERROR_FORCE_NEW_VOTER; + state.currentBallotSerialNumber += 1; + ui.showErrorMessageWithButtons(errorMessage, + new UIElement[]{SystemMessages.getRestartVotingButton()}, + new ErrorMessageRestartCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); } private void doChooseChannel () { @@ -227,7 +197,7 @@ ChannelChoiceCommand.getClass().getName() : doChooseChannel(), new ChannelChoiceCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); } else { - logger.warn("doChooseChannel: current state is " + state.stateIdentifier); + logger.debug("doChooseChannel: current state is " + state.stateIdentifier); // ignore this request } } @@ -236,15 +206,14 @@ ChannelChoiceCommand.getClass().getName() : doChooseChannel(), if (state.stateIdentifier == VBState.CHOOSE_CHANNEL) { logger.debug("doing set channel and ask questions"); state.stateIdentifier = VBState.ANSWER_QUESTIONS; - BallotAnswer[] channelChoiceAnswers = task.channelChoiceAnswers; + List channelChoiceAnswers = task.channelChoiceAnswers; state.channelIdentifier = questionSelector.getChannelIdentifier(channelChoiceAnswers); state.channelSpecificQuestions = questionSelector.selectQuestionsForVoter(channelChoiceAnswers); - state.stateIdentifier = VBState.ANSWER_QUESTIONS; ui.askVoterQuestions(state.channelSpecificQuestions, new VotingCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); } else { - logger.warn("doSetChannelAndAskQuestions: current state is " + state.stateIdentifier); + logger.debug("doSetChannelAndAskQuestions: current state is " + state.stateIdentifier); // ignore this request } } @@ -254,10 +223,8 @@ ChannelChoiceCommand.getClass().getName() : doChooseChannel(), if (state.stateIdentifier == VBState.ANSWER_QUESTIONS) { logger.debug("doing commit"); state.stateIdentifier = VBState.COMMITTING_TO_BALLOT; - VotingBoothEncryptor.EncryptionAndSecrets encryptionAndSecrets = encryptor.encrypt(state.plaintextBallot); - state.encryptedBallot = encryptionAndSecrets.getEncryptedBallot(); - state.secrets = encryptionAndSecrets.getSecrets(); - ui.notifyVoterToWaitForFinish(waitForCommitMessage, + setBallotData (task); + ui.notifyVoterToWaitForFinish(SystemMessages.getWaitForCommitMessage(), new WaitForFinishCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); @@ -266,38 +233,38 @@ ChannelChoiceCommand.getClass().getName() : doChooseChannel(), new OutputDeviceCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); } else { - logger.warn("doCommit: current state is " + state.stateIdentifier); + logger.debug("doCommit: current state is " + state.stateIdentifier); // ignore this request } } - - private void doAudit () { - if (state.stateIdentifier == VBState.CAST_OR_AUDIT) { - logger.debug("doing audit"); - state.stateIdentifier = VBState.FINALIZING; - outputDevice.audit(state.secrets, - new OutputDeviceCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); - ui.notifyVoterToWaitForFinish(waitForAuditMessage, - new WaitForFinishCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); - } - else { - logger.warn("doAudit: current state is " + state.stateIdentifier); - // ignore this request - } + private void setBallotData (EncryptAndCommitBallotCommand task) { + state.plaintextBallot = PlaintextBallot.newBuilder() + .setSerialNumber(task.getBallotSerialNumber()) + .addAllAnswers(task.getVotingAnswers()) + .build(); + VotingBoothEncryptor.EncryptionAndSecrets encryptionAndSecrets = encryptor.encrypt(state.plaintextBallot); + state.encryptedBallot = encryptionAndSecrets.getEncryptedBallot(); + state.secrets = encryptionAndSecrets.getSecrets(); } - private void doCast () { + private void doFinalize (boolean auditRequested) { if (state.stateIdentifier == VBState.CAST_OR_AUDIT) { - logger.debug("casting ballot"); + logger.debug("finalizing"); state.stateIdentifier = VBState.FINALIZING; - outputDevice.castBallot( - new OutputDeviceCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); - ui.notifyVoterToWaitForFinish(waitForCastMessage, + ui.notifyVoterToWaitForFinish(SystemMessages.getWaitForAuditMessage(), new WaitForFinishCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + if (auditRequested) { + outputDevice.audit(state.secrets, + new OutputDeviceCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + } + else { + outputDevice.castBallot( + new OutputDeviceCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + } } else { - logger.warn("doCast: current state is " + state.stateIdentifier); + logger.debug("doFinalize: current state is " + state.stateIdentifier); // ignore this request } } @@ -312,14 +279,16 @@ ChannelChoiceCommand.getClass().getName() : doChooseChannel(), ANSWER_QUESTIONS, COMMITTING_TO_BALLOT, CAST_OR_AUDIT, - FINALIZING + FINALIZING, + FATAL_ERROR_FORCE_NEW_VOTER, + SHUT_DOWN } private class ControllerState { - public VotingBoothImpl.VBState stateIdentifier; + public VBState stateIdentifier; public int channelIdentifier; - public BallotQuestion[] channelSpecificQuestions; + public List channelSpecificQuestions; public PlaintextBallot plaintextBallot; public EncryptedBallot encryptedBallot; public BallotSecrets secrets; @@ -338,12 +307,10 @@ ChannelChoiceCommand.getClass().getName() : doChooseChannel(), public void clearPlaintext () { - //TODO: Do we need safe erasure? plaintextBallot = null; } public void clearCiphertext () { - //TODO: Do we need safe erasure? encryptedBallot = null; secrets = null; } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java index 0a5522f..69d5123 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java @@ -1,6 +1,6 @@ package meerkat.voting.controller.callbacks; - +import meerkat.voting.controller.SystemMessages; import meerkat.voting.controller.commands.*; import meerkat.voting.controller.commands.ControllerCommand; import meerkat.voting.controller.commands.RestartVotingCommand; @@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory; import java.util.concurrent.LinkedBlockingQueue; -public class CastOrAuditCallback extends ControllerCallback { +public class CastOrAuditCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(CastOrAuditCallback.class); public CastOrAuditCallback(int requestId, @@ -20,18 +20,18 @@ public class CastOrAuditCallback extends ControllerCallback { } @Override - public void onSuccess(Object result) { - assert (result instanceof FinalizeBallotChoice); - + public void onSuccess(FinalizeBallotChoice result) { if (result == FinalizeBallotChoice.CAST) { - controllerQueue.add(new CastCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new CastCommand(getRequestIdentifier(), getBallotSerialNumber())); } else if (result == FinalizeBallotChoice.AUDIT) { - controllerQueue.add(new AuditCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new AuditCommand(getRequestIdentifier(), getBallotSerialNumber())); } else { logger.error("CastOrAuditCallback got an unrecognized response: " + result); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), + getBallotSerialNumber(), + SystemMessages.getUnrecognizedFinalizeResponseMessage())); } } @@ -39,7 +39,9 @@ public class CastOrAuditCallback extends ControllerCallback { @Override public void onFailure(Throwable t) { logger.error("CastOrAuditCallback got a failure: " + t); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), + getBallotSerialNumber(), + SystemMessages.getUnrecognizedFinalizeResponseMessage())); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ChannelChoiceCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ChannelChoiceCallback.java index c6db8d4..f6abd5c 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ChannelChoiceCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ChannelChoiceCallback.java @@ -1,18 +1,18 @@ package meerkat.voting.controller.callbacks; -import meerkat.protobuf.Voting; -import meerkat.voting.controller.commands.ChannelDeterminedCommand; -import meerkat.voting.controller.commands.ControllerCommand; -import meerkat.voting.controller.commands.RestartVotingCommand; +import meerkat.protobuf.Voting.*; +import meerkat.voting.controller.SystemMessages; +import meerkat.voting.controller.commands.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; /** * Created by hai on 11/04/16. */ -public class ChannelChoiceCallback extends ControllerCallback { +public class ChannelChoiceCallback extends ControllerCallback> { protected final static Logger logger = LoggerFactory.getLogger(ChannelChoiceCallback.class); public ChannelChoiceCallback(int requestId, @@ -22,22 +22,22 @@ public class ChannelChoiceCallback extends ControllerCallback { } @Override - public void onSuccess(Object result) { - assert (result instanceof Voting.BallotAnswer[]); - if (((Voting.BallotAnswer[])result).length != 0) { + public void onSuccess(List result) { + if (result.size() != 0) { logger.debug("callback for channel choice returned success"); - controllerQueue.add( - new ChannelDeterminedCommand(getRequestIdentifier(), getBallotSerialNumber(), (Voting.BallotAnswer[]) result)); + enqueueCommand(new ChannelDeterminedCommand(getRequestIdentifier(), getBallotSerialNumber(), result)); } else { logger.debug("ChannelChoiceCallback got a cancellation response: " + result); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); } } @Override public void onFailure(Throwable t) { logger.error("channel choice initiated a failure: " + t); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), + getBallotSerialNumber(), + SystemMessages.getUnsuccessfulChannelChoiceMessage())); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ControllerCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ControllerCallback.java index 2c33cbc..d5684d2 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ControllerCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ControllerCallback.java @@ -1,14 +1,18 @@ package meerkat.voting.controller.callbacks; +/** + * Created by hai on 18/05/16. + */ import com.google.common.util.concurrent.FutureCallback; import meerkat.voting.controller.commands.ControllerCommand; import java.util.concurrent.LinkedBlockingQueue; -public abstract class ControllerCallback implements FutureCallback { +public abstract class ControllerCallback implements FutureCallback { + private final int requestIdentifier; private final long ballotSerialNumber; - protected LinkedBlockingQueue controllerQueue; + private LinkedBlockingQueue controllerQueue; protected ControllerCallback (int requestId, long ballotSerialNumber, @@ -21,7 +25,13 @@ public abstract class ControllerCallback implements FutureCallback { protected int getRequestIdentifier () { return requestIdentifier; } + protected long getBallotSerialNumber () { return ballotSerialNumber; } + + protected void enqueueCommand (ControllerCommand command) { + controllerQueue.add(command); + } + } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ErrorMessageRestartCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ErrorMessageRestartCallback.java new file mode 100644 index 0000000..34f1194 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/ErrorMessageRestartCallback.java @@ -0,0 +1,29 @@ +package meerkat.voting.controller.callbacks; + +import meerkat.voting.controller.commands.ControllerCommand; +import meerkat.voting.controller.commands.RestartVotingCommand; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.LinkedBlockingQueue; + +public class ErrorMessageRestartCallback extends ControllerCallback { + protected final static Logger logger = LoggerFactory.getLogger(ErrorMessageRestartCallback.class); + + public ErrorMessageRestartCallback(int requestId, + long ballotSerialNumber, + LinkedBlockingQueue controllerQueue) { + super(requestId, ballotSerialNumber, controllerQueue); + } + + @Override + public void onSuccess(Integer result) { + enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + } + + @Override + public void onFailure(Throwable t) { + logger.error("Error message execution initiated a failure: " + t); + enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + } +} diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/HaltCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/HaltCallback.java deleted file mode 100644 index c251a0f..0000000 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/HaltCallback.java +++ /dev/null @@ -1,32 +0,0 @@ -package meerkat.voting.controller.callbacks; - -import meerkat.voting.controller.commands.ControllerCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.LinkedBlockingQueue; - -/** - * Created by hai on 21/04/16. - */ -public class HaltCallback extends ControllerCallback{ - protected final static Logger logger = LoggerFactory.getLogger(HaltCallback.class); - - public HaltCallback(int requestId, - long ballotSerialNumber, - LinkedBlockingQueue controllerQueue) { - super(requestId, ballotSerialNumber, controllerQueue); - } - - - @Override - public void onSuccess(Object result) { - throw new UnsupportedOperationException("HaltCallback: onSuccess: There cannot be a successful return for this task. Returned value is " + result); - } - - @Override - public void onFailure(Throwable t) { - logger.error("Halting initiated a failure: " + t); - } - -} diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/NewVoterCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/NewVoterCallback.java index bdb53c3..9b4e365 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/NewVoterCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/NewVoterCallback.java @@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory; import java.util.concurrent.LinkedBlockingQueue; -public class NewVoterCallback extends ControllerCallback { +public class NewVoterCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(NewVoterCallback.class); public NewVoterCallback(int requestId, @@ -18,15 +18,14 @@ public class NewVoterCallback extends ControllerCallback { } @Override - public void onSuccess(Object v) { + public void onSuccess(Void v) { logger.debug("callback for new voting returned success"); - assert v==null; - controllerQueue.add(new ChannelChoiceCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new ChannelChoiceCommand(getRequestIdentifier(), getBallotSerialNumber())); } @Override public void onFailure(Throwable t) { logger.error("New voting session got a failure: " + t); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCallback.java index 81a14c4..2432f49 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCallback.java @@ -1,13 +1,15 @@ package meerkat.voting.controller.callbacks; +import meerkat.voting.controller.SystemMessages; import meerkat.voting.controller.commands.ControllerCommand; +import meerkat.voting.controller.commands.ReportErrorCommand; import meerkat.voting.controller.commands.RestartVotingCommand; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.LinkedBlockingQueue; -public class OutputDeviceCallback extends ControllerCallback { +public class OutputDeviceCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceCallback.class); public OutputDeviceCallback(int requestId, @@ -17,13 +19,14 @@ public class OutputDeviceCallback extends ControllerCallback { } @Override - public void onSuccess(Object v) { - assert v instanceof Void; + public void onSuccess(Void v) { } @Override public void onFailure(Throwable t) { logger.error("WaitForFinishCallback got a failure: " + t); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), + getBallotSerialNumber(), + SystemMessages.getOutputDeviceFailureMessage())); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java index 5e0cc1a..5317374 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java @@ -1,15 +1,18 @@ package meerkat.voting.controller.callbacks; -import meerkat.protobuf.Voting; +import meerkat.protobuf.Voting.*; +import meerkat.voting.controller.SystemMessages; import meerkat.voting.controller.commands.ControllerCommand; import meerkat.voting.controller.commands.EncryptAndCommitBallotCommand; +import meerkat.voting.controller.commands.ReportErrorCommand; import meerkat.voting.controller.commands.RestartVotingCommand; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; -public class VotingCallback extends ControllerCallback { +public class VotingCallback extends ControllerCallback> { protected final static Logger logger = LoggerFactory.getLogger(VotingCallback.class); public VotingCallback(int requestId, @@ -19,22 +22,22 @@ public class VotingCallback extends ControllerCallback { } @Override - public void onSuccess(Object result) { - assert result instanceof Voting.BallotAnswer[]; - if (((Voting.BallotAnswer[])result).length != 0) { + public void onSuccess(List result) { + if (result.size() != 0) { logger.debug("callback for voting returned success"); - controllerQueue.add( - new EncryptAndCommitBallotCommand(getRequestIdentifier(), getBallotSerialNumber(), (Voting.BallotAnswer[]) result)); + enqueueCommand(new EncryptAndCommitBallotCommand(getRequestIdentifier(), getBallotSerialNumber(), result)); } else { logger.debug("VotingCallback got a cancellation response: " + result); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); } } @Override public void onFailure(Throwable t) { logger.error("voting initiated a failure: " + t); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), + getBallotSerialNumber(), + SystemMessages.getUnsuccessfulVotingMessage())); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java index d56327d..9f7a159 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java @@ -1,13 +1,15 @@ package meerkat.voting.controller.callbacks; +import meerkat.voting.controller.SystemMessages; import meerkat.voting.controller.commands.ControllerCommand; +import meerkat.voting.controller.commands.ReportErrorCommand; import meerkat.voting.controller.commands.RestartVotingCommand; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.LinkedBlockingQueue; -public class WaitForFinishCallback extends ControllerCallback { +public class WaitForFinishCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(WaitForFinishCallback.class); public WaitForFinishCallback(int requestId, @@ -17,13 +19,14 @@ public class WaitForFinishCallback extends ControllerCallback { } @Override - public void onSuccess(Object v) { - assert v instanceof Void; + public void onSuccess(Void v) { } @Override public void onFailure(Throwable t) { logger.error("WaitForFinishCallback got a failure: " + t); - controllerQueue.add(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), + getBallotSerialNumber(), + SystemMessages.getSomethingWrongMessage())); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/commands/ChannelDeterminedCommand.java b/voting-booth/src/main/java/meerkat/voting/controller/commands/ChannelDeterminedCommand.java index 8fefbe7..47d6f8b 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/commands/ChannelDeterminedCommand.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/commands/ChannelDeterminedCommand.java @@ -1,14 +1,15 @@ package meerkat.voting.controller.commands; -import meerkat.protobuf.Voting; +import meerkat.protobuf.Voting.*; +import java.util.List; /** * Created by hai on 11/04/16. */ public class ChannelDeterminedCommand extends ControllerCommand { - public Voting.BallotAnswer[] channelChoiceAnswers; + public List channelChoiceAnswers; - public ChannelDeterminedCommand(int requestIdentifier, long ballotSerialNumber, Voting.BallotAnswer[] answers) { + public ChannelDeterminedCommand(int requestIdentifier, long ballotSerialNumber, List answers) { super(requestIdentifier, ballotSerialNumber); channelChoiceAnswers = answers; } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java b/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java index bad2ff7..074216f 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java @@ -1,12 +1,18 @@ package meerkat.voting.controller.commands; -import meerkat.protobuf.Voting; +import meerkat.protobuf.Voting.*; + +import java.util.List; public class EncryptAndCommitBallotCommand extends ControllerCommand { - public Voting.BallotAnswer[] votingAnswers; + private final List votingAnswers; - public EncryptAndCommitBallotCommand(int requestIdentifier, long ballotSerialNumber, Voting.BallotAnswer[] answers) { + public EncryptAndCommitBallotCommand(int requestIdentifier, long ballotSerialNumber, List answers) { super(requestIdentifier, ballotSerialNumber); votingAnswers = answers; } + + public List getVotingAnswers() { + return votingAnswers; + } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/commands/ReportErrorCommand.java b/voting-booth/src/main/java/meerkat/voting/controller/commands/ReportErrorCommand.java new file mode 100644 index 0000000..b4a1fe7 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/controller/commands/ReportErrorCommand.java @@ -0,0 +1,16 @@ +package meerkat.voting.controller.commands; + +import meerkat.protobuf.Voting.*; + +public class ReportErrorCommand extends ControllerCommand { + private final UIElement errorMessage; + + public ReportErrorCommand(int requestIdentifier, long ballotSerialNumber, UIElement errorMessage) { + super(requestIdentifier, ballotSerialNumber); + this.errorMessage = errorMessage; + } + + public UIElement getErrorMessage() { + return errorMessage; + } +} diff --git a/voting-booth/src/main/java/meerkat/voting/controller/commands/ShutDownCommand.java b/voting-booth/src/main/java/meerkat/voting/controller/commands/ShutDownCommand.java new file mode 100644 index 0000000..ee3c0f2 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/controller/commands/ShutDownCommand.java @@ -0,0 +1,10 @@ +package meerkat.voting.controller.commands; + +/** + * Created by hai on 11/04/16. + */ +public class ShutDownCommand extends ControllerCommand { + public ShutDownCommand() { + super(0, 0); + } +} diff --git a/voting-booth/src/main/java/meerkat/voting/controller/selector/QuestionSelector.java b/voting-booth/src/main/java/meerkat/voting/controller/selector/QuestionSelector.java index 3fd2188..e409e36 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/selector/QuestionSelector.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/selector/QuestionSelector.java @@ -1,20 +1,18 @@ package meerkat.voting.controller.selector; import meerkat.protobuf.Voting.*; +import java.util.List; /** * Created by hai on 02/05/16. */ -public abstract class QuestionSelector { +public interface QuestionSelector { - protected Object selectionData; - protected BallotQuestion[] allBallotQuestions; + public void setAllBallotQuestions (List allBallotQuestions); - public QuestionSelector(Object selectionData, BallotQuestion[] allBallotQuestions) { - this.selectionData = selectionData; - this.allBallotQuestions = allBallotQuestions; - } + public void setSelectionData(SelectionData data); - public abstract int getChannelIdentifier (BallotAnswer[] channelChoiceAnswers); - public abstract BallotQuestion[] selectQuestionsForVoter (BallotAnswer[] channelChoiceAnswers); + public int getChannelIdentifier (List channelChoiceAnswers); + + public List selectQuestionsForVoter (List channelChoiceAnswers); } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/selector/SelectionData.java b/voting-booth/src/main/java/meerkat/voting/controller/selector/SelectionData.java new file mode 100644 index 0000000..24a1125 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/controller/selector/SelectionData.java @@ -0,0 +1,7 @@ +package meerkat.voting.controller.selector; + +/** + * Created by hai on 11/05/16. + */ +public class SelectionData { +} diff --git a/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleCategoriesData.java b/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleCategoriesData.java index 83ae516..544a86d 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleCategoriesData.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleCategoriesData.java @@ -1,39 +1,60 @@ package meerkat.voting.controller.selector; -import java.util.HashMap; -import java.lang.Math; - /** - * Created by hai on 02/05/16. + * This class is the SelectionData used to initialize a SimpleListCategoriesSelector. + * It holds a table of question categories. + * Every answer in the channel choice phase dictates a category of questions to include in the ballot. + * This class is simply only the data class of these categories. + * Specifically the questionSelectionsByAnswer member is this categories table: + * questionSelectionsByAnswer[questionNumber][answerNumber] is an array of question indices to include in ballot + * whenever the voter answered answerNumber on question questionNumber in the channel choice phase. + * Also the sharedDefaults member is a category of question indices to include for EVERY voter, + * regardless of his channel choice answers */ -public class SimpleCategoriesData { +public class SimpleCategoriesData extends SelectionData{ - private int[] sharedDefaults; - private HashMap questionsSelections; + private int[] sharedDefaults; // a category of questions to include for every voter + // the categories + // first index is the question number, the second is the answer number. the value is an array of question indices in this category + private int[][][] questionSelectionsByAnswer; private int maxQuestionNumber; public SimpleCategoriesData() { sharedDefaults = new int[0]; - questionsSelections = new HashMap(); + questionSelectionsByAnswer = new int[0][][]; maxQuestionNumber = -1; } public void setSharedDefaults(int[] sharedDefaultsIndices) { - this.sharedDefaults = sharedDefaultsIndices; - maxQuestionNumber = Math.max(maxQuestionNumber, maxInt(sharedDefaultsIndices)); + this.sharedDefaults = sharedDefaultsIndices.clone(); + maxQuestionNumber = Math.max(maxQuestionNumber, maxIntInArray(sharedDefaultsIndices)); } public int[] getSharedDefaults() { return sharedDefaults; } - public void setItem(SingleChosenAnswer key, int[] questionIndices) { - questionsSelections.put(key, questionIndices); - maxQuestionNumber = Math.max(maxQuestionNumber, maxInt(questionIndices)); + public void setItem(int questionNumber, int answerNumber, int[] questionIndices) { + if (questionNumber >= questionSelectionsByAnswer.length) { + int[][][] tmp = new int[questionNumber+1][][]; + System.arraycopy(questionSelectionsByAnswer, 0, tmp, 0, questionSelectionsByAnswer.length); + tmp[questionNumber] = new int[0][]; + questionSelectionsByAnswer = tmp; + } + + if (answerNumber >= questionSelectionsByAnswer[questionNumber].length) { + int[][] tmp = new int[answerNumber+1][]; + System.arraycopy(questionSelectionsByAnswer[questionNumber], 0, + tmp, 0, questionSelectionsByAnswer[questionNumber].length); + questionSelectionsByAnswer[questionNumber] = tmp; + } + + questionSelectionsByAnswer[questionNumber][answerNumber] = questionIndices.clone(); + maxQuestionNumber = Math.max(maxQuestionNumber, maxIntInArray(questionIndices)); } - public int[] getItem(SingleChosenAnswer key) { - return questionsSelections.get(key); + public int[] getItem(int questionNumber, int answerNumber) { + return questionSelectionsByAnswer[questionNumber][answerNumber]; } public int getMaxQuestionNumber() { @@ -41,7 +62,7 @@ public class SimpleCategoriesData { } - private static int maxInt(int[] arr) { + private static int maxIntInArray(int[] arr) { int m = -1; for (int i: arr) { m = Math.max(i , m); @@ -53,8 +74,11 @@ public class SimpleCategoriesData { String s = "SimpleCategoriesData:\n"; s += "shared : " + arrayToString(sharedDefaults) + "\n"; s += "map : \n"; - for (SingleChosenAnswer key : questionsSelections.keySet()) { - s += key + " : " + arrayToString(questionsSelections.get(key)) + "\n"; + for (int questionNumber = 0; questionNumber < questionSelectionsByAnswer.length; ++questionNumber) { + for (int answerNumber = 0; answerNumber < questionSelectionsByAnswer[questionNumber].length; ++answerNumber) { + s += "(" + questionNumber + ", " + answerNumber + ") -> " + + arrayToString(questionSelectionsByAnswer[questionNumber][answerNumber]) + "\n"; + } } return s; } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleListCategoriesSelector.java b/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleListCategoriesSelector.java index 31911e6..d953246 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleListCategoriesSelector.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/selector/SimpleListCategoriesSelector.java @@ -1,75 +1,88 @@ package meerkat.voting.controller.selector; -import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException; -import meerkat.protobuf.Voting.*; +import meerkat.protobuf.Voting.BallotAnswer; +import meerkat.protobuf.Voting.BallotQuestion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.List; /** - * Created by hai on 02/05/16. + * A simple implementation of a QuestionSelector. + * This implementation simply regards every single answer in the channel choice phase as an identifier of a category + * Every category is an array of ballot questions. + * Data of categories is initialized and stored by a SimpleCategoriesData object. + * After receiving the answers from a channel choice phase, this class simply gathers all the categories + * chosen and compiles the list of ballot questions to include in the ballot for this voter (a question + * is included if its index appears in any chosen category, or in the default category shared by all voters) */ -public class SimpleListCategoriesSelector extends QuestionSelector { +public class SimpleListCategoriesSelector implements QuestionSelector { protected final static Logger logger = LoggerFactory.getLogger(SimpleListCategoriesSelector.class); + private BallotQuestion[] allBallotQuestions; + private SimpleCategoriesData selectionData; private boolean[] isSelected; - public SimpleListCategoriesSelector(Object selectionData, BallotQuestion[] allBallotQuestions) { - super(selectionData, allBallotQuestions); - initializeAttributes (allBallotQuestions); - } - public SimpleListCategoriesSelector(Object selectionData, ArrayList allBallotQuestions) { - super(selectionData, null); - BallotQuestion[] questionsArr = new BallotQuestion[allBallotQuestions.size()]; - for (int i = 0; i < questionsArr.length; ++i) { - questionsArr[i] = allBallotQuestions.get(i); - } - initializeAttributes (questionsArr); + public SimpleListCategoriesSelector() { + this.allBallotQuestions = null; + this.selectionData = null; } - private void initializeAttributes (BallotQuestion[] allBallotQuestions) { - assert selectionData instanceof SimpleCategoriesData; - this.allBallotQuestions = allBallotQuestions; - SimpleCategoriesData data = (SimpleCategoriesData) selectionData; - int maxQuestionNumber = data.getMaxQuestionNumber(); - int length = allBallotQuestions.length; - if (maxQuestionNumber >= length) { - String errorMessage = "Selection data refers to question index " + maxQuestionNumber + " while we have only " + length + " questions totally"; - logger.error(errorMessage); - throw new ValueException(errorMessage); - } - isSelected = new boolean[allBallotQuestions.length]; - } - - @Override - public int getChannelIdentifier(BallotAnswer[] channelChoiceAnswers) { + public void setAllBallotQuestions(List allBallotQuestions) { + this.allBallotQuestions = (BallotQuestion[])allBallotQuestions.toArray(); + isSelected = new boolean[this.allBallotQuestions.length]; + assertDataValid(); + } + + @Override + public void setSelectionData(SelectionData data) { + if (! (data instanceof SimpleCategoriesData)) { + String errorMessage = "Initialization of SimpleListCategoriesSelector with wrong object type"; + logger.error(errorMessage); + throw new RuntimeException(errorMessage); + } + this.selectionData = (SimpleCategoriesData)data; + assertDataValid(); + } + + private void assertDataValid () { + if (selectionData != null && allBallotQuestions != null) { + int questionsLength = allBallotQuestions.length; + int maxQuestionNumber = selectionData.getMaxQuestionNumber(); + if (maxQuestionNumber >= questionsLength) { + String errorMessage = "Selection data refers to question index " + maxQuestionNumber + " while we have only " + questionsLength + " questions totally"; + logger.error(errorMessage); + throw new IndexOutOfBoundsException(errorMessage); + } + } + } + + @Override + public int getChannelIdentifier(List channelChoiceAnswers) { return 0; } @Override - public BallotQuestion[] selectQuestionsForVoter(BallotAnswer[] channelChoiceAnswers) { - SimpleCategoriesData data = (SimpleCategoriesData)selectionData; + public List selectQuestionsForVoter(List channelChoiceAnswers) { java.util.Arrays.fill(isSelected, false); - markSelected(data.getSharedDefaults()); - markSelectionsOfVoterChannelChoice (channelChoiceAnswers); + markSelected(selectionData.getSharedDefaults()); + markSelectionsOfVoterChannelChoice ((BallotAnswer[])channelChoiceAnswers.toArray()); int[] questionIndices = extractSelectedIndices(); - BallotQuestion[] selectedQuestions = new BallotQuestion[questionIndices.length]; - for (int i = 0; i < questionIndices.length; ++i) { - selectedQuestions[i] = allBallotQuestions[questionIndices[i]]; + List selectedQuestions = new ArrayList<>(); + for (int questionIndex: questionIndices) { + selectedQuestions.add(allBallotQuestions[questionIndex]); } return selectedQuestions; } private void markSelectionsOfVoterChannelChoice(BallotAnswer[] channelChoiceAnswers) { - SimpleCategoriesData data = (SimpleCategoriesData)selectionData; for (int q = 0; q < channelChoiceAnswers.length; ++q) { BallotAnswer ballotAnswer = channelChoiceAnswers[q]; assertAnswerLengthIsOne(ballotAnswer, q); - SingleChosenAnswer key = new SingleChosenAnswer(q, ballotAnswer.getAnswer(0)); - assertKeyInSelectionData(key); - markSelected(data.getItem(key)); + assertKeyInSelectionData(q, (int)ballotAnswer.getAnswer(0)); + markSelected(selectionData.getItem(q, (int)ballotAnswer.getAnswer(0))); } } @@ -81,17 +94,16 @@ public class SimpleListCategoriesSelector extends QuestionSelector { errorMessage += " " + i; } logger.error(errorMessage); - throw new ValueException(errorMessage); + throw new IllegalArgumentException(errorMessage); } } - private void assertKeyInSelectionData(SingleChosenAnswer key) { - SimpleCategoriesData data = (SimpleCategoriesData)selectionData; - int[] questionListToAdd = data.getItem(key); + private void assertKeyInSelectionData(int questionNumber, int answerNumber) { + int[] questionListToAdd = selectionData.getItem(questionNumber, answerNumber); if (null == questionListToAdd) { - String errorMessage = "SimpleListCategoriesSelector could not resolve answer number " + key.answerNumber + " for question number " + key.questionNumber; + String errorMessage = "SimpleListCategoriesSelector could not resolve answer number " + answerNumber + " for question number " + questionNumber; logger.error(errorMessage); - throw new ValueException(errorMessage); + throw new IllegalArgumentException(errorMessage); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/selector/SingleChosenAnswer.java b/voting-booth/src/main/java/meerkat/voting/controller/selector/SingleChosenAnswer.java deleted file mode 100644 index fad377b..0000000 --- a/voting-booth/src/main/java/meerkat/voting/controller/selector/SingleChosenAnswer.java +++ /dev/null @@ -1,31 +0,0 @@ -package meerkat.voting.controller.selector; - -/** - * Created by hai on 02/05/16. - */ -public class SingleChosenAnswer { - public int questionNumber; - public long answerNumber; - - public SingleChosenAnswer(int questionNumber, long answerNumber) { - this.questionNumber = questionNumber; - this.answerNumber = answerNumber; - } - - public String toString() { - return "SingleChosenAnswer(" + questionNumber + ", " + answerNumber + ")"; - } - - public boolean equals (Object other) { - if (!(other instanceof SingleChosenAnswer)) { - return false; - } - SingleChosenAnswer o = (SingleChosenAnswer)other; - return (o.questionNumber == this.questionNumber) && (o.answerNumber == this.answerNumber); - } - - @Override - public int hashCode () { - return questionNumber*1000 + (int)answerNumber; - } -} diff --git a/voting-booth/src/main/java/meerkat/voting/ui/SystemConsoleUI.java b/voting-booth/src/main/java/meerkat/voting/ui/SystemConsoleUI.java index 4b6486e..1ab1574 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/SystemConsoleUI.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/SystemConsoleUI.java @@ -7,9 +7,7 @@ import meerkat.protobuf.Voting.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.util.Date; -import java.util.StringTokenizer; -import java.util.Timer; +import java.util.*; import java.util.concurrent.LinkedBlockingQueue; import meerkat.voting.controller.callbacks.*; @@ -45,54 +43,47 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { logger.info("entered the voting flow"); while (true) { try { - UICommand task = queue.take(); - handleSingleTask (task); + UICommand command = queue.take(); + handleSingleCommand(command); } catch (InterruptedException e) { - logger.warn ("Interrupted while reading from task queue " + e); + logger.warn ("Interrupted while reading from command queue " + e); } } } - private void handleSingleTask (UICommand task) { - if (!(task instanceof TickCommand)) { + private void handleSingleCommand(UICommand command) { + if (!(command instanceof TickCommand)) { if (startWaitingTime != null) { stopWaiting(); } } - if (task instanceof StartSessionUICommand) { - doShowWelcomeScreen((StartSessionUICommand)task); - return; + if (command instanceof StartSessionUICommand) { + doShowWelcomeScreen((StartSessionUICommand)command); } - else if (task instanceof ChannelChoiceUICommand) { - doAskChannelChoiceQuestions((ChannelChoiceUICommand)task); - return; + else if (command instanceof ChannelChoiceUICommand) { + doAskChannelChoiceQuestions((ChannelChoiceUICommand)command); } - else if (task instanceof RaceVotingUICommand) { - doAskVotingQuestions((RaceVotingUICommand)task); - return; + else if (command instanceof RaceVotingUICommand) { + doAskVotingQuestions((RaceVotingUICommand)command); } - else if (task instanceof CastOrAuditUICommand) { - doCastOrAudit ((CastOrAuditUICommand)task); - return; + else if (command instanceof CastOrAuditUICommand) { + doCastOrAudit ((CastOrAuditUICommand)command); } - else if (task instanceof HaltCommand) { - doHalt((HaltCommand)task); - return; + else if (command instanceof FatalErrorUICommand) { + doFatalError((FatalErrorUICommand)command); } - else if (task instanceof WaitForFinishCommand) { - doWaitForFinish((WaitForFinishCommand)task); - return; + else if (command instanceof WaitForFinishUICommand) { + doWaitForFinish((WaitForFinishUICommand)command); } - else if (task instanceof TickCommand) { + else if (command instanceof TickCommand) { doTick (); - return; } else { - String errorMessage = "handleSingleTask: unknown type of UICommand received: " + - task.getClass().getName(); + String errorMessage = "handleSingleCommand: unknown type of UICommand received: " + + command.getClass().getName(); logger.error(errorMessage); throw new RuntimeException(errorMessage); } @@ -105,13 +96,13 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { queue.add(new StartSessionUICommand((ControllerCallback)callback)); } - private void doShowWelcomeScreen(StartSessionUICommand task) { + private void doShowWelcomeScreen(StartSessionUICommand command) { logger.debug("UI entered doShowWelcomeScreen"); System.out.println("Welcome, new voter!"); waitForEnter(null); - ControllerCallback callback = task.getCallback(); + ControllerCallback callback = command.getCallback(); assert (callback instanceof NewVoterCallback); - ((NewVoterCallback)callback).onSuccess(null); + callback.onSuccess(null); } private void stopWaiting () { @@ -138,45 +129,45 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } @Override - public void chooseChannel(BallotQuestion[] questions, FutureCallback callback) { + public void chooseChannel(List questions, FutureCallback> callback) { logger.debug("UI interface call to chooseChannel"); - ChannelChoiceUICommand task = new ChannelChoiceUICommand(questions, (ControllerCallback)callback); - queue.add(task); + ChannelChoiceUICommand command = new ChannelChoiceUICommand(questions, (ControllerCallback)callback); + queue.add(command); } - private void doAskChannelChoiceQuestions (ChannelChoiceUICommand task) { + private void doAskChannelChoiceQuestions (ChannelChoiceUICommand command) { logger.debug("UI: doAskChannelChoiceQuestions"); System.out.println("Showing questions for choosing channel:\n"); try { - BallotAnswer[] answers = askVoterForAnswers(task.getQuestions()); - task.getCallback().onSuccess(answers); + List answers = askVoterForAnswers(command.getQuestions()); + command.getCallback().onSuccess(answers); } catch (IOException e) { String errorMessage = "Channel choice failed due to IOException: " + e; logger.error (errorMessage); System.err.println(errorMessage); - task.getCallback().onFailure(e); + command.getCallback().onFailure(e); } } @Override - public void askVoterQuestions(BallotQuestion[] questions, FutureCallback callback) { + public void askVoterQuestions(List questions, FutureCallback> callback) { logger.debug("UI interface call to chooseChannel"); queue.add(new RaceVotingUICommand(questions, (ControllerCallback)callback)); } - private void doAskVotingQuestions (RaceVotingUICommand task) { + private void doAskVotingQuestions (RaceVotingUICommand command) { logger.debug("UI: doAskVotingQuestions"); System.out.println("Showing questions for race voting:\n"); try { - BallotAnswer[] answers = askVoterForAnswers(task.getQuestions()); - task.getCallback().onSuccess(answers); + List answers = askVoterForAnswers(command.getQuestions()); + command.getCallback().onSuccess(answers); } catch (IOException e) { String errorMessage = "Asking voting questions failed due to IOException: " + e; logger.error (errorMessage); System.err.println(errorMessage); - task.getCallback().onFailure(e); + command.getCallback().onFailure(e); } } @@ -186,7 +177,7 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { queue.add(new CastOrAuditUICommand((ControllerCallback)callback)); } - private void doCastOrAudit(CastOrAuditUICommand task) { + private void doCastOrAudit(CastOrAuditUICommand command) { logger.debug("UI entered doCastOrAudit"); System.out.println ("Finalizing your vote. Do you wish to (C)ast or (A)udit?"); @@ -203,30 +194,30 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { else { throw new IllegalArgumentException("UI could not understand the answer for cast/audit question '" + s + "'"); } - ControllerCallback callback = task.getCallback(); + ControllerCallback callback = command.getCallback(); assert (callback instanceof CastOrAuditCallback); ((CastOrAuditCallback)callback).onSuccess(fChoice); } catch (IllegalArgumentException|IOException e) { String errorMessage = "doCastOrAudit: some error with reading input from console. details: " + e; logger.error(errorMessage); - task.getCallback().onFailure(e); + command.getCallback().onFailure(e); } } @Override - public void notifyVoterToWaitForFinish(UIElement message, FutureCallback callback) { + public void notifyVoterToWaitForFinish(UIElement message, FutureCallback callback) { logger.debug("UI interface call to notifyVoterToWaitForFinish"); - queue.add(new WaitForFinishCommand(message, (ControllerCallback)callback)); + queue.add(new WaitForFinishUICommand(message, (ControllerCallback)callback)); } - public void doWaitForFinish (WaitForFinishCommand task) { + public void doWaitForFinish (WaitForFinishUICommand command) { logger.debug("UI entered doWaitForFinish"); startWaitingTime = new Date(); - UIElement message = task.getMessage(); + UIElement message = command.getMessage(); String messageString; if (message.getType() != UIElementDataType.TEXT) { messageString = "Default message: encountered an error. System halting"; @@ -240,39 +231,57 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { @Override public void showErrorMessageAndHalt(UIElement errorMessage, FutureCallback callback) { logger.debug("UI interface call to showErrorMessageAndHalt"); - queue.add(new HaltCommand(errorMessage, (ControllerCallback)callback)); + throw new UnsupportedOperationException("Not implemented becuase currently not sure if we ever use it."); } - private void doHalt (HaltCommand task) { - logger.debug("UI entered doHalt"); - UIElement errorMessage = task.getErrorMessage(); + @Override + public void showErrorMessageWithButtons(UIElement errorMessage, UIElement[] buttonLabels, FutureCallback callback) { + logger.debug("UI interface call to showErrorMessageWithButtons"); + queue.clear(); + queue.add(new FatalErrorUICommand(errorMessage, buttonLabels, (ControllerCallback)callback)); + } + + private void doFatalError (FatalErrorUICommand command) { + logger.debug("UI entered doFatalError"); + + UIElement errorMessage = command.getErrorMessage(); String errorMessageString; if (errorMessage.getType() != UIElementDataType.TEXT) { errorMessageString = "Default message: encountered an error. System halting"; } else { errorMessageString = bytesToString(errorMessage.getData()); } - System.out.println(errorMessageString); - while (true) { - try { - wait(); - } catch (InterruptedException e) { - logger.error("UI halt has been interrupted. Details: " + e); - ControllerCallback callback = task.getCallback(); - assert callback instanceof HaltCallback; - ((HaltCallback) callback).onFailure(e); + UIElement[] buttonLabels = command.getButtonLabels(); + String[] buttonLabelStrings = new String[buttonLabels.length]; + for (int i = 0; i < buttonLabels.length; ++i) { + if (buttonLabels[i].getType() != UIElementDataType.TEXT) { + buttonLabelStrings[i] = ""; + } else { + buttonLabelStrings[i] = bytesToString(errorMessage.getData()); } } + + System.out.println(errorMessageString); + for (int i = 0; i < buttonLabelStrings.length; ++i) { + System.out.println("" + i + " - " + buttonLabelStrings[i]); + } + + try { + String s = readInputLine(); + Integer chosenButton = new Integer(s); + command.getCallback().onSuccess(chosenButton); + } + catch (IOException e) { + String err = "doFatalError: some error with reading input from console. details: " + e; + logger.error(err); + command.getCallback().onFailure(e); + } + } - @Override - public void showErrorMessageWithButtons(UIElement errorMessage, UIElement[] buttonLabels, FutureCallback callback) { - throw new UnsupportedOperationException(); - } - private void doTick () { if (startWaitingTime != null) { System.out.print ("."); // still waiting @@ -295,9 +304,9 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } - private void assertQuestionsAreValid (BallotQuestion[] questions) { - for (int index = 0; index < questions.length; ++index) { - BallotQuestion question = questions[index]; + private void assertQuestionsAreValid (List questions) { + for (int index = 0; index < questions.size(); ++index) { + BallotQuestion question = questions.get(index); if (question.getIsMandatory()) { String errorMessage = "askVoterQuestions: question number " + index + " is marked as mandatory"; logger.error(errorMessage); @@ -311,14 +320,14 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } } - private BallotAnswer[] askVoterForAnswers(BallotQuestion[] questions) throws IOException { + private List askVoterForAnswers(List questions) throws IOException { assertQuestionsAreValid (questions); - BallotAnswer answers[] = new BallotAnswer[questions.length]; + List answers = new ArrayList<>(); int index = 0; - while (index < questions.length) { - BallotQuestion question = questions[index]; + while (index < questions.size()) { + BallotQuestion question = questions.get(index); System.out.println("Question number " + index); showQuestionOnScreen(question); @@ -330,13 +339,14 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } else if (s.equals("back") || s.equals("b")) { --index; + answers.remove(index); } else if (s.equals("skip") || s.equals("s")) { - answers[index] = translateStringAnswerToProtoBufMessageAnswer(""); + answers.add(translateStringAnswerToProtoBufMessageAnswer("")); ++index; } else { - answers[index] = translateStringAnswerToProtoBufMessageAnswer(s); + answers.add(translateStringAnswerToProtoBufMessageAnswer(s)); ++index; } } diff --git a/voting-booth/src/main/java/meerkat/voting/ui/VotingBoothUI.java b/voting-booth/src/main/java/meerkat/voting/ui/VotingBoothUI.java index ae96f7b..192dd1c 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/VotingBoothUI.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/VotingBoothUI.java @@ -3,6 +3,8 @@ package meerkat.voting.ui; import com.google.common.util.concurrent.FutureCallback; import meerkat.protobuf.Voting.*; +import java.util.List; + /** * An interface for the user interface component of the voting booth @@ -25,14 +27,14 @@ public interface VotingBoothUI { * @param questions questions to determine the right voting channel for this voter * @param callback that's where we store the answers to decide channel upon for the current voter */ - public void chooseChannel (BallotQuestion[] questions, FutureCallback callback); + public void chooseChannel (List questions, FutureCallback> callback); /** * Presents the set of questions to the voter. Collect all his responses. * @param questions all ballot questions to present to the voter * @param callback the responses to the questions collected by the UI, to send back to the controller. Responses are null if voter chose to cancel session */ - public void askVoterQuestions (BallotQuestion[] questions, FutureCallback callback); + public void askVoterQuestions (List questions, FutureCallback> callback); /** * Get a response from the voter on how to finalize the ballot. @@ -51,7 +53,7 @@ public interface VotingBoothUI { * @param message a message to show the user on the UI device while waiting * @param callback a success return value of the wait (cancelling returns false) */ - public void notifyVoterToWaitForFinish (UIElement message, FutureCallback callback); + public void notifyVoterToWaitForFinish (UIElement message, FutureCallback callback); /** * show a fatal error message in the UI. Halts system. Waits for administrator interrupt or reset diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/CastOrAuditUICommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/CastOrAuditUICommand.java index 993f64b..1b2f72f 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/CastOrAuditUICommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/CastOrAuditUICommand.java @@ -1,6 +1,6 @@ package meerkat.voting.ui.uicommands; -import meerkat.voting.controller.callbacks.ControllerCallback; +import meerkat.voting.controller.callbacks.*; /** * Created by hai on 21/04/16. diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/ChannelChoiceUICommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/ChannelChoiceUICommand.java index 22d2ff3..5ad4391 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/ChannelChoiceUICommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/ChannelChoiceUICommand.java @@ -1,22 +1,24 @@ package meerkat.voting.ui.uicommands; import meerkat.protobuf.Voting.*; -import meerkat.voting.controller.callbacks.ControllerCallback; +import meerkat.voting.controller.callbacks.*; + +import java.util.List; /** * Created by hai on 18/04/16. */ public class ChannelChoiceUICommand extends UICommand { - private final BallotQuestion[] questions; + private final List questions; - public ChannelChoiceUICommand(BallotQuestion[] questions, ControllerCallback callback) + public ChannelChoiceUICommand(List questions, ControllerCallback callback) { super(callback); this.questions = questions; } - public BallotQuestion[] getQuestions () { + public List getQuestions () { return this.questions; } } diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/FatalErrorUICommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/FatalErrorUICommand.java new file mode 100644 index 0000000..7679130 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/FatalErrorUICommand.java @@ -0,0 +1,28 @@ +package meerkat.voting.ui.uicommands; + +import meerkat.protobuf.Voting.UIElement; +import meerkat.voting.controller.callbacks.*; + +/** + * Created by hai on 18/04/16. + */ +public class FatalErrorUICommand extends UICommand { + + private final UIElement errorMessage; + private final UIElement[] buttonLabels; + + public FatalErrorUICommand(UIElement errorMessage, UIElement[] buttonLabels, ControllerCallback callback) + { + super(callback); + this.errorMessage = errorMessage; + this.buttonLabels = buttonLabels; + } + + public UIElement getErrorMessage() { + return this.errorMessage; + } + + public UIElement[] getButtonLabels() { + return this.getButtonLabels(); + } +} diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/HaltCommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/HaltCommand.java deleted file mode 100644 index 5213354..0000000 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/HaltCommand.java +++ /dev/null @@ -1,22 +0,0 @@ -package meerkat.voting.ui.uicommands; - -import meerkat.protobuf.Voting.*; -import meerkat.voting.controller.callbacks.ControllerCallback; - -/** - * Created by hai on 18/04/16. - */ -public class HaltCommand extends UICommand { - - private final UIElement errorMessage; - - public HaltCommand(UIElement errorMessage, ControllerCallback callback) - { - super(callback); - this.errorMessage = errorMessage; - } - - public UIElement getErrorMessage () { - return this.errorMessage; - } -} diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/RaceVotingUICommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/RaceVotingUICommand.java index 31d2706..6430e59 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/RaceVotingUICommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/RaceVotingUICommand.java @@ -1,22 +1,24 @@ package meerkat.voting.ui.uicommands; import meerkat.protobuf.Voting.*; -import meerkat.voting.controller.callbacks.ControllerCallback; +import meerkat.voting.controller.callbacks.*; + +import java.util.List; /** * Created by hai on 18/04/16. */ public class RaceVotingUICommand extends UICommand { - private final BallotQuestion[] questions; + private final List questions; - public RaceVotingUICommand(BallotQuestion[] questions, ControllerCallback callback) + public RaceVotingUICommand(List questions, ControllerCallback callback) { super(callback); this.questions = questions; } - public BallotQuestion[] getQuestions () { + public List getQuestions () { return this.questions; } } diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/StartSessionUICommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/StartSessionUICommand.java index f1bc146..393afa7 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/StartSessionUICommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/StartSessionUICommand.java @@ -1,6 +1,6 @@ package meerkat.voting.ui.uicommands; -import meerkat.voting.controller.callbacks.ControllerCallback; +import meerkat.voting.controller.callbacks.*; /** * Created by hai on 18/04/16. diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/TickCommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/TickCommand.java index 3192f4c..0872ea3 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/TickCommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/TickCommand.java @@ -1,6 +1,6 @@ package meerkat.voting.ui.uicommands; -import meerkat.voting.controller.callbacks.ControllerCallback; +import meerkat.voting.controller.callbacks.*; /** * Created by hai on 18/04/16. diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/UICommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/UICommand.java index b22fdef..460b7d0 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/UICommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/UICommand.java @@ -1,6 +1,6 @@ package meerkat.voting.ui.uicommands; -import meerkat.voting.controller.callbacks.ControllerCallback; +import meerkat.voting.controller.callbacks.*; //TODO: make this class generic public abstract class UICommand { diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishCommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishUICommand.java similarity index 60% rename from voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishCommand.java rename to voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishUICommand.java index fe9b1cc..5c48359 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishCommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishUICommand.java @@ -1,17 +1,17 @@ package meerkat.voting.ui.uicommands; import meerkat.protobuf.Voting.*; -import meerkat.voting.controller.callbacks.ControllerCallback; +import meerkat.voting.controller.callbacks.*; /** * Created by hai on 18/04/16. */ -public class WaitForFinishCommand extends UICommand { +public class WaitForFinishUICommand extends UICommand { private final UIElement message; - public WaitForFinishCommand(UIElement message, ControllerCallback callback) + public WaitForFinishUICommand(UIElement message, ControllerCallback callback) { super(callback); this.message = message;