Just added comments as part of the process to comment all the VB files.
Currently I commented the controller callbacks and commands packages, and also the QuestionSelector component.vbdev2
parent
e9732561f4
commit
42ae18df00
|
@ -2,13 +2,16 @@ package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import meerkat.protobuf.Voting.UIElement;
|
import meerkat.protobuf.Voting.UIElement;
|
||||||
import meerkat.voting.controller.commands.*;
|
import meerkat.voting.controller.commands.*;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
|
||||||
import meerkat.voting.ui.VotingBoothUI.*;
|
import meerkat.voting.ui.VotingBoothUI.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller callback for the cast-or-audit request to the UI.
|
||||||
|
* Upon getting a FinalizeBallotChoice response from the voter, the callback then registers a new command
|
||||||
|
* to the controller queue, either a CastCommand or an AuditCommand according to the voter's choice
|
||||||
|
*/
|
||||||
public class CastOrAuditCallback extends ControllerCallback<FinalizeBallotChoice> {
|
public class CastOrAuditCallback extends ControllerCallback<FinalizeBallotChoice> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(CastOrAuditCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(CastOrAuditCallback.class);
|
||||||
protected final UIElement unrecognizedFinalizeResponseMessage;
|
protected final UIElement unrecognizedFinalizeResponseMessage;
|
||||||
|
@ -31,9 +34,7 @@ public class CastOrAuditCallback extends ControllerCallback<FinalizeBallotChoice
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.error("CastOrAuditCallback got an unrecognized response: " + result);
|
logger.error("CastOrAuditCallback got an unrecognized response: " + result);
|
||||||
enqueueCommand(new ReportErrorCommand(getRequestIdentifier(),
|
onFailure(new IllegalArgumentException("CastOrAuditCallback got an unknown result (" + result + ")"));
|
||||||
getBallotSerialNumber(),
|
|
||||||
unrecognizedFinalizeResponseMessage));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,15 @@ import meerkat.protobuf.Voting.*;
|
||||||
import meerkat.voting.controller.commands.*;
|
import meerkat.voting.controller.commands.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 11/04/16.
|
* A controller callback for the channel-choice request to the UI.
|
||||||
|
* Upon receiving the answers for the channel-choice questions, the callback registers a new ChannelDeterminedCommand
|
||||||
|
* to the controller queue, so the controller can then process the answers and set the channel.
|
||||||
|
* If voter cancelled during the process, a cancelling exception is thrown and a RestartVotingCommand is
|
||||||
|
* registered through the onFailure() method
|
||||||
*/
|
*/
|
||||||
public class ChannelChoiceCallback extends ControllerCallback<List<BallotAnswer>> {
|
public class ChannelChoiceCallback extends ControllerCallback<List<BallotAnswer>> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(ChannelChoiceCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(ChannelChoiceCallback.class);
|
||||||
|
@ -26,12 +29,14 @@ public class ChannelChoiceCallback extends ControllerCallback<List<BallotAnswer>
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<BallotAnswer> result) {
|
public void onSuccess(List<BallotAnswer> result) {
|
||||||
logger.debug("callback for channel choice returned success");
|
logger.debug("callback for channel choice returned success");
|
||||||
|
// register the chosen BallotAnswers to a command in the controller queue
|
||||||
enqueueCommand(new ChannelDeterminedCommand(getRequestIdentifier(), getBallotSerialNumber(), result));
|
enqueueCommand(new ChannelDeterminedCommand(getRequestIdentifier(), getBallotSerialNumber(), result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable t) {
|
||||||
if (t instanceof VoterCancelException) {
|
if (t instanceof VoterCancelException) {
|
||||||
|
// voter has cancelled during the UI channel choice process. A VoterCancelException is thrown
|
||||||
logger.debug("ChannelChoiceCallback got a cancellation response");
|
logger.debug("ChannelChoiceCallback got a cancellation response");
|
||||||
enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by hai on 18/05/16.
|
|
||||||
*/
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
import meerkat.voting.controller.commands.ControllerCommand;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base (abstract) class of all callbacks for requests sent by the controller to other components (ui, output-device)
|
||||||
|
* It implements the FutureCallback interface
|
||||||
|
* Its members are:
|
||||||
|
* - requestIdentifier - uniquely identifies the request which this callback responds
|
||||||
|
* - ballotSerialNumber - number of ballot which was currently active when request was sent
|
||||||
|
* - controllerQueue - so the callback can issue and register a new command to the controller, once the request handling is finished
|
||||||
|
*/
|
||||||
public abstract class ControllerCallback<T> implements FutureCallback<T> {
|
public abstract class ControllerCallback<T> implements FutureCallback<T> {
|
||||||
|
|
||||||
private final int requestIdentifier;
|
private final int requestIdentifier;
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
|
import meerkat.voting.controller.commands.*;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
|
||||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
|
||||||
import meerkat.voting.controller.commands.RetryEncryptAndCommitBallotCommand;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is quite a special callback. It is not issued in a normal flow of the voting.
|
||||||
|
* This callback is made only for a request to the UI to choose handling of failure in encryption.
|
||||||
|
* When encryption/signature fails the voter is asked in the UI whether to retry or abort.
|
||||||
|
* This specific callback decides, upon the answer to this request, which command to register in the controller's queue
|
||||||
|
*/
|
||||||
public class EncryptionFailedCallback extends ControllerCallback<Integer> {
|
public class EncryptionFailedCallback extends ControllerCallback<Integer> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(EncryptionFailedCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(EncryptionFailedCallback.class);
|
||||||
|
|
||||||
|
@ -20,18 +22,18 @@ public class EncryptionFailedCallback extends ControllerCallback<Integer> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Integer result) {
|
public void onSuccess(Integer result) {
|
||||||
logger.debug("callback for voting returned success");
|
logger.debug("callback for encryption-failed request is initiated successfully");
|
||||||
int res = result.intValue();
|
int res = result.intValue();
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
logger.debug("voter chose to retry encryption");
|
logger.debug("voter chose to retry encryption");
|
||||||
enqueueCommand(new RetryEncryptAndCommitBallotCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
enqueueCommand(new RetryEncryptAndCommitBallotCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
||||||
}
|
}
|
||||||
else if (res == 1) {
|
else if (res == 1) {
|
||||||
logger.debug("voter chose to cancel the vote");
|
logger.debug("voter chose to abort the vote");
|
||||||
enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
onFailure(new ValueException("EncryptionFailedCallback got an unknown result (" + res + ")"));
|
onFailure(new IllegalArgumentException("EncryptionFailedCallback got an unknown result (" + res + ")"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
import meerkat.voting.controller.commands.*;
|
||||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is quite a special callback. It is not issued in a normal flow of the voting.
|
||||||
|
* This callback is made only for a request to the UI to show the voter an error message.
|
||||||
|
* Upon approval of the voter, the method onSuccess() of this callback is called, and the voting
|
||||||
|
* is reset through a command to the controller's queue
|
||||||
|
*/
|
||||||
public class ErrorMessageRestartCallback extends ControllerCallback<Integer> {
|
public class ErrorMessageRestartCallback extends ControllerCallback<Integer> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(ErrorMessageRestartCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(ErrorMessageRestartCallback.class);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import meerkat.voting.controller.commands.ChannelChoiceCommand;
|
import meerkat.voting.controller.commands.*;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
|
||||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller callback for the StartSession request to the UI.
|
||||||
|
* Upon approval of the voter, it registers a new ChannelChoiceCommand to the controller queue (which
|
||||||
|
* then starts the channel choice process)
|
||||||
|
*/
|
||||||
public class NewVoterCallback extends ControllerCallback<Void> {
|
public class NewVoterCallback extends ControllerCallback<Void> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(NewVoterCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(NewVoterCallback.class);
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import meerkat.protobuf.Voting.UIElement;
|
import meerkat.protobuf.Voting.UIElement;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
import meerkat.voting.controller.commands.*;
|
||||||
import meerkat.voting.controller.commands.ChooseFinalizeOptionCommand;
|
|
||||||
import meerkat.voting.controller.commands.ReportErrorCommand;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller callback for the Commit request to the output-device.
|
||||||
|
* When committing is done, the callback's onSuccess() method is called to register a new ChooseFinalizeOptionCommand
|
||||||
|
* to the controller
|
||||||
|
*/
|
||||||
public class OutputDeviceCommitCallback extends ControllerCallback<Void> {
|
public class OutputDeviceCommitCallback extends ControllerCallback<Void> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceCommitCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceCommitCallback.class);
|
||||||
protected final UIElement outputDeviceFailureMessage;
|
protected final UIElement outputDeviceFailureMessage;
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import meerkat.protobuf.Voting.UIElement;
|
import meerkat.protobuf.Voting.UIElement;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
import meerkat.voting.controller.commands.*;
|
||||||
import meerkat.voting.controller.commands.ReportErrorCommand;
|
|
||||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller callback for the Finalize request to the output-device.
|
||||||
|
* When finalizing (either cast or audit) is done,
|
||||||
|
* the callback's onSuccess() method is called to register a new command to the controller to restart the voting process
|
||||||
|
*/
|
||||||
public class OutputDeviceFinalizeCallback extends ControllerCallback<Void> {
|
public class OutputDeviceFinalizeCallback extends ControllerCallback<Void> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceFinalizeCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceFinalizeCallback.class);
|
||||||
protected final UIElement outputDeviceFailureMessage;
|
protected final UIElement outputDeviceFailureMessage;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 06/06/16.
|
* Just a simple unique exception to throw when a voter aborts/cancels the voting during the voting process
|
||||||
*/
|
*/
|
||||||
public class VoterCancelException extends Exception{
|
public class VoterCancelException extends Exception {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import meerkat.protobuf.Voting.*;
|
import meerkat.protobuf.Voting.*;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
import meerkat.voting.controller.commands.*;
|
||||||
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller callback for the race-voting request to the UI.
|
||||||
|
* Upon receiving the answers for the race questions, the callback registers a new command to process
|
||||||
|
* the voter's answers (encrypt and then commit) into the controller's queue.
|
||||||
|
* If voter cancelled during the process, a cancelling exception is thrown and a RestartVotingCommand is
|
||||||
|
* registered through the onFailure() method
|
||||||
|
*/
|
||||||
public class VotingCallback extends ControllerCallback<List<BallotAnswer>> {
|
public class VotingCallback extends ControllerCallback<List<BallotAnswer>> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(VotingCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(VotingCallback.class);
|
||||||
protected final UIElement unsuccessfulVotingMessage;
|
protected final UIElement unsuccessfulVotingMessage;
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package meerkat.voting.controller.callbacks;
|
package meerkat.voting.controller.callbacks;
|
||||||
|
|
||||||
import meerkat.protobuf.Voting.UIElement;
|
import meerkat.protobuf.Voting.UIElement;
|
||||||
import meerkat.voting.controller.commands.ControllerCommand;
|
import meerkat.voting.controller.commands.*;
|
||||||
import meerkat.voting.controller.commands.ReportErrorCommand;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This callback is attached to requests to UI which ask the voter to wait for some process to finish.
|
||||||
|
* It actually asks nothing in the UI, and it is simply attached to the UI request as a place-holder.
|
||||||
|
* Therefore its onSuccess() method is empty
|
||||||
|
*/
|
||||||
public class WaitForFinishCallback extends ControllerCallback<Void> {
|
public class WaitForFinishCallback extends ControllerCallback<Void> {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(WaitForFinishCallback.class);
|
protected final static Logger logger = LoggerFactory.getLogger(WaitForFinishCallback.class);
|
||||||
protected final UIElement somethingWrongMessage;
|
protected final UIElement somethingWrongMessage;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package meerkat.voting.controller.commands;
|
package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 11/04/16.
|
* a command to audit the ballot
|
||||||
*/
|
*/
|
||||||
public class AuditCommand extends ControllerCommand {
|
public class AuditCommand extends ControllerCommand {
|
||||||
public AuditCommand(int requestIdentifier, long ballotSerialNumber) {
|
public AuditCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package meerkat.voting.controller.commands;
|
package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 11/04/16.
|
* a command to cast the ballot
|
||||||
*/
|
*/
|
||||||
public class CastCommand extends ControllerCommand {
|
public class CastCommand extends ControllerCommand {
|
||||||
public CastCommand(int requestIdentifier, long ballotSerialNumber) {
|
public CastCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package meerkat.voting.controller.commands;
|
package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 11/04/16.
|
* a command to initiate the channel choice flow at the beginning of the voting
|
||||||
*/
|
*/
|
||||||
public class ChannelChoiceCommand extends ControllerCommand {
|
public class ChannelChoiceCommand extends ControllerCommand {
|
||||||
public ChannelChoiceCommand(int requestIdentifier, long ballotSerialNumber) {
|
public ChannelChoiceCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import meerkat.protobuf.Voting.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 11/04/16.
|
* This command is registered in the controller right after the voter answered all the channel choice questions
|
||||||
*/
|
*/
|
||||||
public class ChannelDeterminedCommand extends ControllerCommand {
|
public class ChannelDeterminedCommand extends ControllerCommand {
|
||||||
public List<BallotAnswer> channelChoiceAnswers;
|
public List<BallotAnswer> channelChoiceAnswers;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package meerkat.voting.controller.commands;
|
package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 11/04/16.
|
* a command to initiate asking the voter how to finalize (cast-or-audit) the ballot
|
||||||
*/
|
*/
|
||||||
public class ChooseFinalizeOptionCommand extends ControllerCommand {
|
public class ChooseFinalizeOptionCommand extends ControllerCommand {
|
||||||
public ChooseFinalizeOptionCommand(int requestIdentifier, long ballotSerialNumber) {
|
public ChooseFinalizeOptionCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package meerkat.voting.controller.commands;
|
package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the base class for the controller commands.
|
||||||
|
* These commands are registered in a command queue of the controller.
|
||||||
|
*/
|
||||||
public abstract class ControllerCommand {
|
public abstract class ControllerCommand {
|
||||||
protected final int requestIdentifier;
|
protected final int requestIdentifier;
|
||||||
protected final long ballotSerialNumber;
|
protected final long ballotSerialNumber;
|
||||||
|
|
|
@ -3,6 +3,10 @@ package meerkat.voting.controller.commands;
|
||||||
import meerkat.protobuf.Voting.BallotAnswer;
|
import meerkat.protobuf.Voting.BallotAnswer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a command registered after voter answered all ballot questions.
|
||||||
|
* The controller then initiates an encryption-signature-commit flow
|
||||||
|
*/
|
||||||
public class EncryptAndCommitBallotCommand extends ControllerCommand {
|
public class EncryptAndCommitBallotCommand extends ControllerCommand {
|
||||||
private final List<BallotAnswer> votingAnswers;
|
private final List<BallotAnswer> votingAnswers;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@ package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
import meerkat.protobuf.Voting.*;
|
import meerkat.protobuf.Voting.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command is not a part of the normal flow of the controller.
|
||||||
|
* It asks the controller to handle (report to voter) some error message
|
||||||
|
*/
|
||||||
public class ReportErrorCommand extends ControllerCommand {
|
public class ReportErrorCommand extends ControllerCommand {
|
||||||
private final UIElement errorMessage;
|
private final UIElement errorMessage;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package meerkat.voting.controller.commands;
|
package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a command to restart a voting flow (for a new voter)
|
||||||
|
*/
|
||||||
public class RestartVotingCommand extends ControllerCommand {
|
public class RestartVotingCommand extends ControllerCommand {
|
||||||
public RestartVotingCommand(int requestIdentifier, long ballotSerialNumber) {
|
public RestartVotingCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||||
super(requestIdentifier, ballotSerialNumber);
|
super(requestIdentifier, ballotSerialNumber);
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package meerkat.voting.controller.commands;
|
package meerkat.voting.controller.commands;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is quite a special command not part of the normal voting flow.
|
||||||
|
* It extends the base EncryptAndCommitBallotCommand for occasions where first attempt of encryption failed
|
||||||
|
* and the voter asks to re-try encrypting and committing.
|
||||||
|
*/
|
||||||
public class RetryEncryptAndCommitBallotCommand extends EncryptAndCommitBallotCommand {
|
public class RetryEncryptAndCommitBallotCommand extends EncryptAndCommitBallotCommand {
|
||||||
|
|
||||||
public RetryEncryptAndCommitBallotCommand(int requestIdentifier,
|
public RetryEncryptAndCommitBallotCommand(int requestIdentifier,
|
||||||
|
|
|
@ -4,12 +4,26 @@ import meerkat.protobuf.Voting.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hai on 02/05/16.
|
* An interface for the question-selection component.
|
||||||
|
* This component handles the connection between the channel choice questions and the race questions.
|
||||||
|
* It gets the answers for the channel choice questions and determines which race question to put in the voter's ballot.
|
||||||
|
* It also creates an identifier for this chosen channel. This identifier should appear in the plaintext of the ballot.
|
||||||
|
* The channel identifier does not identify a specific voter, but rather it identifies a specific voting channel
|
||||||
*/
|
*/
|
||||||
public interface QuestionSelector {
|
public interface QuestionSelector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines an identifier for the channel of the voter
|
||||||
|
* @param channelChoiceAnswers The answers given by the voter to the channel choice questions
|
||||||
|
* @return an identifier of the channel. To be used by selectQuestionsForVoter(). This identifier should also appear on the plaintext of the ballot
|
||||||
|
*/
|
||||||
public byte[] getChannelIdentifier (List<BallotAnswer> channelChoiceAnswers);
|
public byte[] getChannelIdentifier (List<BallotAnswer> channelChoiceAnswers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines which race questions to present to the voter according to its channel
|
||||||
|
* @param channelIdentifier the identifier of this specific channel
|
||||||
|
* @return the race questions (to present to the voter)
|
||||||
|
*/
|
||||||
public List<BallotQuestion> selectQuestionsForVoter (byte[] channelIdentifier);
|
public List<BallotQuestion> selectQuestionsForVoter (byte[] channelIdentifier);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,28 +11,47 @@ import java.lang.Math;
|
||||||
/**
|
/**
|
||||||
* A simple implementation of a QuestionSelector.
|
* A simple implementation of a QuestionSelector.
|
||||||
* This implementation simply regards every single answer in the channel choice phase as an identifier of a category
|
* 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.
|
* Every category is an array of ballot race questions.
|
||||||
* Data of categories is initialized and stored by a SimpleCategoriesSelectionData protobuf.
|
* Data of categories is initialized and stored by a SimpleCategoriesSelectionData protobuf.
|
||||||
* After receiving the answers from a channel choice phase, this class simply gathers all the categories
|
* 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
|
* 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)
|
* is included in the ballot if its index appears in any chosen category, or in the default category shared by all voters)
|
||||||
*/
|
*/
|
||||||
public class SimpleListCategoriesSelector implements QuestionSelector {
|
public class SimpleListCategoriesSelector implements QuestionSelector {
|
||||||
protected final static Logger logger = LoggerFactory.getLogger(SimpleListCategoriesSelector.class);
|
protected final static Logger logger = LoggerFactory.getLogger(SimpleListCategoriesSelector.class);
|
||||||
|
|
||||||
|
// all the possible race questions
|
||||||
private final BallotQuestion[] allBallotQuestions;
|
private final BallotQuestion[] allBallotQuestions;
|
||||||
|
|
||||||
|
// this category is presented to any voter (regardless of his answers to the channel choice questions)
|
||||||
private final int[] sharedDefaults;
|
private final int[] sharedDefaults;
|
||||||
|
|
||||||
|
// all the categories.
|
||||||
|
// first index is the channel choice question number
|
||||||
|
// second index is a possible answer to this question
|
||||||
|
// categoryChoosers[questionNumber][answerNumber] is an array of indices (to the ballotQuestions array).
|
||||||
|
// This category of questions is included in the ballot if voter answered this specific answer to this channel choice question
|
||||||
private final int[][][] categoryChoosers;
|
private final int[][][] categoryChoosers;
|
||||||
|
|
||||||
|
|
||||||
private final static byte QUESTION_SELECTED = (byte)1;
|
private final static byte QUESTION_SELECTED = (byte)1;
|
||||||
private final static byte QUESTION_NOT_SELECTED = (byte)0;
|
private final static byte QUESTION_NOT_SELECTED = (byte)0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A very straight-forward constructor for the SimpleListCategoriesSelector
|
||||||
|
* @param allBallotQuestions all possible race questions for this election
|
||||||
|
* @param data a protobuf containing all the index categories
|
||||||
|
*/
|
||||||
public SimpleListCategoriesSelector(List<BallotQuestion> allBallotQuestions, SimpleCategoriesSelectionData data) {
|
public SimpleListCategoriesSelector(List<BallotQuestion> allBallotQuestions, SimpleCategoriesSelectionData data) {
|
||||||
|
// copies the ballot race question list into a member array
|
||||||
this.allBallotQuestions = new BallotQuestion[allBallotQuestions.size()];
|
this.allBallotQuestions = new BallotQuestion[allBallotQuestions.size()];
|
||||||
allBallotQuestions.toArray(this.allBallotQuestions);
|
allBallotQuestions.toArray(this.allBallotQuestions);
|
||||||
|
|
||||||
|
// copies the shared category list (as appears in the protobuf data) into a member array
|
||||||
sharedDefaults = listToIntArray(data.getSharedDefaults().getQuestionIndexList());
|
sharedDefaults = listToIntArray(data.getSharedDefaults().getQuestionIndexList());
|
||||||
|
|
||||||
|
// copies the category lists (as appear in the protobuf data) into a 3-dimensional member array
|
||||||
int[][][] selectionDataTmp = new int[data.getCategoryChooserList().size()][][];
|
int[][][] selectionDataTmp = new int[data.getCategoryChooserList().size()][][];
|
||||||
int channelChoiceQuestionNumber = 0;
|
int channelChoiceQuestionNumber = 0;
|
||||||
for (CategoryChooser catChooser: data.getCategoryChooserList()) {
|
for (CategoryChooser catChooser: data.getCategoryChooserList()) {
|
||||||
|
@ -45,12 +64,21 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
||||||
++channelChoiceQuestionNumber;
|
++channelChoiceQuestionNumber;
|
||||||
}
|
}
|
||||||
categoryChoosers = selectionDataTmp;
|
categoryChoosers = selectionDataTmp;
|
||||||
|
|
||||||
|
// verifies in advance that there are not very suspicious indices in the selection data
|
||||||
assertDataValid();
|
assertDataValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* asserts that the selection data does not contain a question index which is beyond the length of
|
||||||
|
* the ballot race questions array. Otherwise, throws an IndexOutOfBoundsException
|
||||||
|
*/
|
||||||
private void assertDataValid () {
|
private void assertDataValid () {
|
||||||
int questionsLength = allBallotQuestions.length;
|
// find the maximum question index in the selection data
|
||||||
int maxQuestionIndex = -1;
|
int maxQuestionIndex = -1;
|
||||||
|
for (int index: sharedDefaults) {
|
||||||
|
maxQuestionIndex = Math.max(maxQuestionIndex, index);
|
||||||
|
}
|
||||||
for (int[][] categoryChooser: categoryChoosers) {
|
for (int[][] categoryChooser: categoryChoosers) {
|
||||||
for (int[] category: categoryChooser) {
|
for (int[] category: categoryChooser) {
|
||||||
for (int index: category) {
|
for (int index: category) {
|
||||||
|
@ -58,6 +86,9 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// asserts that the maximal question index in the selection data does not overflow the ballot race questions array
|
||||||
|
int questionsLength = allBallotQuestions.length;
|
||||||
if (maxQuestionIndex >= questionsLength) {
|
if (maxQuestionIndex >= questionsLength) {
|
||||||
String errorMessage = "Selection data refers to question index " + maxQuestionIndex + " while we have only " + questionsLength + " questions totally";
|
String errorMessage = "Selection data refers to question index " + maxQuestionIndex + " while we have only " + questionsLength + " questions totally";
|
||||||
logger.error(errorMessage);
|
logger.error(errorMessage);
|
||||||
|
@ -66,8 +97,21 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an implementation of the QuestionSelector interface method.
|
||||||
|
* In this selector class the identifier simply marks all the ballot race questions which appear in at least one
|
||||||
|
* category of the categories chosen by the voter (or in the shared defaults category) in the channel choice round.
|
||||||
|
* @param channelChoiceAnswers The answers given by the voter to the channel choice questions
|
||||||
|
* @return the channel identifier
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] getChannelIdentifier(List<BallotAnswer> channelChoiceAnswers) {
|
public byte[] getChannelIdentifier(List<BallotAnswer> channelChoiceAnswers) {
|
||||||
|
/*
|
||||||
|
* Currently, this implementation of the QuestionSelector interface returns an over-simplified identifier which
|
||||||
|
* is merely an array of booleans (which flags the questions to appear in the ballot)
|
||||||
|
* For elections with more than one possible channel we should return a more printable and recognizable
|
||||||
|
* identifier to be put in the plaintext of the ballot
|
||||||
|
*/
|
||||||
byte[] isSelected = new byte[allBallotQuestions.length];
|
byte[] isSelected = new byte[allBallotQuestions.length];
|
||||||
java.util.Arrays.fill(isSelected, QUESTION_NOT_SELECTED);
|
java.util.Arrays.fill(isSelected, QUESTION_NOT_SELECTED);
|
||||||
|
|
||||||
|
@ -86,6 +130,10 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
||||||
return isSelected;
|
return isSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verifies that the ballot answer is of length 1. (We do not yet handle multi-choice questions in the channel choice round).
|
||||||
|
* Otherwise, throws an exception.
|
||||||
|
*/
|
||||||
private void assertAnswerLengthIsOne (BallotAnswer ballotAnswer, int questionNumber) {
|
private void assertAnswerLengthIsOne (BallotAnswer ballotAnswer, int questionNumber) {
|
||||||
if (ballotAnswer.getAnswerCount() != 1) {
|
if (ballotAnswer.getAnswerCount() != 1) {
|
||||||
String errorMessage = "SimpleListCategoriesSelector expects a single answer for every channel choice question\n";
|
String errorMessage = "SimpleListCategoriesSelector expects a single answer for every channel choice question\n";
|
||||||
|
@ -109,6 +157,9 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
||||||
return selectedQuestions;
|
return selectedQuestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* copies a List of Integers into an int[] array of same length
|
||||||
|
*/
|
||||||
private int[] listToIntArray(List<Integer> l) {
|
private int[] listToIntArray(List<Integer> l) {
|
||||||
int[] res = new int[l.size()];
|
int[] res = new int[l.size()];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
Loading…
Reference in New Issue