From 23e730f566257bf7216e7a2bd35afad153c5241a Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 13 Dec 2024 15:18:04 -0600 Subject: [PATCH] Add an exception in PossibleValueSource.withValuesFromEnum if duplicated id values are given --- .../metadata/MetaDataProducerHelper.java | 5 +- .../possiblevalues/QPossibleValueSource.java | 21 +++- ...ueSourceOfEnumGenericMetaDataProducer.java | 4 +- .../QPossibleValueSourceTest.java | 96 +++++++++++++++++++ 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSourceTest.java diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/MetaDataProducerHelper.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/MetaDataProducerHelper.java index 4fd45277..1ada252c 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/MetaDataProducerHelper.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/MetaDataProducerHelper.java @@ -196,7 +196,8 @@ public class MetaDataProducerHelper /*************************************************************************** ** ***************************************************************************/ - private static MetaDataProducerInterface processMetaDataProducingPossibleValueEnum(Class aClass) + @SuppressWarnings("unchecked") + private static > MetaDataProducerInterface processMetaDataProducingPossibleValueEnum(Class aClass) { String warningPrefix = "Found a class annotated as @" + QMetaDataProducingPossibleValueEnum.class.getSimpleName(); if(!PossibleValueEnum.class.isAssignableFrom(aClass)) @@ -206,7 +207,7 @@ public class MetaDataProducerHelper } PossibleValueEnum[] values = (PossibleValueEnum[]) aClass.getEnumConstants(); - return (new PossibleValueSourceOfEnumGenericMetaDataProducer<>(aClass.getSimpleName(), values)); + return (new PossibleValueSourceOfEnumGenericMetaDataProducer(aClass.getSimpleName(), (PossibleValueEnum[]) values)); } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java index e8fc860b..84a24914 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java @@ -23,7 +23,10 @@ package com.kingsrook.qqq.backend.core.model.metadata.possiblevalues; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface; @@ -97,7 +100,7 @@ public class QPossibleValueSource implements TopLevelMetaDataInterface ** Create a new possible value source, for an enum, with default settings. ** e.g., type=ENUM; name from param values from the param; LABEL_ONLY format *******************************************************************************/ - public static > QPossibleValueSource newForEnum(String name, T[] values) + public static > QPossibleValueSource newForEnum(String name, T[] values) { return new QPossibleValueSource() .withName(name) @@ -553,11 +556,25 @@ public class QPossibleValueSource implements TopLevelMetaDataInterface ** myPossibleValueSource.withValuesFromEnum(MyEnum.values())); ** *******************************************************************************/ - public > QPossibleValueSource withValuesFromEnum(T[] values) + public > QPossibleValueSource withValuesFromEnum(T[] values) { + Set usedIds = new HashSet<>(); + List duplicatedIds = new ArrayList<>(); + for(T t : values) { + if(usedIds.contains(t.getPossibleValueId())) + { + duplicatedIds.add(t.getPossibleValueId()); + } + addEnumValue(new QPossibleValue<>(t.getPossibleValueId(), t.getPossibleValueLabel())); + usedIds.add(t.getPossibleValueId()); + } + + if(!duplicatedIds.isEmpty()) + { + throw (new QRuntimeException("Error: Duplicated id(s) found in enum values: " + duplicatedIds)); } return (this); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/producers/PossibleValueSourceOfEnumGenericMetaDataProducer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/producers/PossibleValueSourceOfEnumGenericMetaDataProducer.java index 9d617b4f..52fbdffa 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/producers/PossibleValueSourceOfEnumGenericMetaDataProducer.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/producers/PossibleValueSourceOfEnumGenericMetaDataProducer.java @@ -37,7 +37,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleVal public class PossibleValueSourceOfEnumGenericMetaDataProducer> implements MetaDataProducerInterface { private final String name; - private final PossibleValueEnum[] values; + private final PossibleValueEnum[] values; @@ -45,7 +45,7 @@ public class PossibleValueSourceOfEnumGenericMetaDataProducer[] values) + public PossibleValueSourceOfEnumGenericMetaDataProducer(String name, PossibleValueEnum[] values) { this.name = name; this.values = values; diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSourceTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSourceTest.java new file mode 100644 index 00000000..73e7de84 --- /dev/null +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSourceTest.java @@ -0,0 +1,96 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2024. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * 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 Affero 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 . + */ + +package com.kingsrook.qqq.backend.core.model.metadata.possiblevalues; + + +import com.kingsrook.qqq.backend.core.BaseTest; +import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + + +/******************************************************************************* + ** Unit test for QPossibleValueSource + *******************************************************************************/ +class QPossibleValueSourceTest extends BaseTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testWithValuesFromEnum() + { + assertThatThrownBy(() -> new QPossibleValueSource().withValuesFromEnum(DupeIds.values())) + .isInstanceOf(QRuntimeException.class) + .hasMessageContaining("Duplicated id(s)") + .hasMessageMatching(".*: \\[1]$"); + } + + + /*************************************************************************** + ** + ***************************************************************************/ + private enum DupeIds implements PossibleValueEnum + { + ONE_A(1, "A"), + TWO_B(2, "B"), + ONE_C(1, "C"); + + + private final int id; + private final String label; + + + + /*************************************************************************** + ** + ***************************************************************************/ + DupeIds(int id, String label) + { + this.id = id; + this.label = label; + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + public Integer getPossibleValueId() + { + return id; + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + public String getPossibleValueLabel() + { + return label; + } + } +} \ No newline at end of file