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.voting.controller.commands.*;
|
||||
import meerkat.voting.controller.commands.ControllerCommand;
|
||||
import meerkat.voting.ui.VotingBoothUI.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(CastOrAuditCallback.class);
|
||||
protected final UIElement unrecognizedFinalizeResponseMessage;
|
||||
|
@ -31,9 +34,7 @@ public class CastOrAuditCallback extends ControllerCallback<FinalizeBallotChoice
|
|||
}
|
||||
else {
|
||||
logger.error("CastOrAuditCallback got an unrecognized response: " + result);
|
||||
enqueueCommand(new ReportErrorCommand(getRequestIdentifier(),
|
||||
getBallotSerialNumber(),
|
||||
unrecognizedFinalizeResponseMessage));
|
||||
onFailure(new IllegalArgumentException("CastOrAuditCallback got an unknown result (" + result + ")"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,12 +4,15 @@ import meerkat.protobuf.Voting.*;
|
|||
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.
|
||||
* 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>> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(ChannelChoiceCallback.class);
|
||||
|
@ -26,12 +29,14 @@ public class ChannelChoiceCallback extends ControllerCallback<List<BallotAnswer>
|
|||
@Override
|
||||
public void onSuccess(List<BallotAnswer> result) {
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
if (t instanceof VoterCancelException) {
|
||||
// voter has cancelled during the UI channel choice process. A VoterCancelException is thrown
|
||||
logger.debug("ChannelChoiceCallback got a cancellation response");
|
||||
enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* 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> {
|
||||
|
||||
private final int requestIdentifier;
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package meerkat.voting.controller.callbacks;
|
||||
|
||||
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
|
||||
import meerkat.voting.controller.commands.ControllerCommand;
|
||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
||||
import meerkat.voting.controller.commands.RetryEncryptAndCommitBallotCommand;
|
||||
import meerkat.voting.controller.commands.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(EncryptionFailedCallback.class);
|
||||
|
||||
|
@ -20,18 +22,18 @@ public class EncryptionFailedCallback extends ControllerCallback<Integer> {
|
|||
|
||||
@Override
|
||||
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();
|
||||
if (res == 0) {
|
||||
logger.debug("voter chose to retry encryption");
|
||||
enqueueCommand(new RetryEncryptAndCommitBallotCommand(getRequestIdentifier(), getBallotSerialNumber()));
|
||||
}
|
||||
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()));
|
||||
}
|
||||
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;
|
||||
|
||||
import meerkat.voting.controller.commands.ControllerCommand;
|
||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
||||
import meerkat.voting.controller.commands.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(ErrorMessageRestartCallback.class);
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package meerkat.voting.controller.callbacks;
|
||||
|
||||
import meerkat.voting.controller.commands.ChannelChoiceCommand;
|
||||
import meerkat.voting.controller.commands.ControllerCommand;
|
||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
||||
import meerkat.voting.controller.commands.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(NewVoterCallback.class);
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package meerkat.voting.controller.callbacks;
|
||||
|
||||
import meerkat.protobuf.Voting.UIElement;
|
||||
import meerkat.voting.controller.commands.ControllerCommand;
|
||||
import meerkat.voting.controller.commands.ChooseFinalizeOptionCommand;
|
||||
import meerkat.voting.controller.commands.ReportErrorCommand;
|
||||
import meerkat.voting.controller.commands.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceCommitCallback.class);
|
||||
protected final UIElement outputDeviceFailureMessage;
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package meerkat.voting.controller.callbacks;
|
||||
|
||||
import meerkat.protobuf.Voting.UIElement;
|
||||
import meerkat.voting.controller.commands.ControllerCommand;
|
||||
import meerkat.voting.controller.commands.ReportErrorCommand;
|
||||
import meerkat.voting.controller.commands.RestartVotingCommand;
|
||||
import meerkat.voting.controller.commands.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceFinalizeCallback.class);
|
||||
protected final UIElement outputDeviceFailureMessage;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
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;
|
||||
|
||||
import meerkat.protobuf.Voting.*;
|
||||
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 meerkat.voting.controller.commands.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
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>> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(VotingCallback.class);
|
||||
protected final UIElement unsuccessfulVotingMessage;
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package meerkat.voting.controller.callbacks;
|
||||
|
||||
import meerkat.protobuf.Voting.UIElement;
|
||||
import meerkat.voting.controller.commands.ControllerCommand;
|
||||
import meerkat.voting.controller.commands.ReportErrorCommand;
|
||||
import meerkat.voting.controller.commands.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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> {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(WaitForFinishCallback.class);
|
||||
protected final UIElement somethingWrongMessage;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package meerkat.voting.controller.commands;
|
||||
|
||||
/**
|
||||
* Created by hai on 11/04/16.
|
||||
* a command to audit the ballot
|
||||
*/
|
||||
public class AuditCommand extends ControllerCommand {
|
||||
public AuditCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package meerkat.voting.controller.commands;
|
||||
|
||||
/**
|
||||
* Created by hai on 11/04/16.
|
||||
* a command to cast the ballot
|
||||
*/
|
||||
public class CastCommand extends ControllerCommand {
|
||||
public CastCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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 ChannelChoiceCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import meerkat.protobuf.Voting.*;
|
|||
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 List<BallotAnswer> channelChoiceAnswers;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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 ChooseFinalizeOptionCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
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 {
|
||||
protected final int requestIdentifier;
|
||||
protected final long ballotSerialNumber;
|
||||
|
|
|
@ -3,6 +3,10 @@ package meerkat.voting.controller.commands;
|
|||
import meerkat.protobuf.Voting.BallotAnswer;
|
||||
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 {
|
||||
private final List<BallotAnswer> votingAnswers;
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@ package meerkat.voting.controller.commands;
|
|||
|
||||
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 {
|
||||
private final UIElement errorMessage;
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package meerkat.voting.controller.commands;
|
||||
|
||||
|
||||
/**
|
||||
* a command to restart a voting flow (for a new voter)
|
||||
*/
|
||||
public class RestartVotingCommand extends ControllerCommand {
|
||||
public RestartVotingCommand(int requestIdentifier, long ballotSerialNumber) {
|
||||
super(requestIdentifier, ballotSerialNumber);
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
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 RetryEncryptAndCommitBallotCommand(int requestIdentifier,
|
||||
|
|
|
@ -4,12 +4,26 @@ import meerkat.protobuf.Voting.*;
|
|||
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 {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
}
|
||||
|
|
|
@ -11,28 +11,47 @@ import java.lang.Math;
|
|||
/**
|
||||
* 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.
|
||||
* Every category is an array of ballot race questions.
|
||||
* 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
|
||||
* 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 {
|
||||
protected final static Logger logger = LoggerFactory.getLogger(SimpleListCategoriesSelector.class);
|
||||
|
||||
// all the possible race questions
|
||||
private final BallotQuestion[] allBallotQuestions;
|
||||
|
||||
// this category is presented to any voter (regardless of his answers to the channel choice questions)
|
||||
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 static byte QUESTION_SELECTED = (byte)1;
|
||||
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) {
|
||||
// copies the ballot race question list into a member array
|
||||
this.allBallotQuestions = new BallotQuestion[allBallotQuestions.size()];
|
||||
allBallotQuestions.toArray(this.allBallotQuestions);
|
||||
|
||||
// copies the shared category list (as appears in the protobuf data) into a member array
|
||||
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 channelChoiceQuestionNumber = 0;
|
||||
for (CategoryChooser catChooser: data.getCategoryChooserList()) {
|
||||
|
@ -45,12 +64,21 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
|||
++channelChoiceQuestionNumber;
|
||||
}
|
||||
categoryChoosers = selectionDataTmp;
|
||||
|
||||
// verifies in advance that there are not very suspicious indices in the selection data
|
||||
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 () {
|
||||
int questionsLength = allBallotQuestions.length;
|
||||
// find the maximum question index in the selection data
|
||||
int maxQuestionIndex = -1;
|
||||
for (int index: sharedDefaults) {
|
||||
maxQuestionIndex = Math.max(maxQuestionIndex, index);
|
||||
}
|
||||
for (int[][] categoryChooser: categoryChoosers) {
|
||||
for (int[] category: categoryChooser) {
|
||||
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) {
|
||||
String errorMessage = "Selection data refers to question index " + maxQuestionIndex + " while we have only " + questionsLength + " questions totally";
|
||||
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
|
||||
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];
|
||||
java.util.Arrays.fill(isSelected, QUESTION_NOT_SELECTED);
|
||||
|
||||
|
@ -86,6 +130,10 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
|||
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) {
|
||||
if (ballotAnswer.getAnswerCount() != 1) {
|
||||
String errorMessage = "SimpleListCategoriesSelector expects a single answer for every channel choice question\n";
|
||||
|
@ -109,6 +157,9 @@ public class SimpleListCategoriesSelector implements QuestionSelector {
|
|||
return selectedQuestions;
|
||||
}
|
||||
|
||||
/*
|
||||
* copies a List of Integers into an int[] array of same length
|
||||
*/
|
||||
private int[] listToIntArray(List<Integer> l) {
|
||||
int[] res = new int[l.size()];
|
||||
int index = 0;
|
||||
|
|
Loading…
Reference in New Issue