From 218677fd96d2c7ae93baf223bd40b56aed656106 Mon Sep 17 00:00:00 2001 From: Hai Brenner Date: Mon, 4 Jul 2016 14:17:11 +0300 Subject: [PATCH] added many comments and JavaDocs --- .../output/outputcommands/OutputCommand.java | 2 + .../voting/storage/StorageManager.java | 2 +- .../voting/storage/StorageManagerMockup.java | 10 +- .../meerkat/voting/ui/SystemConsoleUI.java | 126 ++++++++++++++++-- .../meerkat/voting/ui/TickerTimerTask.java | 2 +- .../java/meerkat/voting/ui/VotingBoothUI.java | 5 +- .../ui/uicommands/CastOrAuditUICommand.java | 2 +- .../ui/uicommands/ChannelChoiceUICommand.java | 2 +- .../ui/uicommands/FatalErrorUICommand.java | 2 +- .../ui/uicommands/RaceVotingUICommand.java | 2 +- .../ui/uicommands/StartSessionUICommand.java | 2 +- .../voting/ui/uicommands/TickCommand.java | 3 +- .../voting/ui/uicommands/UICommand.java | 4 + .../ui/uicommands/WaitForFinishUICommand.java | 3 +- 14 files changed, 142 insertions(+), 25 deletions(-) diff --git a/voting-booth/src/main/java/meerkat/voting/output/outputcommands/OutputCommand.java b/voting-booth/src/main/java/meerkat/voting/output/outputcommands/OutputCommand.java index 7085380..342c314 100644 --- a/voting-booth/src/main/java/meerkat/voting/output/outputcommands/OutputCommand.java +++ b/voting-booth/src/main/java/meerkat/voting/output/outputcommands/OutputCommand.java @@ -2,6 +2,8 @@ package meerkat.voting.output.outputcommands; import meerkat.voting.controller.callbacks.ControllerCallback; +//TODO: make this class generic + /** * Base class for the commands to put in the output-device queue */ diff --git a/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java b/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java index b9ccca7..4a70f79 100644 --- a/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java +++ b/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java @@ -33,7 +33,7 @@ public interface StorageManager { public Map readSystemMessages() throws IOException; - + // These are just static key identifiers for accessing the matching System Messages in the message map public final static String WAIT_FOR_COMMIT_MESSAGE = "waitForCommit"; public final static String WAIT_FOR_AUDIT_MESSAGE = "waitForAudit"; public final static String WAIT_FOR_CAST_MESSAGE = "waitForCast"; diff --git a/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java b/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java index ea9ac08..f556e3b 100644 --- a/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java +++ b/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java @@ -1,6 +1,5 @@ package meerkat.voting.storage; -import com.google.protobuf.ByteString; import meerkat.protobuf.Voting.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -8,7 +7,6 @@ import org.slf4j.LoggerFactory; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.util.HashMap; import java.util.Map; /** @@ -17,13 +15,15 @@ import java.util.Map; */ public class StorageManagerMockup implements StorageManager { - private boolean adminHardwareKeyInserted; - private Logger logger; + private static final Logger logger = LoggerFactory.getLogger(StorageManagerMockup.class); + public static final String electionParamFullFilename = "/home/hai/meerkat-java/meerkat_election_params_tempfile.dat"; public static final String systemMessagesFilename = "/home/hai/meerkat-java/meerkat_booth_system_messages.dat"; + private boolean adminHardwareKeyInserted; + + public StorageManagerMockup () { - logger = LoggerFactory.getLogger(StorageManagerMockup.class); logger.info("A StorageManagerMockup is constructed"); this.adminHardwareKeyInserted = false; } 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 b8a3828..c4f0e83 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/SystemConsoleUI.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/SystemConsoleUI.java @@ -18,20 +18,24 @@ import org.slf4j.LoggerFactory; import static java.lang.System.in; +/** + * an asynchronous thread implementation of the VotingBoothUI interface + * This is a mock-up implementation using just the console as our UI device + */ public class SystemConsoleUI implements VotingBoothUI, Runnable { + private static final Logger logger = LoggerFactory.getLogger(SystemConsoleUI.class); + private BufferedReader bufferedReader; private LinkedBlockingQueue queue; - private final Logger logger; - private final int tickDurationInMillisec = 10; private Date startWaitingTime; private volatile boolean shutDownHasBeenCalled; - public SystemConsoleUI() { - logger = LoggerFactory.getLogger(SystemConsoleUI.class); + final int tickDurationInMillisec = 10; // period between view update calls + logger.info("A VB UI console is constructed"); queue = new LinkedBlockingQueue<>(); bufferedReader = new BufferedReader(new InputStreamReader(in)); @@ -44,6 +48,9 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } + /** + * the run() method. Simply loops and takes commands from the UI's queue and handles them accordingly + */ @Override public void run () { logger.info("UI starts running"); @@ -66,6 +73,13 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { queue.clear(); } + /** + * chooses the next method to run according to the type of the given UICommand. + * Special case for the TickCommand. + * As this command is registered in the queue constantly, we simply ignore this command if the UI is not in + * a waiting state + * @param command any valid UICommand + */ private void handleSingleCommand(UICommand command) { if (!(command instanceof TickCommand)) { if (startWaitingTime != null) { @@ -103,12 +117,20 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } + /** + * start a new session by registering a StartSessionUICommand + * @param callback - a boolean future callback to return when done + */ @Override public void startNewVoterSession(FutureCallback callback) { logger.debug("UI interface call to startNewVoterSession"); queue.add(new StartSessionUICommand((ControllerCallback)callback)); } + /** + * welcomes the new voter at the beginning of the session + * @param command a StartSessionUICommand with a acallback + */ private void doShowWelcomeScreen(StartSessionUICommand command) { logger.debug("UI entered doShowWelcomeScreen"); System.out.println("Welcome, new voter!"); @@ -118,11 +140,19 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { callback.onSuccess(null); } + /** + * marks that the waiting, for something else to have happened, is finished + */ private void stopWaiting () { System.out.println (); startWaitingTime = null; } + + /** + * waits until the ENTER key is pressed in the console + * @param message a message to show the user in the console + */ private void waitForEnter(String message) { if (message != null) { System.out.println(message); @@ -141,6 +171,11 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } } + /** + * call for the channel choice phase by registering a ChannelChoiceUICommand in the queue + * @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 + */ @Override public void chooseChannel(List questions, FutureCallback> callback) { logger.debug("UI interface call to chooseChannel"); @@ -148,6 +183,10 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { queue.add(command); } + /** + * lists the channel choice questions to the voter and gathers the voter's answers + * @param command a ChannelChoiceUICommand with the data and a callback + */ private void doAskChannelChoiceQuestions (ChannelChoiceUICommand command) { logger.debug("UI: doAskChannelChoiceQuestions"); System.out.println("Showing questions for choosing channel:\n"); @@ -166,12 +205,21 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } } + /** + * call for the race voting question phase by registering a RaceVotingUICommand in the queue + * @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 + */ @Override public void askVoterQuestions(List questions, FutureCallback> callback) { logger.debug("UI interface call to chooseChannel"); queue.add(new RaceVotingUICommand(questions, (ControllerCallback)callback)); } + /** + * lists the race voting questions to the voter and gathers the voter's answers + * @param command a RaceVotingUICommand with a callback + */ private void doAskVotingQuestions (RaceVotingUICommand command) { logger.debug("UI: doAskVotingQuestions"); System.out.println("Showing questions for race voting:\n"); @@ -190,12 +238,20 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } } + /** + * call for the cast-or-audit phase by registering a CastOrAuditUICommand in the queue + * @param callback the returned choice of how to finalize the ballot + */ @Override public void castOrAudit(FutureCallback callback) { logger.debug("UI interface call to castOrAudit"); queue.add(new CastOrAuditUICommand((ControllerCallback)callback)); } + /** + * asks the voter whether to cast or audit the ballot + * @param command a simple CastOrAuditUICommand with the callback + */ 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?"); @@ -225,12 +281,21 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } + /** + * makes the UI (and voter) wait for something else to happen, by registering a WaitForFinishUICommand in the queue + * @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) + */ @Override public void notifyVoterToWaitForFinish(UIElement message, FutureCallback callback) { logger.debug("UI interface call to notifyVoterToWaitForFinish"); queue.add(new WaitForFinishUICommand(message, (ControllerCallback)callback)); } + /** + * Tells the voter (in the console) to wait until some other process is finished + * @param command a simple WaitForFinishUICommand with the callback + */ public void doWaitForFinish (WaitForFinishUICommand command) { logger.debug("UI entered doWaitForFinish"); @@ -247,13 +312,23 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { System.out.print ("Waiting : ."); } + /** + * show an error to the voter. Halts the system until a technician handles it + * @param errorMessage message to show in UI device + * @param callback returns interrupt + */ @Override public void showErrorMessageAndHalt(UIElement errorMessage, FutureCallback callback) { logger.debug("UI interface call to showErrorMessageAndHalt"); throw new UnsupportedOperationException("Not implemented becuase currently not sure if we ever use it."); } - + /** + * show an error to the voter. let him press a (chosen) button for handling the error. + * @param errorMessage message to show in UI device + * @param buttonLabels labels for buttons to present to voter + * @param callback the number of the selected button + */ @Override public void showErrorMessageWithButtons(UIElement errorMessage, UIElement[] buttonLabels, FutureCallback callback) { logger.debug("UI interface call to showErrorMessageWithButtons"); @@ -261,6 +336,10 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { queue.add(new FatalErrorUICommand(errorMessage, buttonLabels, (ControllerCallback)callback)); } + /** + * show an error to the voter. let him press a (chosen) button for handling the error. + * @param command a FatalErrorUICommand with the callback + */ private void doFatalError (FatalErrorUICommand command) { logger.debug("UI entered doFatalError"); @@ -301,12 +380,20 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } + /** + * this method is run when a TickCommand was received while in waiting state + */ private void doTick () { if (startWaitingTime != null) { System.out.print ("."); // still waiting } } + /** + * get an input line from the console + * @return a line from the voter + * @throws IOException + */ private String readInputLine() throws IOException{ String s; try { @@ -323,6 +410,11 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } + /** + * asserts that the question data matches the types that we can handle in the ConsoleUI + * (better and more sophisticated UI will be able to handle more types of data) + * @param questions list of the questions + */ private void assertQuestionsAreValid (List questions) { for (int index = 0; index < questions.size(); ++index) { BallotQuestion question = questions.get(index); @@ -339,6 +431,15 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } } + + /** + * present the questions to the voter console sequentially. + * Voter may choose at any time to skip a question, go back or even cancel the whole session + * @param questions list of questions to present + * @return list of answers to the questions (at the same order) + * @throws VoterCancelThrowable this is thrown if a voter chose to cancel in the middle of the process + * @throws IOException + */ private List askVoterForAnswers(List questions) throws VoterCancelThrowable, IOException { assertQuestionsAreValid (questions); @@ -348,7 +449,7 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { while (index < questions.size()) { BallotQuestion question = questions.get(index); System.out.println("Question number " + index); - showQuestionOnScreen(question); + showQuestionInConsole(question); System.out.println("UI screen: Enter your answer. You can also type '(b)ack' or '(c)ancel' or '(s)kip"); String s = readInputLine(); @@ -372,8 +473,11 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { return answers; } - //show question on the screen for the voter - private void showQuestionOnScreen(BallotQuestion question) { + /** + * present a question in the console to the voter + * @param question a text ballot question + */ + private void showQuestionInConsole(BallotQuestion question) { if (!isQuestionOnlyText(question)) { System.err.println("debug: an element in question is not of TEXT type"); throw new UnsupportedOperationException(); @@ -388,6 +492,11 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { } } + /** + * checks whether the data of the question is only text. This is the only type we can handle in ConsoleUI + * @param question a ballot question to check + * @return True if the question data is only text + */ private boolean isQuestionOnlyText (BallotQuestion question) { boolean isText = true; if (question.getQuestion().getType() != UIElementDataType.TEXT @@ -424,5 +533,4 @@ public class SystemConsoleUI implements VotingBoothUI, Runnable { return shutDownHasBeenCalled; } - } diff --git a/voting-booth/src/main/java/meerkat/voting/ui/TickerTimerTask.java b/voting-booth/src/main/java/meerkat/voting/ui/TickerTimerTask.java index a293e5f..594fb6e 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/TickerTimerTask.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/TickerTimerTask.java @@ -7,7 +7,7 @@ import java.util.TimerTask; import java.util.concurrent.LinkedBlockingQueue; /** - * Created by hai on 25/04/16. + * A thread that sends the UI clock TickCommands in a given constant frequency */ class TickerTimerTask extends TimerTask { private LinkedBlockingQueue uiQueue; 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 fccb28e..c4e1f1e 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/VotingBoothUI.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/VotingBoothUI.java @@ -7,10 +7,13 @@ import java.util.List; /** - * An interface for the user interface component of the voting booth + * An interface for the UI component of the voting booth */ public interface VotingBoothUI { + /** + * a simple enum for the voter's finalize choice + */ public enum FinalizeBallotChoice { CAST, AUDIT 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 1b2f72f..6e18b0b 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 @@ -3,7 +3,7 @@ package meerkat.voting.ui.uicommands; import meerkat.voting.controller.callbacks.*; /** - * Created by hai on 21/04/16. + * This command signals the UI that the voter should now choose whether to Cast or Audit the ballot */ public class CastOrAuditUICommand extends UICommand { public CastOrAuditUICommand(ControllerCallback callback) { 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 5ad4391..f225ea6 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 @@ -6,7 +6,7 @@ import meerkat.voting.controller.callbacks.*; import java.util.List; /** - * Created by hai on 18/04/16. + * This command signals the UI to present channel choice questions to the voter and send back the answers */ public class ChannelChoiceUICommand extends UICommand { 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 index 7679130..1d47700 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/FatalErrorUICommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/FatalErrorUICommand.java @@ -4,7 +4,7 @@ import meerkat.protobuf.Voting.UIElement; import meerkat.voting.controller.callbacks.*; /** - * Created by hai on 18/04/16. + * This command signals the UI that a fatal error occurred and it should notify the voter */ public class FatalErrorUICommand extends UICommand { 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 6430e59..6b181e6 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 @@ -6,7 +6,7 @@ import meerkat.voting.controller.callbacks.*; import java.util.List; /** - * Created by hai on 18/04/16. + * This command signals the UI to present the race voting questions to the voter */ public class RaceVotingUICommand extends UICommand { 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 393afa7..d99313e 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 @@ -3,7 +3,7 @@ package meerkat.voting.ui.uicommands; import meerkat.voting.controller.callbacks.*; /** - * Created by hai on 18/04/16. + * This command signals the UI to present a new session to a voter */ public class StartSessionUICommand extends UICommand { 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 0872ea3..2e2d033 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 @@ -3,7 +3,8 @@ package meerkat.voting.ui.uicommands; import meerkat.voting.controller.callbacks.*; /** - * Created by hai on 18/04/16. + * This is a special UI command which just points out that a tick of the clock occurred + * (so a progress bar can advance while waiting) */ public class TickCommand extends UICommand { 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 460b7d0..4ac47a8 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 @@ -3,6 +3,10 @@ package meerkat.voting.ui.uicommands; import meerkat.voting.controller.callbacks.*; //TODO: make this class generic + +/** + * Base class for the commands to put in the UI queue + */ public abstract class UICommand { protected final ControllerCallback callback; diff --git a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishUICommand.java b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishUICommand.java index 5c48359..7006014 100644 --- a/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishUICommand.java +++ b/voting-booth/src/main/java/meerkat/voting/ui/uicommands/WaitForFinishUICommand.java @@ -4,9 +4,8 @@ import meerkat.protobuf.Voting.*; import meerkat.voting.controller.callbacks.*; /** - * Created by hai on 18/04/16. + * This command signals the UI to wait with an appropriate message until a new command replaces this state */ - public class WaitForFinishUICommand extends UICommand { private final UIElement message;