Compare commits

...

49 Commits

Author SHA1 Message Date
1b4e6ca239 [RELEASE] Release v0.24.0 2025-02-24 12:34:41 +01:00
be8a5c713a [FIX] ObjectId manyToOne and OneToMany 2025-02-17 00:16:11 +01:00
c3f03bc1e8 [VERSION] update dev tag version 2025-02-09 22:06:56 +01:00
c7eadc607d [RELEASE] Release v0.23.6 2025-02-09 22:06:53 +01:00
5f89ff7944 [DEV] add variable to permit not check if the DB exist 2025-02-09 22:05:35 +01:00
20d2d004cb [VERSION] update dev tag version 2025-02-06 07:47:20 +01:00
da3c467569 [RELEASE] Release v0.23.4 2025-02-06 07:47:17 +01:00
0c932d4e92 [FEAT] set the object enpty as identical as their parent.
this prevent react-hook-form resolver erreur, it does not support empty object
2025-02-04 21:15:10 +01:00
a400bb99b8 [FEAT] add Jwt token description to be serialize in front 2025-02-02 19:34:23 +01:00
bdc9a4ac4d [VERSION] update dev tag version 2025-01-30 21:45:29 +01:00
b0bf103195 [RELEASE] Release v0.23.2 2025-01-30 21:45:26 +01:00
d36c366ab6 [FIX] zod number gte/lte 2025-01-30 21:25:15 +01:00
cddb4dd7fe [DEV] update dev tag version 2025-01-30 10:01:58 +01:00
218fa3be2e [RELEASE] new version 0.23.0 2025-01-29 23:30:01 +01:00
015c38ff5b [FEAT] add @CheckForeignKey but not tested 2025-01-29 23:30:01 +01:00
24590b2a1e [FIX] correct min and mas size of string 2025-01-29 23:10:53 +01:00
c04660c01a [FEAT] simplify annotation tool 2025-01-29 23:09:49 +01:00
3e81673d38 [FIX] normalize comment when check size 2025-01-29 22:43:22 +01:00
69880df4aa [FIX] missing string size checker 2025-01-29 22:41:08 +01:00
510553550f [FIX] remove unneeded comment 2025-01-29 22:40:34 +01:00
e071d3dbf7 [FEAT] correct the output generation of the typescript ==> missing decimal min and decimal max ==> need to test pattern and email 2025-01-29 00:34:49 +01:00
249e6ad2c8 set JPAChecker agnostic of @ManyToOne primary key type 2025-01-28 23:48:40 +01:00
e156e528c1 [FIX] use instance of DB instead of create a new one 2025-01-28 23:44:36 +01:00
89ab0f3b6a [DEV] update dev tag version 2025-01-28 23:27:30 +01:00
3d5a024084 [RELEASE] new version 0.22.0 2025-01-28 23:27:05 +01:00
ba6478182d [API] move the cheker in the correct folder 2025-01-28 23:25:32 +01:00
cc639243fc [FEAT] add support of @DecimalMin and @DecimalMax 2025-01-28 23:17:34 +01:00
24c226e92c [FEAT] add @Size @Min @Max @parttern @email unit test for JPAChecker 2025-01-28 23:16:18 +01:00
b5fcc3e20c [FEAT,API] remove checker from JsonData and creadte @CheckerAnnotation 2025-01-28 23:15:11 +01:00
d028eb2261 Manage correct rights 2025-01-26 23:38:48 +01:00
ca18d3759d [FIX] congig in config 2025-01-25 15:48:35 +01:00
a7c9bb5e1b [FIX] do not set the table name at unknow when null is find 2025-01-25 15:48:04 +01:00
d011b3a587 [FEAT] add decorator CollectionNotEmpty 2025-01-25 14:41:39 +01:00
6974adbfdf [FEAT] add decorator CollectionItemUnique 2025-01-25 14:41:20 +01:00
461aece7a0 [FEAT] add decorator @CollectionItemNotNull 2025-01-25 14:40:07 +01:00
3f15d560ed [FEAT] better interface for dataJson 2025-01-25 14:38:53 +01:00
8f3c14e28d [FEAT] assert when try to insart null data 2025-01-25 12:16:39 +01:00
0d419f651e [FIX] dataJson checker is not responsive for null data pointer 2025-01-25 12:16:13 +01:00
9dad14d200 [FIX] many-many support every key type 2025-01-25 12:15:25 +01:00
990b7c08da [FIX] correct right: set it when no element is requested 2025-01-18 09:57:55 +01:00
7f393a9e44 [FIX] set User block boolean nullable for creation capability (front pb) 2025-01-18 09:57:52 +01:00
c91291dbce [DOC] log better display of path when call filter authentication 2025-01-18 09:57:47 +01:00
d684b5eaa9 [VERSION] update dev tag version 2025-01-11 17:29:13 +01:00
85b27c0b31 [RELEASE] Release v0.21.0 2025-01-11 17:29:10 +01:00
1abbac944d [FIX] correct the bug of multiple access on the add-on list 2025-01-11 10:42:29 +01:00
cef06889ee [DOC] add comment 2025-01-11 10:42:00 +01:00
1e05e8361a [DEV] update UUID error in ObjectId to be simple 2025-01-08 19:54:08 +01:00
4adc097c6b [DEV] rename RESTErrorResponseExeption in RESTErrorResponseException 2025-01-08 19:53:27 +01:00
69e076e991 [VERSION] update dev tag version 2025-01-06 23:47:01 +01:00
57 changed files with 2475 additions and 856 deletions

View File

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

View File

@ -5,6 +5,10 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.kar.archidata.annotation.checker.Checker;
import org.kar.archidata.annotation.checker.CollectionItemNotNull;
import org.kar.archidata.annotation.checker.CollectionItemUnique;
import org.kar.archidata.annotation.checker.CollectionNotEmpty;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.dataAccess.options.OptionRenameColumn;
import org.kar.archidata.dataAccess.options.OverrideTableName;
@ -24,6 +28,8 @@ import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
@ -35,6 +41,24 @@ import jakarta.ws.rs.DefaultValue;
public class AnnotationTools {
static final Logger LOGGER = LoggerFactory.getLogger(AnnotationTools.class);
public static <TYPE extends Annotation> TYPE get(final Field element, final Class<TYPE> clazz) {
final TYPE[] annotations = element.getDeclaredAnnotationsByType(clazz);
if (annotations.length == 0) {
return null;
}
return annotations[0];
}
public static <TYPE extends Annotation> TYPE[] gets(final Field element, final Class<TYPE> clazz) {
final TYPE[] annotations = element.getDeclaredAnnotationsByType(clazz);
if (annotations.length == 0) {
return null;
}
return annotations;
}
// For SQL declaration table Name
public static String getTableName(final Class<?> clazz, final QueryOptions options) throws DataAccessException {
if (options != null) {
@ -85,6 +109,18 @@ public class AnnotationTools {
return tmp;
}
public static CollectionItemNotNull getCollectionItemNotNull(final Field element) {
return get(element, CollectionItemNotNull.class);
}
public static CollectionItemUnique getCollectionItemUnique(final Field element) {
return get(element, CollectionItemUnique.class);
}
public static CollectionNotEmpty getCollectionNotEmpty(final Field element) {
return get(element, CollectionNotEmpty.class);
}
public static boolean getSchemaReadOnly(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
if (annotation.length == 0) {
@ -134,51 +170,39 @@ public class AnnotationTools {
}
public static ManyToOne getManyToOne(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(ManyToOne.class);
if (annotation.length == 0) {
return null;
}
return (ManyToOne) annotation[0];
return get(element, ManyToOne.class);
}
public static ManyToMany getManyToMany(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(ManyToMany.class);
if (annotation.length == 0) {
return null;
}
return (ManyToMany) annotation[0];
return get(element, ManyToMany.class);
}
public static OneToMany getOneToMany(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(OneToMany.class);
if (annotation.length == 0) {
return null;
}
return (OneToMany) annotation[0];
return get(element, OneToMany.class);
}
public static DataJson getDataJson(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DataJson.class);
if (annotation.length == 0) {
return null;
}
return (DataJson) annotation[0];
return get(element, DataJson.class);
}
public static Long getConstraintsMax(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Max.class);
if (annotation.length == 0) {
return null;
}
return ((Max) annotation[0]).value();
public static Checker[] getConstraintsCheckers(final Field element) {
return gets(element, Checker.class);
}
public static Long getConstraintsMin(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Min.class);
if (annotation.length == 0) {
return null;
}
return ((Min) annotation[0]).value();
public static DecimalMin getConstraintsDecimalMin(final Field element) {
return get(element, DecimalMin.class);
}
public static DecimalMax getConstraintsDecimalMax(final Field element) {
return get(element, DecimalMax.class);
}
public static Max getConstraintsMax(final Field element) {
return get(element, Max.class);
}
public static Min getConstraintsMin(final Field element) {
return get(element, Min.class);
}
public static int getLimitSize(final Field element) {
@ -191,27 +215,15 @@ public class AnnotationTools {
}
public static Size getConstraintsSize(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Size.class);
if (annotation.length == 0) {
return null;
}
return (Size) annotation[0];
return get(element, Size.class);
}
public static String getConstraintsPattern(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Pattern.class);
if (annotation.length == 0) {
return null;
}
return ((Pattern) annotation[0]).regexp();
public static Pattern getConstraintsPattern(final Field element) {
return get(element, Pattern.class);
}
public static boolean getConstraintsEmail(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Email.class);
if (annotation.length == 0) {
return false;
}
return true;
public static Email getConstraintsEmail(final Field element) {
return get(element, Email.class);
}
public static boolean isAnnotationGroup(final Field field, final Class<?> annotationType) {

View File

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

View File

@ -0,0 +1,12 @@
package org.kar.archidata.annotation.checker;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckForeignKey {
Class<?> target();
}

View File

@ -0,0 +1,14 @@
package org.kar.archidata.annotation.checker;
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

@ -0,0 +1,12 @@
package org.kar.archidata.annotation.checker;
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 CollectionItemNotNull {
}

View File

@ -0,0 +1,12 @@
package org.kar.archidata.annotation.checker;
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 {
}

View File

@ -0,0 +1,12 @@
package org.kar.archidata.annotation.checker;
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 CollectionNotEmpty {
}

View File

@ -1,4 +1,4 @@
package org.kar.archidata.annotation;
package org.kar.archidata.annotation.method;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;

View File

@ -1,4 +1,4 @@
package org.kar.archidata.annotation;
package org.kar.archidata.annotation.method;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;

View File

@ -14,7 +14,7 @@ public class ExceptionCatcher implements ExceptionMapper<Exception> {
public Response toResponse(final Exception exception) {
LOGGER.warn("Catch exception (not managed...):");
final RestErrorResponse ret = build(exception);
LOGGER.error("Error UUID={}", ret.uuid);
LOGGER.error("Error OID={}", ret.oid);
exception.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ret).type(MediaType.APPLICATION_JSON)
.build();

View File

@ -15,7 +15,7 @@ public class FailExceptionCatcher implements ExceptionMapper<FailException> {
public Response toResponse(final FailException exception) {
LOGGER.warn("Catch FailException: {}", exception.getLocalizedMessage());
final RestErrorResponse ret = build(exception);
LOGGER.error("Error UUID={}", ret.uuid);
LOGGER.error("Error OID={}", ret.oid);
if (exception.exception != null) {
exception.exception.printStackTrace();
}

View File

@ -8,19 +8,35 @@ import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
/**
* This class catches InputException and maps it to a HTTP response.
*/
public class InputExceptionCatcher implements ExceptionMapper<InputException> {
private static final Logger LOGGER = LoggerFactory.getLogger(InputExceptionCatcher.class);
/**
* This method is called when an InputException is thrown.
* It logs the exception and builds a response with the error details.
*
* @param exception the InputException that was thrown
* @return a Response object containing the error details
*/
@Override
public Response toResponse(final InputException exception) {
LOGGER.warn("Catch InputException:");
final RestErrorResponse ret = build(exception);
LOGGER.error("Error UUID={} ==> '{}'=>'{}'", ret.uuid, exception.missingVariable,
LOGGER.error("Error OID={} ==> '{}'=>'{}'", ret.oid, exception.missingVariable,
exception.getLocalizedMessage());
// exception.printStackTrace();
return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
}
/**
* This method builds a RestErrorResponse object from the InputException.
*
* @param exception the InputException that was thrown
* @return a RestErrorResponse object containing the error details
*/
private RestErrorResponse build(final InputException exception) {
return new RestErrorResponse(exception.status, "Error on input='" + exception.missingVariable + "'",
exception.getMessage());

View File

@ -12,16 +12,29 @@ import jakarta.ws.rs.ext.ExceptionMapper;
public class JacksonExceptionCatcher implements ExceptionMapper<JacksonException> {
private static final Logger LOGGER = LoggerFactory.getLogger(JacksonExceptionCatcher.class);
/**
* This method is called when a JacksonException is thrown.
* It logs the exception, builds a response with the error details, and returns it.
*
* @param exception the JacksonException that was thrown
* @return a Response object containing the error details
*/
@Override
public Response toResponse(final JacksonException exception) {
LOGGER.warn("Catch exception Input data parsing:");
final RestErrorResponse ret = build(exception);
LOGGER.error("Error UUID={}", ret.uuid);
LOGGER.error("Error OID={}", ret.oid);
exception.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ret).type(MediaType.APPLICATION_JSON)
.build();
}
/**
* Builds a RestErrorResponse object from the given exception.
*
* @param exception the Exception that was thrown
* @return a RestErrorResponse object containing the error details
*/
private RestErrorResponse build(final Exception exception) {
return new RestErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Catch JSON Exception",
exception.getMessage());

View File

@ -1,10 +1,9 @@
package org.kar.archidata.catcher;
import java.time.Instant;
import java.util.UUID;
import org.bson.types.ObjectId;
import org.kar.archidata.annotation.NoWriteSpecificMode;
import org.kar.archidata.tools.UuidUtils;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull;
@ -12,7 +11,7 @@ import jakarta.ws.rs.core.Response;
@NoWriteSpecificMode
public class RestErrorResponse {
public UUID uuid = UuidUtils.nextUUID();
public ObjectId oid = new ObjectId();
@NotNull
@Column(length = 0)
public String name; // Mandatory for TS generic error

View File

@ -15,7 +15,7 @@ public class SystemExceptionCatcher implements ExceptionMapper<SystemException>
public Response toResponse(final SystemException exception) {
LOGGER.warn("Catch SystemException:");
final RestErrorResponse ret = build(exception);
LOGGER.error("Error UUID={}", ret.uuid);
LOGGER.error("Error OID={}", ret.oid);
exception.printStackTrace();
return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
}

View File

@ -14,7 +14,7 @@ public class WebApplicationExceptionCatcher implements ExceptionMapper<WebApplic
@Override
public Response toResponse(final WebApplicationException exception) {
final RestErrorResponse ret = build(exception);
LOGGER.error("Error UUID={}", ret.uuid);
LOGGER.error("Error OID={}", ret.oid);
return Response.status(exception.getResponse().getStatusInfo().toEnum()).entity(ret)
.type(MediaType.APPLICATION_JSON).build();
}

View File

@ -0,0 +1,898 @@
package org.kar.archidata.checker;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalTime;
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.regex.Pattern;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.checker.CheckForeignKey;
import org.kar.archidata.annotation.checker.Checker;
import org.kar.archidata.annotation.checker.CollectionItemNotNull;
import org.kar.archidata.annotation.checker.CollectionItemUnique;
import org.kar.archidata.annotation.checker.CollectionNotEmpty;
import org.kar.archidata.dataAccess.DBAccess;
import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.dataAccess.options.CheckFunctionInterface;
import org.kar.archidata.dataAccess.options.CheckFunctionVoid;
import org.kar.archidata.dataAccess.options.Condition;
import org.kar.archidata.dataAccess.options.ConditionChecker;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.exception.InputException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.persistence.ManyToOne;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Size;
public class CheckJPA<T> implements CheckFunctionInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(CheckJPA.class);
private final Class<?> clazz;
/** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */
public interface CheckInterface<K> {
/** This function implementation is design to check if the updated class is valid of not for insertion
* @param ioDb Access on the Data-Base
* @param baseName Base of the name input that is displayed in exception generated.
* @param data The object that might be injected.
* @param modifiedValue List of fields that modification is requested.
* @param options Some query option that the checker can need to generate basic check.
* @throws Exception Exception is generate if the data are incorrect. */
void check(
final DBAccess ioDb,
final String baseName,
final K data,
List<String> modifiedValue,
final QueryOptions options) throws Exception;
}
protected Map<String, List<CheckInterface<T>>> checking = null;
protected void add(final String field, final CheckInterface<T> checkFunction) throws DataAccessException {
if (!AnnotationTools.hasFieldsName(this.clazz, field)) {
LOGGER.error("Try to add a JPA Filter on an inexistant Field: '{}' not in {}", field,
AnnotationTools.getAllFieldsNames(this.clazz));
throw new DataAccessException("Try to add a JPA Filter on an inexistant Field: '" + field + "' not in "
+ AnnotationTools.getAllFieldsNames(this.clazz));
}
List<CheckInterface<T>> actions = this.checking.get(field);
if (actions == null) {
actions = new ArrayList<>();
this.checking.put(field, actions);
}
actions.add(checkFunction);
}
public CheckJPA(final Class<T> clazz) {
this.clazz = clazz;
}
public void initialize() throws Exception {
if (this.checking != null) {
return;
}
try {
this.checking = new HashMap<>();
// create Table:
final List<String> primaryKeys = new ArrayList<>();
for (final Field field : this.clazz.getFields()) {
final String fieldName = field.getName(); // AnnotationTools.getFieldName(field);
if (AnnotationTools.isPrimaryKey(field)) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
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)) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
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)) {
add(fieldName,
(
final DBAccess ioDb,
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();
if (type == Long.class || type == long.class) {
final DecimalMax maxValueDecimal = AnnotationTools.getConstraintsDecimalMax(field);
if (maxValueDecimal != null) {
final long maxValue = Long.parseLong(maxValueDecimal.value());
final boolean inclusive = maxValueDecimal.inclusive();
final String exceptionComment = "Value too height max=" + maxValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Long elemTyped = (Long) elem;
if (inclusive) {
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
} else if (elemTyped >= maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final DecimalMin minValueDecimal = AnnotationTools.getConstraintsDecimalMin(field);
if (minValueDecimal != null) {
final long minValue = Long.parseLong(minValueDecimal.value());
final boolean inclusive = minValueDecimal.inclusive();
final String exceptionComment = "Value too low min=" + minValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Long elemTyped = (Long) elem;
if (inclusive) {
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
} else if (elemTyped <= minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Max maxValue = AnnotationTools.getConstraintsMax(field);
if (maxValue != null) {
final Long maxValueTmp = maxValue.value();
final String exceptionComment = "Value too height max=" + maxValueTmp + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Long elemTyped = (Long) elem;
if (elemTyped > maxValueTmp) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Min minValue = AnnotationTools.getConstraintsMin(field);
if (minValue != null) {
final Long minValueTmp = minValue.value();
final String exceptionComment = "Value too low min=" + minValueTmp + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Long elemTyped = (Long) elem;
if (elemTyped < minValueTmp) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
} else if (type == Integer.class || type == int.class) {
final DecimalMax maxValueDecimal = AnnotationTools.getConstraintsDecimalMax(field);
if (maxValueDecimal != null) {
final int maxValue = Integer.parseInt(maxValueDecimal.value());
final boolean inclusive = maxValueDecimal.inclusive();
final String exceptionComment = "Value too height max=" + maxValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Integer elemTyped = (Integer) elem;
if (inclusive) {
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
} else if (elemTyped >= maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final DecimalMin minValueDecimal = AnnotationTools.getConstraintsDecimalMin(field);
if (minValueDecimal != null) {
final int minValue = Integer.parseInt(minValueDecimal.value());
final boolean inclusive = minValueDecimal.inclusive();
final String exceptionComment = "Value too low min=" + minValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Integer elemTyped = (Integer) elem;
if (inclusive) {
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
} else if (elemTyped <= minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Max maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) {
final int maxValue = (int) maxValueRoot.value();
final String exceptionComment = "Value too height max=" + maxValue + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Integer elemTyped = (Integer) elem;
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Min minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) {
final int minValue = (int) minValueRoot.value();
final String exceptionComment = "Value too low min=" + minValue + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Integer elemTyped = (Integer) elem;
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
} else if (type == Boolean.class || type == boolean.class) {
} else if (type == Float.class || type == float.class) {
final DecimalMax maxValueDecimal = AnnotationTools.getConstraintsDecimalMax(field);
if (maxValueDecimal != null) {
final float maxValue = Float.parseFloat(maxValueDecimal.value());
final boolean inclusive = maxValueDecimal.inclusive();
final String exceptionComment = "Value too height max=" + maxValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Float elemTyped = (Float) elem;
if (inclusive) {
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
} else if (elemTyped >= maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final DecimalMin minValueDecimal = AnnotationTools.getConstraintsDecimalMin(field);
if (minValueDecimal != null) {
final float minValue = Float.parseFloat(minValueDecimal.value());
final boolean inclusive = minValueDecimal.inclusive();
final String exceptionComment = "Value too low min=" + minValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Float elemTyped = (Float) elem;
if (inclusive) {
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
} else if (elemTyped <= minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Max maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) {
final float maxValue = maxValueRoot.value();
final String exceptionComment = "Value too height max=" + maxValue + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Float elemTyped = (Float) elem;
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Min minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) {
final float minValue = minValueRoot.value();
final String exceptionComment = "Value too low min=" + minValue + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Float elemTyped = (Float) elem;
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
} else if (type == Double.class || type == double.class) {
final DecimalMax maxValueDecimal = AnnotationTools.getConstraintsDecimalMax(field);
if (maxValueDecimal != null) {
final double maxValue = Float.parseFloat(maxValueDecimal.value());
final boolean inclusive = maxValueDecimal.inclusive();
final String exceptionComment = "Value too height max=" + maxValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Double elemTyped = (Double) elem;
if (inclusive) {
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
} else if (elemTyped >= maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final DecimalMin minValueDecimal = AnnotationTools.getConstraintsDecimalMin(field);
if (minValueDecimal != null) {
final double minValue = Float.parseFloat(minValueDecimal.value());
final boolean inclusive = minValueDecimal.inclusive();
final String exceptionComment = "Value too low min=" + minValue
+ (inclusive ? " (inclusive)" : " (exclusive)");
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Double elemTyped = (Double) elem;
if (inclusive) {
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName,
"Value too Low min: " + minValue);
}
} else if (elemTyped <= minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Max maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) {
final double maxValue = maxValueRoot.value();
final String exceptionComment = "Value too height max=" + maxValue + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Double elemTyped = (Double) elem;
if (elemTyped > maxValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
final Min minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) {
final double minValue = minValueRoot.value();
final String exceptionComment = "Value too low min=" + minValue + " (inclusive)";
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final Double elemTyped = (Double) elem;
if (elemTyped < minValue) {
throw new InputException(baseName + fieldName, exceptionComment);
}
});
}
} else if (type == Date.class || type == Timestamp.class) {
} else if (type == LocalDate.class) {
} else if (type == LocalTime.class) {
} else if (type == String.class) {
final Size limitSize = AnnotationTools.getConstraintsSize(field);
if (limitSize != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final String elemTyped = (String) elem;
if (elemTyped.length() > limitSize.max()) {
throw new InputException(baseName + fieldName,
"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 jakarta.validation.constraints.Pattern patternString = AnnotationTools
.getConstraintsPattern(field);
if (patternString != null && patternString.regexp() != null) {
final Pattern pattern = Pattern.compile(patternString.regexp());
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final String elemTyped = (String) elem;
if (!pattern.matcher(elemTyped).find()) {
throw new InputException(baseName + fieldName,
"does not match the required pattern (constraints) must be '" + pattern
+ "'");
}
});
}
if (AnnotationTools.getConstraintsEmail(field) != null) {
final String emailPattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
final Pattern pattern = Pattern.compile(emailPattern);
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final String elemTyped = (String) elem;
if (!pattern.matcher(elemTyped).find()) {
throw new InputException(baseName + fieldName,
"does not match the required pattern[email] (constraints) must be '"
+ emailPattern + "'");
}
});
}
} else if (type.isEnum()) {
// nothing to do.
}
final Checker[] checkers = AnnotationTools.getConstraintsCheckers(field);
if (checkers != null) {
for (final Checker checker : checkers) {
if (checker == null || checker.value() == CheckFunctionVoid.class) {
continue;
}
final CheckFunctionInterface checkerInstance = checker.value().getDeclaredConstructor()
.newInstance();
if (Collection.class.isAssignableFrom(field.getType())) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> 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;
}
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 {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> 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;
}
checkerInstance.check(ioDb, baseName + fieldName + '.', tmpData, null, options);
});
}
}
}
final CheckForeignKey foreighKey = AnnotationTools.get(field, CheckForeignKey.class);
if (foreighKey != null) {
if (Collection.class.isAssignableFrom(field.getType())) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> 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;
}
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
final Condition conditionCheck = condCheckers.isEmpty() ? null
: condCheckers.get(0).toCondition();
final Collection<?> tmpCollection = (Collection<?>) tmpData;
final Object[] elements = tmpCollection.toArray();
for (int iii = 0; iii < elements.length; iii++) {
if (elements[iii] == null) {
continue;
}
final Long count = ioDb.count(foreighKey.target(), elements[iii],
conditionCheck);
if (count != 1) {
throw new InputException(baseName + fieldName + '[' + iii + ']',
"Foreign-key does not exist in the DB:" + elements[iii]);
}
}
});
} else {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object tmpData = field.get(data);
if (tmpData == null) {
return;
}
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
final Condition conditionCheck = condCheckers.isEmpty() ? null
: condCheckers.get(0).toCondition();
final Long count = ioDb.count(foreighKey.target(), tmpData, conditionCheck);
if (count != 1) {
throw new InputException(baseName + fieldName,
"Foreign-key does not exist in the DB:" + tmpData);
}
});
}
}
// check if we really want to keep it ...
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
final Condition conditionCheck = condCheckers.isEmpty() ? null
: condCheckers.get(0).toCondition();
final long count = ioDb.count(annotationManyToOne.targetEntity(), elem, conditionCheck);
if (count == 0) {
throw new InputException(baseName + fieldName,
"Foreign element does not exist in the DB:" + elem);
}
});
}
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,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object tmpData = field.get(data);
if (tmpData == null) {
return;
}
final Collection<?> tmpCollection = (Collection<?>) tmpData;
final Set<Object> 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())) {
throw new DataAccessException(
"Request @CollectionItemNotNull on a non collection field: '" + fieldName + "'");
}
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object tmpData = field.get(data);
if (tmpData == null) {
return;
}
final Collection<?> tmpCollection = (Collection<?>) tmpData;
final Object[] elements = tmpCollection.toArray();
for (int iii = 0; iii < elements.length; iii++) {
if (elements[iii] == null) {
throw new InputException(baseName + fieldName + '[' + iii + ']',
"Collection can not contain NULL item");
}
}
});
}
final CollectionNotEmpty collectionNotEmpty = AnnotationTools.getCollectionNotEmpty(field);
if (collectionNotEmpty != null) {
if (!Collection.class.isAssignableFrom(field.getType())) {
throw new DataAccessException(
"Request @collectionNotEmpty on a non collection field: '" + fieldName + "'");
}
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object tmpData = field.get(data);
if (tmpData == null) {
return;
}
final Collection<?> tmpCollection = (Collection<?>) tmpData;
if (tmpCollection.isEmpty()) {
throw new InputException(baseName + fieldName, "Collection can not be empty");
}
});
}
// keep this is last ==> take more time...
if (AnnotationTools.isUnique(field)) {
// Create the request ...
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
Object other = null;
if (condCheckers.isEmpty()) {
other = ioDb.getWhere(this.clazz,
new Condition(new QueryCondition(fieldName, "==", field.get(data))));
} else {
other = ioDb.getWhere(this.clazz,
new Condition(new QueryCondition(fieldName, "==", field.get(data))),
condCheckers.get(0).toCondition());
}
if (other != null) {
throw new InputException(baseName + fieldName,
"The field is already exist in the DB");
}
});
}
}
} catch (final Exception ex) {
this.checking = null;
throw ex;
}
}
public void check(final Object data) throws Exception {
check(null, "", data, null, null);
}
public void check(final String baseName, final Object data) throws Exception {
check(null, baseName, data, null, null);
}
public void check(final DBAccess ioDb, final String baseName, final Object data) throws Exception {
check(ioDb, baseName, data, null, null);
}
public void check(final DBAccess ioDb, final String baseName, final Object data, final List<String> modifiedValue)
throws Exception {
check(ioDb, baseName, data, modifiedValue, null);
}
@Override
public void check(
final DBAccess ioDb,
final String baseName,
final Object data,
List<String> modifiedValue,
final QueryOptions options) throws Exception {
if (this.checking == null) {
initialize();
}
if (modifiedValue == null) {
modifiedValue = AnnotationTools.getAllFieldsNames(this.clazz);
}
if (!(this.clazz.isAssignableFrom(data.getClass()))) {
throw new DataAccessException("Incompatatyble type of Object" + data.getClass().getCanonicalName());
}
@SuppressWarnings("unchecked")
final T dataCasted = (T) data;
for (final String filter : modifiedValue) {
final List<CheckInterface<T>> actions = this.checking.get(filter);
if (actions == null) {
continue;
}
for (final CheckInterface<T> action : actions) {
action.check(ioDb, baseName, dataCasted, modifiedValue, options);
}
}
checkTyped(dataCasted, modifiedValue, options);
}
public void checkTyped(final T data, final List<String> modifiedValue, final QueryOptions options)
throws Exception {
// nothing to do ...
}
}

View File

@ -61,20 +61,8 @@ import jakarta.ws.rs.InternalServerErrorException;
public class DBAccessSQL extends DBAccess {
final static Logger LOGGER = LoggerFactory.getLogger(DBAccessSQL.class);
// by default we manage some add-on that permit to manage non-native model (like json serialization, List of external key as String list...)
final static List<DataAccessAddOn> addOn = new ArrayList<>();
{
addOn.add(new AddOnManyToMany());
addOn.add(new AddOnManyToOne());
addOn.add(new AddOnOneToMany());
addOn.add(new AddOnDataJson());
}
/** Add a new add-on on the current management.
* @param addOn instantiate object on the Add-on */
public static void addAddOn(final DataAccessAddOn addOn) {
DBAccessSQL.addOn.add(addOn);
}
final static List<DataAccessAddOn> addOn = List.of(new AddOnManyToMany(), new AddOnManyToOne(),
new AddOnOneToMany(), new AddOnDataJson());
private final DbIoSql db;
@ -170,7 +158,7 @@ public class DBAccessSQL extends DBAccess {
} else {
// TODO : Maybe connect with a temporary not specified connection interface to a db ...
final PreparedStatement ps = this.db.getConnection()
.prepareStatement("SHOW TABLES IN `" + this.db.getCongig().getDbName() + "`");
.prepareStatement("SHOW TABLES IN `" + this.db.getConfig().getDbName() + "`");
final ResultSet rs = ps.executeQuery();
// LOGGER.info("List all tables: equals? '{}'", name);
while (rs.next()) {
@ -827,6 +815,9 @@ public class DBAccessSQL extends DBAccess {
@Override
@SuppressFBWarnings("SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING")
public <T> T insert(final T data, final QueryOption... option) throws Exception {
if (data == null) {
throw new DataAccessException("Try to check a null data ==> wrong API");
}
final Class<?> clazz = data.getClass();
final QueryOptions options = new QueryOptions(option);

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bson.types.ObjectId;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.AnnotationTools.FieldName;
import org.kar.archidata.dataAccess.CountInOut;
@ -72,7 +73,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
if (objectClass == Long.class || objectClass == UUID.class) {
if (objectClass == Long.class || objectClass == UUID.class || objectClass == ObjectId.class) {
return true;
}
final ManyToMany decorators = field.getDeclaredAnnotation(ManyToMany.class);
@ -135,7 +136,11 @@ public class AddOnManyToMany implements DataAccessAddOn {
querySelect.append("'");
if (objectClass == Long.class) {
querySelect.append(SEPARATOR_LONG);
} else if (objectClass == UUID.class) {} else {
} else if (objectClass == UUID.class) {
// ???
} else if (objectClass == ObjectId.class) {
// ???
} else {
final Class<?> foreignKeyType = AnnotationTools.getPrimaryKeyField(objectClass).getType();
if (foreignKeyType == Long.class) {
querySelect.append(SEPARATOR_LONG);
@ -193,7 +198,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
// TODO: manage better the eager and lazy !!
if (objectClass == Long.class || objectClass == UUID.class) {
if (objectClass == Long.class || objectClass == UUID.class || objectClass == ObjectId.class) {
generateConcatQuery(tableName, primaryKey, field, querySelect, query, name, count, options);
}
final ManyToMany decorators = field.getDeclaredAnnotation(ManyToMany.class);
@ -234,6 +239,11 @@ public class AddOnManyToMany implements DataAccessAddOn {
field.set(data, idList);
count.inc();
return;
} else if (objectClass == ObjectId.class) {
final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value);
field.set(data, idList);
count.inc();
return;
}
final ManyToMany decorators = field.getDeclaredAnnotation(ManyToMany.class);
if (decorators == null) {
@ -285,6 +295,27 @@ public class AddOnManyToMany implements DataAccessAddOn {
};
lazyCall.add(lambda);
}
} else if (foreignKeyType == ObjectId.class) {
final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value);
// field.set(data, idList);
count.inc();
if (idList != null && idList.size() > 0) {
final FieldName idField = AnnotationTools.getFieldName(AnnotationTools.getIdField(objectClass),
options);
// In the lazy mode, the request is done in asynchronous mode, they will be done after...
final LazyGetter lambda = () -> {
final List<ObjectId> childs = new ArrayList<>(idList);
// TODO: update to have get with abstract types ....
@SuppressWarnings("unchecked")
final Object foreignData = ioDb.getsWhere(decorators.targetEntity(),
new Condition(new QueryInList<>(idField.inTable(), childs)));
if (foreignData == null) {
return;
}
field.set(data, foreignData);
};
lazyCall.add(lambda);
}
}
}
}
@ -309,9 +340,10 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
if (objectClass != Long.class && objectClass != UUID.class) {
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<"
+ objectClass.getCanonicalName() + ">");
if (objectClass != Long.class && objectClass != UUID.class && objectClass != ObjectId.class) {
throw new DataAccessException(
"Can not ManyToMany with other than List<Long> or List<UUID> or List<ObjectId> Model: List<"
+ objectClass.getCanonicalName() + ">");
}
final FieldName columnName = AnnotationTools.getFieldName(field, options);
final String linkTableName = generateLinkTableName(tableName, columnName.inTable());
@ -348,19 +380,20 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
if (objectClass != Long.class && objectClass != UUID.class) {
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<"
+ objectClass.getCanonicalName() + ">");
if (objectClass != Long.class && objectClass != UUID.class && objectClass != ObjectId.class) {
throw new DataAccessException(
"Can not ManyToMany with other than List<Long> or List<UUID> or List<ObjectId> Model: List<"
+ objectClass.getCanonicalName() + ">");
}
final FieldName columnName = AnnotationTools.getFieldName(field, options);
final String linkTableName = generateLinkTableName(tableName, columnName.inTable());
@SuppressWarnings("unchecked")
final List<Long> dataCasted = (List<Long>) data;
final List<Object> dataCasted = (List<Object>) data;
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableGeneric> insertElements = new ArrayList<>();
for (final Long remoteKey : dataCasted) {
for (final Object remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}

View File

@ -7,6 +7,7 @@ import java.sql.Types;
import java.util.List;
import java.util.UUID;
import org.bson.types.ObjectId;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.AnnotationTools.FieldName;
import org.kar.archidata.dataAccess.CountInOut;
@ -66,6 +67,8 @@ public class AddOnManyToOne implements DataAccessAddOn {
ps.setNull(iii.value, Types.VARCHAR);
} else if (field.getType() == UUID.class) {
ps.setNull(iii.value, Types.BINARY);
} else if (field.getType() == ObjectId.class) {
ps.setNull(iii.value, Types.BINARY);
}
} else if (field.getType() == Long.class) {
final Long dataTyped = (Long) data;
@ -84,6 +87,11 @@ public class AddOnManyToOne implements DataAccessAddOn {
LOGGER.info("Generate UUTD for DB: {}", dataTyped);
final byte[] dataByte = UuidUtils.asBytes(dataTyped);
ps.setBytes(iii.value, dataByte);
} else if (field.getType() == ObjectId.class) {
final ObjectId dataTyped = (ObjectId) data;
LOGGER.info("Generate ObjectId for DB: {}", dataTyped);
final byte[] dataByte = dataTyped.toByteArray();
ps.setBytes(iii.value, dataByte);
} else {
final Field idField = AnnotationTools.getFieldOfId(field.getType());
final Object uid = idField.get(data);
@ -101,7 +109,8 @@ public class AddOnManyToOne implements DataAccessAddOn {
@Override
public boolean canInsert(final Field field) {
if (field.getType() == Long.class || field.getType() == Integer.class || field.getType() == Short.class
|| field.getType() == String.class || field.getType() == UUID.class) {
|| field.getType() == String.class || field.getType() == UUID.class
|| field.getType() == ObjectId.class) {
return true;
}
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
@ -120,7 +129,7 @@ public class AddOnManyToOne implements DataAccessAddOn {
public boolean canRetrieve(final Field field) {
final Class<?> classType = field.getType();
if (classType == Long.class || classType == Integer.class || classType == Short.class
|| classType == String.class || classType == UUID.class) {
|| classType == String.class || classType == UUID.class || classType == ObjectId.class) {
return true;
}
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
@ -141,7 +150,8 @@ public class AddOnManyToOne implements DataAccessAddOn {
@NotNull final CountInOut count,
final QueryOptions options) throws Exception {
if (field.getType() == Long.class || field.getType() == Integer.class || field.getType() == Short.class
|| field.getType() == String.class || field.getType() == UUID.class) {
|| field.getType() == String.class || field.getType() == UUID.class
|| field.getType() == ObjectId.class) {
querySelect.append(" ");
querySelect.append(tableName);
querySelect.append(".");
@ -230,6 +240,15 @@ public class AddOnManyToOne implements DataAccessAddOn {
}
return;
}
if (field.getType() == ObjectId.class) {
final byte[] tmp = rs.getBytes(count.value);
count.inc();
if (!rs.wasNull()) {
final ObjectId foreignKey = new ObjectId(tmp);
field.set(data, foreignKey);
}
return;
}
final Class<?> objectClass = field.getType();
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
if (decorators == null) {
@ -279,6 +298,22 @@ public class AddOnManyToOne implements DataAccessAddOn {
};
lazyCall.add(lambda);
}
} else if (remotePrimaryKeyType == ObjectId.class) {
// here we have the field, the data and the the remote value ==> can create callback that generate the update of the value ...
final ObjectId foreignKey = ioDb.getListOfRawOID(rs, count.value);
count.inc();
if (foreignKey != null) {
// In the lazy mode, the request is done in asynchronous mode, they will be done after...
final LazyGetter lambda = () -> {
// TODO: update to have get with abstract types ....
final Object foreignData = ioDb.get(decorators.targetEntity(), foreignKey);
if (foreignData == null) {
return;
}
field.set(data, foreignData);
};
lazyCall.add(lambda);
}
}
}
}
@ -298,7 +333,7 @@ public class AddOnManyToOne implements DataAccessAddOn {
final QueryOptions options) throws Exception {
final Class<?> classType = field.getType();
if (classType == Long.class || classType == Integer.class || classType == Short.class
|| classType == String.class || classType == UUID.class) {
|| classType == String.class || classType == UUID.class || classType == ObjectId.class) {
DataFactory.createTablesSpecificType(tableName, primaryField, field, mainTableBuilder, preActionList,
postActionList, createIfNotExist, createDrop, fieldId, classType, options);
} else {

View File

@ -10,6 +10,7 @@ import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.bson.types.ObjectId;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.AnnotationTools.FieldName;
import org.kar.archidata.dataAccess.CountInOut;
@ -110,7 +111,7 @@ public class AddOnOneToMany implements DataAccessAddOn {
}
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
if (objectClass == Long.class || objectClass == UUID.class) {
if (objectClass == Long.class || objectClass == UUID.class || objectClass == ObjectId.class) {
return true;
}
final OneToMany decorators = field.getDeclaredAnnotation(OneToMany.class);
@ -201,7 +202,7 @@ public class AddOnOneToMany implements DataAccessAddOn {
return;
}
// TODO: manage better the eager and lazy !!
if (objectClass == Long.class || objectClass == UUID.class) {
if (objectClass == Long.class || objectClass == UUID.class || objectClass == ObjectId.class) {
generateConcatQuery(tableName, primaryKey, field, querySelect, query, name, count, options,
decorators.targetEntity(), decorators.mappedBy());
return;
@ -250,22 +251,35 @@ public class AddOnOneToMany implements DataAccessAddOn {
field.set(data, idList);
count.inc();
return;
} else if (objectClass == ObjectId.class) {
final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value);
field.set(data, idList);
count.inc();
return;
}
if (objectClass == decorators.targetEntity()) {
Long parentIdTmp = null;
UUID parendUuidTmp = null;
ObjectId parendOidTmp = null;
try {
final String modelData = rs.getString(count.value);
parentIdTmp = Long.valueOf(modelData);
count.inc();
} catch (final NumberFormatException ex) {
final List<UUID> idList = ioDb.getListOfRawUUIDs(rs, count.value);
parendUuidTmp = idList.get(0);
count.inc();
try {
final List<UUID> idList = ioDb.getListOfRawUUIDs(rs, count.value);
parendUuidTmp = idList.get(0);
count.inc();
} catch (final NumberFormatException ex2) {
// TODO : How to manage ObjectId ==> I am not sure it works well...
final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value);
parendOidTmp = idList.get(0);
count.inc();
}
}
final Long parentId = parentIdTmp;
final UUID parendUuid = parendUuidTmp;
final ObjectId parendOid = parendOidTmp;
final String mappingKey = decorators.mappedBy();
// We get the parent ID ... ==> need to request the list of elements
if (objectClass == Long.class) {
@ -276,6 +290,10 @@ public class AddOnOneToMany implements DataAccessAddOn {
LOGGER.error("Need to retreive all primary key of all elements");
//field.set(data, idList);
return;
} else if (objectClass == ObjectId.class) {
LOGGER.error("Need to retreive all primary key of all elements");
//field.set(data, idList);
return;
}
if (objectClass == decorators.targetEntity()) {
if (decorators.fetch() == FetchType.EAGER) {
@ -303,6 +321,17 @@ public class AddOnOneToMany implements DataAccessAddOn {
field.set(data, foreignData);
};
lazyCall.add(lambda);
} else if (parendOid != null) {
final LazyGetter lambda = () -> {
@SuppressWarnings("unchecked")
final Object foreignData = ioDb.getsWhere(decorators.targetEntity(),
new Condition(new QueryCondition(mappingKey, "=", parendOid)));
if (foreignData == null) {
return;
}
field.set(data, foreignData);
};
lazyCall.add(lambda);
}
}
}

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. */
public interface CheckFunctionInterface {
/** 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 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. */

View File

@ -1,575 +0,0 @@
package org.kar.archidata.dataAccess.options;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.DBAccess;
import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.exception.InputException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonValue;
import jakarta.persistence.ManyToOne;
import jakarta.validation.constraints.Size;
public class CheckJPA<T> implements CheckFunctionInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(CheckJPA.class);
private final Class<?> clazz;
/** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */
public interface CheckInterface<K> {
/** This function implementation is design to check if the updated class is valid of not for insertion
* @param ioDb Access on the Data-Base
* @param baseName Base of the name input that is displayed in exception generated.
* @param data The object that might be injected.
* @param modifiedValue List of fields that modification is requested.
* @param options Some query option that the checker can need to generate basic check.
* @throws Exception Exception is generate if the data are incorrect. */
void check(
final DBAccess ioDb,
final String baseName,
final K data,
List<String> modifiedValue,
final QueryOptions options) throws Exception;
}
protected Map<String, List<CheckInterface<T>>> checking = null;
protected void add(final String field, final CheckInterface<T> checkFunction) throws DataAccessException {
if (!AnnotationTools.hasFieldsName(this.clazz, field)) {
LOGGER.error("Try to add a JPA Filter on an inexistant Field: '{}' not in {}", field,
AnnotationTools.getAllFieldsNames(this.clazz));
throw new DataAccessException("Try to add a JPA Filter on an inexistant Field: '" + field + "' not in "
+ AnnotationTools.getAllFieldsNames(this.clazz));
}
List<CheckInterface<T>> actions = this.checking.get(field);
if (actions == null) {
actions = new ArrayList<>();
this.checking.put(field, actions);
}
actions.add(checkFunction);
}
public CheckJPA(final Class<T> clazz) {
this.clazz = clazz;
}
public void initialize() throws Exception {
if (this.checking != null) {
return;
}
try {
this.checking = new HashMap<>();
// create Table:
final List<String> primaryKeys = new ArrayList<>();
for (final Field field : this.clazz.getFields()) {
final String fieldName = field.getName(); // AnnotationTools.getFieldName(field);
if (AnnotationTools.isPrimaryKey(field)) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
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)) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
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)) {
add(fieldName,
(
final DBAccess ioDb,
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();
if (type == Long.class || type == long.class) {
final Long maxValue = AnnotationTools.getConstraintsMax(field);
if (maxValue != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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);
if (minValue != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
final Condition conditionCheck = condCheckers.isEmpty() ? null
: condCheckers.get(0).toCondition();
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) {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) {
final int maxValue = maxValueRoot.intValue();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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);
if (minValueRoot != null) {
final int minValue = minValueRoot.intValue();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
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) {
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
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 == Float.class || type == float.class) {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) {
final float maxValue = maxValueRoot.floatValue();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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);
if (minValueRoot != null) {
final float minValue = minValueRoot.floatValue();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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) {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) {
final double maxValue = maxValueRoot.doubleValue();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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);
if (minValueRoot != null) {
final double minValue = minValueRoot.doubleValue();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
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 == LocalDate.class) {
} else if (type == LocalTime.class) {
} else if (type == String.class) {
final int maxSizeString = AnnotationTools.getLimitSize(field);
if (maxSizeString > 0) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
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);
if (limitSize != null) {
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final String elemTyped = (String) elem;
if (elemTyped.length() > limitSize.max()) {
throw new InputException(baseName + fieldName,
"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);
if (patternString != null) {
final Pattern pattern = Pattern.compile(patternString);
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
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 + "'");
}
});
}
if (AnnotationTools.getConstraintsEmail(field)) {
final String emailPattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
final Pattern pattern = Pattern.compile(emailPattern);
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final Object elem = field.get(data);
if (elem == null) {
return;
}
final String elemTyped = (String) elem;
if (!pattern.matcher(elemTyped).find()) {
throw new InputException(baseName + fieldName,
"does not match the required pattern[email] (constraints) must be '"
+ emailPattern + "'");
}
});
}
} 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()) {
// nothing to do.
}
final DataJson dataJson = AnnotationTools.getDataJson(field);
if (dataJson != null && dataJson.checker() != null) {
final CheckFunctionInterface checkerInstance = dataJson.checker().getDeclaredConstructor()
.newInstance();
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
// get the field of the specific element
final Object tmpData = field.get(data);
checkerInstance.check(ioDb, baseName, tmpData, null, options);
});
}
// keep this is last ==> take more time...
if (AnnotationTools.isUnique(field)) {
// Create the request ...
add(fieldName,
(
final DBAccess ioDb,
final String baseName,
final T data,
final List<String> modifiedValue,
final QueryOptions options) -> {
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
Object other = null;
if (condCheckers.isEmpty()) {
other = DataAccess.getWhere(this.clazz,
new Condition(new QueryCondition(fieldName, "==", field.get(data))));
} else {
other = DataAccess.getWhere(this.clazz,
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");
}
});
}
}
} catch (final Exception ex) {
this.checking = null;
throw ex;
}
}
public void check(final Object data) throws Exception {
check(null, "", data, null, null);
}
public void check(final String baseName, final Object data) throws Exception {
check(null, baseName, data, null, null);
}
public void check(final DBAccess ioDb, final String baseName, final Object data) throws Exception {
check(ioDb, baseName, data, null, null);
}
public void check(final DBAccess ioDb, final String baseName, final Object data, final List<String> modifiedValue)
throws Exception {
check(ioDb, baseName, data, modifiedValue, null);
}
@Override
public void check(
final DBAccess ioDb,
final String baseName,
final Object data,
List<String> modifiedValue,
final QueryOptions options) throws Exception {
if (this.checking == null) {
initialize();
}
if (modifiedValue == null) {
modifiedValue = AnnotationTools.getAllFieldsNames(this.clazz);
}
if (!(this.clazz.isAssignableFrom(data.getClass()))) {
throw new DataAccessException("Incompatatyble type of Object" + data.getClass().getCanonicalName());
}
@SuppressWarnings("unchecked")
final T dataCasted = (T) data;
for (final String filter : modifiedValue) {
final List<CheckInterface<T>> actions = this.checking.get(filter);
if (actions == null) {
continue;
}
for (final CheckInterface<T> action : actions) {
action.check(ioDb, baseName, dataCasted, modifiedValue, options);
}
}
checkTyped(dataCasted, modifiedValue, options);
}
public void checkTyped(final T data, final List<String> modifiedValue, final QueryOptions options)
throws Exception {
// nothing to do ...
}
}

View File

@ -76,7 +76,7 @@ public abstract class DbIo implements Closeable {
return this.config.equals(config);
}
public DbConfig getCongig() {
public DbConfig getConfig() {
return this.config;
}
}

View File

@ -1,17 +1,18 @@
package org.kar.archidata.exception;
import java.util.UUID;
import org.bson.types.ObjectId;
public class RESTErrorResponseExeption extends Exception {
public UUID uuid;
public class RESTErrorResponseException extends Exception {
private static final long serialVersionUID = 1L;
public ObjectId oid;
public String time;
public String name;
public String message;
public int status;
public String statusMessage;
public RESTErrorResponseExeption() {
this.uuid = null;
public RESTErrorResponseException() {
this.oid = new ObjectId();
this.time = null;
this.name = null;
this.message = null;
@ -19,9 +20,9 @@ public class RESTErrorResponseExeption extends Exception {
this.statusMessage = null;
}
public RESTErrorResponseExeption(final UUID uuid, final String time, final String name, final String message,
public RESTErrorResponseException(final ObjectId oid, final String time, final String name, final String message,
final int status, final String statusMessage) {
this.uuid = uuid;
this.oid = oid;
this.time = time;
this.name = name;
this.message = message;
@ -31,7 +32,7 @@ public class RESTErrorResponseExeption extends Exception {
@Override
public String toString() {
return "RESTErrorResponseExeption [uuid=" + this.uuid + ", time=" + this.time + ", name=" + this.name
return "RESTErrorResponseExeption [oid=" + this.oid + ", time=" + this.time + ", name=" + this.name
+ ", message=" + this.message + ", status=" + this.status + ", statusMessage=" + this.statusMessage
+ "]";
}

View File

@ -151,38 +151,6 @@ public class DotClassElement {
return ".optional()";
}
public String maxSizeZod(final FieldProperty field) {
final StringBuilder builder = new StringBuilder();
final Class<?> clazz = field.model().getOriginClasses();
if (clazz == String.class) {
if (field.sizeMin() > 0) {
builder.append(".min(");
builder.append(field.sizeMin());
builder.append(")");
}
if (field.sizeMax() > 0) {
builder.append(".max(");
builder.append(field.sizeMax());
builder.append(")");
}
}
if (clazz == short.class || clazz == Short.class || clazz == int.class || clazz == Integer.class
|| clazz == long.class || clazz == Long.class || clazz == float.class || clazz == Float.class
|| clazz == double.class || clazz == Double.class) {
if (field.min() != null && field.min() > 0) {
builder.append(".min(");
builder.append(field.min());
builder.append(")");
}
if (field.max() != null && field.max() > 0) {
builder.append(".max(");
builder.append(field.max());
builder.append(")");
}
}
return builder.toString();
}
public String readOnlyZod(final FieldProperty field) {
if (field.readOnly()) {
return ".readonly()";

View File

@ -7,11 +7,11 @@ import java.util.Arrays;
import java.util.List;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.archidata.annotation.ARCHIVE;
import org.kar.archidata.annotation.AsyncType;
import org.kar.archidata.annotation.FormDataOptional;
import org.kar.archidata.annotation.RESTORE;
import org.kar.archidata.annotation.TypeScriptProgress;
import org.kar.archidata.annotation.method.ARCHIVE;
import org.kar.archidata.annotation.method.RESTORE;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.ws.rs.Consumes;

View File

@ -18,6 +18,12 @@ import org.slf4j.LoggerFactory;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
public class ClassObjectModel extends ClassModel {
@ -61,24 +67,31 @@ public class ClassObjectModel extends ClassModel {
ClassModel model,
ClassModel linkClass, // link class when use remote ID (ex: list<UUID>)
String comment,
int sizeMin, // String SizeMin
int sizeMax, // String SizeMax
Long min, // number min value
Long max, // number max value
Size stringSize, // String Size
Min min, // number min value
Max max, // number max value
DecimalMin decimalMin,
DecimalMax decimalMax,
Pattern pattern,
Email email,
Boolean readOnly,
Boolean notNull,
Boolean columnNotNull,
Boolean nullable) {
public FieldProperty(final String name, final ClassModel model, final ClassModel linkClass,
final String comment, final int sizeMin, final int sizeMax, final Long min, final Long max,
final Boolean readOnly, final Boolean notNull, final Boolean columnNotNull, final Boolean nullable) {
final String comment, final Size stringSize, final Min min, final Max max, final DecimalMin decimalMin,
final DecimalMax decimalMax, final Pattern pattern, final Email email, final Boolean readOnly,
final Boolean notNull, final Boolean columnNotNull, final Boolean nullable) {
this.name = name;
this.model = model;
this.linkClass = linkClass;
this.comment = comment;
this.sizeMin = sizeMin;
this.sizeMax = sizeMax;
this.stringSize = stringSize;
this.decimalMin = decimalMin;
this.decimalMax = decimalMax;
this.pattern = pattern;
this.email = email;
this.min = min;
this.max = max;
this.readOnly = readOnly;
@ -88,17 +101,6 @@ public class ClassObjectModel extends ClassModel {
}
private static int getStringMinSize(final Field field) throws DataAccessException {
final Size size = AnnotationTools.getConstraintsSize(field);
return size != null ? size.min() : 0;
}
private static int getStringMaxSize(final Field field) throws DataAccessException {
final Size size = AnnotationTools.getConstraintsSize(field);
final int colomnLimitSize = AnnotationTools.getLimitSize(field);
return size == null ? colomnLimitSize : colomnLimitSize < size.max() ? colomnLimitSize : size.max();
}
private static Class<?> getSubModelIfExist2(final Field field) {
final ManyToOne manyToOne = AnnotationTools.getManyToOne(field);
if (manyToOne != null) {
@ -137,10 +139,13 @@ public class ClassObjectModel extends ClassModel {
ClassModel.getModel(field.getGenericType(), previous), //
getSubModelIfExist(field, previous), //
AnnotationTools.getSchemaDescription(field), //
getStringMinSize(field), //
getStringMaxSize(field), //
AnnotationTools.getConstraintsSize(field), //
AnnotationTools.getConstraintsMin(field), //
AnnotationTools.getConstraintsMax(field), //
AnnotationTools.getConstraintsDecimalMin(field), //
AnnotationTools.getConstraintsDecimalMax(field), //
AnnotationTools.getConstraintsPattern(field), //
AnnotationTools.getConstraintsEmail(field), //
AnnotationTools.getSchemaReadOnly(field), //
AnnotationTools.getConstraintsNotNull(field), //
AnnotationTools.getColumnNotNull(field), //

View File

@ -259,28 +259,61 @@ public class TsClassElement {
final StringBuilder builder = new StringBuilder();
final Class<?> clazz = field.model().getOriginClasses();
if (clazz == String.class) {
if (field.sizeMin() > 0) {
builder.append(".min(");
builder.append(field.sizeMin());
builder.append(")");
if (field.stringSize() != null) {
if (field.stringSize().min() > 0) {
// A string size can not be lower at 0
builder.append(".min(");
builder.append(field.stringSize().min());
builder.append(")");
}
if (field.stringSize().max() != Integer.MAX_VALUE) {
builder.append(".max(");
builder.append(field.stringSize().max());
builder.append(")");
}
}
if (field.sizeMax() > 0) {
builder.append(".max(");
builder.append(field.sizeMax());
/*Must be tested before
if (field.pattern() != null) {
builder.append(".regex((");
builder.append(field.pattern().regexp());
builder.append(")");
}
}*/
/*Must be tested before
if (field.email() != null) {
builder.append(".regex((");
builder.append(field.email().regexp());
builder.append(")");
}*/
}
if (clazz == short.class || clazz == Short.class || clazz == int.class || clazz == Integer.class
|| clazz == long.class || clazz == Long.class || clazz == float.class || clazz == Float.class
|| clazz == double.class || clazz == Double.class) {
if (field.min() != null && field.min() > 0) {
builder.append(".min(");
builder.append(field.min());
if (field.min() != null) {
builder.append(".gte(");
builder.append(field.min().value());
builder.append(")");
}
if (field.max() != null && field.max() > 0) {
builder.append(".max(");
builder.append(field.max());
if (field.max() != null) {
builder.append(".lte(");
builder.append(field.max().value());
builder.append(")");
}
if (field.decimalMax() != null) {
if (field.decimalMax().inclusive()) {
builder.append(".lte(");
} else {
builder.append(".lt(");
}
builder.append(field.decimalMax().value());
builder.append(")");
}
if (field.decimalMin() != null) {
if (field.decimalMin().inclusive()) {
builder.append(".gte(");
} else {
builder.append(".gt(");
}
builder.append(field.decimalMin().value());
builder.append(")");
}
}
@ -320,16 +353,19 @@ public class TsClassElement {
out.append("export const ");
out.append(this.zodName);
out.append(" = ");
// Check if the object is empty:
boolean isEmpty = model.getFields().size() == 0;
if (model.getExtendsClass() != null) {
final ClassModel parentClass = model.getExtendsClass();
final TsClassElement tsParentModel = tsGroup.find(parentClass);
out.append(tsParentModel.zodName);
out.append(".extend({");
if (!isEmpty) {
out.append(".extend({\n");
}
} else {
out.append("zod.object({");
out.append("zod.object({\n");
}
out.append("\n");
for (final FieldProperty field : model.getFields()) {
final ClassModel fieldModel = field.model();
if (field.comment() != null) {
@ -357,7 +393,11 @@ public class TsClassElement {
out.append(",\n");
}
final List<String> omitField = model.getReadOnlyField();
out.append("\n});\n");
if (model.getExtendsClass() != null && isEmpty) {
out.append(";\n");
} else {
out.append("\n});\n");
}
out.append(generateZodInfer(this.tsTypeName, this.zodName));
out.append(generateExportCheckFunctionWrite(""));
// check if we need to generate write mode :
@ -369,17 +409,18 @@ public class TsClassElement {
out.append("export const ");
out.append(this.zodName);
out.append("Write = ");
isEmpty = model.getFields().stream().filter(field -> !field.readOnly()).count() == 0;
if (model.getExtendsClass() != null) {
final ClassModel parentClass = model.getExtendsClass();
final TsClassElement tsParentModel = tsGroup.find(parentClass);
out.append(tsParentModel.zodName);
out.append("Write");
out.append(".extend({");
if (!isEmpty) {
out.append(".extend({\n");
}
} else {
out.append("zod.object({");
out.append("zod.object({\n");
}
out.append("\n");
for (final FieldProperty field : model.getFields()) {
// remove all readOnly field
if (field.readOnly()) {
@ -417,7 +458,11 @@ public class TsClassElement {
}
out.append(",\n");
}
out.append("\n});\n");
if (model.getExtendsClass() != null && isEmpty) {
out.append(";\n");
} else {
out.append("\n});\n");
}
out.append(generateZodInfer(this.tsTypeName + "Write", this.zodName + "Write"));
// Check only the input value ==> no need of the output
out.append(generateExportCheckFunctionWrite("Write"));

View File

@ -4,7 +4,6 @@ import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey/45814178#45814178
@ -119,7 +118,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
final boolean isApplicationToken = apikeyHeader != null;
final boolean isJwtToken = isTokenBasedAuthentication(authorizationHeader);
if (!isApplicationToken && !isJwtToken) {
LOGGER.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath());
LOGGER.warn("REJECTED unauthorized: /{}", requestContext.getUriInfo().getPath());
abortWithUnauthorized(requestContext, "REJECTED unauthorized: " + requestContext.getUriInfo().getPath());
return;
}
@ -208,7 +207,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
// The WWW-Authenticate header is sent along with the response
LOGGER.warn("abortWithUnauthorized:");
final RestErrorResponse ret = new RestErrorResponse(Response.Status.UNAUTHORIZED, "Unauthorized", message);
LOGGER.error("Error UUID={}", ret.uuid);
LOGGER.error("Error OID={}", ret.oid);
requestContext.abortWith(Response.status(ret.status)
.header(HttpHeaders.WWW_AUTHENTICATE,
AUTHENTICATION_SCHEME + " base64(HEADER).base64(CONTENT).base64(KEY)")
@ -217,7 +216,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
private void abortWithForbidden(final ContainerRequestContext requestContext, final String message) {
final RestErrorResponse ret = new RestErrorResponse(Response.Status.FORBIDDEN, "FORBIDDEN", message);
LOGGER.error("Error UUID={}", ret.uuid);
LOGGER.error("Error OID={}", ret.oid);
requestContext.abortWith(Response.status(ret.status).header(HttpHeaders.WWW_AUTHENTICATE, message).entity(ret)
.type(MediaType.APPLICATION_JSON).build());
}
@ -246,7 +245,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
final Object rowRight = ret.getClaim("right");
if (rowRight != null) {
LOGGER.info("Detect right in Authentication Filter: {}", rowRight);
user.right = (Map<String, Map<String, Object>>) ret.getClaim("right");
user.right = RightSafeCaster.safeCastAndTransform(ret.getClaim("right"));
/*
if (rights.containsKey(this.applicationName)) {
user.right = rights.get(this.applicationName);

View File

@ -26,7 +26,7 @@ public class MySecurityContext implements SecurityContext {
return this.contextPrincipale;
}
public Object getRightOfRoleInGroup(final String group, final String role) {
public PartRight getRightOfRoleInGroup(final String group, final String role) {
if (this.contextPrincipale.userByToken != null) {
return this.contextPrincipale.userByToken.getRight(group, role);
}
@ -67,21 +67,14 @@ public class MySecurityContext implements SecurityContext {
return false;
}
// get associated Roles:
final Object rightPart = getRightOfRoleInGroup(group, role);
LOGGER.info("detect : {}", rightPart);
long dataRight = 0;
if (rightPart instanceof final Long rightPartCasted) {
dataRight = rightPartCasted;
} else if (rightPart instanceof final Integer rightPartCasted) {
dataRight = rightPartCasted;
}
if (dataRight == PartRight.READ_WRITE.getValue()) {
final PartRight rightPart = getRightOfRoleInGroup(group, role);
if (PartRight.READ_WRITE.equals(rightPart)) {
return true;
}
if (!needRead && needWrite && dataRight == PartRight.WRITE.getValue()) {
if (!needRead && needWrite && PartRight.WRITE.equals(rightPart)) {
return true;
}
if (needRead && !needWrite && dataRight == PartRight.READ.getValue()) {
if (needRead && !needWrite && PartRight.READ.equals(rightPart)) {
return true;
}
return false;

View File

@ -27,4 +27,27 @@ public enum PartRight {
}
throw new IllegalArgumentException("PartRight: Unknown value: " + value);
}
public static PartRight fromValue(final long value) {
for (final PartRight element : values()) {
if (element.getValue() == value) {
return element;
}
}
throw new IllegalArgumentException("PartRight: Unknown value: " + value);
}
public static PartRight fromString(final String value) {
if (value == null) {
throw new IllegalArgumentException("La chaîne ne peut pas être nulle");
}
return switch (value.toUpperCase()) {
case "NONE" -> NONE;
case "READ" -> READ;
case "WRITE" -> WRITE;
case "READ_WRITE" -> READ_WRITE;
default -> throw new IllegalArgumentException("Valeur inconnue pour PartRight : " + value);
};
}
}

View File

@ -0,0 +1,61 @@
package org.kar.archidata.filter;
import java.util.Map;
public class RightSafeCaster {
@SuppressWarnings("unchecked")
public static Map<String, Map<String, PartRight>> safeCastAndTransform(final Object obj) {
if (!(obj instanceof Map)) {
throw new IllegalArgumentException("L'objet n'est pas un Map");
}
final Map<?, ?> outerMap = (Map<?, ?>) obj;
// Résultat final après vérification et transformation
final Map<String, Map<String, PartRight>> resultMap = new java.util.HashMap<>();
for (final Map.Entry<?, ?> outerEntry : outerMap.entrySet()) {
if (!(outerEntry.getKey() instanceof String)) {
throw new IllegalArgumentException("Une clé du Map externe n'est pas de type String");
}
if (!(outerEntry.getValue() instanceof Map)) {
throw new IllegalArgumentException("Une valeur du Map externe n'est pas un Map");
}
final String outerKey = (String) outerEntry.getKey();
final Map<?, ?> innerMap = (Map<?, ?>) outerEntry.getValue();
final Map<String, PartRight> transformedInnerMap = new java.util.HashMap<>();
for (final Map.Entry<?, ?> innerEntry : innerMap.entrySet()) {
if (!(innerEntry.getKey() instanceof String)) {
throw new IllegalArgumentException("Une clé du Map interne n'est pas de type String");
}
final String innerKey = (String) innerEntry.getKey();
final Object value = innerEntry.getValue();
PartRight partRight;
if (value instanceof PartRight) {
partRight = (PartRight) value;
} else if (value instanceof final Integer valueCasted) {
partRight = PartRight.fromValue(valueCasted);
} else if (value instanceof final Long valueCasted) {
partRight = PartRight.fromValue(valueCasted);
} else if (value instanceof final String valueCasted) {
partRight = PartRight.fromString(valueCasted);
} else {
throw new IllegalArgumentException("The Map Value is neither PartRight nor String nor Integer");
}
transformedInnerMap.put(innerKey, partRight);
}
resultMap.put(outerKey, transformedInnerMap);
}
return resultMap;
}
}

View File

@ -11,6 +11,7 @@ import org.kar.archidata.dataAccess.DataFactory;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.db.DbConfig;
import org.kar.archidata.migration.model.Migration;
import org.kar.archidata.tools.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -130,35 +131,40 @@ public class MigrationEngine {
}
private void createTableIfAbleOrWaitAdmin(final DbConfig configInput) throws MigrationException {
final DbConfig config = configInput.clone();
config.setDbName(null);
final String dbName = configInput.getDbName();
LOGGER.info("Verify existance of '{}'", dbName);
try (final DBAccess da = DBAccess.createInterface(config)) {
boolean exist = da.isDBExist(dbName);
if (!exist) {
LOGGER.warn("DB: '{}' DOES NOT EXIST ==> create one", dbName);
// create the local DB:
da.createDB(dbName);
}
exist = da.isDBExist(dbName);
while (!exist) {
LOGGER.error("DB: '{}' DOES NOT EXIST after trying to create one ", dbName);
LOGGER.error("Waiting administrator create a new one, we check after 30 seconds...");
try {
Thread.sleep(30000);
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if (ConfigBaseVariable.getDBAbleToCreate()) {
final DbConfig config = configInput.clone();
config.setDbName(null);
final String dbName = configInput.getDbName();
LOGGER.info("Verify existance of '{}'", dbName);
try (final DBAccess da = DBAccess.createInterface(config)) {
boolean exist = da.isDBExist(dbName);
if (!exist) {
LOGGER.warn("DB: '{}' DOES NOT EXIST ==> create one", dbName);
// create the local DB:
da.createDB(dbName);
}
exist = da.isDBExist(dbName);
while (!exist) {
LOGGER.error("DB: '{}' DOES NOT EXIST after trying to create one ", dbName);
LOGGER.error("Waiting administrator create a new one, we check after 30 seconds...");
try {
Thread.sleep(30000);
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
exist = da.isDBExist(dbName);
}
} catch (final InternalServerErrorException e) {
e.printStackTrace();
throw new MigrationException("TODO ...");
} catch (final IOException e) {
e.printStackTrace();
throw new MigrationException("TODO ...");
}
} catch (final InternalServerErrorException e) {
e.printStackTrace();
throw new MigrationException("TODO ...");
} catch (final IOException e) {
e.printStackTrace();
throw new MigrationException("TODO ...");
} else {
final String dbName = configInput.getDbName();
LOGGER.warn("DB: '{}' is not check if it EXIST", dbName);
}
}

View File

@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Size;
@Table(name = "data")
@DataIfNotExists
@ -14,9 +15,11 @@ import jakarta.persistence.Table;
public class Data extends OIDGenericDataSoftDelete {
@Column(length = 128, nullable = false)
@Schema(description = "Sha512 of the data")
@Size(max = 512)
public String sha512;
@Column(length = 128, nullable = false)
@Schema(description = "Mime -type of the media")
@Size(max = 512)
public String mimeType;
@Column(nullable = false)
@Schema(description = "Size in Byte of the data")

View File

@ -48,8 +48,10 @@ public class User extends GenericDataSoftDelete {
@DefaultValue("'0'")
@Column(nullable = false)
public boolean blocked = false;
@Nullable
public Boolean blocked = false;
@Column(length = 512)
@Size(max = 512)
public String blockedReason;
@Schema(description = "List of Id of the specific covers")

View File

@ -4,6 +4,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.kar.archidata.filter.PartRight;
public class UserByToken {
public static final int TYPE_USER = -1;
public static final int TYPE_APPLICATION = -2;
@ -11,10 +13,11 @@ public class UserByToken {
public Integer type = null;
public Long id = null;
public Long parentId = null; // FOr application, this is the id of the application, and of user token, this is the USERID
// For application, this is the id of the application, and of user token, this is the USERID
public Long parentId = null;
public String name = null;
// Right map
public Map<String, Map<String, Object>> right = new HashMap<>();
public Map<String, Map<String, PartRight>> right = new HashMap<>();
public Set<String> getGroups() {
return this.right.keySet();
@ -27,11 +30,11 @@ public class UserByToken {
return this.right.containsKey(group);
}
public Object getRight(final String group, final String key) {
public PartRight getRight(final String group, final String key) {
if (!this.right.containsKey(group)) {
return null;
}
final Map<String, Object> rightGroup = this.right.get(group);
final Map<String, PartRight> rightGroup = this.right.get(group);
if (!rightGroup.containsKey(key)) {
return null;
}

View File

@ -0,0 +1,13 @@
package org.kar.archidata.model.token;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
public class JwtHeader {
@Size(max = 128)
@NotNull
public String typ;
@Size(max = 128)
@NotNull
public String alg;
}

View File

@ -0,0 +1,29 @@
package org.kar.archidata.model.token;
import java.util.Map;
import jakarta.validation.constraints.NotNull;
public class JwtPayload {
// User identification
@NotNull
public String sub;
// Application destination
@NotNull
public String application;
// Emitter of the token
@NotNull
public String iss;
// Access Right Map<application, Map< section, right>>
@NotNull
public Map<String, Map<String, Long>> right;
// user name
@NotNull
public String login;
// Expiration (timestamp)
@NotNull
public Long exp;
// Create time (timestamp)
@NotNull
public Long iat;
}

View File

@ -0,0 +1,12 @@
package org.kar.archidata.model.token;
import jakarta.validation.constraints.NotNull;
public class JwtToken {
@NotNull
public JwtHeader header;
@NotNull
public JwtPayload payload;
@NotNull
public String signature;
}

View File

@ -3,6 +3,7 @@ package org.kar.archidata.tools;
public class ConfigBaseVariable {
static public String tmpDataFolder;
static public String dataFolder;
static public String dbAbleToCreate;
static public String dbType;
static public String dbHost;
static public String dbPort;
@ -23,6 +24,7 @@ public class ConfigBaseVariable {
public static void clearAllValue() {
tmpDataFolder = System.getenv("DATA_TMP_FOLDER");
dataFolder = System.getenv("DATA_FOLDER");
dbAbleToCreate = System.getenv("DB_ABLE_TO_CREATE");
dbType = System.getenv("DB_TYPE");
dbHost = System.getenv("DB_HOST");
dbPort = System.getenv("DB_PORT");
@ -58,6 +60,13 @@ public class ConfigBaseVariable {
return dataFolder;
}
public static boolean getDBAbleToCreate() {
if (dbAbleToCreate == null) {
return true;
}
return Boolean.getBoolean(dbAbleToCreate);
}
public static String getDBType() {
if (dbType == null) {
return "mysql";
@ -100,9 +109,6 @@ public class ConfigBaseVariable {
}
public static String getDBName() {
if (bdDatabase == null) {
return "unknown";
}
return bdDatabase;
}

View File

@ -198,7 +198,7 @@ public class JWTWrapper {
.claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
.expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning
// add right if needed:
if (rights != null && !rights.isEmpty()) {
if (rights != null) {
builder.claim("right", rights);
}
// Prepare JWT with claims set

View File

@ -11,7 +11,7 @@ import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;
import org.kar.archidata.exception.RESTErrorResponseExeption;
import org.kar.archidata.exception.RESTErrorResponseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -37,7 +37,7 @@ public class RESTApi {
}
public <T> List<T> gets(final Class<T> clazz, final String urlOffset)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
final HttpClient client = HttpClient.newHttpClient();
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
.uri(URI.create(this.baseUrl + urlOffset));
@ -48,71 +48,70 @@ public class RESTApi {
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
try {
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseExeption.class);
final RESTErrorResponseException out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseException.class);
throw out;
} catch (final MismatchedInputException ex) {
throw new IOException(
"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(),
this.mapper.getTypeFactory().constructCollectionType(List.class, clazz));
}
public <T> T get(final Class<T> clazz, final String urlOffset)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSendJson("GET", clazz, urlOffset, null);
}
public <T, U> T post(final Class<T> clazz, final String urlOffset, final U data)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSend("POST", clazz, urlOffset, data);
}
public <T, U> T postJson(final Class<T> clazz, final String urlOffset, final String body)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSendJson("POST", clazz, urlOffset, body);
}
public <T> T postMap(final Class<T> clazz, final String urlOffset, final Map<String, Object> data)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSendMap("POST", clazz, urlOffset, data);
}
public <T, U> T put(final Class<T> clazz, final String urlOffset, final U data)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSend("PUT", clazz, urlOffset, data);
}
public <T, U> T putJson(final Class<T> clazz, final String urlOffset, final String body)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSendJson("PUT", clazz, urlOffset, body);
}
public <T> T putMap(final Class<T> clazz, final String urlOffset, final Map<String, Object> data)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSendMap("PUT", clazz, urlOffset, data);
}
public <T, U> T patch(final Class<T> clazz, final String urlOffset, final U data)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSend("PATCH", clazz, urlOffset, data);
}
public <T, U> T patchJson(final Class<T> clazz, final String urlOffset, final String body)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSendJson("PATCH", clazz, urlOffset, body);
}
public <T> T patchMap(final Class<T> clazz, final String urlOffset, final Map<String, Object> data)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return modelSendMap("PATCH", clazz, urlOffset, data);
}
protected <T, U> T modelSend(final String model, final Class<T> clazz, final String urlOffset, final U data)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
if (data == null) {
return modelSendJson(model, clazz, urlOffset, null);
} else {
@ -123,7 +122,7 @@ public class RESTApi {
@SuppressWarnings("unchecked")
public <T, U> T modelSendJson(final String model, final Class<T> clazz, final String urlOffset, String body)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
final HttpClient client = HttpClient.newHttpClient();
// client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
@ -138,13 +137,14 @@ public class RESTApi {
} else {
requestBuilding = requestBuilding.header("Content-Type", "application/json");
}
LOGGER.trace("publish body: {}", body);
final HttpRequest request = requestBuilding.method(model, BodyPublishers.ofString(body)).build();
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
LOGGER.trace("Receive Error: {}", httpResponse.body());
try {
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseExeption.class);
final RESTErrorResponseException out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseException.class);
throw out;
} catch (final MismatchedInputException ex) {
throw new IOException(
@ -171,7 +171,7 @@ public class RESTApi {
final String model,
final Class<T> clazz,
final String urlOffset,
final Map<String, Object> data) throws RESTErrorResponseExeption, IOException, InterruptedException {
final Map<String, Object> data) throws RESTErrorResponseException, IOException, InterruptedException {
final HttpClient client = HttpClient.newHttpClient();
String body = null;
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
@ -189,8 +189,8 @@ public class RESTApi {
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
try {
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseExeption.class);
final RESTErrorResponseException out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseException.class);
throw out;
} catch (final MismatchedInputException ex) {
throw new IOException(
@ -210,7 +210,7 @@ public class RESTApi {
* Call a DELETE on a REST API
* @param urlOffset Offset to call the API
*/
public void delete(final String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
public void delete(final String urlOffset) throws RESTErrorResponseException, IOException, InterruptedException {
delete(Void.class, urlOffset);
}
@ -222,7 +222,7 @@ public class RESTApi {
* @return The parsed object received.
*/
public <T> T delete(final Class<T> clazz, final String urlOffset)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return simpleRequest("DELETE", clazz, urlOffset);
}
@ -230,7 +230,7 @@ public class RESTApi {
* Call an ARCHIVE on a REST API
* @param urlOffset Offset to call the API
*/
public void archive(final String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
public void archive(final String urlOffset) throws RESTErrorResponseException, IOException, InterruptedException {
archive(Void.class, urlOffset);
}
@ -242,7 +242,7 @@ public class RESTApi {
* @return The parsed object received.
*/
public <T> T archive(final Class<T> clazz, final String urlOffset)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return simpleRequest("ARCHIVE", clazz, urlOffset);
}
@ -250,7 +250,7 @@ public class RESTApi {
* Call an RESTORE on a REST API
* @param urlOffset Offset to call the API
*/
public void restore(final String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
public void restore(final String urlOffset) throws RESTErrorResponseException, IOException, InterruptedException {
restore(Void.class, urlOffset);
}
@ -262,7 +262,7 @@ public class RESTApi {
* @return The parsed object received.
*/
public <T> T restore(final Class<T> clazz, final String urlOffset)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
return simpleRequest("RESTORE", clazz, urlOffset);
}
@ -275,7 +275,7 @@ public class RESTApi {
* @return The parsed object received.
*/
public <T> T simpleRequest(final String model, final Class<T> clazz, final String urlOffset)
throws RESTErrorResponseExeption, IOException, InterruptedException {
throws RESTErrorResponseException, IOException, InterruptedException {
final HttpClient client = HttpClient.newHttpClient();
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
.uri(URI.create(this.baseUrl + urlOffset));
@ -286,8 +286,8 @@ public class RESTApi {
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
try {
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseExeption.class);
final RESTErrorResponseException out = this.mapper.readValue(httpResponse.body(),
RESTErrorResponseException.class);
throw out;
} catch (final MismatchedInputException ex) {
throw new IOException(

View File

@ -4,9 +4,9 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.kar.archidata.annotation.ARCHIVE;
import org.kar.archidata.annotation.AsyncType;
import org.kar.archidata.annotation.RESTORE;
import org.kar.archidata.annotation.method.ARCHIVE;
import org.kar.archidata.annotation.method.RESTORE;
import org.kar.archidata.exception.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -2,9 +2,9 @@ package test.kar.archidata.apiExtern.resource;
import java.util.List;
import org.kar.archidata.annotation.ARCHIVE;
import org.kar.archidata.annotation.AsyncType;
import org.kar.archidata.annotation.RESTORE;
import org.kar.archidata.annotation.method.ARCHIVE;
import org.kar.archidata.annotation.method.RESTORE;
import org.kar.archidata.dataAccess.DataAccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -0,0 +1,240 @@
package test.kar.archidata.checker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.kar.archidata.exception.InputException;
import test.kar.archidata.checker.model.JpaBaseModel;
import test.kar.archidata.checker.model.JpaBaseModel.JpaBaseModelChecker;
public class TestJPACheckerDecimalMax {
@Test
public void testDecimalMaxIncludeInteger() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxIncludeInteger = 75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeInteger = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeInteger = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeInteger = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxIncludeIntegerObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxIncludeIntegerObject = 75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeIntegerObject = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeIntegerObject = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeIntegerObject = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxIncludeLong() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxIncludeLong = 75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeLong = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeLong = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeLong = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxIncludeLongObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxIncludeLongObject = 75L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeLongObject = 74L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeLongObject = 76L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeLongObject = 100L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxIncludeFloat() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
// can not be tested
//data.testDecimalMaxIncludeFloat = 75.56f;
//Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeFloat = 75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeFloat = 75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeFloat = 100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxIncludeFloatObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxIncludeFloatObject = 75.56f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeFloatObject = 75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeFloatObject = 75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeFloatObject = 100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxIncludeDouble() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
// can not be tested
//data.testDecimalMaxIncludeDouble = 75.56d;
//Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeDouble = 75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeDouble = 75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeDouble = 100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxIncludeDoubleObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
//data.testDecimalMaxIncludeDoubleObject = 75.56d;
//Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeDoubleObject = 75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxIncludeDoubleObject = 75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxIncludeDoubleObject = 100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
// exclude
@Test
public void testDecimalMaxExcludeInteger() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeInteger = 75;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeInteger = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeInteger = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeInteger = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxExcludeIntegerObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeIntegerObject = 75;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeIntegerObject = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeIntegerObject = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeIntegerObject = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxExcludeLong() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeLong = 75;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeLong = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeLong = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeLong = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxExcludeLongObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeLongObject = 75L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeLongObject = 74L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeLongObject = 76L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeLongObject = 100L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxExcludeFloat() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeFloat = 75.56f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeFloat = 75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeFloat = 75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeFloat = 100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxExcludeFloatObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeFloatObject = 75.56f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeFloatObject = 75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeFloatObject = 75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeFloatObject = 100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxExcludeDouble() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeDouble = 75.56d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeDouble = 75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeDouble = 75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeDouble = 100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMaxExcludeDoubleObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMaxExcludeDoubleObject = 75.56d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeDoubleObject = 75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMaxExcludeDoubleObject = 75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMaxExcludeDoubleObject = 100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
}

View File

@ -0,0 +1,240 @@
package test.kar.archidata.checker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.kar.archidata.exception.InputException;
import test.kar.archidata.checker.model.JpaBaseModel;
import test.kar.archidata.checker.model.JpaBaseModel.JpaBaseModelChecker;
public class TestJPACheckerDecimalMin {
@Test
public void testDecimalMinIncludeInteger() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinIncludeInteger = -75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeInteger = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeInteger = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeInteger = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinIncludeIntegerObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinIncludeIntegerObject = -75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeIntegerObject = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeIntegerObject = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeIntegerObject = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinIncludeLong() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinIncludeLong = -75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeLong = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeLong = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeLong = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinIncludeLongObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinIncludeLongObject = -75L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeLongObject = -74L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeLongObject = -76L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeLongObject = -100L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinIncludeFloat() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinIncludeFloat = -75.56f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeFloat = -75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeFloat = -75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeFloat = -100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinIncludeFloatObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinIncludeFloatObject = -75.56f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeFloatObject = -75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeFloatObject = -75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeFloatObject = -100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinIncludeDouble() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
// can not be tested
//data.testDecimalMinIncludeDouble = -75.56d;
//Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeDouble = -75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeDouble = -75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeDouble = -100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinIncludeDoubleObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
// can not be tested
//data.testDecimalMinIncludeDoubleObject = -75.56d;
//Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeDoubleObject = -75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinIncludeDoubleObject = -75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinIncludeDoubleObject = -100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
// exclude
@Test
public void testDecimalMinExcludeInteger() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeInteger = -75;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeInteger = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeInteger = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeInteger = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinExcludeIntegerObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeIntegerObject = -75;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeIntegerObject = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeIntegerObject = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeIntegerObject = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinExcludeLong() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeLong = -75;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeLong = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeLong = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeLong = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinExcludeLongObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeLongObject = -75L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeLongObject = -74L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeLongObject = -76L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeLongObject = -100L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinExcludeFloat() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeFloat = -75.56f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeFloat = -75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeFloat = -75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeFloat = -100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinExcludeFloatObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeFloatObject = -75.56f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeFloatObject = -75.5599f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeFloatObject = -75.5601f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeFloatObject = -100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinExcludeDouble() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeDouble = -75.56d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeDouble = -75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeDouble = -75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeDouble = -100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testDecimalMinExcludeDoubleObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testDecimalMinExcludeDoubleObject = -75.56d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeDoubleObject = -75.5599d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testDecimalMinExcludeDoubleObject = -75.5601d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testDecimalMinExcludeDoubleObject = -100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
}

View File

@ -0,0 +1,30 @@
package test.kar.archidata.checker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.kar.archidata.exception.InputException;
import test.kar.archidata.checker.model.JpaBaseModel;
import test.kar.archidata.checker.model.JpaBaseModel.JpaBaseModelChecker;
public class TestJPACheckerEMail {
@Test
public void testEMail() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testEMail = "s@s.ds";
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testEMail = "yuio.sdf@sqdf.com";
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testEMail = "s@s.s";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testEMail = "sq@qsd";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testEMail = "sqsdfsdf";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testEMail = "56465456";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
}

View File

@ -0,0 +1,123 @@
package test.kar.archidata.checker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.kar.archidata.exception.InputException;
import test.kar.archidata.checker.model.JpaBaseModel;
import test.kar.archidata.checker.model.JpaBaseModel.JpaBaseModelChecker;
public class TestJPACheckerMax {
@Test
public void testMaxInteger() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxInteger = 75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxInteger = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxInteger = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxInteger = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMaxIntegerObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxIntegerObject = 75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxIntegerObject = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxIntegerObject = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxIntegerObject = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMaxLong() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxLong = 75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxLong = 74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxLong = 76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxLong = 100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMaxLongObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxLongObject = 75L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxLongObject = 74L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxLongObject = 76L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxLongObject = 100L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMaxFloat() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxFloat = 75f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxFloat = 74.99f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxFloat = 75.01f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxFloat = 100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMaxFloatObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxFloatObject = 75f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxFloatObject = 74.99f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxFloatObject = 75.01f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxFloatObject = 100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMaxDouble() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxDouble = 75d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxDouble = 74.99d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxDouble = 75.01d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxDouble = 100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMaxDoubleObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMaxDoubleObject = 75d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxDoubleObject = 74.99d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMaxDoubleObject = 75.01d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMaxDoubleObject = 100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
}

View File

@ -0,0 +1,123 @@
package test.kar.archidata.checker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.kar.archidata.exception.InputException;
import test.kar.archidata.checker.model.JpaBaseModel;
import test.kar.archidata.checker.model.JpaBaseModel.JpaBaseModelChecker;
public class TestJPACheckerMin {
@Test
public void testMinInteger() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinInteger = -75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinInteger = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinInteger = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinInteger = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMinIntegerObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinIntegerObject = -75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinIntegerObject = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinIntegerObject = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinIntegerObject = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMinLong() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinLong = -75;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinLong = -74;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinLong = -76;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinLong = -100;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMinLongObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinLongObject = -75L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinLongObject = -74L;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinLongObject = -76L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinLongObject = -100L;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMinFloat() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinFloat = -75f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinFloat = -74.99f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinFloat = -75.01f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinFloat = -100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMinFloatObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinFloatObject = -75f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinFloatObject = -74.99f;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinFloatObject = -75.01f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinFloatObject = -100f;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMinDouble() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinDouble = -75d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinDouble = -74.99d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinDouble = -75.01d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinDouble = -100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
@Test
public void testMinDoubleObject() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testMinDoubleObject = -75d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinDoubleObject = -74.99d;
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testMinDoubleObject = -75.01d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testMinDoubleObject = -100d;
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
}

View File

@ -0,0 +1,26 @@
package test.kar.archidata.checker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.kar.archidata.exception.InputException;
import test.kar.archidata.checker.model.JpaBaseModel;
import test.kar.archidata.checker.model.JpaBaseModel.JpaBaseModelChecker;
public class TestJPACheckerPattern {
@Test
public void testPattern() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testPattern = "0";
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testPattern = "1234567890";
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testPattern = "q";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testPattern = "qsdf4653";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
}

View File

@ -0,0 +1,26 @@
package test.kar.archidata.checker;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.kar.archidata.exception.InputException;
import test.kar.archidata.checker.model.JpaBaseModel;
import test.kar.archidata.checker.model.JpaBaseModel.JpaBaseModelChecker;
public class TestJPACheckerSize {
@Test
public void testSize() throws Exception {
final JpaBaseModelChecker checker = new JpaBaseModelChecker();
final JpaBaseModel data = new JpaBaseModel();
data.testSize = "000";
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testSize = "00000000";
Assertions.assertDoesNotThrow(() -> checker.check(data));
data.testSize = "00";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
data.testSize = "000000000";
Assertions.assertThrows(InputException.class, () -> checker.check(data));
}
}

View File

@ -0,0 +1,132 @@
package test.kar.archidata.checker.model;
import org.kar.archidata.checker.CheckJPA;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
public class JpaBaseModel {
// Simple checker declaration
public static class JpaBaseModelChecker extends CheckJPA<JpaBaseModel> {
public JpaBaseModelChecker() {
super(JpaBaseModel.class);
}
}
// Simple data to verify if the checker is active
@Size(min = 3, max = 8)
public String testSize;
@Pattern(regexp = "^[0-9]+$")
public String testPattern;
@Email
public String testEMail;
@Min(-75)
public int testMinInteger;
@Min(-75)
public Integer testMinIntegerObject;
@Min(-75)
public long testMinLong;
@Min(-75)
public Long testMinLongObject;
@Min(-75)
public float testMinFloat;
@Min(-75)
public Float testMinFloatObject;
@Min(-75)
public double testMinDouble;
@Min(-75)
public Double testMinDoubleObject;
@Max(75)
public int testMaxInteger;
@Max(75)
public Integer testMaxIntegerObject;
@Max(75)
public long testMaxLong;
@Max(75)
public Long testMaxLongObject;
@Max(75)
public float testMaxFloat;
@Max(75)
public Float testMaxFloatObject;
@Max(75)
public double testMaxDouble;
@Max(75)
public Double testMaxDoubleObject;
@DecimalMin("-75")
public int testDecimalMinIncludeInteger;
@DecimalMin("-75")
public Integer testDecimalMinIncludeIntegerObject;
@DecimalMin("-75")
public long testDecimalMinIncludeLong;
@DecimalMin("-75")
public Long testDecimalMinIncludeLongObject;
@DecimalMin("-75.56")
public float testDecimalMinIncludeFloat;
@DecimalMin("-75.56")
public Float testDecimalMinIncludeFloatObject;
@DecimalMin("-75.56")
public double testDecimalMinIncludeDouble;
@DecimalMin("-75.56")
public Double testDecimalMinIncludeDoubleObject;
@DecimalMax("75")
public int testDecimalMaxIncludeInteger;
@DecimalMax("75")
public Integer testDecimalMaxIncludeIntegerObject;
@DecimalMax("75")
public long testDecimalMaxIncludeLong;
@DecimalMax("75")
public Long testDecimalMaxIncludeLongObject;
@DecimalMax("75.56")
public float testDecimalMaxIncludeFloat;
@DecimalMax("75.56")
public Float testDecimalMaxIncludeFloatObject;
@DecimalMax("75.56")
public double testDecimalMaxIncludeDouble;
@DecimalMax("75.56")
public Double testDecimalMaxIncludeDoubleObject;
@DecimalMin(value = "-75", inclusive = false)
public int testDecimalMinExcludeInteger;
@DecimalMin(value = "-75", inclusive = false)
public Integer testDecimalMinExcludeIntegerObject;
@DecimalMin(value = "-75", inclusive = false)
public long testDecimalMinExcludeLong;
@DecimalMin(value = "-75", inclusive = false)
public Long testDecimalMinExcludeLongObject;
@DecimalMin(value = "-75.56", inclusive = false)
public float testDecimalMinExcludeFloat;
@DecimalMin(value = "-75.56", inclusive = false)
public Float testDecimalMinExcludeFloatObject;
@DecimalMin(value = "-75.56", inclusive = false)
public double testDecimalMinExcludeDouble;
@DecimalMin(value = "-75.56", inclusive = false)
public Double testDecimalMinExcludeDoubleObject;
@DecimalMax(value = "75", inclusive = false)
public int testDecimalMaxExcludeInteger;
@DecimalMax(value = "75", inclusive = false)
public Integer testDecimalMaxExcludeIntegerObject;
@DecimalMax(value = "75", inclusive = false)
public long testDecimalMaxExcludeLong;
@DecimalMax(value = "75", inclusive = false)
public Long testDecimalMaxExcludeLongObject;
@DecimalMax(value = "75.56", inclusive = false)
public float testDecimalMaxExcludeFloat;
@DecimalMax(value = "75.56", inclusive = false)
public Float testDecimalMaxExcludeFloatObject;
@DecimalMax(value = "75.56", inclusive = false)
public double testDecimalMaxExcludeDouble;
@DecimalMax(value = "75.56", inclusive = false)
public Double testDecimalMaxExcludeDoubleObject;
}

View File

@ -1,6 +1,6 @@
package test.kar.archidata.dataAccess.model;
import org.kar.archidata.dataAccess.options.CheckJPA;
import org.kar.archidata.checker.CheckJPA;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

View File

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

View File

@ -1 +1 @@
0.20.4
0.24.0