[FEAT,API] remove checker from JsonData and creadte @CheckerAnnotation

This commit is contained in:
Edouard DUPIN 2025-01-28 23:15:11 +01:00
parent d028eb2261
commit b5fcc3e20c
7 changed files with 74 additions and 69 deletions

View File

@ -189,6 +189,14 @@ public class AnnotationTools {
return (DataJson) annotation[0]; return (DataJson) annotation[0];
} }
public static Checker[] getCheckers(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Checker.class);
if (annotation.length == 0) {
return null;
}
return (Checker[]) annotation;
}
public static Long getConstraintsMax(final Field element) { public static Long getConstraintsMax(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Max.class); final Annotation[] annotation = element.getDeclaredAnnotationsByType(Max.class);
if (annotation.length == 0) { if (annotation.length == 0) {

View File

@ -0,0 +1,14 @@
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;
import org.kar.archidata.dataAccess.options.CheckFunctionInterface;
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Checker {
Class<? extends CheckFunctionInterface> value();
}

View File

@ -5,13 +5,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.kar.archidata.dataAccess.options.CheckFunctionInterface;
import org.kar.archidata.dataAccess.options.CheckFunctionVoid;
@Target({ ElementType.TYPE, ElementType.FIELD }) @Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface DataJson { public @interface DataJson {
Class<? extends CheckFunctionInterface> checker() default CheckFunctionVoid.class;
Class<?> targetEntity() default Void.class; Class<?> targetEntity() default Void.class;
} }

View File

@ -9,7 +9,7 @@ import org.kar.archidata.dataAccess.QueryOptions;
/** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */ /** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */
public interface CheckFunctionInterface { public interface CheckFunctionInterface {
/** This function implementation is design to check if the updated class is valid of not for insertion /** This function implementation is design to check if the updated class is valid of not for insertion
* @param baseName NAme of the object to be precise with the use of what fail. * @param baseName Name of the object to be precise with the use of what fail.
* @param data The object that might be injected. * @param data The object that might be injected.
* @param modifiedValue List of fields that might be check. If null, then all column must be checked. * @param modifiedValue List of fields that might be check. If null, then all column must be checked.
* @throws Exception Exception is generate if the data are incorrect. */ * @throws Exception Exception is generate if the data are incorrect. */

View File

@ -16,10 +16,10 @@ import java.util.UUID;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.kar.archidata.annotation.AnnotationTools; import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.Checker;
import org.kar.archidata.annotation.CollectionItemNotNull; import org.kar.archidata.annotation.CollectionItemNotNull;
import org.kar.archidata.annotation.CollectionItemUnique; import org.kar.archidata.annotation.CollectionItemUnique;
import org.kar.archidata.annotation.CollectionNotEmpty; import org.kar.archidata.annotation.CollectionNotEmpty;
import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.DBAccess; import org.kar.archidata.dataAccess.DBAccess;
import org.kar.archidata.dataAccess.DataAccess; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.QueryCondition; import org.kar.archidata.dataAccess.QueryCondition;
@ -29,8 +29,6 @@ import org.kar.archidata.exception.InputException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonValue;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
@ -458,68 +456,57 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
}); });
} }
} else if (type == JsonValue.class) {
final DataJson jsonAnnotation = AnnotationTools.getDataJson(field);
if (jsonAnnotation != null && jsonAnnotation.checker() != CheckFunctionVoid.class) {
// Here if we have an error it crash at start and no new instance after creation...
final CheckFunctionInterface instance = jsonAnnotation.checker().getDeclaredConstructor()
.newInstance();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
instance.checkAll(ioDb, baseName + fieldName + ".", field.get(data), options);
});
}
} else if (type.isEnum()) { } else if (type.isEnum()) {
// nothing to do. // nothing to do.
} }
final DataJson dataJson = AnnotationTools.getDataJson(field); final Checker[] checkers = AnnotationTools.getCheckers(field);
if (dataJson != null && dataJson.checker() != null) { if (checkers != null) {
final CheckFunctionInterface checkerInstance = dataJson.checker().getDeclaredConstructor() for (final Checker checker : checkers) {
.newInstance(); if (checker == null || checker.value() == CheckFunctionVoid.class) {
if (Collection.class.isAssignableFrom(field.getType())) { continue;
add(fieldName, }
( final CheckFunctionInterface checkerInstance = checker.value().getDeclaredConstructor()
final DBAccess ioDb, .newInstance();
final String baseName, if (Collection.class.isAssignableFrom(field.getType())) {
final T data, add(fieldName,
final List<String> modifiedValue, (
final QueryOptions options) -> { final DBAccess ioDb,
// get the field of the specific element final String baseName,
final Object tmpData = field.get(data); final T data,
// It is not the objective of this element to check if it is authorize to set NULL final List<String> modifiedValue,
if (tmpData == null) { final QueryOptions options) -> {
return; // get the field of the specific element
} final Object tmpData = field.get(data);
final Collection<?> tmpCollection = (Collection<?>) tmpData; // It is not the objective of this element to check if it is authorize to set NULL
final Object[] elements = tmpCollection.toArray(); if (tmpData == null) {
for (int iii = 0; iii < elements.length; iii++) { return;
if (elements[iii] != null) {
checkerInstance.check(ioDb, baseName + fieldName + '[' + iii + "].",
elements[iii], null, options);
} }
} final Collection<?> tmpCollection = (Collection<?>) tmpData;
}); final Object[] elements = tmpCollection.toArray();
} else { for (int iii = 0; iii < elements.length; iii++) {
add(fieldName, if (elements[iii] != null) {
( checkerInstance.check(ioDb, baseName + fieldName + '[' + iii + "].",
final DBAccess ioDb, elements[iii], null, options);
final String baseName, }
final T data, }
final List<String> modifiedValue, });
final QueryOptions options) -> { } else {
// get the field of the specific element add(fieldName,
final Object tmpData = field.get(data); (
// It is not the objective of this element to check if it is authorize to set NULL final DBAccess ioDb,
if (tmpData == null) { final String baseName,
return; final T data,
} final List<String> modifiedValue,
checkerInstance.check(ioDb, baseName + fieldName + '.', tmpData, null, options); 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;
}
checkerInstance.check(ioDb, baseName + fieldName + '.', tmpData, null, options);
});
}
} }
} }
final CollectionItemUnique collectionUnique = AnnotationTools.getCollectionItemUnique(field); final CollectionItemUnique collectionUnique = AnnotationTools.getCollectionItemUnique(field);

View File

@ -56,7 +56,6 @@ public class RESTApi {
"Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body()); "Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
} }
} }
//return this.mapper.readValue(httpResponse.body(), new TypeReference<List<T>>() {});
return this.mapper.readValue(httpResponse.body(), return this.mapper.readValue(httpResponse.body(),
this.mapper.getTypeFactory().constructCollectionType(List.class, clazz)); this.mapper.getTypeFactory().constructCollectionType(List.class, clazz));
} }

View File

@ -1,5 +1,6 @@
package test.kar.archidata.dataAccess.model; package test.kar.archidata.dataAccess.model;
import org.kar.archidata.annotation.Checker;
import org.kar.archidata.annotation.DataJson; import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.options.CheckJPA; import org.kar.archidata.dataAccess.options.CheckJPA;
@ -11,6 +12,7 @@ public class DataWithSubJson {
} }
} }
@DataJson(checker = DataInJson.DataInJsonChecker.class) @DataJson()
@Checker(DataInJson.DataInJsonChecker.class)
public DataInJson dataSerialized; public DataInJson dataSerialized;
} }