From 6974adbfdf862e318d836bc74f3097e4098ed8f8 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sat, 25 Jan 2025 14:41:20 +0100 Subject: [PATCH] [FEAT] add decorator CollectionItemUnique --- .../archidata/annotation/AnnotationTools.java | 8 +++++ .../annotation/CollectionItemUnique.java | 12 +++++++ .../dataAccess/options/CheckJPA.java | 31 ++++++++++--------- 3 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/org/kar/archidata/annotation/CollectionItemUnique.java diff --git a/src/org/kar/archidata/annotation/AnnotationTools.java b/src/org/kar/archidata/annotation/AnnotationTools.java index 36f6ac8..c0ba17d 100644 --- a/src/org/kar/archidata/annotation/AnnotationTools.java +++ b/src/org/kar/archidata/annotation/AnnotationTools.java @@ -93,6 +93,14 @@ public class AnnotationTools { return (CollectionItemNotNull) annotation[0]; } + public static CollectionItemUnique getCollectionItemUnique(final Field element) { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(CollectionItemUnique.class); + if (annotation.length == 0) { + return null; + } + return (CollectionItemUnique) annotation[0]; + } + public static boolean getSchemaReadOnly(final Field element) { final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class); if (annotation.length == 0) { diff --git a/src/org/kar/archidata/annotation/CollectionItemUnique.java b/src/org/kar/archidata/annotation/CollectionItemUnique.java new file mode 100644 index 0000000..0bf1828 --- /dev/null +++ b/src/org/kar/archidata/annotation/CollectionItemUnique.java @@ -0,0 +1,12 @@ +package org.kar.archidata.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface CollectionItemUnique { + +} diff --git a/src/org/kar/archidata/dataAccess/options/CheckJPA.java b/src/org/kar/archidata/dataAccess/options/CheckJPA.java index 732e335..008c732 100644 --- a/src/org/kar/archidata/dataAccess/options/CheckJPA.java +++ b/src/org/kar/archidata/dataAccess/options/CheckJPA.java @@ -8,13 +8,16 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; import org.kar.archidata.annotation.AnnotationTools; import org.kar.archidata.annotation.CollectionItemNotNull; +import org.kar.archidata.annotation.CollectionItemUnique; import org.kar.archidata.annotation.DataJson; import org.kar.archidata.dataAccess.DBAccess; import org.kar.archidata.dataAccess.DataAccess; @@ -518,6 +521,12 @@ public class CheckJPA implements CheckFunctionInterface { }); } } + final CollectionItemUnique collectionUnique = AnnotationTools.getCollectionItemUnique(field); + if (collectionUnique != null) { + if (!Collection.class.isAssignableFrom(field.getType())) { + throw new DataAccessException( + "Request @CollectionItemUnique on a non collection field: '" + fieldName + "'"); + } add(fieldName, ( final DBAccess ioDb, @@ -525,24 +534,18 @@ public class CheckJPA implements CheckFunctionInterface { final T data, final List modifiedValue, final QueryOptions options) -> { - // get the field of the specific element final Object tmpData = field.get(data); - // It is not the objective of this element to check if it is authorize to set NULL if (tmpData == null) { return; } - if (tmpData instanceof Collection) { - final Collection tmpCollection = (Collection) tmpData; - final Object[] elements = tmpCollection.toArray(); - for (int iii = 0; iii < elements.length; iii++) { - if (elements[iii] != null) { - checkerInstance.check(ioDb, baseName + '.' + fieldName + '[' + iii + ']', - elements[iii], null, options); - } - } - - } else { - checkerInstance.check(ioDb, baseName + '.' + fieldName, tmpData, null, options); + final Collection tmpCollection = (Collection) tmpData; + final Set uniqueValues = new HashSet<>(tmpCollection); + if (uniqueValues.size() != tmpCollection.size()) { + throw new InputException(baseName + fieldName, + "Cannot insert multiple times the same elements"); + } + }); + } final CollectionItemNotNull collectionNotNull = AnnotationTools.getCollectionItemNotNull(field); if (collectionNotNull != null) { if (!Collection.class.isAssignableFrom(field.getType())) {