[DEV] update the basic exception model

This commit is contained in:
Edouard DUPIN 2023-11-13 23:33:05 +01:00
parent d1a866277d
commit b48916be07
5 changed files with 103 additions and 110 deletions

View File

@ -10,16 +10,16 @@ import jakarta.ws.rs.ext.ExceptionMapper;
public class FailException404API implements ExceptionMapper<ClientErrorException> {
private static final Logger LOGGER = LoggerFactory.getLogger(FailException404API.class);
@Override
public Response toResponse(ClientErrorException exception) {
RestErrorResponse ret = build(exception);
public Response toResponse(final ClientErrorException exception) {
final RestErrorResponse ret = build(exception);
LOGGER.error("Error UUID={}", ret.uuid);
return Response.status(exception.getResponse().getStatusInfo().toEnum()).entity(ret).type(MediaType.APPLICATION_JSON).build();
}
private RestErrorResponse build(ClientErrorException exception) {
private RestErrorResponse build(final ClientErrorException exception) {
return new RestErrorResponse(exception.getResponse().getStatusInfo().toEnum(), "Catch system exception", exception.getMessage());
}
}

View File

@ -26,6 +26,7 @@ import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.dataAccess.addOn.AddOnManyToOne;
import org.kar.archidata.dataAccess.addOn.AddOnSQLTableExternalForeinKeyAsList;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -274,7 +275,7 @@ public class DataAccess {
ps.setString(iii.value, tmp.toString());
}
} else {
throw new Exception("Unknown Field Type");
throw new DataAccessException("Unknown Field Type");
}
iii.inc();
}
@ -430,7 +431,7 @@ public class DataAccess {
// TODO: maybe do something stupid if not exist ???
}
} else {
throw new Exception("Unknown Field Type");
throw new DataAccessException("Unknown Field Type");
}
count.inc();
}
@ -448,6 +449,15 @@ public class DataAccess {
return null;
}
public static <T> List<T> insertMultiple(final List<T> data, final QueryOptions options) throws Exception {
final List<T> out = new ArrayList<>();
for (final T elem : data) {
final T tmp = insert(elem, options);
out.add(tmp);
}
return out;
}
public static <T> T insert(final T data) throws Exception {
return insert(data, null);
}
@ -603,6 +613,20 @@ public class DataAccess {
return insert(data);
}
public static <ID_TYPE> QueryCondition getTableIdCondition(final Class<?> clazz, final ID_TYPE idKey) throws Exception {
// Find the ID field type ....
final Field idField = AnnotationTools.getIdField(clazz);
if (idField == null) {
throw new DataAccessException("The class have no annotation @Id ==> can not determine the default type searching");
}
// check the compatibility of the id and the declared ID
final Class<?> typeClass = idField.getType();
if (idKey == typeClass) {
throw new DataAccessException("Request update with the wrong type ...");
}
return new QueryCondition(AnnotationTools.getFieldName(idField), "=", idKey);
}
/**
* Update an object with the inserted json data
*
@ -615,21 +639,10 @@ public class DataAccess {
* @throws Exception
*/
public static <T, ID_TYPE> int updateWithJson(final Class<T> clazz, final ID_TYPE id, final String jsonData) throws Exception {
// Find the ID field type ....
final Field idField = AnnotationTools.getIdField(clazz);
if (idField == null) {
throw new Exception("The class have no annotation @Id ==> can not determine the default type searching");
}
// check the compatibility of the id and the declared ID
final Class<?> typeClass = idField.getType();
if (id == typeClass) {
throw new Exception("Request update with the wrong type ...");
}
// Udpade Json Value
return updateWithJson(clazz, new QueryCondition(AnnotationTools.getFieldName(idField), "=", id), jsonData);
return updateWhereWithJson(clazz, getTableIdCondition(clazz, id), jsonData);
}
public static <T> int updateWithJson(final Class<T> clazz, final QueryItem condition, final String jsonData) throws Exception {
public static <T> int updateWhereWithJson(final Class<T> clazz, final QueryItem condition, final String jsonData) throws Exception {
final ObjectMapper mapper = new ObjectMapper();
// parse the object to be sure the data are valid:
final T data = mapper.readValue(jsonData, clazz);
@ -659,17 +672,7 @@ public class DataAccess {
* @throws Exception
*/
public static <T, ID_TYPE> int update(final T data, final ID_TYPE id, final List<String> filterValue) throws Exception {
// Find the ID field type ....
final Field idField = AnnotationTools.getIdField(data.getClass());
if (idField == null) {
throw new Exception("The class have no annotation @Id ==> can not determine the default type searching");
}
// check the compatibility of the id and the declared ID
final Class<?> typeClass = idField.getType();
if (id == typeClass) {
throw new Exception("Request update with the wriong type ...");
}
return updateWhere(data, new QueryCondition(AnnotationTools.getFieldName(idField), "=", id), null, filterValue);
return updateWhere(data, getTableIdCondition(data.getClass(), id), null, filterValue);
}
public static <T> int updateWhere(final T data, final QueryItem condition, final QueryOptions options, final List<String> filterValue) throws Exception {
@ -799,7 +802,7 @@ public class DataAccess {
} else if (value.getClass().isEnum()) {
ps.setString(iii.value, value.toString());
} else {
throw new Exception("Not manage type ==> need to add it ...");
throw new DataAccessException("Not manage type ==> need to add it ...");
}
}
@ -1014,25 +1017,12 @@ public class DataAccess {
}
// TODO : detect the @Id
public static <T> T get(final Class<T> clazz, final long id) throws Exception {
public static <T, ID_TYPE> T get(final Class<T> clazz, final ID_TYPE id) throws Exception {
return get(clazz, id, null);
}
public static <T> T get(final Class<T> clazz, final long id, final QueryOptions options) throws Exception {
Field primaryKeyField = null;
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
if (AnnotationTools.isPrimaryKey(elem)) {
primaryKeyField = elem;
}
}
if (primaryKeyField != null) {
return DataAccess.getWhere(clazz, new QueryCondition(AnnotationTools.getFieldName(primaryKeyField), "=", id), options);
}
throw new Exception("Missing primary Key...");
public static <T, ID_TYPE> T get(final Class<T> clazz, final ID_TYPE id, final QueryOptions options) throws Exception {
return DataAccess.getWhere(clazz, getTableIdCondition(clazz, id), options);
}
public static String getCurrentTimeStamp() {
@ -1048,11 +1038,11 @@ public class DataAccess {
}
// TODO : detect the @Id
public static int delete(final Class<?> clazz, final long id) throws Exception {
public static <ID_TYPE> int delete(final Class<?> clazz, final ID_TYPE id) throws Exception {
return delete(clazz, id, null);
}
public static int delete(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
public static <ID_TYPE> int delete(final Class<?> clazz, final ID_TYPE id, final QueryOptions options) throws Exception {
final String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
if (hasDeletedFieldName != null) {
return deleteSoft(clazz, id, options);
@ -1070,8 +1060,8 @@ public class DataAccess {
}
}
public static int deleteHard(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
return deleteHardWhere(clazz, new QueryCondition("id", "=", id), options);
public static <ID_TYPE> int deleteHard(final Class<?> clazz, final ID_TYPE id, final QueryOptions options) throws Exception {
return deleteHardWhere(clazz, getTableIdCondition(clazz, id), options);
}
public static int deleteHardWhere(final Class<?> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
@ -1097,8 +1087,8 @@ public class DataAccess {
}
}
private static int deleteSoft(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
return deleteSoftWhere(clazz, new QueryCondition("id", "=", id), options);
private static <ID_TYPE> int deleteSoft(final Class<?> clazz, final ID_TYPE id, final QueryOptions options) throws Exception {
return deleteSoftWhere(clazz, getTableIdCondition(clazz, id), options);
}
public static String getDBNow() {
@ -1148,19 +1138,19 @@ public class DataAccess {
}
}
public static int unsetDelete(final Class<?> clazz, final long id) throws Exception {
return unsetDeleteWhere(clazz, new QueryCondition("id", "=", id), null);
public static <ID_TYPE> int unsetDelete(final Class<?> clazz, final ID_TYPE id) throws Exception {
return unsetDeleteWhere(clazz, getTableIdCondition(clazz, id), null);
}
public static int unsetDelete(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
return unsetDeleteWhere(clazz, new QueryCondition("id", "=", id), options);
public static <ID_TYPE> int unsetDelete(final Class<?> clazz, final ID_TYPE id, final QueryOptions options) throws Exception {
return unsetDeleteWhere(clazz, getTableIdCondition(clazz, id), options);
}
public static int unsetDeleteWhere(final Class<?> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz, options);
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
if (deletedFieldName == null) {
throw new Exception("The class " + clazz.getCanonicalName() + " has no deleted field");
throw new DataAccessException("The class " + clazz.getCanonicalName() + " has no deleted field");
}
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
final StringBuilder query = new StringBuilder();

View File

@ -12,6 +12,7 @@ import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.annotation.UpdateTimestamp;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,7 +23,7 @@ import jakarta.persistence.GenerationType;
public class DataFactory {
static final Logger LOGGER = LoggerFactory.getLogger(DataFactory.class);
public static String convertTypeInSQL(final Class<?> type, final String fieldName) throws Exception {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
if (type == Long.class || type == long.class) {
@ -123,23 +124,23 @@ public class DataFactory {
return out.toString();
}
}
throw new Exception("Imcompatible type of element in object for: " + type.getCanonicalName());
throw new DataAccessException("Imcompatible type of element in object for: " + type.getCanonicalName());
}
public static void createTablesSpecificType(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> preOtherTables, final List<String> postOtherTables,
final boolean createIfNotExist, final boolean createDrop, final int fieldId, final Class<?> classModel) throws Exception {
final String name = AnnotationTools.getFieldName(elem);
final Integer limitSize = AnnotationTools.getLimitSize(elem);
final boolean notNull = AnnotationTools.getNotNull(elem);
final boolean primaryKey = AnnotationTools.isPrimaryKey(elem);
final GenerationType strategy = AnnotationTools.getStrategy(elem);
final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
final String comment = AnnotationTools.getComment(elem);
final String defaultValue = AnnotationTools.getDefault(elem);
if (fieldId == 0) {
mainTableBuilder.append("\n\t\t`");
} else {
@ -199,10 +200,10 @@ public class DataFactory {
triggerBuilder.append(name);
triggerBuilder.append(" = datetime('now') WHERE id = NEW.id; \n");
triggerBuilder.append("END;");
postOtherTables.add(triggerBuilder.toString());
}
mainTableBuilder.append(" ");
}
} else {
@ -237,11 +238,11 @@ public class DataFactory {
mainTableBuilder.append("DEFAULT ");
mainTableBuilder.append(defaultValue);
mainTableBuilder.append(" ");
}
if (primaryKey && "sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("PRIMARY KEY ");
}
if (strategy == GenerationType.IDENTITY) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
@ -250,16 +251,16 @@ public class DataFactory {
mainTableBuilder.append("AUTOINCREMENT ");
}
} else if (strategy != null) {
throw new Exception("Can not generate a stategy different of IDENTITY");
throw new DataAccessException("Can not generate a stategy different of IDENTITY");
}
if (comment != null && !"sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("COMMENT '");
mainTableBuilder.append(comment.replace('\'', '\''));
mainTableBuilder.append("' ");
}
}
private static boolean isFieldFromSuperClass(final Class<?> model, final String filedName) {
final Class<?> superClass = model.getSuperclass();
if (superClass == null) {
@ -279,14 +280,14 @@ public class DataFactory {
}
return false;
}
public static List<String> createTable(final Class<?> clazz) throws Exception {
return createTable(clazz, null);
}
public static List<String> createTable(final Class<?> clazz, final QueryOptions options) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz, options);
boolean createDrop = false;
if (options != null) {
final Object data = options.get(QueryOptions.CREATE_DROP_TABLE);
@ -296,7 +297,7 @@ public class DataFactory {
LOGGER.error("'{}' ==> has not a Boolean value: {}", QueryOptions.CREATE_DROP_TABLE, data);
}
}
final boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(DataIfNotExists.class).length != 0;
final List<String> preActionList = new ArrayList<>();
final List<String> postActionList = new ArrayList<>();
@ -316,7 +317,7 @@ public class DataFactory {
int fieldId = 0;
LOGGER.debug("===> TABLE `{}`", tableName);
final List<String> primaryKeys = new ArrayList<>();
for (final Field elem : clazz.getFields()) {
// DEtect the primary key (support only one primary key right now...
if (AnnotationTools.isPrimaryKey(elem)) {
@ -353,7 +354,7 @@ public class DataFactory {
if (addOn != null) {
addOn.createTables(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId);
} else {
throw new Exception(
throw new DataAccessException(
"Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType());
}
} else {
@ -397,5 +398,5 @@ public class DataFactory {
preActionList.addAll(postActionList);
return preActionList;
}
}

View File

@ -20,6 +20,7 @@ import org.kar.archidata.dataAccess.QueryItem;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.dataAccess.QueryOr;
import org.kar.archidata.dataAccess.addOn.model.LinkTable;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,43 +32,43 @@ import jakarta.validation.constraints.NotNull;
public class AddOnManyToMany implements DataAccessAddOn {
static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class);
static final String SEPARATOR = "-";
@Override
public Class<?> getAnnotationClass() {
return ManyToMany.class;
}
@Override
public String getSQLFieldType(final Field elem) {
return null;
}
@Override
public boolean isCompatibleField(final Field elem) {
final ManyToMany decorators = elem.getDeclaredAnnotation(ManyToMany.class);
return decorators != null;
}
@Override
public void insertData(final PreparedStatement ps, final Field field, final Object rootObject, final CountInOut iii) throws SQLException, IllegalArgumentException, IllegalAccessException {
}
@Override
public boolean canInsert(final Field field) {
return false;
}
@Override
public boolean canRetrieve(final Field field) {
return true;
}
public static String generateLinkTableNameField(final String tableName, final Field field) throws Exception {
final String name = AnnotationTools.getFieldName(field);
return generateLinkTableName(tableName, name);
}
public static String generateLinkTableName(final String tableName, final String name) {
String localName = name;
if (name.endsWith("s")) {
@ -75,10 +76,10 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
return tableName + "_link_" + localName;
}
public void generateConcatQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry,
@NotNull final String name, @NotNull final CountInOut elemCount, final QueryOptions options) {
final String linkTableName = generateLinkTableName(tableName, name);
final String tmpVariable = "tmp_" + Integer.toString(elemCount.value);
querrySelect.append(" (SELECT GROUP_CONCAT(");
@ -120,7 +121,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
*/
elemCount.inc();
}
@Override
public void generateQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry, @NotNull final String name,
@NotNull final CountInOut elemCount, final QueryOptions options) throws Exception {
@ -137,13 +138,13 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
if (objectClass == decorators.targetEntity()) {
if (decorators.fetch() == FetchType.EAGER) {
throw new Exception("EAGER is not supported for list of element...");
throw new DataAccessException("EAGER is not supported for list of element...");
} else {
generateConcatQuerry(tableName, field, querrySelect, querry, name, elemCount, options);
}
}
}
@Override
public void fillFromQuerry(final ResultSet rs, final Field field, final Object data, final CountInOut count, final QueryOptions options, final List<LazyGetter> lazyCall) throws Exception {
if (field.getType() != List.class) {
@ -161,7 +162,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
if (objectClass == decorators.targetEntity()) {
if (decorators.fetch() == FetchType.EAGER) {
throw new Exception("EAGER is not supported for list of element...");
throw new DataAccessException("EAGER is not supported for list of element...");
} else {
final List<Long> idList = DataAccess.getListOfIds(rs, count.value, SEPARATOR);
//field.set(data, idList);
@ -186,16 +187,16 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
}
}
public static void addLink(final Class<?> clazz, final long localKey, final String column, final long remoteKey) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz);
final String linkTableName = generateLinkTableName(tableName, column);
final LinkTable insertElement = new LinkTable(localKey, remoteKey);
final QueryOptions options = new QueryOptions(QueryOptions.OVERRIDE_TABLE_NAME, linkTableName);
DataAccess.insert(insertElement, options);
}
public static int removeLink(final Class<?> clazz, final long localKey, final String column, final long remoteKey) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz);
final String linkTableName = generateLinkTableName(tableName, column);
@ -203,7 +204,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
final QueryAnd condition = new QueryAnd(new QueryCondition("object1Id", "=", localKey), new QueryCondition("object2Id", "=", remoteKey));
return DataAccess.deleteWhere(LinkTable.class, condition, options);
}
@Override
public void createTables(final String tableName, final Field field, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> postActionList,
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {

View File

@ -13,6 +13,7 @@ import org.kar.archidata.dataAccess.DataAccessAddOn;
import org.kar.archidata.dataAccess.DataFactory;
import org.kar.archidata.dataAccess.LazyGetter;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.exception.DataAccessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,12 +23,12 @@ import jakarta.validation.constraints.NotNull;
public class AddOnManyToOne implements DataAccessAddOn {
static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class);
@Override
public Class<?> getAnnotationClass() {
return ManyToOne.class;
}
@Override
public String getSQLFieldType(final Field elem) throws Exception {
final String fieldName = AnnotationTools.getFieldName(elem);
@ -39,13 +40,13 @@ public class AddOnManyToOne implements DataAccessAddOn {
}
return null;
}
@Override
public boolean isCompatibleField(final Field elem) {
final ManyToOne decorators = elem.getDeclaredAnnotation(ManyToOne.class);
return decorators != null;
}
@Override
public void insertData(final PreparedStatement ps, final Field field, final Object rootObject, final CountInOut iii) throws Exception {
final Object data = field.get(rootObject);
@ -59,7 +60,7 @@ public class AddOnManyToOne implements DataAccessAddOn {
final Object uid = idField.get(data);
if (uid == null) {
ps.setNull(iii.value, Types.BIGINT);
throw new Exception("Not implemented adding subClasses ==> add it manualy before...");
throw new DataAccessException("Not implemented adding subClasses ==> add it manualy before...");
} else {
final Long dataLong = (Long) uid;
ps.setLong(iii.value, dataLong);
@ -67,7 +68,7 @@ public class AddOnManyToOne implements DataAccessAddOn {
}
iii.inc();
}
@Override
public boolean canInsert(final Field field) {
if (field.getType() == Long.class) {
@ -79,7 +80,7 @@ public class AddOnManyToOne implements DataAccessAddOn {
}
return false;
}
@Override
public boolean canRetrieve(final Field field) {
if (field.getType() == Long.class) {
@ -91,7 +92,7 @@ public class AddOnManyToOne implements DataAccessAddOn {
}
return false;
}
@Override
public void generateQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry, @NotNull final String name,
@NotNull final CountInOut elemCount, final QueryOptions options) throws Exception {
@ -130,14 +131,14 @@ public class AddOnManyToOne implements DataAccessAddOn {
return;
}
}
/*
SELECT k.id, r.id
FROM `right` k
LEFT OUTER JOIN `rightDescription` r ON k.rightDescriptionId=r.id
*/
}
@Override
public void fillFromQuerry(final ResultSet rs, final Field field, final Object data, final CountInOut count, final QueryOptions options, final List<LazyGetter> lazyCall) throws Exception {
if (field.getType() == Long.class) {
@ -179,7 +180,7 @@ public class AddOnManyToOne implements DataAccessAddOn {
}
}
}
// TODO : refacto this table to manage a generic table with dynamic name to be serialisable with the default system
@Override
public void createTables(final String tableName, final Field field, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> postActionList,