diff --git a/src/org/kar/archidata/dataAccess/DataAccess.java b/src/org/kar/archidata/dataAccess/DataAccess.java index ac8a0de..a10b325 100644 --- a/src/org/kar/archidata/dataAccess/DataAccess.java +++ b/src/org/kar/archidata/dataAccess/DataAccess.java @@ -796,7 +796,7 @@ public class DataAccess { // External checker of data: final List checks = options.get(CheckFunction.class); for (final CheckFunction check : checks) { - check.getChecker().check("", data, AnnotationTools.getFieldsNames(clazz)); + check.getChecker().check("", data, AnnotationTools.getFieldsNames(clazz), options); } final DBEntry entry = DBInterfaceOption.getAutoEntry(options); @@ -1119,7 +1119,7 @@ public class DataAccess { if (options != null) { final List checks = options.get(CheckFunction.class); for (final CheckFunction check : checks) { - check.getChecker().check("", data, filter.getValues()); + check.getChecker().check("", data, filter.getValues(), options); } } final List asyncActions = new ArrayList<>(); @@ -1293,8 +1293,7 @@ public class DataAccess { return stmt.execute(query); } - public static T getWhere(final Class clazz, final QueryOption... option) throws Exception { - final QueryOptions options = new QueryOptions(option); + public static T getWhere(final Class clazz, final QueryOptions options) throws Exception { options.add(new Limit(1)); final List values = getsWhere(clazz, options); if (values.size() == 0) { @@ -1303,6 +1302,11 @@ public class DataAccess { return values.get(0); } + public static T getWhere(final Class clazz, final QueryOption... option) throws Exception { + final QueryOptions options = new QueryOptions(option); + return getWhere(clazz, options); + } + public static void generateSelectField(// final StringBuilder querySelect, // final StringBuilder query, // @@ -1484,12 +1488,19 @@ public class DataAccess { return data; } - public static long count(final Class clazz, final ID_TYPE id) throws Exception { - return DataAccess.countWhere(clazz, new Condition(getTableIdCondition(clazz, id))); + public static long count(final Class clazz, final ID_TYPE id, final QueryOption... option) + throws Exception { + final QueryOptions options = new QueryOptions(option); + options.add(new Condition(getTableIdCondition(clazz, id))); + return DataAccess.countWhere(clazz, options); } public static long countWhere(final Class clazz, final QueryOption... option) throws Exception { final QueryOptions options = new QueryOptions(option); + return countWhere(clazz, options); + } + + public static long countWhere(final Class clazz, final QueryOptions options) throws Exception { final Condition condition = conditionFusionOrEmpty(options, false); final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz); DBEntry entry = DBInterfaceOption.getAutoEntry(options); diff --git a/src/org/kar/archidata/dataAccess/options/CheckFunctionInterface.java b/src/org/kar/archidata/dataAccess/options/CheckFunctionInterface.java index 87b28f9..6c8940a 100644 --- a/src/org/kar/archidata/dataAccess/options/CheckFunctionInterface.java +++ b/src/org/kar/archidata/dataAccess/options/CheckFunctionInterface.java @@ -3,6 +3,7 @@ package org.kar.archidata.dataAccess.options; import java.util.List; import org.kar.archidata.annotation.AnnotationTools; +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 { @@ -11,10 +12,11 @@ public interface CheckFunctionInterface { * @param data The object that might be injected. * @param filterValue List of fields that might be check. If null, then all column must be checked. * @throws Exception Exception is generate if the data are incorrect. */ - void check(final String baseName, Object data, List filterValue) throws Exception; + void check(final String baseName, Object data, List filterValue, final QueryOptions options) + throws Exception; - default void checkAll(final String baseName, final Object data) throws Exception { - check(baseName, data, AnnotationTools.getAllFieldsNames(data.getClass())); + default void checkAll(final String baseName, final Object data, final QueryOptions options) throws Exception { + check(baseName, data, AnnotationTools.getAllFieldsNames(data.getClass()), options); } } diff --git a/src/org/kar/archidata/dataAccess/options/CheckFunctionVoid.java b/src/org/kar/archidata/dataAccess/options/CheckFunctionVoid.java index 78fc011..f98fda7 100644 --- a/src/org/kar/archidata/dataAccess/options/CheckFunctionVoid.java +++ b/src/org/kar/archidata/dataAccess/options/CheckFunctionVoid.java @@ -2,10 +2,16 @@ package org.kar.archidata.dataAccess.options; import java.util.List; +import org.kar.archidata.dataAccess.QueryOptions; + /** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */ public class CheckFunctionVoid implements CheckFunctionInterface { @Override - public void check(final String baseName, Object data, List filterValue) { + public void check( + final String baseName, + final Object data, + final List filterValue, + final QueryOptions options) { } diff --git a/src/org/kar/archidata/dataAccess/options/CheckJPA.java b/src/org/kar/archidata/dataAccess/options/CheckJPA.java index 43dec83..c2f4cc6 100644 --- a/src/org/kar/archidata/dataAccess/options/CheckJPA.java +++ b/src/org/kar/archidata/dataAccess/options/CheckJPA.java @@ -16,6 +16,7 @@ import org.kar.archidata.annotation.AnnotationTools; import org.kar.archidata.annotation.DataJson; 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; @@ -37,7 +38,7 @@ public class CheckJPA implements CheckFunctionInterface { * @param data The object that might be injected. * @param filterValue List of fields that might be check. If null, then all column must be checked. * @throws Exception Exception is generate if the data are incorrect. */ - void check(final String baseName, final K data) throws Exception; + void check(final String baseName, final K data, final QueryOptions options) throws Exception; } protected Map>> checking = null; @@ -66,20 +67,20 @@ public class CheckJPA implements CheckFunctionInterface { for (final Field field : this.clazz.getFields()) { final String fieldName = field.getName(); // AnnotationTools.getFieldName(field); if (AnnotationTools.isPrimaryKey(field)) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { throw new InputException(baseName + fieldName, "This is a '@Id' (primaryKey) ==> can not be change"); }); } if (AnnotationTools.getConstraintsNotNull(field)) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, 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 String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { throw new InputException(baseName + fieldName, "It is forbidden to change this field"); }); } @@ -88,7 +89,7 @@ public class CheckJPA implements CheckFunctionInterface { if (type == Long.class || type == long.class) { final Long maxValue = AnnotationTools.getConstraintsMax(field); if (maxValue != null) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -101,7 +102,7 @@ public class CheckJPA implements CheckFunctionInterface { } final Long minValue = AnnotationTools.getConstraintsMin(field); if (minValue != null) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -114,12 +115,19 @@ public class CheckJPA implements CheckFunctionInterface { } final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; } - final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem); + final List condCheckers = options.get(ConditionChecker.class); + long count = 0; + if (condCheckers.isEmpty()) { + count = DataAccess.count(annotationManyToOne.targetEntity(), elem); + } else { + count = DataAccess.count(annotationManyToOne.targetEntity(), elem, + condCheckers.get(0).toCondition()); + } if (count == 0) { throw new InputException(baseName + fieldName, "Foreign element does not exist in the DB:" + elem); @@ -131,7 +139,7 @@ public class CheckJPA implements CheckFunctionInterface { final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); if (maxValueRoot != null) { final int maxValue = maxValueRoot.intValue(); - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -145,7 +153,7 @@ public class CheckJPA implements CheckFunctionInterface { final Long minValueRoot = AnnotationTools.getConstraintsMin(field); if (minValueRoot != null) { final int minValue = minValueRoot.intValue(); - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -158,7 +166,7 @@ public class CheckJPA implements CheckFunctionInterface { } final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -173,7 +181,7 @@ public class CheckJPA implements CheckFunctionInterface { } else if (type == UUID.class) { final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -191,7 +199,7 @@ public class CheckJPA implements CheckFunctionInterface { final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); if (maxValueRoot != null) { final float maxValue = maxValueRoot.floatValue(); - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -205,7 +213,7 @@ public class CheckJPA implements CheckFunctionInterface { final Long minValueRoot = AnnotationTools.getConstraintsMin(field); if (minValueRoot != null) { final float minValue = minValueRoot.floatValue(); - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -220,7 +228,7 @@ public class CheckJPA implements CheckFunctionInterface { final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); if (maxValueRoot != null) { final double maxValue = maxValueRoot.doubleValue(); - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -234,7 +242,7 @@ public class CheckJPA implements CheckFunctionInterface { final Long minValueRoot = AnnotationTools.getConstraintsMin(field); if (minValueRoot != null) { final double minValue = minValueRoot.doubleValue(); - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -254,7 +262,7 @@ public class CheckJPA implements CheckFunctionInterface { } else if (type == String.class) { final int maxSizeString = AnnotationTools.getLimitSize(field); if (maxSizeString > 0) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -268,7 +276,7 @@ public class CheckJPA implements CheckFunctionInterface { } final Size limitSize = AnnotationTools.getConstraintsSize(field); if (limitSize != null) { - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -287,7 +295,7 @@ public class CheckJPA implements CheckFunctionInterface { final String patternString = AnnotationTools.getConstraintsPattern(field); if (patternString != null) { final Pattern pattern = Pattern.compile(patternString); - add(fieldName, (final String baseName, final T data) -> { + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { final Object elem = field.get(data); if (elem == null) { return; @@ -306,8 +314,8 @@ public class CheckJPA implements CheckFunctionInterface { // 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 String baseName, final T data) -> { - instance.checkAll(baseName + fieldName + ".", field.get(data)); + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { + instance.checkAll(baseName + fieldName + ".", field.get(data), options); }); } } else if (type.isEnum()) { @@ -316,9 +324,17 @@ public class CheckJPA implements CheckFunctionInterface { // keep this is last ==> take more time... if (AnnotationTools.isUnique(field)) { // Create the request ... - add(fieldName, (final String baseName, final T data) -> { - final Object other = DataAccess.getWhere(this.clazz, - new Condition(new QueryCondition(fieldName, "==", field.get(data)))); + add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { + final List 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"); } @@ -333,7 +349,11 @@ public class CheckJPA implements CheckFunctionInterface { } @Override - public void check(final String baseName, final Object data, final List filterValue) throws Exception { + public void check( + final String baseName, + final Object data, + final List filterValue, + final QueryOptions options) throws Exception { if (this.checking == null) { initialize(); } @@ -348,13 +368,13 @@ public class CheckJPA implements CheckFunctionInterface { continue; } for (final CheckInterface action : actions) { - action.check(baseName, dataCasted); + action.check(baseName, dataCasted, options); } } - checkTyped(dataCasted, filterValue); + checkTyped(dataCasted, filterValue, options); } - public void checkTyped(final T data, final List filterValue) throws Exception { + public void checkTyped(final T data, final List filterValue, final QueryOptions options) throws Exception { // nothing to do ... } } diff --git a/src/org/kar/archidata/dataAccess/options/ConditionChecker.java b/src/org/kar/archidata/dataAccess/options/ConditionChecker.java new file mode 100644 index 0000000..0439197 --- /dev/null +++ b/src/org/kar/archidata/dataAccess/options/ConditionChecker.java @@ -0,0 +1,21 @@ +package org.kar.archidata.dataAccess.options; + +import org.kar.archidata.dataAccess.QueryItem; + +/** Condition model apply to the check models. */ +public class ConditionChecker extends QueryOption { + public final QueryItem condition; + + public ConditionChecker(final QueryItem items) { + this.condition = items; + } + + public ConditionChecker() { + this.condition = null; + } + + public Condition toCondition() { + return new Condition(this.condition); + } + +} diff --git a/src/org/kar/archidata/externalRestApi/TsApiGeneration.java b/src/org/kar/archidata/externalRestApi/TsApiGeneration.java index f0961aa..33f4399 100644 --- a/src/org/kar/archidata/externalRestApi/TsApiGeneration.java +++ b/src/org/kar/archidata/externalRestApi/TsApiGeneration.java @@ -55,7 +55,7 @@ public class TsApiGeneration { if (tsModel.nativeType != DefinedPosition.NATIVE) { imports.add(model); } - if (tsModel.nativeType == DefinedPosition.BASIC) { + if (tsModel.nativeType != DefinedPosition.NORMAL) { return tsModel.tsTypeName; } if (writeMode) {