Compare commits

..

No commits in common. "abf1ddcf2482a6ee79c139951abbd3a0416b0770" and "c9b9d38efeb96495e9038cc7fc99913c0a8c4214" have entirely different histories.

4 changed files with 196 additions and 303 deletions

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>kangaroo-and-rabbit</groupId> <groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId> <artifactId>archidata</artifactId>
<version>0.17.0</version> <version>0.16.0</version>
<properties> <properties>
<java.version>21</java.version> <java.version>21</java.version>
<maven.compiler.version>3.1</maven.compiler.version> <maven.compiler.version>3.1</maven.compiler.version>

View File

@ -10,9 +10,9 @@ 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 filterValue 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. */
void check(final String baseName, Object data, List<String> modifiedValue, final QueryOptions options) void check(final String baseName, Object data, List<String> filterValue, final QueryOptions options)
throws Exception; throws Exception;
default void checkAll(final String baseName, final Object data, final QueryOptions options) throws Exception { default void checkAll(final String baseName, final Object data, final QueryOptions options) throws Exception {

View File

@ -35,13 +35,10 @@ public class CheckJPA<T> implements CheckFunctionInterface {
/** 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 CheckInterface<K> { public interface CheckInterface<K> {
/** 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 Base of the name input that is displayed in exception generated.
* @param data The object that might be injected. * @param data The object that might be injected.
* @param modifiedValue List of fields that modification is requested. * @param filterValue List of fields that might be check. If null, then all column must be checked.
* @param options Some query option that the checker can need to generate basic check.
* @throws Exception Exception is generate if the data are incorrect. */ * @throws Exception Exception is generate if the data are incorrect. */
void check(final String baseName, final K data, List<String> modifiedValue, final QueryOptions options) void check(final String baseName, final K data, final QueryOptions options) throws Exception;
throws Exception;
} }
protected Map<String, List<CheckInterface<T>>> checking = null; protected Map<String, List<CheckInterface<T>>> checking = null;
@ -70,182 +67,128 @@ public class CheckJPA<T> implements CheckFunctionInterface {
for (final Field field : this.clazz.getFields()) { for (final Field field : this.clazz.getFields()) {
final String fieldName = field.getName(); // AnnotationTools.getFieldName(field); final String fieldName = field.getName(); // AnnotationTools.getFieldName(field);
if (AnnotationTools.isPrimaryKey(field)) { if (AnnotationTools.isPrimaryKey(field)) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( throw new InputException(baseName + fieldName,
final String baseName, "This is a '@Id' (primaryKey) ==> can not be change");
final T data, });
final List<String> modifiedValue,
final QueryOptions options) -> {
throw new InputException(baseName + fieldName,
"This is a '@Id' (primaryKey) ==> can not be change");
});
} }
if (AnnotationTools.getConstraintsNotNull(field)) { if (AnnotationTools.getConstraintsNotNull(field)) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( if (field.get(data) == null) {
final String baseName, throw new InputException(baseName + fieldName, "Can not be null");
final T data, }
final List<String> modifiedValue, });
final QueryOptions options) -> {
if (field.get(data) == null) {
throw new InputException(baseName + fieldName, "Can not be null");
}
});
} }
if (AnnotationTools.isCreatedAtField(field) || AnnotationTools.isUpdateAtField(field)) { if (AnnotationTools.isCreatedAtField(field) || AnnotationTools.isUpdateAtField(field)) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( throw new InputException(baseName + fieldName, "It is forbidden to change this field");
final String baseName, });
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
throw new InputException(baseName + fieldName, "It is forbidden to change this field");
});
} }
final Class<?> type = field.getType(); final Class<?> type = field.getType();
if (type == Long.class || type == long.class) { if (type == Long.class || type == long.class) {
final Long maxValue = AnnotationTools.getConstraintsMax(field); final Long maxValue = AnnotationTools.getConstraintsMax(field);
if (maxValue != null) { if (maxValue != null) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Long elemTyped = (Long) elem;
final Object elem = field.get(data); if (elemTyped > maxValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
return; }
} });
final Long elemTyped = (Long) elem;
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName,
"Value too height max: " + maxValue);
}
});
} }
final Long minValue = AnnotationTools.getConstraintsMin(field); final Long minValue = AnnotationTools.getConstraintsMin(field);
if (minValue != null) { if (minValue != null) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Long elemTyped = (Long) elem;
final Object elem = field.get(data); if (elemTyped < minValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
return; }
} });
final Long elemTyped = (Long) elem;
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName,
"Value too Low min: " + minValue);
}
});
} }
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
final Object elem = field.get(data); final Condition conditionCheck = condCheckers.isEmpty() ? null
if (elem == null) { : condCheckers.get(0).toCondition();
return; final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem,
} conditionCheck);
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class); if (count == 0) {
final Condition conditionCheck = condCheckers.isEmpty() ? null throw new InputException(baseName + fieldName,
: condCheckers.get(0).toCondition(); "Foreign element does not exist in the DB:" + elem);
final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem, }
conditionCheck); });
if (count == 0) {
throw new InputException(baseName + fieldName,
"Foreign element does not exist in the DB:" + elem);
}
});
} }
} else if (type == Integer.class || type == int.class) { } else if (type == Integer.class || type == int.class) {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) { if (maxValueRoot != null) {
final int maxValue = maxValueRoot.intValue(); final int maxValue = maxValueRoot.intValue();
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Integer elemTyped = (Integer) elem;
final Object elem = field.get(data); if (elemTyped > maxValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
return; }
} });
final Integer elemTyped = (Integer) elem;
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName,
"Value too height max: " + maxValue);
}
});
} }
final Long minValueRoot = AnnotationTools.getConstraintsMin(field); final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) { if (minValueRoot != null) {
final int minValue = minValueRoot.intValue(); final int minValue = minValueRoot.intValue();
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Integer elemTyped = (Integer) elem;
final Object elem = field.get(data); if (elemTyped < minValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
return; }
} });
final Integer elemTyped = (Integer) elem;
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName,
"Value too Low min: " + minValue);
}
});
} }
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
final Object elem = field.get(data); if (count == 0) {
if (elem == null) { throw new InputException(baseName + fieldName,
return; "Foreign element does not exist in the DB:" + elem);
} }
final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem); });
if (count == 0) {
throw new InputException(baseName + fieldName,
"Foreign element does not exist in the DB:" + elem);
}
});
} }
} else if (type == UUID.class) { } else if (type == UUID.class) {
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
final Object elem = field.get(data); if (count == 0) {
if (elem == null) { throw new InputException(baseName + fieldName,
return; "Foreign element does not exist in the DB:" + elem);
} }
final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem); });
if (count == 0) {
throw new InputException(baseName + fieldName,
"Foreign element does not exist in the DB:" + elem);
}
});
} }
} else if (type == Boolean.class || type == boolean.class) { } else if (type == Boolean.class || type == boolean.class) {
@ -253,83 +196,59 @@ public class CheckJPA<T> implements CheckFunctionInterface {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) { if (maxValueRoot != null) {
final float maxValue = maxValueRoot.floatValue(); final float maxValue = maxValueRoot.floatValue();
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Float elemTyped = (Float) elem;
final Object elem = field.get(data); if (elemTyped > maxValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
return; }
} });
final Float elemTyped = (Float) elem;
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName,
"Value too height max: " + maxValue);
}
});
} }
final Long minValueRoot = AnnotationTools.getConstraintsMin(field); final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) { if (minValueRoot != null) {
final float minValue = minValueRoot.floatValue(); final float minValue = minValueRoot.floatValue();
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Float elemTyped = (Float) elem;
final Object elem = field.get(data); if (elemTyped < minValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
return; }
} });
final Float elemTyped = (Float) elem;
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName,
"Value too Low min: " + minValue);
}
});
} }
} else if (type == Double.class || type == double.class) { } else if (type == Double.class || type == double.class) {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) { if (maxValueRoot != null) {
final double maxValue = maxValueRoot.doubleValue(); final double maxValue = maxValueRoot.doubleValue();
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Double elemTyped = (Double) elem;
final Object elem = field.get(data); if (elemTyped > maxValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
return; }
} });
final Double elemTyped = (Double) elem;
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName,
"Value too height max: " + maxValue);
}
});
} }
final Long minValueRoot = AnnotationTools.getConstraintsMin(field); final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) { if (minValueRoot != null) {
final double minValue = minValueRoot.doubleValue(); final double minValue = minValueRoot.doubleValue();
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final Double elemTyped = (Double) elem;
final Object elem = field.get(data); if (elemTyped < minValue) {
if (elem == null) { throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
return; }
} });
final Double elemTyped = (Double) elem;
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName,
"Value too Low min: " + minValue);
}
});
} }
} else if (type == Date.class || type == Timestamp.class) { } else if (type == Date.class || type == Timestamp.class) {
@ -340,66 +259,51 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} else if (type == String.class) { } else if (type == String.class) {
final int maxSizeString = AnnotationTools.getLimitSize(field); final int maxSizeString = AnnotationTools.getLimitSize(field);
if (maxSizeString > 0) { if (maxSizeString > 0) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final String elemTyped = (String) elem;
final Object elem = field.get(data); if (elemTyped.length() > maxSizeString) {
if (elem == null) { throw new InputException(baseName + fieldName,
return; "Too long size must be <= " + maxSizeString);
} }
final String elemTyped = (String) elem; });
if (elemTyped.length() > maxSizeString) {
throw new InputException(baseName + fieldName,
"Too long size must be <= " + maxSizeString);
}
});
} }
final Size limitSize = AnnotationTools.getConstraintsSize(field); final Size limitSize = AnnotationTools.getConstraintsSize(field);
if (limitSize != null) { if (limitSize != null) {
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final String elemTyped = (String) elem;
final Object elem = field.get(data); if (elemTyped.length() > limitSize.max()) {
if (elem == null) { throw new InputException(baseName + fieldName,
return; "Too long size (constraints) must be <= " + limitSize.max());
} }
final String elemTyped = (String) elem; if (elemTyped.length() < limitSize.min()) {
if (elemTyped.length() > limitSize.max()) { throw new InputException(baseName + fieldName,
throw new InputException(baseName + fieldName, "Too small size (constraints) must be >= " + limitSize.min());
"Too long size (constraints) must be <= " + limitSize.max()); }
} });
if (elemTyped.length() < limitSize.min()) {
throw new InputException(baseName + fieldName,
"Too small size (constraints) must be >= " + limitSize.min());
}
});
} }
final String patternString = AnnotationTools.getConstraintsPattern(field); final String patternString = AnnotationTools.getConstraintsPattern(field);
if (patternString != null) { if (patternString != null) {
final Pattern pattern = Pattern.compile(patternString); final Pattern pattern = Pattern.compile(patternString);
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final Object elem = field.get(data);
final String baseName, if (elem == null) {
final T data, return;
final List<String> modifiedValue, }
final QueryOptions options) -> { final String elemTyped = (String) elem;
final Object elem = field.get(data); if (!pattern.matcher(elemTyped).find()) {
if (elem == null) { throw new InputException(baseName + fieldName,
return; "does not match the required pattern (constraints) must be '" + patternString
} + "'");
final String elemTyped = (String) elem; }
if (!pattern.matcher(elemTyped).find()) { });
throw new InputException(baseName + fieldName,
"does not match the required pattern (constraints) must be '"
+ patternString + "'");
}
});
} }
} else if (type == JsonValue.class) { } else if (type == JsonValue.class) {
final DataJson jsonAnnotation = AnnotationTools.getDataJson(field); final DataJson jsonAnnotation = AnnotationTools.getDataJson(field);
@ -407,14 +311,9 @@ public class CheckJPA<T> implements CheckFunctionInterface {
// Here if we have an error it crash at start and no new instance after creation... // Here if we have an error it crash at start and no new instance after creation...
final CheckFunctionInterface instance = jsonAnnotation.checker().getDeclaredConstructor() final CheckFunctionInterface instance = jsonAnnotation.checker().getDeclaredConstructor()
.newInstance(); .newInstance();
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( instance.checkAll(baseName + fieldName + ".", field.get(data), options);
final String baseName, });
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
instance.checkAll(baseName + fieldName + ".", field.get(data), options);
});
} }
} else if (type.isEnum()) { } else if (type.isEnum()) {
// nothing to do. // nothing to do.
@ -422,26 +321,21 @@ public class CheckJPA<T> implements CheckFunctionInterface {
// keep this is last ==> take more time... // keep this is last ==> take more time...
if (AnnotationTools.isUnique(field)) { if (AnnotationTools.isUnique(field)) {
// Create the request ... // Create the request ...
add(fieldName, add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
( final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
final String baseName, Object other = null;
final T data, if (condCheckers.isEmpty()) {
final List<String> modifiedValue, other = DataAccess.getWhere(this.clazz,
final QueryOptions options) -> { new Condition(new QueryCondition(fieldName, "==", field.get(data))));
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class); } else {
Object other = null; other = DataAccess.getWhere(this.clazz,
if (condCheckers.isEmpty()) { new Condition(new QueryCondition(fieldName, "==", field.get(data))),
other = DataAccess.getWhere(this.clazz, condCheckers.get(0).toCondition());
new Condition(new QueryCondition(fieldName, "==", field.get(data)))); }
} else { if (other != null) {
other = DataAccess.getWhere(this.clazz, throw new InputException(baseName + fieldName, "Name already exist in the DB");
new Condition(new QueryCondition(fieldName, "==", field.get(data))), }
condCheckers.get(0).toCondition()); });
}
if (other != null) {
throw new InputException(baseName + fieldName, "Name already exist in the DB");
}
});
} }
} }
@ -455,7 +349,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
public void check( public void check(
final String baseName, final String baseName,
final Object data, final Object data,
final List<String> modifiedValue, final List<String> filterValue,
final QueryOptions options) throws Exception { final QueryOptions options) throws Exception {
if (this.checking == null) { if (this.checking == null) {
initialize(); initialize();
@ -465,20 +359,19 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final T dataCasted = (T) data; final T dataCasted = (T) data;
for (final String filter : modifiedValue) { for (final String filter : filterValue) {
final List<CheckInterface<T>> actions = this.checking.get(filter); final List<CheckInterface<T>> actions = this.checking.get(filter);
if (actions == null) { if (actions == null) {
continue; continue;
} }
for (final CheckInterface<T> action : actions) { for (final CheckInterface<T> action : actions) {
action.check(baseName, dataCasted, modifiedValue, options); action.check(baseName, dataCasted, options);
} }
} }
checkTyped(dataCasted, modifiedValue, options); checkTyped(dataCasted, filterValue, options);
} }
public void checkTyped(final T data, final List<String> modifiedValue, final QueryOptions options) public void checkTyped(final T data, final List<String> filterValue, final QueryOptions options) throws Exception {
throws Exception {
// nothing to do ... // nothing to do ...
} }
} }

View File

@ -1 +1 @@
0.17.0 0.16.0