From 8c0ef61b21cd8cf4fa797f2074388b3420973fe6 Mon Sep 17 00:00:00 2001 From: uhensler <none@none> Date: Wed, 11 Oct 2017 14:38:14 +0200 Subject: [PATCH] OO-3067: Handle exception if a course reminder rule is invalid and add some validations in GUI to avoid invalid reminder rules --- .../gta/ui/BeforeDateTaskRuleEditor.java | 20 ++++++++ .../reminder/ui/AttemptsRuleEditor.java | 23 +++++++-- .../ui/InitialAttemptsRuleEditor.java | 23 +++++++-- .../course/reminder/ui/ScoreRuleEditor.java | 20 ++++++++ .../reminder/manager/ReminderRuleEngine.java | 51 +++++++++++++++---- .../reminder/ui/CourseLaunchRuleEditor.java | 20 ++++++++ ...oryEntryLifecycleAfterValidRuleEditor.java | 20 ++++++++ .../ui/_i18n/LocalStrings_de.properties | 1 + .../ui/_i18n/LocalStrings_en.properties | 1 + .../manager/ReminderRuleEngineTest.java | 29 +++++++++++ 10 files changed, 193 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/olat/course/nodes/gta/ui/BeforeDateTaskRuleEditor.java b/src/main/java/org/olat/course/nodes/gta/ui/BeforeDateTaskRuleEditor.java index 01e275aea9b..c56f25166ed 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/BeforeDateTaskRuleEditor.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/BeforeDateTaskRuleEditor.java @@ -214,11 +214,31 @@ public class BeforeDateTaskRuleEditor extends RuleEditorFragment { if(!StringHelper.containsNonWhitespace(valueEl.getValue())) { valueEl.setErrorKey("form.mandatory.hover", null); allOk &= false; + } else { + allOk &= validateInt(valueEl); } return allOk; } + private boolean validateInt(TextElement el) { + boolean allOk = true; + + if(el.isVisible()) { + String value = el.getValue(); + if(StringHelper.containsNonWhitespace(value)) { + try { + Integer.parseInt(value); + } catch(Exception e) { + allOk = false; + el.setErrorKey("error.wrong.int", null); + } + } + } + + return allOk; + } + @Override public ReminderRule getConfiguration() { ReminderRuleImpl configuredRule = null; diff --git a/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java b/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java index 82bf022d195..dc3684a3b41 100644 --- a/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java +++ b/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java @@ -181,13 +181,30 @@ public class AttemptsRuleEditor extends RuleEditorFragment { if(!StringHelper.containsNonWhitespace(valueEl.getValue())) { valueEl.setErrorKey("form.mandatory.hover", null); allOk &= false; - } else if(!StringHelper.isLong(valueEl.getValue())) { - valueEl.setErrorKey("error.int", null); - allOk &= false; + } else { + allOk &= validateInt(valueEl); } return allOk; } + + private boolean validateInt(TextElement el) { + boolean allOk = true; + + if(el.isVisible()) { + String value = el.getValue(); + if(StringHelper.containsNonWhitespace(value)) { + try { + Integer.parseInt(value); + } catch(Exception e) { + allOk = false; + el.setErrorKey("error.wrong.int", null); + } + } + } + + return allOk; + } @Override public ReminderRule getConfiguration() { diff --git a/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java b/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java index 42078729ee6..100332efaf2 100644 --- a/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java +++ b/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java @@ -185,13 +185,30 @@ public class InitialAttemptsRuleEditor extends RuleEditorFragment { if(!StringHelper.containsNonWhitespace(valueEl.getValue())) { valueEl.setErrorKey("form.mandatory.hover", null); allOk &= false; - } else if(!StringHelper.isLong(valueEl.getValue())) { - valueEl.setErrorKey("error.int", null); - allOk &= false; + } else { + allOk &= validateInt(valueEl); } return allOk; } + + private boolean validateInt(TextElement el) { + boolean allOk = true; + + if(el.isVisible()) { + String value = el.getValue(); + if(StringHelper.containsNonWhitespace(value)) { + try { + Integer.parseInt(value); + } catch(Exception e) { + allOk = false; + el.setErrorKey("error.wrong.int", null); + } + } + } + + return allOk; + } @Override public ReminderRule getConfiguration() { diff --git a/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java b/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java index 28cd5759355..55fd2852379 100644 --- a/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java +++ b/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java @@ -174,10 +174,30 @@ public class ScoreRuleEditor extends RuleEditorFragment { if(!StringHelper.containsNonWhitespace(valueEl.getValue())) { valueEl.setErrorKey("form.mandatory.hover", null); allOk &= false; + } else { + allOk &= validateInt(valueEl); } return allOk; } + + private boolean validateInt(TextElement el) { + boolean allOk = true; + + if(el.isVisible()) { + String value = el.getValue(); + if(StringHelper.containsNonWhitespace(value)) { + try { + Integer.parseInt(value); + } catch(Exception e) { + allOk = false; + el.setErrorKey("error.wrong.int", null); + } + } + } + + return allOk; + } @Override public ReminderRule getConfiguration() { diff --git a/src/main/java/org/olat/modules/reminder/manager/ReminderRuleEngine.java b/src/main/java/org/olat/modules/reminder/manager/ReminderRuleEngine.java index b22df840e70..1d4b0a19793 100644 --- a/src/main/java/org/olat/modules/reminder/manager/ReminderRuleEngine.java +++ b/src/main/java/org/olat/modules/reminder/manager/ReminderRuleEngine.java @@ -28,6 +28,8 @@ import java.util.Set; import org.olat.basesecurity.GroupRoles; import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.modules.reminder.FilterRuleSPI; import org.olat.modules.reminder.IdentitiesProviderRuleSPI; import org.olat.modules.reminder.Reminder; @@ -56,6 +58,8 @@ import org.springframework.stereotype.Service; @Service public class ReminderRuleEngine { + private static final OLog log = Tracing.createLoggerFor(ReminderRuleEngine.class); + public static final String DATE_RULE_TYPE = DateRuleSPI.class.getSimpleName(); public static final String USER_PROP_RULE_TYPE = UserPropertyRuleSPI.class.getSimpleName(); public static final String REPO_ROLE_RULE_TYPE = RepositoryEntryRoleRuleSPI.class.getSimpleName(); @@ -84,11 +88,7 @@ public class ReminderRuleEngine { } List<ReminderRule> ruleList = new ArrayList<>(rules.getRules()); - //1. Date rules doesn't need database queries - boolean allOk = evaluateDateRule(ruleList); - if(allOk) { - allOk = evaluateRepositoryEntryRule(reminder.getEntry(), ruleList); - } + boolean allOk = evaluate(reminder, ruleList); List<Identity> identities; if(allOk) { @@ -103,6 +103,21 @@ public class ReminderRuleEngine { } return identities; } + + public boolean evaluate(Reminder reminder, List<ReminderRule> ruleList) { + boolean allOk = true; + try { + // 1. Date rules doesn't need database queries + allOk = evaluateDateRule(ruleList); + if (allOk) { + allOk = evaluateRepositoryEntryRule(reminder.getEntry(), ruleList); + } + } catch (Exception e) { + allOk = false; + log.error("", e); + } + return allOk; + } /** * @@ -163,9 +178,7 @@ public class ReminderRuleEngine { identities = null; for(ReminderRule rule:identitiesProviderRules) { - RuleSPI ruleSpi = reminderModule.getRuleSPIByType(rule.getType()); - IdentitiesProviderRuleSPI identitiesProviderRuleSpi = (IdentitiesProviderRuleSPI)ruleSpi; - List<Identity> members = identitiesProviderRuleSpi.evaluate(entry, rule); + List<Identity> members = getMembers(entry, rule); if(identities == null) { identities = members; } else { @@ -189,6 +202,18 @@ public class ReminderRuleEngine { } return identities; } + + public List<Identity> getMembers(RepositoryEntry entry, ReminderRule rule) { + List<Identity> members = new ArrayList<>(); + try { + RuleSPI ruleSpi = reminderModule.getRuleSPIByType(rule.getType()); + IdentitiesProviderRuleSPI identitiesProviderRuleSpi = (IdentitiesProviderRuleSPI)ruleSpi; + members = identitiesProviderRuleSpi.evaluate(entry, rule); + } catch (Exception e) { + log.error("", e); + } + return members; + } /** * Remove identities of the list which not match the user properties rules if any. @@ -239,11 +264,19 @@ public class ReminderRuleEngine { } for(ReminderRule rule:filterRules) { + filterByRule(entry, identities, rule); + } + } + + public void filterByRule(RepositoryEntry entry, List<Identity> identities, ReminderRule rule) { + try { RuleSPI ruleSpi = reminderModule.getRuleSPIByType(rule.getType()); if(ruleSpi instanceof FilterRuleSPI) { FilterRuleSPI filter = (FilterRuleSPI)ruleSpi; filter.filter(entry, identities, rule); - } + } + } catch (Exception e) { + log.error("", e); } } } diff --git a/src/main/java/org/olat/modules/reminder/ui/CourseLaunchRuleEditor.java b/src/main/java/org/olat/modules/reminder/ui/CourseLaunchRuleEditor.java index e614199ee8e..8d1eb673093 100644 --- a/src/main/java/org/olat/modules/reminder/ui/CourseLaunchRuleEditor.java +++ b/src/main/java/org/olat/modules/reminder/ui/CourseLaunchRuleEditor.java @@ -117,10 +117,30 @@ public class CourseLaunchRuleEditor extends RuleEditorFragment { if(!StringHelper.containsNonWhitespace(valueEl.getValue())) { valueEl.setErrorKey("form.mandatory.hover", null); allOk &= false; + } else { + allOk &= validateInt(valueEl); } return allOk; } + + private boolean validateInt(TextElement el) { + boolean allOk = true; + + if(el.isVisible()) { + String value = el.getValue(); + if(StringHelper.containsNonWhitespace(value)) { + try { + Integer.parseInt(value); + } catch(Exception e) { + allOk = false; + el.setErrorKey("error.wrong.int", null); + } + } + } + + return allOk; + } @Override public ReminderRule getConfiguration() { diff --git a/src/main/java/org/olat/modules/reminder/ui/RepositoryEntryLifecycleAfterValidRuleEditor.java b/src/main/java/org/olat/modules/reminder/ui/RepositoryEntryLifecycleAfterValidRuleEditor.java index e9ed6535563..1c03c5bc348 100644 --- a/src/main/java/org/olat/modules/reminder/ui/RepositoryEntryLifecycleAfterValidRuleEditor.java +++ b/src/main/java/org/olat/modules/reminder/ui/RepositoryEntryLifecycleAfterValidRuleEditor.java @@ -121,10 +121,30 @@ public class RepositoryEntryLifecycleAfterValidRuleEditor extends RuleEditorFrag if(!StringHelper.containsNonWhitespace(valueEl.getValue())) { valueEl.setErrorKey("form.mandatory.hover", null); allOk &= false; + } else { + allOk &= validateInt(valueEl); } return allOk; } + + private boolean validateInt(TextElement el) { + boolean allOk = true; + + if(el.isVisible()) { + String value = el.getValue(); + if(StringHelper.containsNonWhitespace(value)) { + try { + Integer.parseInt(value); + } catch(Exception e) { + allOk = false; + el.setErrorKey("error.wrong.int", null); + } + } + } + + return allOk; + } @Override public ReminderRule getConfiguration() { diff --git a/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_de.properties index 9d79a70eae1..25a6646b059 100644 --- a/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_de.properties @@ -8,6 +8,7 @@ default.send.time=Standard Sendezeit f\u00FCr Erinnerungen enable.reminders=Kurserinnerungen einschalten enable.sms.reminders=SMS Erinnerungen error.group.not.found=Gruppe existiert nicht in diesem Kurs +error.wrong.int=Falsches Zahlenformat. Beispiele\: -1, 0, 2, +10 interval=Zeitintervall interval.24=1 Mal pro Tag interval.12=2 Mal pro Tag diff --git a/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_en.properties index 2a185d8f5a6..8e6404b98ea 100644 --- a/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/reminder/ui/_i18n/LocalStrings_en.properties @@ -8,6 +8,7 @@ default.send.time=Default time to send reminders enable.reminders=Activate course reminders enable.sms.reminders=SMS reminders error.group.not.found=Group doesn't exist within this course +error.wrong.int=Wrong numeral format. Examples\: -1, 0, 2, +10 interval=Interval interval.24=Once a day interval.12=Twice a day diff --git a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java index 55a6408ca70..5ae4df4f5d5 100644 --- a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java +++ b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java @@ -19,8 +19,11 @@ */ package org.olat.modules.reminder.manager; +import static org.assertj.core.api.Assertions.assertThat; + import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.Date; import java.util.List; @@ -1064,4 +1067,30 @@ public class ReminderRuleEngineTest extends OlatTestCase { return testNode.getIdent(); } + + @Test + public void evaluateRuleListThrowsException() { + List<ReminderRule> ruleList = Collections.<ReminderRule>emptyList(); + + boolean ollOk = ruleEngine.evaluate(null, ruleList); + + Assert.assertFalse(ollOk); + } + + @Test + public void getMembersThrowsException() { + + List<Identity> members = ruleEngine.getMembers(null, null); + + assertThat(members).isNotNull().isEmpty(); + } + + @Test + public void getFilterThrowsException() { + ReminderRuleImpl rule = new ReminderRuleImpl(); + rule.setType(ScoreRuleSPI.class.getSimpleName()); + rule.setRightOperand("no integer"); + + ruleEngine.filterByRule(null, null, rule); + } } -- GitLab