This is an automated email from the git hooks/post-receive script. New change to branch feature/148-configuration-methodes-de-votes in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git from 050ad685 fixes #130 sauvegarde de la langue de l'UI new 065aa161 Ajouter la configuration des méthodes vote (ref #148). Adaptation pour Normal, Cumulatif (ancien pourcentage), Nombre et Borda The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 065aa1618483d53b8267cfd69fb7324b0cbc11b7 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Oct 4 15:03:39 2017 +0200 Ajouter la configuration des méthodes vote (ref #148). Adaptation pour Normal, Cumulatif (ancien pourcentage), Nombre et Borda Summary of changes: .../h2/V3_1_0_3__add_vote_counting_config.sql | 23 +++++ .../V3_1_0_3__add_vote_counting_config.sql | 23 +++++ pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 29157 -> 29234 bytes pollen-rest-api/pom.xml | 1 - .../pollen/rest/api/converter/JacksonConfig.java | 2 + .../converter/VoteCountingConfigDeserializer.java | 111 +++++++++++++++++++++ .../org/chorem/pollen/services/bean/PollBean.java | 20 ++-- .../pollen/services/service/PollService.java | 10 +- .../services/service/VoteCountingService.java | 66 ++++++++++-- .../pollen/services/service/VoteService.java | 28 ++++-- pollen-ui-riot-js/src/main/web/i18n/en.json | 17 ++-- pollen-ui-riot-js/src/main/web/i18n/fr.json | 17 ++-- pollen-ui-riot-js/src/main/web/js/PollForm.js | 2 +- .../src/main/web/tag/poll/Settings.tag.html | 58 ++++------- .../src/main/web/tag/poll/Votes.tag.html | 8 +- .../web/tag/voteCountingType/BordaConfig.tag.html | 107 ++++++++++++++++++++ .../voteCountingType/BordaDetailResult.tag.html | 12 +-- .../tag/voteCountingType/CumulativeConfig.tag.html | 34 +++++++ .../MaxChoicesNumberConfig.tag.html | 60 +++++++++++ pollen-votecounting-aggregator/pom.xml | 4 +- pollen-votecounting-api/pom.xml | 4 + .../pollen/votecounting/AbstractVoteCounting.java | 14 ++- .../votecounting/AbstractVoteCountingStrategy.java | 10 +- .../chorem/pollen/votecounting/VoteCounting.java | 14 ++- .../pollen/votecounting/VoteCountingFactory.java | 3 +- .../pollen/votecounting/VoteCountingStrategy.java | 5 +- .../model/EmptyVoteCountingConfig.java | 7 ++ .../votecounting/model/MaxChoicesNumberConfig.java | 17 ++++ .../votecounting/model/VoteCountingConfig.java | 7 ++ .../chorem/pollen/votecounting/BordaConfig.java | 21 ++++ .../pollen/votecounting/BordaVoteCounting.java | 7 +- .../votecounting/BordaVoteCountingStrategy.java | 38 ++++++- .../pollen-votecounting-borda_fr_FR.properties | 2 +- .../BordaVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/CondorcetVoteCounting.java | 8 +- .../CondorcetVoteCountingStrategy.java | 3 +- .../pollen-votecounting-condorcet_fr_FR.properties | 2 +- .../CondorcetVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/CoombsVoteCounting.java | 8 +- .../votecounting/CoombsVoteCountingStrategy.java | 3 +- .../pollen-votecounting-coombs_en_GB.properties | 2 +- .../pollen-votecounting-coombs_fr_FR.properties | 2 +- .../CoombsVoteCountingStrategyTest.java | 8 +- .../LICENSE.txt | 0 .../README.md | 0 .../pom.xml | 6 +- .../pollen/votecounting/CumulativeConfig.java | 19 ++++ .../votecounting/CumulativeVoteCounting.java | 21 ++-- .../CumulativeVoteCountingStrategy.java | 2 +- .../org.chorem.pollen.votecounting.VoteCounting | 1 + ...pollen-votecounting-cumulative_en_GB.properties | 4 + ...pollen-votecounting-cumulative_fr_FR.properties | 4 + .../CumulativeVoteCountingStrategyTest.java | 14 +-- .../votecounting/VoteCountingFactoryTest.java | 2 +- .../src/test/resources/log4j.properties | 0 .../votecounting/InstantRunoffVoteCounting.java | 16 +-- .../InstantRunoffVoteCountingStrategy.java | 3 +- .../InstantRunoffVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/NormalVoteCounting.java | 16 +-- .../votecounting/NormalVoteCountingStrategy.java | 3 +- .../NormalVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/NumberVoteCounting.java | 16 +-- .../votecounting/NumberVoteCountingStrategy.java | 9 +- .../NumberVoteCountingStrategyTest.java | 9 +- .../org.chorem.pollen.votecounting.VoteCounting | 1 - ...pollen-votecounting-percentage_en_GB.properties | 4 - ...pollen-votecounting-percentage_fr_FR.properties | 4 - 68 files changed, 781 insertions(+), 195 deletions(-) create mode 100644 pollen-persistence/src/main/resources/db/migration/h2/V3_1_0_3__add_vote_counting_config.sql create mode 100644 pollen-persistence/src/main/resources/db/migration/postgresql/V3_1_0_3__add_vote_counting_config.sql create mode 100644 pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/VoteCountingConfigDeserializer.java create mode 100644 pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaConfig.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/voteCountingType/CumulativeConfig.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/voteCountingType/MaxChoicesNumberConfig.tag.html create mode 100644 pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/EmptyVoteCountingConfig.java create mode 100644 pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/MaxChoicesNumberConfig.java create mode 100644 pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingConfig.java create mode 100644 pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaConfig.java rename {pollen-votecounting-percentage => pollen-votecounting-cumulative}/LICENSE.txt (100%) rename {pollen-votecounting-percentage => pollen-votecounting-cumulative}/README.md (100%) rename {pollen-votecounting-percentage => pollen-votecounting-cumulative}/pom.xml (93%) create mode 100644 pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeConfig.java rename pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java => pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCounting.java (77%) rename pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java => pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategy.java (97%) create mode 100644 pollen-votecounting-cumulative/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting create mode 100644 pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_en_GB.properties create mode 100644 pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_fr_FR.properties rename pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java => pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java (97%) rename {pollen-votecounting-percentage => pollen-votecounting-cumulative}/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (95%) rename {pollen-votecounting-percentage => pollen-votecounting-cumulative}/src/test/resources/log4j.properties (100%) delete mode 100644 pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting delete mode 100644 pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_en_GB.properties delete mode 100644 pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_fr_FR.properties -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/148-configuration-methodes-de-votes in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 065aa1618483d53b8267cfd69fb7324b0cbc11b7 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Oct 4 15:03:39 2017 +0200 Ajouter la configuration des méthodes vote (ref #148). Adaptation pour Normal, Cumulatif (ancien pourcentage), Nombre et Borda --- .../h2/V3_1_0_3__add_vote_counting_config.sql | 23 +++++ .../V3_1_0_3__add_vote_counting_config.sql | 23 +++++ pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 29157 -> 29234 bytes pollen-rest-api/pom.xml | 1 - .../pollen/rest/api/converter/JacksonConfig.java | 2 + .../converter/VoteCountingConfigDeserializer.java | 111 +++++++++++++++++++++ .../org/chorem/pollen/services/bean/PollBean.java | 20 ++-- .../pollen/services/service/PollService.java | 10 +- .../services/service/VoteCountingService.java | 66 ++++++++++-- .../pollen/services/service/VoteService.java | 28 ++++-- pollen-ui-riot-js/src/main/web/i18n/en.json | 17 ++-- pollen-ui-riot-js/src/main/web/i18n/fr.json | 17 ++-- pollen-ui-riot-js/src/main/web/js/PollForm.js | 2 +- .../src/main/web/tag/poll/Settings.tag.html | 58 ++++------- .../src/main/web/tag/poll/Votes.tag.html | 8 +- .../web/tag/voteCountingType/BordaConfig.tag.html | 107 ++++++++++++++++++++ .../voteCountingType/BordaDetailResult.tag.html | 12 +-- .../tag/voteCountingType/CumulativeConfig.tag.html | 34 +++++++ .../MaxChoicesNumberConfig.tag.html | 60 +++++++++++ pollen-votecounting-aggregator/pom.xml | 4 +- pollen-votecounting-api/pom.xml | 4 + .../pollen/votecounting/AbstractVoteCounting.java | 14 ++- .../votecounting/AbstractVoteCountingStrategy.java | 10 +- .../chorem/pollen/votecounting/VoteCounting.java | 14 ++- .../pollen/votecounting/VoteCountingFactory.java | 3 +- .../pollen/votecounting/VoteCountingStrategy.java | 5 +- .../model/EmptyVoteCountingConfig.java | 7 ++ .../votecounting/model/MaxChoicesNumberConfig.java | 17 ++++ .../votecounting/model/VoteCountingConfig.java | 7 ++ .../chorem/pollen/votecounting/BordaConfig.java | 21 ++++ .../pollen/votecounting/BordaVoteCounting.java | 7 +- .../votecounting/BordaVoteCountingStrategy.java | 38 ++++++- .../pollen-votecounting-borda_fr_FR.properties | 2 +- .../BordaVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/CondorcetVoteCounting.java | 8 +- .../CondorcetVoteCountingStrategy.java | 3 +- .../pollen-votecounting-condorcet_fr_FR.properties | 2 +- .../CondorcetVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/CoombsVoteCounting.java | 8 +- .../votecounting/CoombsVoteCountingStrategy.java | 3 +- .../pollen-votecounting-coombs_en_GB.properties | 2 +- .../pollen-votecounting-coombs_fr_FR.properties | 2 +- .../CoombsVoteCountingStrategyTest.java | 8 +- .../LICENSE.txt | 0 .../README.md | 0 .../pom.xml | 6 +- .../pollen/votecounting/CumulativeConfig.java | 19 ++++ .../votecounting/CumulativeVoteCounting.java | 21 ++-- .../CumulativeVoteCountingStrategy.java | 2 +- .../org.chorem.pollen.votecounting.VoteCounting | 1 + ...pollen-votecounting-cumulative_en_GB.properties | 4 + ...pollen-votecounting-cumulative_fr_FR.properties | 4 + .../CumulativeVoteCountingStrategyTest.java | 14 +-- .../votecounting/VoteCountingFactoryTest.java | 2 +- .../src/test/resources/log4j.properties | 0 .../votecounting/InstantRunoffVoteCounting.java | 16 +-- .../InstantRunoffVoteCountingStrategy.java | 3 +- .../InstantRunoffVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/NormalVoteCounting.java | 16 +-- .../votecounting/NormalVoteCountingStrategy.java | 3 +- .../NormalVoteCountingStrategyTest.java | 8 +- .../pollen/votecounting/NumberVoteCounting.java | 16 +-- .../votecounting/NumberVoteCountingStrategy.java | 9 +- .../NumberVoteCountingStrategyTest.java | 9 +- .../org.chorem.pollen.votecounting.VoteCounting | 1 - ...pollen-votecounting-percentage_en_GB.properties | 4 - ...pollen-votecounting-percentage_fr_FR.properties | 4 - 68 files changed, 781 insertions(+), 195 deletions(-) diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_1_0_3__add_vote_counting_config.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_1_0_3__add_vote_counting_config.sql new file mode 100644 index 00000000..85448132 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_1_0_3__add_vote_counting_config.sql @@ -0,0 +1,23 @@ +-- add vote counting type configuration +alter table poll add votecountingconfig longvarchar; + +-- 1 Normal ; +UPDATE poll set votecountingconfig = concat('{maxChoiceNumber: ', maxChoiceNumber, '}') where votecountingtype = 1; + +-- 2 Pourcentage +UPDATE poll set votecountingconfig = '{weight: 100}' where votecountingtype = 2; + +-- 3 Condorcet +UPDATE poll set votecountingconfig = '' where votecountingtype = 3; + +-- 4 Number +UPDATE poll set votecountingconfig = concat('{maxChoiceNumber: ', maxChoiceNumber, '}') where votecountingtype = 4; + +-- 5 Boda +UPDATE poll set votecountingconfig = '{maxChoiceNumber: 0, pointsByRank: null}' where votecountingtype = 5; + +-- 6 Instant runoff +UPDATE poll set votecountingconfig = '' where votecountingtype = 6; + +-- 6 Coombs +UPDATE poll set votecountingconfig = '' where votecountingtype = 7; \ No newline at end of file diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_1_0_3__add_vote_counting_config.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_1_0_3__add_vote_counting_config.sql new file mode 100644 index 00000000..c3a80bd5 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_1_0_3__add_vote_counting_config.sql @@ -0,0 +1,23 @@ +-- add vote counting type configuration +alter table poll add votecountingconfig text; + +-- 1 Normal ; +UPDATE poll set votecountingconfig = concat('{maxChoiceNumber: ', maxChoiceNumber, '}') where votecountingtype = 1; + +-- 2 Pourcentage +UPDATE poll set votecountingconfig = '{weight: 100}' where votecountingtype = 2; + +-- 3 Condorcet +UPDATE poll set votecountingconfig = '' where votecountingtype = 3; + +-- 4 Number +UPDATE poll set votecountingconfig = concat('{maxChoiceNumber: ', maxChoiceNumber, '}') where votecountingtype = 4; + +-- 5 Boda +UPDATE poll set votecountingconfig = '{maxChoiceNumber: 0, pointsByRank: null}' where votecountingtype = 5; + +-- 6 Instant runoff +UPDATE poll set votecountingconfig = '' where votecountingtype = 6; + +-- 6 Coombs +UPDATE poll set votecountingconfig = '' where votecountingtype = 7; \ No newline at end of file diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index 4d9d4fbb..28095962 100644 --- a/pollen-persistence/src/main/xmi/pollen.properties +++ b/pollen-persistence/src/main/xmi/pollen.properties @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # #L% ###m -model.tagvalue.version=3.1.0.2 +model.tagvalue.version=3.1.0.3 #model.tagValue.notGenerateToString=true #model.tagValue.constantPrefix=PROPERTY_ #model.tagValue.useEnumerationName=true diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index e77a7ac6..e4adfd28 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/pom.xml b/pollen-rest-api/pom.xml index 864c7dbd..3fcca8db 100644 --- a/pollen-rest-api/pom.xml +++ b/pollen-rest-api/pom.xml @@ -68,7 +68,6 @@ <artifactId>pollen-votecounting-aggregator</artifactId> <version>${project.version}</version> <type>pom</type> - <scope>runtime</scope> </dependency> <dependency> <groupId>${project.groupId}</groupId> diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/JacksonConfig.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/JacksonConfig.java index 93984b95..ba152e8c 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/JacksonConfig.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/JacksonConfig.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; @@ -44,6 +45,7 @@ public class JacksonConfig implements ContextResolver<ObjectMapper> { module.addSerializer(PollenEntityRef.class, new PollenEntityRefSerializer()); module.addDeserializer(PollenEntityId.class, new PollenEntityIdDeserializer()); module.addDeserializer(PollenEntityRef.class, new PollenEntityRefDeserializer()); + module.addDeserializer(VoteCountingConfig.class, new VoteCountingConfigDeserializer()); objectMapper.registerModule(module); } diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/VoteCountingConfigDeserializer.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/VoteCountingConfigDeserializer.java new file mode 100644 index 00000000..504c5b32 --- /dev/null +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/converter/VoteCountingConfigDeserializer.java @@ -0,0 +1,111 @@ +package org.chorem.pollen.rest.api.converter; + +/*- + * #%L + * Pollen :: Rest Api + * %% + * Copyright (C) 2009 - 2017 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import org.chorem.pollen.votecounting.BordaConfig; +import org.chorem.pollen.votecounting.CumulativeConfig; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; + +import java.io.IOException; +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class VoteCountingConfigDeserializer extends JsonDeserializer<VoteCountingConfig> { + + @Override + public VoteCountingConfig deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + + VoteCountingConfigTemp configTemp = ctxt.readValue(p, VoteCountingConfigTemp.class); + + VoteCountingConfig config; + + if (configTemp.getMaxChoiceNumber() != null) { + + if (configTemp.getPointsByRank() != null) { + + BordaConfig bordaConfig = new BordaConfig(); + bordaConfig.setMaxChoiceNumber(configTemp.getMaxChoiceNumber()); + bordaConfig.setPointsByRank(configTemp.getPointsByRank()); + config = bordaConfig; + + } else { + + MaxChoicesNumberConfig maxChoicesNumberConfig = new MaxChoicesNumberConfig(); + maxChoicesNumberConfig.setMaxChoiceNumber(configTemp.getMaxChoiceNumber()); + config = maxChoicesNumberConfig; + } + } else if (configTemp.getPoints() != null) { + + CumulativeConfig cumulativeConfig = new CumulativeConfig(); + cumulativeConfig.setPoints(configTemp.getPoints()); + config = cumulativeConfig; + + } else { + + config = new EmptyVoteCountingConfig(); + + } + + return config; + + } + + static class VoteCountingConfigTemp { + + protected Integer maxChoiceNumber; + + protected List<Integer> pointsByRank; + + protected Integer points; + + public Integer getMaxChoiceNumber() { + return maxChoiceNumber; + } + + public void setMaxChoiceNumber(Integer maxChoiceNumber) { + this.maxChoiceNumber = maxChoiceNumber; + } + + public List<Integer> getPointsByRank() { + return pointsByRank; + } + + public void setPointsByRank(List<Integer> pointsByRank) { + this.pointsByRank = pointsByRank; + } + + public Integer getPoints() { + return points; + } + + public void setPoints(Integer points) { + this.points = points; + } + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java index dd89ed27..b1d2bbaf 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java @@ -28,6 +28,7 @@ import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollType; import org.chorem.pollen.persistence.entity.ResultVisibility; import org.chorem.pollen.persistence.entity.VoteVisibility; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import java.util.Date; import java.util.Objects; @@ -80,8 +81,6 @@ public class PollBean extends PollenBean<Poll> { protected Date endDate; - protected int maxChoiceNumber; - protected boolean choiceAddAllowed; protected boolean anonymousVoteAllowed; @@ -142,6 +141,7 @@ public class PollBean extends PollenBean<Poll> { protected String creatorAvatar; + protected VoteCountingConfig voteCountingConfig; public String getPermission() { return permission; @@ -215,14 +215,6 @@ public class PollBean extends PollenBean<Poll> { this.endDate = endDate; } - public int getMaxChoiceNumber() { - return maxChoiceNumber; - } - - public void setMaxChoiceNumber(int maxChoiceNumber) { - this.maxChoiceNumber = maxChoiceNumber; - } - public boolean isChoiceAddAllowed() { return choiceAddAllowed; } @@ -473,4 +465,12 @@ public class PollBean extends PollenBean<Poll> { public void setCreatorAvatar(String creatorAvatar) { this.creatorAvatar = creatorAvatar; } + + public VoteCountingConfig getVoteCountingConfig() { + return voteCountingConfig; + } + + public void setVoteCountingConfig(VoteCountingConfig voteCountingConfig) { + this.voteCountingConfig = voteCountingConfig; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index 314f96b9..ee82987b 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -98,7 +98,6 @@ public class PollService extends PollenServiceSupport { bean.setEndChoiceDate(entity.getEndChoiceDate()); bean.setBeginDate(entity.getBeginDate()); bean.setEndDate(entity.getEndDate()); - bean.setMaxChoiceNumber(entity.getMaxChoiceNumber()); bean.setChoiceAddAllowed(entity.isChoiceAddAllowed()); bean.setAnonymousVoteAllowed(entity.isAnonymousVoteAllowed()); bean.setContinuousResults(entity.isContinuousResults()); @@ -115,6 +114,7 @@ public class PollService extends PollenServiceSupport { bean.setCommentNotification(entity.isCommentNotification()); bean.setNewChoiceNotification(entity.isNewChoiceNotification()); bean.setNotificationLocale(entity.getNotificationLocale()); + bean.setVoteCountingConfig(getVoteCountingService().getVoteCountingConfig(entity)); Date now = getNow(); if (Polls.isFinished(entity, now)) { @@ -256,7 +256,9 @@ public class PollService extends PollenServiceSupport { // -- default values -- // PollenServicesConfig pollenServiceConfig = getPollenServiceConfig(); - pollBean.setVoteCountingType(pollenServiceConfig.getDefaultVoteCountingType()); + int voteCountingType = pollenServiceConfig.getDefaultVoteCountingType(); + pollBean.setVoteCountingType(voteCountingType); + pollBean.setVoteCountingConfig(getVoteCountingService().newConfig(voteCountingType)); pollBean.setPollType(pollenServiceConfig.getDefaultPollType()); pollBean.setVoteVisibility(pollenServiceConfig.getDefaultVoteVisibility()); pollBean.setCommentVisibility(pollenServiceConfig.getDefaultCommentVisibility()); @@ -531,7 +533,6 @@ public class PollService extends PollenServiceSupport { toSave.setContinuousResults(poll.isContinuousResults()); toSave.setDescription(poll.getDescription()); toSave.setPollType(poll.getPollType()); - toSave.setMaxChoiceNumber(poll.getMaxChoiceNumber()); toSave.setTitle(poll.getTitle()); toSave.setChoiceType(poll.getChoiceType()); toSave.setWithMe(poll.isWithMe()); @@ -563,6 +564,9 @@ public class PollService extends PollenServiceSupport { toSave.setEndChoiceDate(poll.getEndChoiceDate()); } + String configToJson = getVoteCountingService().configToJson(poll.getVoteCountingConfig()); + toSave.setVoteCountingConfig(configToJson); + // -- choice -- // if (CollectionUtils.isNotEmpty(choices)) { diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteCountingService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteCountingService.java index 145cb25d..4ee03c36 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteCountingService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteCountingService.java @@ -23,12 +23,15 @@ package org.chorem.pollen.services.service; import com.google.common.base.Preconditions; import com.google.common.collect.Sets; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.Polls; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.persistence.entity.VoteToChoice; import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; +import org.chorem.pollen.services.PollenTechnicalException; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.ListVoteCountingResultBean; import org.chorem.pollen.services.bean.VoteBean; @@ -41,6 +44,7 @@ import org.chorem.pollen.votecounting.VoteCountingStrategy; import org.chorem.pollen.votecounting.model.ListOfVoter; import org.chorem.pollen.votecounting.model.ListVoteCountingResult; import org.chorem.pollen.votecounting.model.SimpleVoter; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -82,6 +86,52 @@ public class VoteCountingService extends PollenServiceSupport { } + public <S extends VoteCountingStrategy<C>, C extends VoteCountingConfig> C newConfig(int voteCountingType) { + + VoteCountingFactory voteCountingFactory = serviceContext.getVoteCountingFactory(); + + VoteCounting<S, C> voteCounting = voteCountingFactory.getVoteCounting(voteCountingType); + + Class<C> configType = voteCounting.getConfigType(); + + try { + return configType.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new PollenTechnicalException(e); + } + } + + protected <C extends VoteCountingConfig> C configFromJson(String json, Class<C> configType) { + Gson gson = new GsonBuilder().create(); + if (json == null || "null".equals(json)) { + try { + return configType.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new PollenTechnicalException(e); + } + } + return gson.fromJson(json, configType); + } + + protected <C extends VoteCountingConfig> String configToJson(C config) { + Gson gson = new GsonBuilder().create(); + return gson.toJson(config); + } + + public <S extends VoteCountingStrategy<C>, C extends VoteCountingConfig> C getVoteCountingConfig(Poll poll) { + VoteCounting<S, C> voteCounting = getVoteCounting(poll); + return configFromJson(poll.getVoteCountingConfig(), voteCounting.getConfigType()); + } + + public <S extends VoteCountingStrategy<C>, C extends VoteCountingConfig> VoteCountingStrategy<C> getVoteCountingStrategy(Poll poll) { + VoteCounting<S, C> voteCounting = getVoteCounting(poll); + VoteCountingStrategy<C> strategy = voteCounting.newStrategy(); + C config = configFromJson(poll.getVoteCountingConfig(), voteCounting.getConfigType()); + strategy.setConfig(config); + + return strategy; + } + public VoteCountingResultBean getSimpleResult(String pollId) { Preconditions.checkNotNull(pollId); @@ -89,8 +139,7 @@ public class VoteCountingService extends PollenServiceSupport { Poll poll = getPollService().getPoll0(pollId); List<Vote> votes = getVotes(poll); - VoteCounting voteCounting = getVoteCounting(poll); - VoteCountingStrategy strategy = voteCounting.newStrategy(); + VoteCountingStrategy strategy = getVoteCountingStrategy(poll); ListOfVoter groupOfVoter = toSimpleVotersGroup(votes); @@ -123,8 +172,7 @@ public class VoteCountingService extends PollenServiceSupport { VoterList mainVoterList = getVoterListService().getMainVoterList0(poll); List<Vote> votes = getVotes(poll); - VoteCounting voteCounting = getVoteCounting(poll); - VoteCountingStrategy strategy = voteCounting.newStrategy(); + VoteCountingStrategy strategy = getVoteCountingStrategy(poll); // Create a groupVoter including of the root voters ListOfVoter listOfVoter = toListOfVoters(poll, mainVoterList, votes); @@ -245,12 +293,12 @@ public class VoteCountingService extends PollenServiceSupport { } - protected VoteCounting getVoteCounting(Poll poll) { + protected <S extends VoteCountingStrategy<C>, C extends VoteCountingConfig> VoteCounting<S, C> getVoteCounting(Poll poll) { int id = poll.getVoteCountingType(); VoteCountingFactory voteCountingFactory = serviceContext.getVoteCountingFactory(); - VoteCounting result = voteCountingFactory.getVoteCounting(id); + VoteCounting<S, C> result = voteCountingFactory.getVoteCounting(id); Preconditions.checkNotNull( result, "Could not find vote counting for id " + id); @@ -259,7 +307,7 @@ public class VoteCountingService extends PollenServiceSupport { } - protected ErrorMap voteIsValid(VoteBean vote, VoteCounting voteCounting, List<ChoiceBean> choices) { + protected <C extends VoteCountingConfig> ErrorMap voteIsValid(VoteBean vote, VoteCounting<?, C> voteCounting, List<ChoiceBean> choices, C config) { ErrorMap errors = new ErrorMap(); Map<String, String> choiceNamesById = choices.stream().collect(Collectors.toMap(ChoiceBean::getEntityId, ChoiceBean::getChoiceValue)); @@ -287,8 +335,8 @@ public class VoteCountingService extends PollenServiceSupport { check(errors, "totalVoteValue", - voteCounting.isTotalVoteValueValid(total), - voteCounting.getTotalVoteValueNotValidMessage(getLocale())); + voteCounting.isTotalVoteValueValid(total, config), + voteCounting.getTotalVoteValueNotValidMessage(getLocale(), config)); return errors; } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java index 61fae5cc..223a2e42 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java @@ -43,6 +43,8 @@ import org.chorem.pollen.services.bean.VoteBean; import org.chorem.pollen.services.bean.VoteToChoiceBean; import org.chorem.pollen.services.service.security.PermissionVerb; import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; @@ -302,7 +304,7 @@ public class VoteService extends PollenServiceSupport { return errors; } - protected ErrorMap checkVote(Poll poll, VoteBean vote, List<ChoiceBean> choices) { + protected <C extends VoteCountingConfig> ErrorMap checkVote(Poll poll, VoteBean vote, List<ChoiceBean> choices) { ErrorMap errors = new ErrorMap(); @@ -336,20 +338,26 @@ public class VoteService extends PollenServiceSupport { } - VoteCounting voteCounting = getVoteCountingService().getVoteCounting(poll); + VoteCounting<?, C> voteCounting = getVoteCountingService().getVoteCounting(poll); + C config = getVoteCountingService().getVoteCountingConfig(poll); - ErrorMap valueErrors = getVoteCountingService().voteIsValid(vote, voteCounting, choices); + + ErrorMap valueErrors = getVoteCountingService().voteIsValid(vote, voteCounting, choices, config); valueErrors.copyTo(errors, "vote."); - if (poll.getMaxChoiceNumber() > 0) { - int nbChoice = 0; - for (VoteToChoiceBean voteToChoice : vote.getChoice()) { - if (voteCounting.isChoiceInVote(voteToChoice.getVoteValue())) { - nbChoice++; + if (MaxChoicesNumberConfig.class.isInstance(config)) { + MaxChoicesNumberConfig maxChoicesNumberConfig = MaxChoicesNumberConfig.class.cast(config); + + if (maxChoicesNumberConfig.getMaxChoiceNumber() > 0) { + int nbChoice = 0; + for (VoteToChoiceBean voteToChoice : vote.getChoice()) { + if (voteCounting.isChoiceInVote(voteToChoice.getVoteValue())) { + nbChoice++; + } } - } - check(errors, "vote.limitedVote", nbChoice <= poll.getMaxChoiceNumber(), l(getLocale(), "pollen.error.vote.limitedVote.overflow")); + check(errors, "vote.limitedVote", nbChoice <= maxChoicesNumberConfig.getMaxChoiceNumber(), l(getLocale(), "pollen.error.vote.limitedVote.overflow")); + } } //TODO Finish validation diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index 864b4f6e..91e85b3e 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -83,8 +83,8 @@ "poll_results_results": "Results", "poll_results_unit_1_one": "vote", "poll_results_unit_1_many": "votes", - "poll_results_unit_2_one": "%", - "poll_results_unit_2_many": "%", + "poll_results_unit_2_one": "point", + "poll_results_unit_2_many": "points", "poll_results_unit_3_one": "battle", "poll_results_unit_3_many": "battles", "poll_results_unit_4_one": "", @@ -141,8 +141,8 @@ "poll_votes_noVote": "No vote", "poll_votes_results_unit_1_one": "vote", "poll_votes_results_unit_1_many": "votes", - "poll_votes_results_unit_2_one": "%", - "poll_votes_results_unit_2_many": "%", + "poll_votes_results_unit_2_one": "point", + "poll_votes_results_unit_2_many": "points", "poll_votes_results_unit_3_one": "battle", "poll_votes_results_unit_3_many": "battles", "poll_votes_results_unit_4_one": "", @@ -313,7 +313,13 @@ "poll_settings_votersConfiguration": "Voters configuration", "poll_settings_voters": "Fill voters separated by space", "poll_settings_addChoices": "add choices by users", - "poll_settings_limitChoices": "Limit number of choices to use on a vote", + "poll_settings_voteCountingConfig_limitChoices": "Limit number of choices to use on a vote", + "poll_settings_voteCountingConfig_maxChoiceNumber": "Maximum number of choices", + "poll_settings_voteCountingConfig_bordaDefault": "default points distibution", + "poll_settings_voteCountingConfig_pointsByRank": "number of points allocated by rank", + "poll_settings_voteCountingConfig_rank": "Rank", + "poll_settings_voteCountingConfig_points": "points", + "poll_settings_voteCountingConfig_cumulativePoints": "number of points to allocate", "poll_settings_votesConfiguration": "Votes configuration", "poll_settings_voteCountingType": "Vote counting type used to compute poll's results.", "poll_settings_voteCountingType_normal": "Normal", @@ -328,7 +334,6 @@ "poll_settings_endDate": "to", "poll_settings_beginChoiceDate": "Add choices from", "poll_settings_endChoiceDate": "to", - "poll_settings_maxChoiceNumber": "Maximum number of choices", "poll_settings_freePoll": "Everybody can vote (Public poll)", "poll_settings_restrictedPoll": "Only invited people can vote (Private poll)", "poll_settings_restrictedPoll_withMe": "I also want to participate", diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 630120cc..43a10aec 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -83,8 +83,8 @@ "poll_results_results": "Résultats", "poll_results_unit_1_one": "vote", "poll_results_unit_1_many": "votes", - "poll_results_unit_2_one": "%", - "poll_results_unit_2_many": "%", + "poll_results_unit_2_one": "point", + "poll_results_unit_2_many": "points", "poll_results_unit_3_one": "combat", "poll_results_unit_3_many": "combats", "poll_results_unit_4_one": "", @@ -141,8 +141,8 @@ "poll_votes_noVote": "Aucun vote", "poll_votes_results_unit_1_one": "vote", "poll_votes_results_unit_1_many": "votes", - "poll_votes_results_unit_2_one": "%", - "poll_votes_results_unit_2_many": "%", + "poll_votes_results_unit_2_one": "point", + "poll_votes_results_unit_2_many": "points", "poll_votes_results_unit_3_one": "combat", "poll_votes_results_unit_3_many": "combats", "poll_votes_results_unit_4_one": "", @@ -313,7 +313,13 @@ "poll_settings_votersConfiguration": "Configuration des participants", "poll_settings_voters": "Renseignez la liste des participants", "poll_settings_addChoices": "Ajout de choix par les participants", - "poll_settings_limitChoices": "Limiter le nombre de choix par vote", + "poll_settings_voteCountingConfig_limitChoices": "Limiter le nombre de choix par vote", + "poll_settings_voteCountingConfig_maxChoiceNumber": "Nombre maximum de choix", + "poll_settings_voteCountingConfig_bordaDefault": "Répartition des points par défaut", + "poll_settings_voteCountingConfig_pointsByRank": "Nombre de points distribués par rang", + "poll_settings_voteCountingConfig_rank": "Rang", + "poll_settings_voteCountingConfig_points": "points", + "poll_settings_voteCountingConfig_cumulativePoints": "Nombre de points à distribuer", "poll_settings_votesConfiguration": "Configuration des votes", "poll_settings_voteCountingType": "Type de scrutin pour effectuer le dépouillement du sondage", "poll_settings_voteCountingType_normal": "Normal", @@ -328,7 +334,6 @@ "poll_settings_endDate": "au", "poll_settings_beginChoiceDate": "Ajout de choix du", "poll_settings_endChoiceDate": "au", - "poll_settings_maxChoiceNumber": "Nombre maximum de choix", "poll_settings_freePoll": "Tout le monde peut voter (Sondage public)", "poll_settings_restrictedPoll": "Seul les invités peuvent voter (Sondage privé)", "poll_settings_restrictedPoll_withMe": "Je participe au sondage", diff --git a/pollen-ui-riot-js/src/main/web/js/PollForm.js b/pollen-ui-riot-js/src/main/web/js/PollForm.js index ef2a2fda..97c90b8d 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollForm.js +++ b/pollen-ui-riot-js/src/main/web/js/PollForm.js @@ -260,7 +260,7 @@ class PollForm { this.model.addChoices = false; this.model.beginChoiceDate = undefined; this.model.endChoiceDate = undefined; - this.model.maxChoiceNumber = undefined; + this.model.voteCountingConfig = {}; this.model.voteCountingType = 1; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html index e26ca8e7..40bfec72 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html @@ -10,18 +10,21 @@ it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. #L% */ require("../components/date-time-picker.tag.html"); require("../components/Checkbox.tag.html"); +require("../voteCountingType/MaxChoicesNumberConfig.tag.html"); +require("../voteCountingType/BordaConfig.tag.html"); +require("../voteCountingType/CumulativeConfig.tag.html"); <Settings> <div class="form-section" show={form.creation}> @@ -137,29 +140,20 @@ require("../components/Checkbox.tag.html"); disabled={form.hasVotes || opts.form.model.closed}/> </div> </div> - <div show="{canLimitNumberOfChoices}" class="o-form-element"> - <Checkbox label="{__.limitChoices}" - name="limitChoices" - id="limitChoices" - ref="limitChoices" - disabled={form.hasVotes || opts.form.model.closed} - checkboxchecked={form.model.limitChoices} - ontogglecheckbox={toggleLimitChoices}/> - </div> - <div show="{form.model.limitChoices}" class="o-form-element"> - <label class="c-label" for="maxChoiceNumber"> - {__.maxChoiceNumber} - </label> - <input name="maxChoiceNumber" - tabindex="1" - id="maxChoiceNumber" - ref="maxChoiceNumber" - class="c-field c-field--label" - disabled={form.hasVotes || opts.form.model.closed} - value={form.model.maxChoiceNumber} - min="{form.model.limitChoices ? 1 : 0}" max="{form.choices.length}" - type="number"> - </div> + <MaxChoicesNumberConfig if={opts.form.model.voteCountingType == 1 || opts.form.model.voteCountingType == 4} + ref="config" + config={form.model.voteCountingConfig} + count-choices={form.choices.length} + disabled={form.hasVotes || form.model.closed}/> + <BordaConfig if={opts.form.model.voteCountingType == 5} + ref="config" + config={form.model.voteCountingConfig} + count-choices={form.choices.length} + disabled={form.hasVotes || form.model.closed}/> + <CumulativeConfig if={opts.form.model.voteCountingType == 2} + ref="config" + config={form.model.voteCountingConfig} + disabled={form.hasVotes || form.model.closed}/> </div> </div> @@ -337,7 +331,6 @@ require("../components/Checkbox.tag.html"); this.showOptions = this.form.showOptions; this.showHelp = false; this.voteCountingTypes = new Map(this.form.voteCountingTypes.map((t) => [t.id.toString(), t])); - this.canLimitNumberOfChoices = this.voteCountingTypes.get(this.form.model.voteCountingType.toString()).canLimitNumberOfChoices; this.form.model.votePeriod = this.form.model.beginDate || this.form.model.endDate; this.notifyMeBeforePollEnds = this.form.model.creatorEmail && this.form.model.notifyMeHoursBeforePollEnds > 0; this.disableNotifyMeBeforePollEnds = !this.form.model.creatorEmail || !this.form.model.votePeriod || !this.form.model.endDate; @@ -388,14 +381,6 @@ require("../components/Checkbox.tag.html"); this.update(); }; - this.toggleLimitChoices = () => { - this.form.model.limitChoices = !this.form.model.limitChoices; - if (this.form.model.limitChoices && !this.form.model.maxChoiceNumber) { - this.form.model.maxChoiceNumber = 1; - } - this.update(); - }; - this.toggleVotePeriod = () => { this.form.model.votePeriod = !this.form.model.votePeriod; this.updateDisableNotifyMeBeforePollEnds(); @@ -431,8 +416,6 @@ require("../components/Checkbox.tag.html"); } else { this.form.model.voteCountingType = e.target.value; } - this.canLimitNumberOfChoices = this.voteCountingTypes.get(this.form.model.voteCountingType).canLimitNumberOfChoices; - this.form.model.limitChoices &= this.canLimitNumberOfChoices; this.updateVoteCountingTypeHelp(); }; @@ -458,13 +441,13 @@ require("../components/Checkbox.tag.html"); this.form.model.addChoices = this.refs.addChoices.checked; this.form.model.beginChoiceDate = this.refs.addChoices.checked ? this.refs.beginChoiceDate.getValue() : undefined; this.form.model.endChoiceDate = this.refs.addChoices.checked ? this.refs.endChoiceDate.getValue() : undefined; - this.form.model.maxChoiceNumber = this.refs.limitChoices.checked ? this.refs.maxChoiceNumber.value : undefined; this.form.model.beginDate = this.refs.votePeriod.checked ? this.refs.beginDate.getValue() : undefined; this.form.model.voteVisibility = this.refs.voteVisibility.value; this.form.model.anonymousVoteAllowed = this.refs.anonymousVote.checked; this.form.model.resultVisibility = this.refs.resultVisibility.value; this.form.model.commentVisibility = this.refs.commentVisibility.value; + this.form.model.voteCountingConfig = this.refs.config ? this.refs.config.getConfig() : {}; } this.form.model.endDate = this.refs.votePeriod.checked ? this.refs.endDate.getValue() : undefined; @@ -485,7 +468,6 @@ require("../components/Checkbox.tag.html"); this.listen("locale", () => { this.form.reloadVoteCountingTypes().then(() => { this.voteCountingTypes = new Map(this.form.voteCountingTypes.map((t) => [t.id.toString(), t])); - this.canLimitNumberOfChoices = this.voteCountingTypes.get(this.form.model.voteCountingType.toString()).canLimitNumberOfChoices; this.updateVoteCountingTypeHelp(); }); }); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html index 5d25d051..9e88a4a4 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html @@ -71,7 +71,7 @@ require("../components/Avatar.tag.html"); <input if={!pollTypeCheckbox} class="text c-field {c-field--error: !voteInEdition && error && (error['vote.voteValue#' + choice.id] || error['vote.totalVoteValue'])}" type="number" - required + required={!poll.voteCountingConfig.maxChoiceNumber} min="{poll.voteCountingTypeValue && poll.voteCountingTypeValue.minimumValue}" max="{poll.voteCountingTypeValue && poll.voteCountingTypeValue.maximumValue}" onchange="{onVoteChanged}" @@ -119,7 +119,7 @@ require("../components/Avatar.tag.html"); </button> </div> <div class="c-hint--static c-hint--error" if="{tooManyChoicesSelected}"> - {__.tooManyChoicesSelected} {poll.maxChoiceNumber} + {__.tooManyChoicesSelected} {poll.voteCountingConfig.maxChoiceNumber} </div> <div class="c-hint--static c-hint--error" if="{error}"> <div each={fields in error}> @@ -335,7 +335,7 @@ require("../components/Avatar.tag.html"); }; this.onVoteChanged = () => { - if (this.loaded && this.poll.maxChoiceNumber) { + if (this.loaded && this.poll.voteCountingConfig.maxChoiceNumber) { var selectedChoiceNb = 0; this.poll.choices.forEach(c => { var choiceValue = this.getChoiceVoteValue(c.id + "_voteValue"); @@ -343,7 +343,7 @@ require("../components/Avatar.tag.html"); selectedChoiceNb++; } }); - this.tooManyChoicesSelected = selectedChoiceNb > this.poll.maxChoiceNumber; + this.tooManyChoicesSelected = selectedChoiceNb > this.poll.voteCountingConfig.maxChoiceNumber; } else { this.tooManyChoicesSelected = false; } diff --git a/pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaConfig.tag.html b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaConfig.tag.html new file mode 100644 index 00000000..e15a2653 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaConfig.tag.html @@ -0,0 +1,107 @@ +require("./MaxChoicesNumberConfig.tag.html"); + +<BordaConfig> + + <MaxChoicesNumberConfig ref="maxChoiceNumber" + config={opts.config} + count-choices={opts.countChoices} + disabled={opts.disabled} + onchange={updatePointsByRank}/> + + <div class="o-form-element"> + <Checkbox label="{__.bordaDefault}" + name="bordaDefault" + id="bordaDefault" + ref="bordaDefault" + disabled={opts.disabled} + checkboxchecked={opts.config.pointsByRankDefault} + ontogglecheckbox={toggleBordaDefault}/> + </div> + <div class="o-form-element"> + <label class="c-label" for="maxChoiceNumber"> + {__.pointsByRank} + </label> + <div class="c-input-group c-input-group--stacked c-field--label"> + <div class="o-field ranks" + each={value, index in opts.config.pointsByRank || []}> + <i class="rank">{parent.__.rank} {index + 1} :</i> + <input name="points-{index}" + tabindex="1" + id="points-{index}" + ref="points" + class="c-field" + disabled={parent.opts.disabled || parent.opts.config.pointsByRankDefault} + value={value} + min="{index + 1 === parent.opts.config.pointsByRank.length ? 1 : parent.opts.config.pointsByRank[index + 1]}" + max="{index === 0 ? undefined : parent.opts.config.pointsByRank[index - 1]}" + onChange={parent.pointsChange(index)} + type="number"> + <i class="points">{parent.__.points}</i> + </div> + </div> + </div> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "poll_settings_voteCountingConfig"); + + if (this.opts.config.pointsByRankDefault === undefined) { + this.opts.config.pointsByRankDefault = this.opts.config.pointsByRank === undefined || this.opts.config.pointsByRank === null; + } + + + this.toggleBordaDefault = () => { + this.opts.config.pointsByRankDefault = !this.opts.config.pointsByRankDefault; + if (this.opts.config.pointsByRankDefault) { + this.updatePointsByRank(); + } + this.update(); + }; + + this.updatePointsByRank = () => { + let length = this.opts.config.maxChoiceNumber || this.opts.countChoices; + this.opts.config.pointsByRank = Array.from(Array(length).keys(), x => length - x); + }; + + this.pointsChange = index => () => { + this.opts.config.pointsByRank[index] = this.refs.points[index].valueAsNumber; + }; + + this.getConfig = () => { + let config = this.refs.maxChoiceNumber.getConfig(); + config.pointsByRank = this.opts.config.pointsByRankDefault ? null : this.refs.points.map(input => input.valueAsNumber); + return config; + }; + + if (!this.opts.config.pointsByRank) { + this.updatePointsByRank(); + } + + + </script> + + <style> + + .ranks .rank { + left: .5em; + position: absolute; + top: 50%; + transform: translateY(-50%); + color: var(--default); + } + + .ranks .points { + right: .5em; + position: absolute; + top: 50%; + transform: translateY(-50%); + color: var(--default); + } + + .ranks .c-field { + padding-left: 5em; + padding-right: 4em; + } + </stryle> + +</BordaConfig> diff --git a/pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaDetailResult.tag.html b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaDetailResult.tag.html index 7fa67c9a..a5b25608 100644 --- a/pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaDetailResult.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/BordaDetailResult.tag.html @@ -8,12 +8,12 @@ it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. #L% @@ -25,15 +25,15 @@ require("../poll/ChoiceView.tag.html"); <table class="ranks"> <tr> <td class="cell">{__.ranks}</td> - <td class="cell rank" each={rank in Array.from(Array(poll.choices.length).keys())}> + <td class="cell rank" each={rank in Array.from(Array(poll.voteCountingConfig.maxChoiceNumber || poll.choices.length).keys())}> {rank + 1} </td> <td class="cell"></td> </tr> <tr> <td class="cell separator-top">{__.points}</td> - <td class="cell separator-top" each={rank in Array.from(Array(poll.choices.length).keys())}> - {poll.choices.length - rank} + <td class="cell separator-top" each={rank in Array.from(Array(poll.voteCountingConfig.maxChoiceNumber || poll.choices.length).keys())}> + {poll.voteCountingConfig.pointsByRank ? poll.voteCountingConfig.pointsByRank[rank] : (poll.voteCountingConfig.maxChoiceNumber || poll.choices.length) - rank} </td> <td class="cell score">{__.total}</td> </tr> @@ -41,7 +41,7 @@ require("../poll/ChoiceView.tag.html"); <td class="cell separator-top"> <ChoiceView choice={choice} center="true"/> </td> - <td class="cell separator-top" each={rank in Array.from(Array(poll.choices.length).keys())}> + <td class="cell separator-top" each={rank in Array.from(Array(poll.voteCountingConfig.maxChoiceNumber || poll.choices.length).keys())}> {getRankScore(choice, rank)} </td> <td class="cell separator-top score"> diff --git a/pollen-ui-riot-js/src/main/web/tag/voteCountingType/CumulativeConfig.tag.html b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/CumulativeConfig.tag.html new file mode 100644 index 00000000..e2b4f9c2 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/CumulativeConfig.tag.html @@ -0,0 +1,34 @@ +<CumulativeConfig> + + <div class="o-form-element"> + <label class="c-label" for="points"> + {__.cumulativePoints} + </label> + <input name="points" + tabindex="1" + id="points" + ref="points" + class="c-field c-field--label" + disabled={opts.disabled} + value={opts.config.points} + min="2" + type="number"> + </div> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "poll_settings_voteCountingConfig"); + + if (!this.opts.config.points) { + this.opts.config.points = 100; + } + + this.getConfig = () => { + return { + points: this.refs.points.valueAsNumber + }; + }; + + </script> + +</CumulativeConfig> diff --git a/pollen-ui-riot-js/src/main/web/tag/voteCountingType/MaxChoicesNumberConfig.tag.html b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/MaxChoicesNumberConfig.tag.html new file mode 100644 index 00000000..5eed5c93 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voteCountingType/MaxChoicesNumberConfig.tag.html @@ -0,0 +1,60 @@ +<MaxChoicesNumberConfig> + + <div class="o-form-element"> + <Checkbox label="{__.limitChoices}" + name="limitChoices" + id="limitChoices" + ref="limitChoices" + disabled={opts.disabled} + checkboxchecked={opts.config.maxChoiceNumber > 0} + ontogglecheckbox={toggleLimitChoices}/> + </div> + <div show={opts.config.maxChoiceNumber > 0} class="o-form-element"> + <label class="c-label" for="maxChoiceNumber"> + {__.maxChoiceNumber} + </label> + <input name="maxChoiceNumber" + tabindex="1" + id="maxChoiceNumber" + ref="maxChoiceNumber" + class="c-field c-field--label" + disabled={opts.disabled} + value={Math.max(1, opts.config.maxChoiceNumber)} + min="1" max="{opts.countChoices}" + type="number" + onchange={maxChoiceNumberChange}> + </div> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "poll_settings_voteCountingConfig"); + + this.toggleLimitChoices = () => { + if (this.opts.config.maxChoiceNumber === 0) { + this.opts.config.maxChoiceNumber = this.opts.countChoices; + } else { + this.opts.config.maxChoiceNumber = 0; + } + if (this.opts.onchange) { + this.opts.onchange(); + } + this.update(); + }; + + this.maxChoiceNumberChange = () => { + this.opts.config.maxChoiceNumber = this.refs.maxChoiceNumber.valueAsNumber; + if (this.opts.onchange) { + this.opts.onchange(); + } + }; + + this.getConfig = () => { + return { + maxChoiceNumber: this.refs.limitChoices.checked ? this.refs.maxChoiceNumber.valueAsNumber : 0 + }; + }; + + </script> + + +</MaxChoicesNumberConfig> diff --git a/pollen-votecounting-aggregator/pom.xml b/pollen-votecounting-aggregator/pom.xml index 21f7884e..d5e69273 100644 --- a/pollen-votecounting-aggregator/pom.xml +++ b/pollen-votecounting-aggregator/pom.xml @@ -41,7 +41,7 @@ <modules> <module>../pollen-votecounting-normal</module> - <module>../pollen-votecounting-percentage</module> + <module>../pollen-votecounting-cumulative</module> <module>../pollen-votecounting-condorcet</module> <module>../pollen-votecounting-number</module> <module>../pollen-votecounting-borda</module> @@ -57,7 +57,7 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-percentage</artifactId> + <artifactId>pollen-votecounting-cumulative</artifactId> <version>${project.version}</version> </dependency> <dependency> diff --git a/pollen-votecounting-api/pom.xml b/pollen-votecounting-api/pom.xml index c6b796ae..61491300 100644 --- a/pollen-votecounting-api/pom.xml +++ b/pollen-votecounting-api/pom.xml @@ -63,6 +63,10 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> </dependencies> diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java index d05c3377..7e28a8fd 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java @@ -21,6 +21,8 @@ package org.chorem.pollen.votecounting; * #L% */ +import org.chorem.pollen.votecounting.model.VoteCountingConfig; + import java.util.Locale; import static org.nuiton.i18n.I18n.l; @@ -31,7 +33,7 @@ import static org.nuiton.i18n.I18n.l; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public abstract class AbstractVoteCounting<S extends VoteCountingStrategy> implements VoteCounting<S> { +public abstract class AbstractVoteCounting<S extends VoteCountingStrategy<C>, C extends VoteCountingConfig> implements VoteCounting<S, C> { /** Unique id of the vote counting type. */ protected final int id; @@ -39,6 +41,9 @@ public abstract class AbstractVoteCounting<S extends VoteCountingStrategy> imple /** Type of strategy used to vote count. */ protected final Class<S> strategyType; + /** Type of config used to vote count. */ + protected final Class<C> configType; + /** I18n key for name of this vote counting type. */ protected final String i18nName; @@ -50,11 +55,13 @@ public abstract class AbstractVoteCounting<S extends VoteCountingStrategy> imple protected AbstractVoteCounting(int id, Class<S> strategyType, + Class<C> configType, String i18nName, String i18nShortHelp, String i18nHelp) { this.id = id; this.strategyType = strategyType; + this.configType = configType; this.i18nName = i18nName; this.i18nShortHelp = i18nShortHelp; this.i18nHelp = i18nHelp; @@ -90,4 +97,9 @@ public abstract class AbstractVoteCounting<S extends VoteCountingStrategy> imple public final int getId() { return id; } + + @Override + public Class<C> getConfigType() { + return configType; + } } diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java index 50f6cf03..ffd402bf 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java @@ -29,6 +29,7 @@ import org.chorem.pollen.votecounting.model.ChoiceIdAble; import org.chorem.pollen.votecounting.model.ChoiceScore; import org.chorem.pollen.votecounting.model.ListOfVoter; import org.chorem.pollen.votecounting.model.ListVoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import org.chorem.pollen.votecounting.model.VoteCountingDetailResult; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; @@ -49,7 +50,7 @@ import java.util.stream.Collectors; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public abstract class AbstractVoteCountingStrategy implements VoteCountingStrategy { +public abstract class AbstractVoteCountingStrategy<C extends VoteCountingConfig> implements VoteCountingStrategy<C> { public static final BigDecimal ZERO_D = BigDecimal.valueOf(0.); @@ -65,6 +66,13 @@ public abstract class AbstractVoteCountingStrategy implements VoteCountingStrate return v1.intValue() - v2.intValue(); }; + protected C config; + + @Override + public void setConfig(C config) { + this.config = config; + } + @Override public final ListVoteCountingResult votecount(ListOfVoter listOfVoter) { diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java index b3ec2f24..eb127b3b 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; */ import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import java.util.Locale; @@ -31,7 +32,7 @@ import java.util.Locale; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public interface VoteCounting<S extends VoteCountingStrategy> { +public interface VoteCounting<S extends VoteCountingStrategy<C>, C extends VoteCountingConfig> { /** * Obtains a fresh instance of a vote coutning strategy. @@ -42,6 +43,13 @@ public interface VoteCounting<S extends VoteCountingStrategy> { S newStrategy(); /** + * get vote couting config type + * + * @return a vote counting config type . + */ + Class<C> getConfigType(); + + /** * Obtains the unique id of this strategy. * * @return the unique id of this strategy. @@ -116,7 +124,7 @@ public interface VoteCounting<S extends VoteCountingStrategy> { * @return {@code true} if the total values of a vote is valid, * {@code false} otherwhise. */ - boolean isTotalVoteValueValid(Double totalValues); + boolean isTotalVoteValueValid(Double totalValues, C config); /** * If the total values of a vote is not valid, gets the localized error @@ -125,7 +133,7 @@ public interface VoteCounting<S extends VoteCountingStrategy> { * @param locale the locale used to render the error message * @return the localized validation message */ - String getTotalVoteValueNotValidMessage(Locale locale); + String getTotalVoteValueNotValidMessage(Locale locale, C config); /** * Tests if a given vote value is null or not. diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java index 361d7f57..d5a50dc3 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java @@ -24,6 +24,7 @@ package org.chorem.pollen.votecounting; import com.google.common.collect.Maps; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import java.util.Iterator; import java.util.Locale; @@ -77,7 +78,7 @@ public class VoteCountingFactory implements Iterable<VoteCounting> { } - public VoteCounting getVoteCounting(int strategyId) throws VoteCountingNotFound { + public <S extends VoteCountingStrategy<C>, C extends VoteCountingConfig> VoteCounting<S, C> getVoteCounting(int strategyId) throws VoteCountingNotFound { VoteCounting type = voteCountings.get(strategyId); if (type == null) { diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java index 93f9de1f..598beb66 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; import org.chorem.pollen.votecounting.model.ListOfVoter; import org.chorem.pollen.votecounting.model.ListVoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteCountingConfig; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -34,7 +35,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public interface VoteCountingStrategy { +public interface VoteCountingStrategy<C extends VoteCountingConfig> { /** * Vote count for the given {@code group} of voters and return the @@ -60,4 +61,6 @@ public interface VoteCountingStrategy { * @return the vot for choices */ Set<VoteForChoice> toVoteForChoices(VoteCountingResult voteCountingResult); + + void setConfig(C config); } diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/EmptyVoteCountingConfig.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/EmptyVoteCountingConfig.java new file mode 100644 index 00000000..140850d6 --- /dev/null +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/EmptyVoteCountingConfig.java @@ -0,0 +1,7 @@ +package org.chorem.pollen.votecounting.model; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class EmptyVoteCountingConfig implements VoteCountingConfig { +} diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/MaxChoicesNumberConfig.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/MaxChoicesNumberConfig.java new file mode 100644 index 00000000..5d48c0b6 --- /dev/null +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/MaxChoicesNumberConfig.java @@ -0,0 +1,17 @@ +package org.chorem.pollen.votecounting.model; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class MaxChoicesNumberConfig implements VoteCountingConfig { + + protected int maxChoiceNumber; + + public int getMaxChoiceNumber() { + return maxChoiceNumber; + } + + public void setMaxChoiceNumber(int maxChoiceNumber) { + this.maxChoiceNumber = maxChoiceNumber; + } +} diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingConfig.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingConfig.java new file mode 100644 index 00000000..21e317e8 --- /dev/null +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingConfig.java @@ -0,0 +1,7 @@ +package org.chorem.pollen.votecounting.model; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public interface VoteCountingConfig { +} diff --git a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaConfig.java b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaConfig.java new file mode 100644 index 00000000..3def5e15 --- /dev/null +++ b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaConfig.java @@ -0,0 +1,21 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class BordaConfig extends MaxChoicesNumberConfig { + + protected List<Integer> pointsByRank; + + public List<Integer> getPointsByRank() { + return pointsByRank; + } + + public void setPointsByRank(List<Integer> pointsByRank) { + this.pointsByRank = pointsByRank; + } +} diff --git a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java index c9168a49..637bcc7f 100644 --- a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java +++ b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java @@ -34,13 +34,14 @@ import static org.nuiton.i18n.I18n.n; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public class BordaVoteCounting extends AbstractVoteCounting<BordaVoteCountingStrategy> { +public class BordaVoteCounting extends AbstractVoteCounting<BordaVoteCountingStrategy, BordaConfig> { public static final int ID = 5; public BordaVoteCounting() { super(ID, BordaVoteCountingStrategy.class, + BordaConfig.class, n("pollen.voteCountingType.borda"), n("pollen.voteCountingType.borda.shortHelp"), n("pollen.voteCountingType.borda.help") @@ -48,7 +49,7 @@ public class BordaVoteCounting extends AbstractVoteCounting<BordaVoteCountingStr } @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { + public String getTotalVoteValueNotValidMessage(Locale locale, BordaConfig config) { // no validation on total value, so no message return null; } @@ -102,7 +103,7 @@ public class BordaVoteCounting extends AbstractVoteCounting<BordaVoteCountingStr } @Override - public boolean isTotalVoteValueValid(Double totalValues) { + public boolean isTotalVoteValueValid(Double totalValues, BordaConfig config) { // no validation on total value return true; } diff --git a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java index b2fb5605..befd8304 100644 --- a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java +++ b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java @@ -21,6 +21,7 @@ package org.chorem.pollen.votecounting; import com.google.common.collect.Sets; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.pollen.votecounting.model.ChoiceScore; @@ -39,7 +40,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { +public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy<BordaConfig> { /** Logger. */ private static final Log log = @@ -59,6 +60,12 @@ public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { log.debug("Nb choices: " + nbChoices); } + // nb Ranks + int nbRanks = nbChoices; + if (config.getMaxChoiceNumber() > 0) { + nbRanks = config.getMaxChoiceNumber(); + } + // calcul pour chaque votant de sa liste des choix dans son ordre préféré Map<Voter, List<Set<String>>> voterSortedChoices = @@ -70,10 +77,32 @@ public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { for (Map.Entry<Voter, List<Set<String>>> entry : voterSortedChoices.entrySet()) { Voter voter = entry.getKey(); double weight = voter.getWeight(); - double choiceWeight = nbChoices * weight; + List<Integer> pointsByRank = config.getPointsByRank(); + int rank = 0; + for (Set<String> sortedChoiceId : entry.getValue()) { + double choiceWeight; + + if (CollectionUtils.isNotEmpty(pointsByRank)) { + + if (pointsByRank.size() > rank) { + + choiceWeight = pointsByRank.get(rank) * weight; + + } else { + + choiceWeight = 0; + + } + + } else { + + choiceWeight = (nbRanks - rank) * weight; + + } + for (String choiceId : sortedChoiceId) { scores.get(choiceId).addScoreValue(choiceWeight); @@ -81,7 +110,10 @@ public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { } rank++; - choiceWeight -= weight; + + if (rank > nbRanks) { + break; + } } } diff --git a/pollen-votecounting-borda/src/main/resources/i18n/pollen-votecounting-borda_fr_FR.properties b/pollen-votecounting-borda/src/main/resources/i18n/pollen-votecounting-borda_fr_FR.properties index 789614f5..dd0d5b77 100644 --- a/pollen-votecounting-borda/src/main/resources/i18n/pollen-votecounting-borda_fr_FR.properties +++ b/pollen-votecounting-borda/src/main/resources/i18n/pollen-votecounting-borda_fr_FR.properties @@ -1,4 +1,4 @@ pollen.error.vote.invalidBordaVoteValue=La valeur du vote '%2$s' pour le choix %1$s n'est pas correcte, seul des valeurs entières sont autorisées. pollen.voteCountingType.borda=Borda -pollen.voteCountingType.borda.help=Classer les choix par ordre de préférence de 1 à N (1\=préféré).<br/> Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur.<br/>Pour chaque vote, on attribue des points aux choix en fonction de leur rang (comme pour le concours de l'Eurovision) ; le gagnant est le choix avec le plus de points.<br/>Pour en savoir plus \: <a href\='http\://fr.wikipedia.org/wiki/M%C3%A9thode_Borda' target\='\#doc'>http\://fr.wikip [...] +pollen.voteCountingType.borda.help=Classer les choix par ordre de préférence de 1 à N (1\=préféré).<br/> Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur.<br/>Pour chaque vote, on attribue des points aux choix en fonction de leur rang (comme pour le concours de l'Eurovision) ; le gagnant est le choix avec le plus de points.<br/>Pour en savoir plus \: <a href\='http\://fr.wikipedia.org/wiki/M%C3%A9thode_Borda' target\='\#doc'>http\://fr.wikip [...] pollen.voteCountingType.borda.shortHelp=Classer les choix par ordre de préférence de 1 à N (1\=préféré). diff --git a/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java b/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java index bb9404f3..53b07c12 100644 --- a/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java +++ b/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java @@ -54,19 +54,21 @@ public class BordaVoteCountingStrategyTest { public static final String CHOICE_D = "d"; - protected static VoteCounting voteCounting; + protected static BordaVoteCounting voteCounting; - protected VoteCountingStrategy strategy; + protected BordaVoteCountingStrategy strategy; @BeforeClass public static void beforeClass() throws Exception { VoteCountingFactory factory = new VoteCountingFactory(); - voteCounting = factory.getVoteCounting(BordaVoteCounting.ID); + voteCounting = BordaVoteCounting.class.cast(factory.getVoteCounting(BordaVoteCounting.ID)); } @Before public void setUp() throws Exception { strategy = voteCounting.newStrategy(); + BordaConfig config = new BordaConfig(); + strategy.setConfig(config); } @Test diff --git a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java index 4949d521..f43e8ea6 100644 --- a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java +++ b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; */ import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import java.util.Locale; @@ -34,13 +35,14 @@ import static org.nuiton.i18n.I18n.n; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public class CondorcetVoteCounting extends AbstractVoteCounting<CondorcetVoteCountingStrategy> { +public class CondorcetVoteCounting extends AbstractVoteCounting<CondorcetVoteCountingStrategy, EmptyVoteCountingConfig> { public static final int ID = 3; public CondorcetVoteCounting() { super(ID, CondorcetVoteCountingStrategy.class, + EmptyVoteCountingConfig.class, n("pollen.voteCountingType.condorcet"), n("pollen.voteCountingType.condorcet.shortHelp"), n("pollen.voteCountingType.condorcet.help") @@ -48,7 +50,7 @@ public class CondorcetVoteCounting extends AbstractVoteCounting<CondorcetVoteCou } @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { + public String getTotalVoteValueNotValidMessage(Locale locale, EmptyVoteCountingConfig config) { // no validation on total value, so no message return null; } @@ -102,7 +104,7 @@ public class CondorcetVoteCounting extends AbstractVoteCounting<CondorcetVoteCou } @Override - public boolean isTotalVoteValueValid(Double totalValues) { + public boolean isTotalVoteValueValid(Double totalValues, EmptyVoteCountingConfig config) { // no validation on total value return true; } diff --git a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java index a2d122d7..7db1fb77 100644 --- a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java +++ b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java @@ -24,6 +24,7 @@ import com.google.common.collect.Sets; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -38,7 +39,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy { +public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy<EmptyVoteCountingConfig> { /** Logger. */ private static final Log log = diff --git a/pollen-votecounting-condorcet/src/main/resources/i18n/pollen-votecounting-condorcet_fr_FR.properties b/pollen-votecounting-condorcet/src/main/resources/i18n/pollen-votecounting-condorcet_fr_FR.properties index f79011b4..0452c805 100644 --- a/pollen-votecounting-condorcet/src/main/resources/i18n/pollen-votecounting-condorcet_fr_FR.properties +++ b/pollen-votecounting-condorcet/src/main/resources/i18n/pollen-votecounting-condorcet_fr_FR.properties @@ -1,4 +1,4 @@ pollen.error.vote.invalidCondorcetVoteValue=La valeur du vote '%2$s' pour le choix %1$s n'est pas correcte, seul des valeurs entières sont autorisées. pollen.voteCountingType.condorcet=Condorcet -pollen.voteCountingType.condorcet.help=Classer les choix par ordre de préférence de 1 à N (1\=préféré).<br/>Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur.<br/>Dans cette méthode, le gagnant est celui qui remporte le plus de combats par rapport aux autres choix.<br/>Pour en savoir plus \: <a href\='http\://fr.wikipedia.org/wiki/M%C3%A9thode_Condorcet' target\='\#doc'>http\://fr.wikipedia.org/wiki/M%C3%A9thode_Condorcet</a> +pollen.voteCountingType.condorcet.help=Classer les choix par ordre de préférence de 1 à N (1\=préféré).<br/>Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur.<br/>Dans cette méthode, le gagnant est celui qui remporte le plus de combats par rapport aux autres choix.<br/>Pour en savoir plus \: <a href\='http\://fr.wikipedia.org/wiki/M%C3%A9thode_Condorcet' target\='\#doc'>http\://fr.wikipedia.org/wiki/Méthode_Condorcet</a> pollen.voteCountingType.condorcet.shortHelp=Classer les choix par ordre de préférence de 1 à N (1\=préféré). diff --git a/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java b/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java index 59eb5c0a..04f811b8 100644 --- a/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java +++ b/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; import com.google.common.collect.Sets; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import org.chorem.pollen.votecounting.model.ListOfVoter; import org.chorem.pollen.votecounting.model.ListVoteCountingResult; import org.chorem.pollen.votecounting.model.SimpleVoter; @@ -52,19 +53,20 @@ public class CondorcetVoteCountingStrategyTest { public static final String CHOICE_C = "c"; - protected static VoteCounting voteCounting; + protected static CondorcetVoteCounting voteCounting; - protected VoteCountingStrategy strategy; + protected CondorcetVoteCountingStrategy strategy; @BeforeClass public static void beforeClass() throws Exception { VoteCountingFactory factory = new VoteCountingFactory(); - voteCounting = factory.getVoteCounting(CondorcetVoteCounting.ID); + voteCounting = CondorcetVoteCounting.class.cast(factory.getVoteCounting(CondorcetVoteCounting.ID)); } @Before public void setUp() throws Exception { strategy = voteCounting.newStrategy(); + strategy.setConfig(new EmptyVoteCountingConfig()); } @Test diff --git a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java index 955c5467..1d30fbd0 100644 --- a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java +++ b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; */ import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import java.util.Locale; @@ -34,13 +35,14 @@ import static org.nuiton.i18n.I18n.n; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public class CoombsVoteCounting extends AbstractVoteCounting<CoombsVoteCountingStrategy> { +public class CoombsVoteCounting extends AbstractVoteCounting<CoombsVoteCountingStrategy, EmptyVoteCountingConfig> { public static final int ID = 7; public CoombsVoteCounting() { super(ID, CoombsVoteCountingStrategy.class, + EmptyVoteCountingConfig.class, n("pollen.voteCountingType.coombs"), n("pollen.voteCountingType.coombs.shortHelp"), n("pollen.voteCountingType.coombs.help") @@ -48,7 +50,7 @@ public class CoombsVoteCounting extends AbstractVoteCounting<CoombsVoteCountingS } @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { + public String getTotalVoteValueNotValidMessage(Locale locale, EmptyVoteCountingConfig config) { // no validation on total value, so no message return null; } @@ -103,7 +105,7 @@ public class CoombsVoteCounting extends AbstractVoteCounting<CoombsVoteCountingS } @Override - public boolean isTotalVoteValueValid(Double totalValues) { + public boolean isTotalVoteValueValid(Double totalValues, EmptyVoteCountingConfig config) { // no validation on total value return true; } diff --git a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java index 0ab194ee..2048d8e7 100644 --- a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java +++ b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java @@ -25,6 +25,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -43,7 +44,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { +public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy<EmptyVoteCountingConfig> { @Override public VoteCountingResult votecount(Set<Voter> voters) { diff --git a/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_en_GB.properties b/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_en_GB.properties index b70fc7ef..d6902ca1 100644 --- a/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_en_GB.properties +++ b/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_en_GB.properties @@ -1,4 +1,4 @@ pollen.error.vote.invalidCoombsVoteValue=The value '%2$s' of vote for choice %1$s is not valid, only integer values are authorized. pollen.voteCountingType.coombs=Coombs -pollen.voteCountingType.coombs.help=Rank choices by preference order from 1 to N (1\=favorite).<br/>Only the rank is taken into account, not the values. Two choices can have the same value.<br/>In this method, the choice which is last the most times is eliminated round by round until only one remains.<br/>More about this method\: <a href\='http\://en.wikipedia.org/wiki/Coombs%27_method' target\='\#doc'>http\://en.wikipedia.org/wiki/Coombs%27_method</a> +pollen.voteCountingType.coombs.help=Rank choices by preference order from 1 to N (1\=favorite).<br/>Only the rank is taken into account, not the values. Two choices can have the same value.<br/>In this method, the choice which is last the most times is eliminated round by round until only one remains.<br/>More about this method\: <a href\='http\://en.wikipedia.org/wiki/Coombs%27_method' target\='\#doc'>http\://en.wikipedia.org/wiki/Coombs_method</a> pollen.voteCountingType.coombs.shortHelp=Rank choices by preference order from 1 to N (1\=favorite). diff --git a/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_fr_FR.properties b/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_fr_FR.properties index 6674d907..a62223d3 100644 --- a/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_fr_FR.properties +++ b/pollen-votecounting-coombs/src/main/resources/i18n/pollen-votecounting-coombs_fr_FR.properties @@ -1,4 +1,4 @@ pollen.error.vote.invalidCoombsVoteValue=La valeur du vote '%2$s' pour le choix %1$s n'est pas correcte, seul des valeurs entières sont autorisées. pollen.voteCountingType.coombs=Coombs -pollen.voteCountingType.coombs.help=Classer les choix par ordre de préférence de 1 à N (1\=préféré).<br/>Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur.<br/>Dans cette méthode, le choix qui arrive le plus souvent en dernier de liste est éliminé à chaque tour, jusqu'à ce qu'il n'en reste qu'un.<br/>Pour en savoir plus \: <a href\='http\://fr.wikipedia.org/wiki/M%C3%A9thode_de_Coombs' target\='\#doc'>http\://fr.wikipedia.org/wiki/M%C3%A9thod [...] +pollen.voteCountingType.coombs.help=Classer les choix par ordre de préférence de 1 à N (1\=préféré).<br/>Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur.<br/>Dans cette méthode, le choix qui arrive le plus souvent en dernier de liste est éliminé à chaque tour, jusqu'à ce qu'il n'en reste qu'un.<br/>Pour en savoir plus \: <a href\='http\://fr.wikipedia.org/wiki/M%C3%A9thode_de_Coombs' target\='\#doc'>http\://fr.wikipedia.org/wiki/Méthode_de_ [...] pollen.voteCountingType.coombs.shortHelp=Classer les choix par ordre de préférence de 1 à N (1\=préféré). diff --git a/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java b/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java index 014a241c..9e388fb6 100644 --- a/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java +++ b/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java @@ -21,6 +21,7 @@ package org.chorem.pollen.votecounting; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.Voter; @@ -52,19 +53,20 @@ public class CoombsVoteCountingStrategyTest { public static final String CHOICE_D = "Ville D"; - protected static VoteCounting voteCounting; + protected static CoombsVoteCounting voteCounting; - protected VoteCountingStrategy strategy; + protected CoombsVoteCountingStrategy strategy; @BeforeClass public static void beforeClass() throws Exception { VoteCountingFactory factory = new VoteCountingFactory(); - voteCounting = factory.getVoteCounting(CoombsVoteCounting.ID); + voteCounting = CoombsVoteCounting.class.cast(factory.getVoteCounting(CoombsVoteCounting.ID)); } @Before public void setUp() throws Exception { strategy = voteCounting.newStrategy(); + strategy.setConfig(new EmptyVoteCountingConfig()); } @Test diff --git a/pollen-votecounting-percentage/LICENSE.txt b/pollen-votecounting-cumulative/LICENSE.txt similarity index 100% rename from pollen-votecounting-percentage/LICENSE.txt rename to pollen-votecounting-cumulative/LICENSE.txt diff --git a/pollen-votecounting-percentage/README.md b/pollen-votecounting-cumulative/README.md similarity index 100% rename from pollen-votecounting-percentage/README.md rename to pollen-votecounting-cumulative/README.md diff --git a/pollen-votecounting-percentage/pom.xml b/pollen-votecounting-cumulative/pom.xml similarity index 93% rename from pollen-votecounting-percentage/pom.xml rename to pollen-votecounting-cumulative/pom.xml index 1d75c4b9..8efd327a 100644 --- a/pollen-votecounting-percentage/pom.xml +++ b/pollen-votecounting-cumulative/pom.xml @@ -31,10 +31,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-percentage</artifactId> + <artifactId>pollen-votecounting-cumulative</artifactId> - <name>Pollen :: VoteCounting :: Percentage</name> - <description>Implements the percentage vote counting</description> + <name>Pollen :: VoteCounting :: Cumulative</name> + <description>Implements the cumulative vote counting</description> <dependencies> diff --git a/pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeConfig.java b/pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeConfig.java new file mode 100644 index 00000000..4ff961e4 --- /dev/null +++ b/pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeConfig.java @@ -0,0 +1,19 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.VoteCountingConfig; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CumulativeConfig implements VoteCountingConfig { + + protected int points; + + public int getPoints() { + return points; + } + + public void setPoints(int points) { + this.points = points; + } +} diff --git a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java b/pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCounting.java similarity index 77% rename from pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java rename to pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCounting.java index efd1e3ea..4ed03213 100644 --- a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java +++ b/pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCounting.java @@ -34,16 +34,17 @@ import static org.nuiton.i18n.I18n.n; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public class PercentageVoteCounting extends AbstractVoteCounting<PercentageVoteCountingStrategy> { +public class CumulativeVoteCounting extends AbstractVoteCounting<CumulativeVoteCountingStrategy, CumulativeConfig> { public static final int ID = 2; - public PercentageVoteCounting() { + public CumulativeVoteCounting() { super(ID, - PercentageVoteCountingStrategy.class, - n("pollen.voteCountingType.percentage"), - n("pollen.voteCountingType.percentage.shortHelp"), - n("pollen.voteCountingType.percentage.help") + CumulativeVoteCountingStrategy.class, + CumulativeConfig.class, + n("pollen.voteCountingType.cumulative"), + n("pollen.voteCountingType.cumulative.shortHelp"), + n("pollen.voteCountingType.cumulative.help") ); } @@ -89,8 +90,8 @@ public class PercentageVoteCounting extends AbstractVoteCounting<PercentageVoteC } @Override - public boolean isTotalVoteValueValid(Double totalValues) { - return totalValues == null || totalValues == 100; + public boolean isTotalVoteValueValid(Double totalValues, CumulativeConfig cumulativeConfig) { + return totalValues == null || totalValues == cumulativeConfig.getPoints(); } @Override @@ -102,8 +103,8 @@ public class PercentageVoteCounting extends AbstractVoteCounting<PercentageVoteC } @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - return l(locale, "pollen.error.vote.percentage"); + public String getTotalVoteValueNotValidMessage(Locale locale, CumulativeConfig cumulativeConfig) { + return l(locale, "pollen.error.vote.cumulative", cumulativeConfig.getPoints()); } } diff --git a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java b/pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategy.java similarity index 97% rename from pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java rename to pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategy.java index d503fd01..583629a6 100644 --- a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java +++ b/pollen-votecounting-cumulative/src/main/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategy.java @@ -36,7 +36,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class PercentageVoteCountingStrategy extends AbstractVoteCountingStrategy { +public class CumulativeVoteCountingStrategy extends AbstractVoteCountingStrategy<CumulativeConfig> { @Override public VoteCountingResult votecount(Set<Voter> voters) { diff --git a/pollen-votecounting-cumulative/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting b/pollen-votecounting-cumulative/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting new file mode 100644 index 00000000..afd5c887 --- /dev/null +++ b/pollen-votecounting-cumulative/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.CumulativeVoteCounting diff --git a/pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_en_GB.properties b/pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_en_GB.properties new file mode 100644 index 00000000..00701bf7 --- /dev/null +++ b/pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_en_GB.properties @@ -0,0 +1,4 @@ +pollen.error.vote.cumulative=choices sum must be equals to %1$s +pollen.voteCountingType.cumulative=Cumulative +pollen.voteCountingType.cumulative.help=Each voter has a given number of points. He distributes this number of points freely between all choices. The choice of the most points wins.<br/>More about this method\: <a href\='http\://en.wikipedia.org/wiki/Cumulative_voting' target\='\#doc'>http\://en.wikipedia.org/wiki/Cumulative_voting</a> +pollen.voteCountingType.cumulative.shortHelp=Allocate your points between all choices. diff --git a/pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_fr_FR.properties b/pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_fr_FR.properties new file mode 100644 index 00000000..8c27e46f --- /dev/null +++ b/pollen-votecounting-cumulative/src/main/resources/i18n/pollen-votecounting-cumulative_fr_FR.properties @@ -0,0 +1,4 @@ +pollen.error.vote.cumulative=La somme de tout les choix doit être égale à %1$s +pollen.voteCountingType.cumulative=Cumulatif +pollen.voteCountingType.cumulative.help=Chaque votant possède un nombre de points donnés. Il distribue ce nombre de points librement entre tous les choix. Le choix récoltant le plus de points gagne. <br/>Pour en savoir plus \: <a href\='http\://fr.wikipedia.org/wiki/Vote_cumulatif' target\='\#doc'>http\://fr.wikipedia.org/wiki/Vote_cumulatif</a> +pollen.voteCountingType.cumulative.shortHelp=Répartir vos points entre tous les choix. diff --git a/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java b/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java similarity index 97% rename from pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java rename to pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java index bcb8856a..b6bb2fe9 100644 --- a/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java +++ b/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java @@ -39,12 +39,12 @@ import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests the {@link PercentageVoteCountingStrategy}. + * Tests the {@link CumulativeVoteCountingStrategy}. * * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class PercentageVoteCountingStrategyTest { +public class CumulativeVoteCountingStrategyTest { public static final String CHOICE_A = "a"; @@ -52,20 +52,22 @@ public class PercentageVoteCountingStrategyTest { public static final String CHOICE_C = "c"; - protected static VoteCounting voteCounting; + protected static CumulativeVoteCounting voteCounting; - protected VoteCountingStrategy strategy; + protected CumulativeVoteCountingStrategy strategy; @BeforeClass public static void beforeClass() throws Exception { VoteCountingFactory factory = new VoteCountingFactory(); - voteCounting = factory.getVoteCounting(PercentageVoteCounting.ID); + voteCounting = CumulativeVoteCounting.class.cast(factory.getVoteCounting(CumulativeVoteCounting.ID)); } @Before public void setUp() throws Exception { - strategy = voteCounting.newStrategy(); + CumulativeConfig config = new CumulativeConfig(); + config.setPoints(100); + strategy.setConfig(config); } @Test diff --git a/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java b/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java similarity index 95% rename from pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java rename to pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java index 423f6984..f247f2cc 100644 --- a/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java +++ b/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java @@ -36,7 +36,7 @@ public class VoteCountingFactoryTest { VoteCountingFactory factory = new VoteCountingFactory(); VoteCounting voteCounting = - factory.getVoteCounting(PercentageVoteCounting.ID); + factory.getVoteCounting(CumulativeVoteCounting.ID); Assert.assertNotNull(voteCounting); } } diff --git a/pollen-votecounting-percentage/src/test/resources/log4j.properties b/pollen-votecounting-cumulative/src/test/resources/log4j.properties similarity index 100% rename from pollen-votecounting-percentage/src/test/resources/log4j.properties rename to pollen-votecounting-cumulative/src/test/resources/log4j.properties diff --git a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java index 1fafc24c..111368cd 100644 --- a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java +++ b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; */ import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import java.util.Locale; @@ -34,21 +35,22 @@ import static org.nuiton.i18n.I18n.n; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public class InstantRunoffVoteCounting extends AbstractVoteCounting<InstantRunoffVoteCountingStrategy> { +public class InstantRunoffVoteCounting extends AbstractVoteCounting<InstantRunoffVoteCountingStrategy, EmptyVoteCountingConfig> { public static final int ID = 6; public InstantRunoffVoteCounting() { super(ID, - InstantRunoffVoteCountingStrategy.class, - n("pollen.voteCountingType.instantRunoff"), - n("pollen.voteCountingType.instantRunoff.shortHelp"), - n("pollen.voteCountingType.instantRunoff.help") + InstantRunoffVoteCountingStrategy.class, + EmptyVoteCountingConfig.class, + n("pollen.voteCountingType.instantRunoff"), + n("pollen.voteCountingType.instantRunoff.shortHelp"), + n("pollen.voteCountingType.instantRunoff.help") ); } @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { + public String getTotalVoteValueNotValidMessage(Locale locale, EmptyVoteCountingConfig config) { // no validation on total value, so no message return null; } @@ -103,7 +105,7 @@ public class InstantRunoffVoteCounting extends AbstractVoteCounting<InstantRunof } @Override - public boolean isTotalVoteValueValid(Double totalValues) { + public boolean isTotalVoteValueValid(Double totalValues, EmptyVoteCountingConfig config) { // no validation on total value return true; } diff --git a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java index 5bb19870..4d0900bb 100644 --- a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java +++ b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java @@ -24,6 +24,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -42,7 +43,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrategy { +public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrategy<EmptyVoteCountingConfig> { @Override public VoteCountingResult votecount(Set<Voter> voters) { diff --git a/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java b/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java index 8f3580d2..96b78afc 100644 --- a/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java +++ b/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java @@ -21,6 +21,7 @@ package org.chorem.pollen.votecounting; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.EmptyVoteCountingConfig; import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.Voter; @@ -51,19 +52,20 @@ public class InstantRunoffVoteCountingStrategyTest { public static final String CHOICE_D = "Ville D"; - protected static VoteCounting voteCounting; + protected static InstantRunoffVoteCounting voteCounting; - protected VoteCountingStrategy strategy; + protected InstantRunoffVoteCountingStrategy strategy; @BeforeClass public static void beforeClass() throws Exception { VoteCountingFactory factory = new VoteCountingFactory(); - voteCounting = factory.getVoteCounting(InstantRunoffVoteCounting.ID); + voteCounting = InstantRunoffVoteCounting.class.cast(factory.getVoteCounting(InstantRunoffVoteCounting.ID)); } @Before public void setUp() throws Exception { strategy = voteCounting.newStrategy(); + strategy.setConfig(new EmptyVoteCountingConfig()); } @Test diff --git a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java index c69bc61e..e271e7b5 100644 --- a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java +++ b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; */ import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; import java.util.Locale; @@ -33,16 +34,17 @@ import static org.nuiton.i18n.I18n.n; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public class NormalVoteCounting extends AbstractVoteCounting<NormalVoteCountingStrategy> { +public class NormalVoteCounting extends AbstractVoteCounting<NormalVoteCountingStrategy, MaxChoicesNumberConfig> { public static final int ID = 1; public NormalVoteCounting() { super(ID, - NormalVoteCountingStrategy.class, - n("pollen.voteCountingType.normal"), - n("pollen.voteCountingType.normal.shortHelp"), - n("pollen.voteCountingType.normal.help") + NormalVoteCountingStrategy.class, + MaxChoicesNumberConfig.class, + n("pollen.voteCountingType.normal"), + n("pollen.voteCountingType.normal.shortHelp"), + n("pollen.voteCountingType.normal.help") ); } @@ -88,7 +90,7 @@ public class NormalVoteCounting extends AbstractVoteCounting<NormalVoteCountingS } @Override - public boolean isTotalVoteValueValid(Double totalValues) { + public boolean isTotalVoteValueValid(Double totalValues, MaxChoicesNumberConfig config) { // no validation on total value return true; } @@ -102,7 +104,7 @@ public class NormalVoteCounting extends AbstractVoteCounting<NormalVoteCountingS } @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { + public String getTotalVoteValueNotValidMessage(Locale locale, MaxChoicesNumberConfig config) { // no validation on total values, so no message return null; } diff --git a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java index 456e19c3..c65455ac 100644 --- a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java +++ b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; import com.google.common.collect.Sets; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -38,7 +39,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class NormalVoteCountingStrategy extends AbstractVoteCountingStrategy { +public class NormalVoteCountingStrategy extends AbstractVoteCountingStrategy<MaxChoicesNumberConfig> { @Override public VoteCountingResult votecount(Set<Voter> voters) { diff --git a/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java b/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java index 918b1667..2650b970 100644 --- a/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java +++ b/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java @@ -24,6 +24,7 @@ import com.google.common.collect.Sets; import org.chorem.pollen.votecounting.model.ChoiceScore; import org.chorem.pollen.votecounting.model.ListOfVoter; import org.chorem.pollen.votecounting.model.ListVoteCountingResult; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; import org.chorem.pollen.votecounting.model.SimpleVoter; import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; import org.chorem.pollen.votecounting.model.VoteCountingResult; @@ -52,19 +53,20 @@ public class NormalVoteCountingStrategyTest { public static final String CHOICE_C = "c"; - protected static VoteCounting voteCounting; + protected static NormalVoteCounting voteCounting; - protected VoteCountingStrategy strategy; + protected NormalVoteCountingStrategy strategy; @BeforeClass public static void beforeClass() throws Exception { VoteCountingFactory factory = new VoteCountingFactory(); - voteCounting = factory.getVoteCounting(NormalVoteCounting.ID); + voteCounting = NormalVoteCounting.class.cast(factory.getVoteCounting(NormalVoteCounting.ID)); } @Before public void setUp() throws Exception { strategy = voteCounting.newStrategy(); + strategy.setConfig(new MaxChoicesNumberConfig()); } @Test diff --git a/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java b/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java index 1c9f5c8d..1aad2a1d 100644 --- a/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java +++ b/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; */ import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; import java.util.Locale; @@ -33,16 +34,17 @@ import static org.nuiton.i18n.I18n.n; * @author Tony Chemit - dev@tchemit.fr * @since 1.6 */ -public class NumberVoteCounting extends AbstractVoteCounting<NumberVoteCountingStrategy> { +public class NumberVoteCounting extends AbstractVoteCounting<NumberVoteCountingStrategy, MaxChoicesNumberConfig> { public static final int ID = 4; public NumberVoteCounting() { super(ID, - NumberVoteCountingStrategy.class, - n("pollen.voteCountingType.number"), - n("pollen.voteCountingType.number.shortHelp"), - n("pollen.voteCountingType.number.help") + NumberVoteCountingStrategy.class, + MaxChoicesNumberConfig.class, + n("pollen.voteCountingType.number"), + n("pollen.voteCountingType.number.shortHelp"), + n("pollen.voteCountingType.number.help") ); } @@ -88,13 +90,13 @@ public class NumberVoteCounting extends AbstractVoteCounting<NumberVoteCountingS } @Override - public boolean isTotalVoteValueValid(Double totalValues) { + public boolean isTotalVoteValueValid(Double totalValues, MaxChoicesNumberConfig config) { // no validation on total value return true; } @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { + public String getTotalVoteValueNotValidMessage(Locale locale, MaxChoicesNumberConfig config) { // no validation on total values, so no message return null; } diff --git a/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java b/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java index 8b5deaf5..8108b0a9 100644 --- a/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java +++ b/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java @@ -22,6 +22,7 @@ package org.chorem.pollen.votecounting; import com.google.common.collect.Sets; import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -35,7 +36,7 @@ import java.util.Set; * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ -public class NumberVoteCountingStrategy extends AbstractVoteCountingStrategy { +public class NumberVoteCountingStrategy extends AbstractVoteCountingStrategy<MaxChoicesNumberConfig> { @Override public VoteCountingResult votecount(Set<Voter> voters) { @@ -59,7 +60,11 @@ public class NumberVoteCountingStrategy extends AbstractVoteCountingStrategy { for (ChoiceScore choiceScore : voteCountingResult.getScores()) { - double score = choiceScore.getScoreValue().doubleValue(); + double score = 0; + if (choiceScore.getScoreValue() != null) { + score = choiceScore.getScoreValue().doubleValue(); + } + VoteForChoice voteForChoice = VoteForChoice.newVote( choiceScore.getChoiceId(), score); diff --git a/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java b/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java index 7706453a..4dc057a7 100644 --- a/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java +++ b/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java @@ -24,6 +24,7 @@ import com.google.common.collect.Sets; import org.chorem.pollen.votecounting.model.ChoiceScore; import org.chorem.pollen.votecounting.model.ListOfVoter; import org.chorem.pollen.votecounting.model.ListVoteCountingResult; +import org.chorem.pollen.votecounting.model.MaxChoicesNumberConfig; import org.chorem.pollen.votecounting.model.SimpleVoter; import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; import org.chorem.pollen.votecounting.model.VoteCountingResult; @@ -52,19 +53,21 @@ public class NumberVoteCountingStrategyTest { public static final String CHOICE_C = "c"; - protected static VoteCounting voteCounting; + protected static NumberVoteCounting voteCounting; + + protected NumberVoteCountingStrategy strategy; - protected VoteCountingStrategy strategy; @BeforeClass public static void beforeClass() throws Exception { VoteCountingFactory factory = new VoteCountingFactory(); - voteCounting = factory.getVoteCounting(NumberVoteCounting.ID); + voteCounting = NumberVoteCounting.class.cast(factory.getVoteCounting(NumberVoteCounting.ID)); } @Before public void setUp() throws Exception { strategy = voteCounting.newStrategy(); + strategy.setConfig(new MaxChoicesNumberConfig()); } @Test diff --git a/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting b/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting deleted file mode 100644 index 2b668e8a..00000000 --- a/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting +++ /dev/null @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.PercentageVoteCounting diff --git a/pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_en_GB.properties b/pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_en_GB.properties deleted file mode 100644 index 0f239566..00000000 --- a/pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_en_GB.properties +++ /dev/null @@ -1,4 +0,0 @@ -pollen.error.vote.percentage=choices sum must be equals to 100% -pollen.voteCountingType.percentage=Percentage -pollen.voteCountingType.percentage.help=Allocate choices to get a 100% total. -pollen.voteCountingType.percentage.shortHelp=Allocate choices to get a 100% total. diff --git a/pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_fr_FR.properties b/pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_fr_FR.properties deleted file mode 100644 index a8bdf881..00000000 --- a/pollen-votecounting-percentage/src/main/resources/i18n/pollen-votecounting-percentage_fr_FR.properties +++ /dev/null @@ -1,4 +0,0 @@ -pollen.error.vote.percentage=La somme de tout les choix doit être égale à 100% -pollen.voteCountingType.percentage=Pourcentage -pollen.voteCountingType.percentage.help=Répartir les choix de manière à obtenir 100% au total. -pollen.voteCountingType.percentage.shortHelp=Répartir les choix de manière à obtenir 100% au total. -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm