Compare commits
	
		
			39 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 218fa3be2e | |||
| 015c38ff5b | |||
| 24590b2a1e | |||
| c04660c01a | |||
| 3e81673d38 | |||
| 69880df4aa | |||
| 510553550f | |||
| e071d3dbf7 | |||
| 249e6ad2c8 | |||
| e156e528c1 | |||
| 89ab0f3b6a | |||
| 3d5a024084 | |||
| ba6478182d | |||
| cc639243fc | |||
| 24c226e92c | |||
| b5fcc3e20c | |||
| d028eb2261 | |||
| ca18d3759d | |||
| a7c9bb5e1b | |||
| d011b3a587 | |||
| 6974adbfdf | |||
| 461aece7a0 | |||
| 3f15d560ed | |||
| 8f3c14e28d | |||
| 0d419f651e | |||
| 9dad14d200 | |||
| 990b7c08da | |||
| 7f393a9e44 | |||
| c91291dbce | |||
| d684b5eaa9 | |||
| 85b27c0b31 | |||
| 1abbac944d | |||
| cef06889ee | |||
| 1e05e8361a | |||
| 4adc097c6b | |||
| 69e076e991 | |||
| 5e478e3caa | |||
| 5a97f794f6 | |||
| ac59e17de8 | 
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
| 	<groupId>kangaroo-and-rabbit</groupId> | ||||
| 	<artifactId>archidata</artifactId> | ||||
| 	<version>0.20.2</version> | ||||
| 	<version>0.23.0</version> | ||||
| 	<properties> | ||||
| 		<java.version>21</java.version> | ||||
| 		<maven.compiler.version>3.1</maven.compiler.version> | ||||
|   | ||||
| @@ -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; | ||||
| 	public static DecimalMin getConstraintsDecimalMin(final Field element) { | ||||
| 		return get(element, DecimalMin.class); | ||||
| 	} | ||||
| 		return ((Min) annotation[0]).value(); | ||||
|  | ||||
| 	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) { | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/org/kar/archidata/annotation/checker/Checker.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/org/kar/archidata/annotation/checker/Checker.java
									
									
									
									
									
										Normal 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(); | ||||
| } | ||||
| @@ -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 { | ||||
|  | ||||
| } | ||||
| @@ -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 { | ||||
|  | ||||
| } | ||||
| @@ -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 { | ||||
|  | ||||
| } | ||||
| @@ -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; | ||||
| @@ -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; | ||||
| @@ -89,13 +89,18 @@ public class DataResource { | ||||
|  | ||||
| 	public static String getFileDataOld(final UUID uuid) { | ||||
| 		final String stringUUID = uuid.toString(); | ||||
| 		final String filePath = ConfigBaseVariable.getMediaDataFolder() + File.separator + stringUUID + File.separator | ||||
| 				+ "data"; | ||||
| 		final String part1 = stringUUID.substring(0, 2); | ||||
| 		final String part2 = stringUUID.substring(2, 4); | ||||
| 		final String part3 = stringUUID.substring(4); | ||||
| 		final String finalPath = part1 + File.separator + part2; | ||||
| 		String filePath = ConfigBaseVariable.getMediaDataFolder() + "_uuid" + File.separator + finalPath | ||||
| 				+ File.separator; | ||||
| 		try { | ||||
| 			createFolder(ConfigBaseVariable.getMediaDataFolder() + File.separator + stringUUID + File.separator); | ||||
| 			createFolder(filePath); | ||||
| 		} catch (final IOException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 		filePath += part3; | ||||
| 		return filePath; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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(); | ||||
| 		} | ||||
|   | ||||
| @@ -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()); | ||||
|   | ||||
| @@ -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()); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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(); | ||||
| 	} | ||||
|   | ||||
| @@ -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(); | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										898
									
								
								src/org/kar/archidata/checker/CheckJPA.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										898
									
								
								src/org/kar/archidata/checker/CheckJPA.java
									
									
									
									
									
										Normal 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 ... | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -355,12 +355,12 @@ public class AddOnManyToMany implements DataAccessAddOn { | ||||
| 		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"); | ||||
| 			} | ||||
|   | ||||
| @@ -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. */ | ||||
|   | ||||
| @@ -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 ... | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -76,7 +76,7 @@ public abstract class DbIo implements Closeable { | ||||
| 		return this.config.equals(config); | ||||
| 	} | ||||
|  | ||||
| 	public DbConfig getCongig() { | ||||
| 	public DbConfig getConfig() { | ||||
| 		return this.config; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| 				+ "]"; | ||||
| 	} | ||||
| @@ -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()"; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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), // | ||||
|   | ||||
| @@ -259,30 +259,59 @@ public class TsClassElement { | ||||
| 		final StringBuilder builder = new StringBuilder(); | ||||
| 		final Class<?> clazz = field.model().getOriginClasses(); | ||||
| 		if (clazz == String.class) { | ||||
| 			if (field.sizeMin() > 0) { | ||||
| 			if (field.stringSize() != null) { | ||||
| 				if (field.stringSize().min() > 0) { | ||||
| 					// A string size can not be lower at 0 | ||||
| 					builder.append(".min("); | ||||
| 				builder.append(field.sizeMin()); | ||||
| 					builder.append(field.stringSize().min()); | ||||
| 					builder.append(")"); | ||||
| 				} | ||||
| 			if (field.sizeMax() > 0) { | ||||
| 				if (field.stringSize().max() != Integer.MAX_VALUE) { | ||||
| 					builder.append(".max("); | ||||
| 				builder.append(field.sizeMax()); | ||||
| 					builder.append(field.stringSize().max()); | ||||
| 					builder.append(")"); | ||||
| 				} | ||||
| 			} | ||||
| 			/*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) { | ||||
| 			if (field.min() != null) { | ||||
| 				builder.append(".min("); | ||||
| 				builder.append(field.min()); | ||||
| 				builder.append(field.min().value()); | ||||
| 				builder.append(")"); | ||||
| 			} | ||||
| 			if (field.max() != null && field.max() > 0) { | ||||
| 			if (field.max() != null) { | ||||
| 				builder.append(".max("); | ||||
| 				builder.append(field.max()); | ||||
| 				builder.append(field.max().value()); | ||||
| 				builder.append(")"); | ||||
| 			} | ||||
| 			if (field.decimalMax() != null) { | ||||
| 				builder.append(".max("); | ||||
| 				builder.append(field.decimalMax().value()); | ||||
| 				builder.append(", { inclusive: "); | ||||
| 				builder.append(field.decimalMax().inclusive() ? "true" : "false"); | ||||
| 				builder.append("})"); | ||||
| 			} | ||||
| 			if (field.decimalMin() != null) { | ||||
| 				builder.append(".min("); | ||||
| 				builder.append(field.decimalMin().value()); | ||||
| 				builder.append(", { inclusive: "); | ||||
| 				builder.append(field.decimalMin().inclusive() ? "true" : "false"); | ||||
| 				builder.append("})"); | ||||
| 			} | ||||
| 		} | ||||
| 		return builder.toString(); | ||||
| 	} | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
| 		}; | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										61
									
								
								src/org/kar/archidata/filter/RightSafeCaster.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/org/kar/archidata/filter/RightSafeCaster.java
									
									
									
									
									
										Normal 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; | ||||
| 	} | ||||
| } | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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; | ||||
| 		} | ||||
|   | ||||
| @@ -100,9 +100,6 @@ public class ConfigBaseVariable { | ||||
| 	} | ||||
|  | ||||
| 	public static String getDBName() { | ||||
| 		if (bdDatabase == null) { | ||||
| 			return "unknown"; | ||||
| 		} | ||||
| 		return bdDatabase; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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( | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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)); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -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)); | ||||
| 	} | ||||
|  | ||||
| } | ||||
							
								
								
									
										30
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerEMail.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerEMail.java
									
									
									
									
									
										Normal 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)); | ||||
| 	} | ||||
|  | ||||
| } | ||||
							
								
								
									
										123
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerMax.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerMax.java
									
									
									
									
									
										Normal 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)); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										123
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerMin.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerMin.java
									
									
									
									
									
										Normal 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)); | ||||
| 	} | ||||
| } | ||||
| @@ -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)); | ||||
| 	} | ||||
|  | ||||
| } | ||||
							
								
								
									
										26
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerSize.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								test/src/test/kar/archidata/checker/TestJPACheckerSize.java
									
									
									
									
									
										Normal 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)); | ||||
| 	} | ||||
|  | ||||
| } | ||||
							
								
								
									
										132
									
								
								test/src/test/kar/archidata/checker/model/JpaBaseModel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								test/src/test/kar/archidata/checker/model/JpaBaseModel.java
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| 0.20.2 | ||||
| 0.23.0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user