From 29c1a299c868e8c9b5acc8d848a5c39d842627c90cdaaba1457de159919067a8 Mon Sep 17 00:00:00 2001 From: Minimons Date: Sun, 21 Jun 2026 18:29:10 +0200 Subject: [PATCH] 9: Support percentage expressions in alarm targets --- .../impl/ref/AlarmConfigurationParser.tjava | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava index f5cb01e..010c950 100644 --- a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava +++ b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava @@ -83,9 +83,55 @@ public final class AlarmConfigurationParser { ); } + private static BigDecimal parseTargetPercentage( + String targetStr, + int operatorIndex, + boolean add + ) { + BigDecimal base = new BigDecimal(targetStr.substring(0, operatorIndex)); + String percentStr = targetStr.substring(operatorIndex + 1, targetStr.length() - 1); + BigDecimal percent = new BigDecimal(percentStr); + + BigDecimal delta = base + .multiply(percent) + .divide(BigDecimal.valueOf(100)); + + BigDecimal target = add ? base.add(delta) : base.subtract(delta); + + validateTarget(base, targetStr); + validateTarget(percent, targetStr); + validateTarget(target, targetStr); + + return target; + } + + private static void validateTarget(BigDecimal target, String originalTargetStr) { + if (target.compareTo(BigDecimal.ZERO) < 0) { + throw new IllegalArgumentException( + "Target must be zero or positive: " + originalTargetStr + ); + } + } + private static BigDecimal parseTarget(String targetStr) { - BigDecimal t = new BigDecimal(targetStr); - return t; + String trimmedTargetStr = targetStr.trim(); + + if (trimmedTargetStr.endsWith("%")) { + int plusIndex = trimmedTargetStr.indexOf('+'); + int minusIndex = trimmedTargetStr.indexOf('-', 1); + + if (plusIndex >= 0) { + return parseTargetPercentage(trimmedTargetStr, plusIndex, true); + } + + if (minusIndex >= 0) { + return parseTargetPercentage(trimmedTargetStr, minusIndex, false); + } + } + + BigDecimal target = new BigDecimal(trimmedTargetStr); + validateTarget(target, targetStr); + return target; } private static final class Cursor {