From 59d328737ef4e461a849b061d0824636422b5921 Mon Sep 17 00:00:00 2001 From: Alexander Nittka Date: Sat, 14 Dec 2024 06:06:14 +0100 Subject: [PATCH] validation enhancements * trigger type production start * betty modifiers * csv entry count --- .../db/constants/ProgrammeModifier.java | 12 ++++++ .../org/tvtower/db/constants/TriggerType.java | 22 ++++++++++ .../db/validation/CommonTagsValidator.java | 43 +++++++++++++++---- .../tvtower/db/validation/NewsValidator.java | 5 ++- 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/org.tvtower.db/src/org/tvtower/db/constants/ProgrammeModifier.java b/org.tvtower.db/src/org/tvtower/db/constants/ProgrammeModifier.java index 1bd70d7..5de4331 100644 --- a/org.tvtower.db/src/org/tvtower/db/constants/ProgrammeModifier.java +++ b/org.tvtower.db/src/org/tvtower/db/constants/ProgrammeModifier.java @@ -17,6 +17,9 @@ public class ProgrammeModifier extends TVTEnum implements ModifierValueValidator public static final String NOT_LIVE = "topicality::notLive"; public static final String TIMES_BROADCASTED = "topicality::timesBroadcasted"; public static final String PER_VIEWER_REVENUE = "callin::perViewerRevenue"; + public static final String BETTY_ABSOLUTE = "betty::pointsabsolute"; + public static final String BETTY_QUALITY = "betty::rawquality"; + public static final String BETTY_MOD = "betty::pointsmod"; private static final BigDecimal TWO = new BigDecimal(2); private static final BigDecimal FIVE = new BigDecimal(5); @@ -32,6 +35,9 @@ public class ProgrammeModifier extends TVTEnum implements ModifierValueValidator add(NOT_LIVE, "topicality loss if not live"); add(TIMES_BROADCASTED, "topicality loss due to number of broadcasts"); add(PER_VIEWER_REVENUE, "income per viewer for call-in"); + add(BETTY_ABSOLUTE, "absolute Betty points added/removed"); + add(BETTY_QUALITY, "programme quality for Betty"); + add(BETTY_MOD, "factor for Betty point calculation"); } @Override @@ -41,6 +47,12 @@ public Optional getValueError(Modifier m) { BigDecimal max = TWO; if (AGE.equals(m.getModName())) { max = FIVE; + } else if (BETTY_ABSOLUTE.equals(m.getModName())) { + return CommonValidation.getIntRangeError(m.getValue(), "value", -500, 500, true); + } else if (BETTY_QUALITY.equals(m.getModName())) { + max = BigDecimal.ONE; + }else if (BETTY_MOD.equals(m.getModName())) { + min=max.negate(); } return CommonValidation.getDecimalRangeError(m.getValue(), "value", min, max, true); } diff --git a/org.tvtower.db/src/org/tvtower/db/constants/TriggerType.java b/org.tvtower.db/src/org/tvtower/db/constants/TriggerType.java index 663986e..4ce38e4 100644 --- a/org.tvtower.db/src/org/tvtower/db/constants/TriggerType.java +++ b/org.tvtower.db/src/org/tvtower/db/constants/TriggerType.java @@ -1,5 +1,10 @@ package org.tvtower.db.constants; +import org.eclipse.xtext.EcoreUtil2; +import org.tvtower.db.database.Effect; +import org.tvtower.db.database.NewsItem; +import org.tvtower.db.database.ScriptTemplate; + public class TriggerType extends TVTEnum { TriggerType() { @@ -8,6 +13,23 @@ public class TriggerType extends TVTEnum { add("broadcastDone", "after every broadcast"); add("broadcastFirstTime", "on the first broadcast"); add("broadcastFirstTimeDone", "when the first broadcast is done"); + add("productionStart", "on starting the production in the studio"); + } + + /** + * check if trigger type is allowed in the effect's context + * */ + public boolean isSupported(Effect e) { + if("happen".equals(e.getTrigger())){ + if(EcoreUtil2.getContainerOfType(e, NewsItem.class)==null) { + return false; + } + }else if("productionStart".equals(e.getTrigger())) { + if(EcoreUtil2.getContainerOfType(e, ScriptTemplate.class)==null) { + return false; + } + } + return true; } } diff --git a/org.tvtower.db/src/org/tvtower/db/validation/CommonTagsValidator.java b/org.tvtower.db/src/org/tvtower/db/validation/CommonTagsValidator.java index 075c069..71ab8d4 100644 --- a/org.tvtower.db/src/org/tvtower/db/validation/CommonTagsValidator.java +++ b/org.tvtower.db/src/org/tvtower/db/validation/CommonTagsValidator.java @@ -52,6 +52,7 @@ import org.tvtower.db.validation.expressionhelper.ScriptExpression; import org.tvtower.db.validation.expressionhelper.SimpleExpression; +import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.Sets; import com.google.inject.Inject; @@ -153,6 +154,7 @@ public void checkLanguageStringsContainer(ContainsLanguageStrings c) { //prepare duplicate entry checks Set languages = new HashSet<>(); AtomicInteger optionsCount = new AtomicInteger(-1); + AtomicInteger csvCount = new AtomicInteger(-1); if (checkLocalizationDuplicates) { int languageCount = c.getLstrings().size(); if (languageCount == 0) { @@ -178,7 +180,7 @@ public void checkLanguageStringsContainer(ContainsLanguageStrings c) { } else { languages.add(language); } - validateOptionsCount(l, optionsCount); + validateOptionsCount(l, optionsCount, csvCount); if("de".equals(language)) { String content=l.getText(); if(germanContainsIllegalQuote(content)) { @@ -224,18 +226,41 @@ private boolean germanContainsIllegalQuote(String s) { return false; } - private void validateOptionsCount(LanguageString s, AtomicInteger optionsCount) { - int count = -1; + private void validateOptionsCount(LanguageString s, AtomicInteger optionsCount, AtomicInteger csvCount) { + int optCount = -1; + int dataCount = -1; + List options = new ArrayList<>(); if (!Strings.isNullOrEmpty(s.getText())) { - //TODO what about options within an expression - count = s.getText().split("\\|").length; + // TODO what about options within an expression + options = Splitter.on('|').splitToList(s.getText()); + optCount = options.size(); + } + for (String option : options) { + // remove html entities + option = option.replaceAll("&\\w+;", ""); + int singleDataCount = option.split(";", -1).length; + if (dataCount < 0) { + dataCount = singleDataCount; + if (csvCount.get() < 0) { + csvCount.set(dataCount); + } + } else if (singleDataCount != dataCount) { + int index = options.indexOf(option) + 1; + error("alternative " + index + " has " + singleDataCount + " csv entries, " + dataCount + + " in others for this language", s, $.getLanguageString_Text()); + } } if (optionsCount.get() < 0) { - if (count >= 0) { - optionsCount.set(count); + if (optCount >= 0) { + optionsCount.set(optCount); } - } else if (count >= 0 && count != optionsCount.get()) { - error("options count mismatch with other language", s, $.getLanguageString_Text()); + } else if (optCount >= 0 && optCount != optionsCount.get()) { + error("options count mismatch wrt other language", s, $.getLanguageString_Text()); + } + // mark mismatch only if one semicolon was found at all + // semicolon might be part of regular text + if (dataCount > 1 && csvCount.get() > 1 && dataCount != csvCount.get()) { + error("csv data entry count mismatch wrt other language", s, $.getLanguageString_Text()); } } diff --git a/org.tvtower.db/src/org/tvtower/db/validation/NewsValidator.java b/org.tvtower.db/src/org/tvtower/db/validation/NewsValidator.java index ff0c8e5..d7af267 100644 --- a/org.tvtower.db/src/org/tvtower/db/validation/NewsValidator.java +++ b/org.tvtower.db/src/org/tvtower/db/validation/NewsValidator.java @@ -177,7 +177,6 @@ public void checkNewsProbability(NewsProbability e) { $.getNewsProbability_News()); } - //TODO extend check effects to programme and scripts @Check public void checkEffect(Effect e) { Constants.triggerType.isValidValue(e.getTrigger(), "trigger", true) @@ -190,6 +189,10 @@ public void checkEffect(Effect e) { Constants._boolean.isValidValue(e.getEnable(), "enable", false) .ifPresent(err -> error(err, $.getEffect_Enable())); + if(!Constants.triggerType.isSupported(e)) { + error("trigger type not supported for this element", $.getEffect_Trigger()); + } + if (e.getType() != null) { Boolean checkMinMax = Boolean.FALSE; Boolean genreExpected = Boolean.FALSE;