[DEV] add management of UUID (not tested)

This commit is contained in:
Edouard DUPIN 2024-02-26 19:37:51 +01:00
parent e0b7ed1e1e
commit 56609e4f59
16 changed files with 623 additions and 93 deletions

View File

@ -114,6 +114,12 @@
<artifactId>jackson-dataformat-csv</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>

View File

@ -15,6 +15,7 @@ import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.CreationTimestamp;
@ -191,7 +192,14 @@ public class DataAccess {
}
protected static <T> void setValuedb(final Class<?> type, final T data, final CountInOut iii, final Field field, final PreparedStatement ps) throws Exception {
if (type == Long.class) {
if (type == UUID.class) {
final Object tmp = field.get(data);
if (tmp == null) {
ps.setNull(iii.value, Types.BINARY);
} else {
ps.setObject(iii.value, tmp);
}
} else if (type == Long.class) {
final Object tmp = field.get(data);
if (tmp == null) {
ps.setNull(iii.value, Types.BIGINT);
@ -288,7 +296,15 @@ public class DataAccess {
}
protected static <T> void setValueFromDb(final Class<?> type, final Object data, final CountInOut count, final Field field, final ResultSet rs, final CountInOut countNotNull) throws Exception {
if (type == Long.class) {
if (type == UUID.class) {
final UUID tmp = rs.getObject(count.value, UUID.class);
if (rs.wasNull()) {
field.set(data, null);
} else {
field.set(data, tmp);
countNotNull.inc();
}
} else if (type == Long.class) {
final Long tmp = rs.getLong(count.value);
if (rs.wasNull()) {
field.set(data, null);
@ -449,6 +465,16 @@ public class DataAccess {
// TODO: this function will replace the previous one !!!
protected static RetreiveFromDB createSetValueFromDbCallback(final int count, final Field field) throws Exception {
final Class<?> type = field.getType();
if (type == UUID.class) {
return (final ResultSet rs, final Object obj) -> {
final UUID tmp = rs.getObject(count, UUID.class);
if (rs.wasNull()) {
field.set(obj, null);
} else {
field.set(obj, tmp);
}
};
}
if (type == Long.class) {
return (final ResultSet rs, final Object obj) -> {
final Long tmp = rs.getLong(count);
@ -672,6 +698,7 @@ public class DataAccess {
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
final List<Field> asyncFieldUpdate = new ArrayList<>();
Long uniqueSQLID = null;
UUID uniqueSQLUUID = null;
final String tableName = AnnotationTools.getTableName(clazz, options);
// real add in the BDD:
try {
@ -788,7 +815,12 @@ public class DataAccess {
// Retrieve uid inserted
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
uniqueSQLID = generatedKeys.getLong(1);
if (primaryKeyField.getType() == UUID.class) {
uniqueSQLUUID = generatedKeys.getObject(1, UUID.class);
} else {
uniqueSQLID = generatedKeys.getLong(1);
}
} else {
throw new SQLException("Creating node failed, no ID obtained (1).");
}
@ -802,6 +834,8 @@ public class DataAccess {
primaryKeyField.set(data, uniqueSQLID);
} else if (primaryKeyField.getType() == long.class) {
primaryKeyField.setLong(data, uniqueSQLID);
} else if (primaryKeyField.getType() == UUID.class) {
primaryKeyField.set(data, uniqueSQLUUID);
} else {
LOGGER.error("Can not manage the primary filed !!!");
}
@ -1160,6 +1194,10 @@ public class DataAccess {
querySelect.append(query.toString());
query = querySelect;
condition.whereAppendQuery(query, tableName, options, deletedFieldName);
final GroupBy groups = options.get(GroupBy.class);
if (groups != null) {
groups.generateQuerry(query, null);
}
final OrderBy orders = options.get(OrderBy.class);
if (orders != null) {
orders.generateQuerry(query, tableName);
@ -1508,7 +1546,14 @@ public class DataAccess {
}
}
/* - useful code to manage external query: List<T> query<T>(class<T> clazz, ); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2"); */
/** Execute a simple query with external property.
* @param <TYPE> Type of the data generate.
* @param clazz Class that might be analyze.
* @param query Base of the query.
* @param parameters "?" parameter of the query.
* @param option Optional parameters
* @return The list of element requested
* @throws Exception */
public static <TYPE> List<TYPE> query(final Class<TYPE> clazz, final String query, final List<Object> parameters, final QueryOption... option) throws Exception {
final QueryOptions options = new QueryOptions(option);
return query(clazz, query, parameters, options);
@ -1529,6 +1574,19 @@ public class DataAccess {
try {
final CountInOut count = new CountInOut();
condition.whereAppendQuery(query, null, options, null);
final GroupBy groups = options.get(GroupBy.class);
if (groups != null) {
groups.generateQuerry(query, null);
}
final OrderBy orders = options.get(OrderBy.class);
if (orders != null) {
orders.generateQuerry(query, null);
}
final Limit limit = options.get(Limit.class);
if (limit != null) {
limit.generateQuerry(query, null);
}
LOGGER.warn("generate the query: '{}'", query.toString());
// prepare the request:
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
@ -1540,16 +1598,21 @@ public class DataAccess {
iii.inc();
}
condition.injectQuerry(ps, iii);
if (limit != null) {
limit.injectQuerry(ps, iii);
}
// execute the request
final ResultSet rs = ps.executeQuery();
final ResultSetMetaData rsmd = rs.getMetaData();
final List<RetreiveFromDB> actionToRetreive = new ArrayList<>();
LOGGER.info("Field:");
for (int jjj = 0; jjj < rsmd.getColumnCount(); jjj++) {
final String name = rsmd.getColumnName(jjj + 1);
final String label = rsmd.getColumnLabel(jjj + 1);
LOGGER.info(" - {}:{}", jjj, label);
// find field name ...
final Field field = AnnotationTools.getFieldNamed(clazz, name);
final Field field = AnnotationTools.getFieldNamed(clazz, label);
if (field == null) {
throw new DataAccessException("Querry with unknown field: '" + name + "'");
throw new DataAccessException("Querry with unknown field: '" + label + "'");
}
// create the callback...
final RetreiveFromDB element = createSetValueFromDbCallback(jjj + 1, field);
@ -1558,7 +1621,6 @@ public class DataAccess {
while (rs.next()) {
count.value = 1;
final CountInOut countNotNull = new CountInOut(0);
Object data = null;
for (final Constructor<?> contructor : clazz.getConstructors()) {
if (contructor.getParameterCount() == 0) {
@ -1590,5 +1652,4 @@ public class DataAccess {
}
return outs;
}
}

View File

@ -0,0 +1,387 @@
package org.kar.archidata.dataAccess;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.kar.archidata.dataAccess.exportTools.TableQuery;
import org.kar.archidata.dataAccess.exportTools.TableQueryTypes;
import org.kar.archidata.dataAccess.options.Condition;
import org.kar.archidata.dataAccess.options.DBInterfaceOption;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.tools.DateTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public class DataExport {
static final Logger LOGGER = LoggerFactory.getLogger(DataExport.class);
public static final String CSV_TYPE = "text/csv";
@SuppressWarnings("unchecked")
protected static RetreiveFromDB createSetValueFromDbCallbackTable(final int count, final Class<?> type, final int id) throws Exception {
if (type == UUID.class) {
return (final ResultSet rs, final Object obj) -> {
final UUID tmp = rs.getObject(count, UUID.class);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == Long.class) {
return (final ResultSet rs, final Object obj) -> {
final Long tmp = rs.getLong(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == long.class) {
return (final ResultSet rs, final Object obj) -> {
final Long tmp = rs.getLong(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == Integer.class) {
return (final ResultSet rs, final Object obj) -> {
final Integer tmp = rs.getInt(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == int.class) {
return (final ResultSet rs, final Object obj) -> {
final Integer tmp = rs.getInt(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == Float.class) {
return (final ResultSet rs, final Object obj) -> {
final Float tmp = rs.getFloat(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == float.class) {
return (final ResultSet rs, final Object obj) -> {
final Float tmp = rs.getFloat(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == Double.class) {
return (final ResultSet rs, final Object obj) -> {
final Double tmp = rs.getDouble(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == double.class) {
return (final ResultSet rs, final Object obj) -> {
final Double tmp = rs.getDouble(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == Boolean.class) {
return (final ResultSet rs, final Object obj) -> {
final Boolean tmp = rs.getBoolean(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == boolean.class) {
return (final ResultSet rs, final Object obj) -> {
final Boolean tmp = rs.getBoolean(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == Timestamp.class) {
return (final ResultSet rs, final Object obj) -> {
final Timestamp tmp = rs.getTimestamp(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type == Date.class) {
return (final ResultSet rs, final Object obj) -> {
try {
final Timestamp tmp = rs.getTimestamp(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, Date.from(tmp.toInstant()));
}
} catch (final SQLException ex) {
final String tmp = rs.getString(count);
LOGGER.error("Fail to parse the SQL time !!! {}", tmp);
if (!rs.wasNull()) {
final Date date = DateTools.parseDate(tmp);
LOGGER.error("Fail to parse the SQL time !!! {}", date);
final List<Object> data = (List<Object>) (obj);
data.set(id, date);
}
}
};
}
if (type == LocalDate.class) {
return (final ResultSet rs, final Object obj) -> {
final java.sql.Date tmp = rs.getDate(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp.toLocalDate());
}
};
}
if (type == LocalTime.class) {
return (final ResultSet rs, final Object obj) -> {
final java.sql.Time tmp = rs.getTime(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp.toLocalTime());
}
};
}
if (type == String.class) {
return (final ResultSet rs, final Object obj) -> {
final String tmp = rs.getString(count);
if (!rs.wasNull()) {
final List<Object> data = (List<Object>) (obj);
data.set(id, tmp);
}
};
}
if (type.isEnum()) {
return (final ResultSet rs, final Object obj) -> {
final String tmp = rs.getString(count);
if (!rs.wasNull()) {
boolean find = false;
final Object[] arr = type.getEnumConstants();
for (final Object elem : arr) {
if (elem.toString().equals(tmp)) {
final List<Object> data = (List<Object>) (obj);
data.set(id, elem);
find = true;
break;
}
}
if (!find) {
throw new DataAccessException("Enum value does not exist in the Model: '" + tmp + "'");
}
}
};
}
throw new DataAccessException("Unknown Field Type");
}
private static int getQueryPropertyId(final List<TableQueryTypes> properties, final String name) throws DataAccessException {
for (int iii = 0; iii < properties.size(); iii++) {
if (properties.get(iii).name.equals(name)) {
return iii;
}
}
throw new DataAccessException("Querry with unknown field: '" + name + "'");
}
public static TableQuery queryTable(final List<TableQueryTypes> headers, final String query, final List<Object> parameters, final QueryOption... option) throws Exception {
final QueryOptions options = new QueryOptions(option);
return queryTable(headers, query, parameters, options);
}
public static TableQuery queryTable(final List<TableQueryTypes> headers, final String queryBase, final List<Object> parameters, final QueryOptions options) throws Exception {
final List<LazyGetter> lazyCall = new ArrayList<>();
// TODO ... final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
Condition condition = options.get(Condition.class);
if (condition == null) {
condition = new Condition();
}
final StringBuilder query = new StringBuilder(queryBase);
final TableQuery out = new TableQuery(headers);
// real add in the BDD:
try {
final CountInOut count = new CountInOut();
condition.whereAppendQuery(query, null, options, null);
final GroupBy groups = options.get(GroupBy.class);
if (groups != null) {
groups.generateQuerry(query, null);
}
final OrderBy orders = options.get(OrderBy.class);
if (orders != null) {
orders.generateQuerry(query, null);
}
final Limit limit = options.get(Limit.class);
if (limit != null) {
limit.generateQuerry(query, null);
}
LOGGER.warn("generate the query: '{}'", query.toString());
// prepare the request:
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
final CountInOut iii = new CountInOut(1);
if (parameters != null) {
for (final Object elem : parameters) {
DataAccess.addElement(ps, elem, iii);
}
iii.inc();
}
condition.injectQuerry(ps, iii);
if (limit != null) {
limit.injectQuerry(ps, iii);
}
// execute the request
final ResultSet rs = ps.executeQuery();
final ResultSetMetaData rsmd = rs.getMetaData();
final List<RetreiveFromDB> actionToRetreive = new ArrayList<>();
LOGGER.info("Field:");
for (int jjj = 0; jjj < rsmd.getColumnCount(); jjj++) {
final String label = rsmd.getColumnLabel(jjj + 1);
final String typeName = rsmd.getColumnTypeName(jjj + 1);
final int typeId = rsmd.getColumnType(jjj + 1);
final int id = getQueryPropertyId(headers, label);
LOGGER.info(" - {}:{} type=[{}] {} REQUEST={}", jjj, label, typeId, typeName, headers.get(id).type.getCanonicalName());
// create the callback...
final RetreiveFromDB element = createSetValueFromDbCallbackTable(jjj + 1, headers.get(id).type, id);
actionToRetreive.add(element);
}
while (rs.next()) {
count.value = 1;
final List<Object> data = Arrays.asList(new Object[headers.size()]);
for (final RetreiveFromDB action : actionToRetreive) {
action.doRequest(rs, data);
}
out.values.add(data);
}
LOGGER.info("Async calls: {}", lazyCall.size());
for (final LazyGetter elem : lazyCall) {
elem.doRequest();
}
} catch (final SQLException ex) {
ex.printStackTrace();
throw ex;
} catch (final Exception ex) {
ex.printStackTrace();
} finally {
entry.close();
}
return out;
}
public static String CSVReplaceSeparator(final String data, final String separator) {
if (data == null) {
return "";
}
final String separatorLine = "\n";
final String separatorLineReplace = "\\n";
return data.replaceAll(separator, "__SEP__").replaceAll(separatorLine, separatorLineReplace);
}
public static String tableToCSV(final TableQuery data) {
final String separator = ";";
final StringBuilder out = new StringBuilder();
// generate header:
boolean first = true;
for (final TableQueryTypes elem : data.headers) {
if (!first) {
out.append(separator);
} else {
first = false;
}
out.append(CSVReplaceSeparator(elem.title, separator));
}
out.append("\n");
// generate body:
first = true;
for (final List<Object> line : data.values) {
for (final Object elem : line) {
if (!first) {
out.append(separator);
} else {
first = false;
}
if (elem != null) {
out.append(CSVReplaceSeparator(elem.toString(), separator));
}
}
out.append("\n");
}
return out.toString();
}
public static Response convertInResponse(final TableQuery dataOut, final String accept) throws DataAccessException, IOException {
if (CSV_TYPE.equals(accept)) {
// CSV serialization
String out = null;
try {
out = DataExport.tableToCSV(dataOut);
} catch (final Exception e) {
LOGGER.error("Fail to generate CSV....");
e.printStackTrace();
throw new DataAccessException("Fail in CSV convertion data");
}
return Response.ok(out).header("Content-Type", CSV_TYPE).build();
}
if (MediaType.APPLICATION_JSON.equals(accept)) {
LOGGER.info("Start mapping josn");
final ObjectMapper objectMapper = new ObjectMapper();
LOGGER.info("Start find modules josn");
objectMapper.findAndRegisterModules();
LOGGER.info("Start map object");
String out;
try {
out = objectMapper.writeValueAsString(dataOut);
} catch (final JsonProcessingException e) {
LOGGER.error("Fail to generate JSON....");
e.printStackTrace();
throw new DataAccessException("Fail in JSON convertion data");
}
LOGGER.info("generate response");
return Response.ok(out).header("Content-Type", MediaType.APPLICATION_JSON).build();
}
throw new IOException("This type is not managed: '" + accept + "'");
}
}

View File

@ -7,6 +7,7 @@ import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.CreationTimestamp;
@ -27,6 +28,9 @@ public class DataFactory {
public static String convertTypeInSQL(final Class<?> type, final String fieldName) throws Exception {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
if (type == UUID.class) {
return "binary(16)";
}
if (type == Long.class || type == long.class) {
return "bigint";
}
@ -75,6 +79,9 @@ public class DataFactory {
return out.toString();
}
} else {
if (type == UUID.class) {
return "BINARY(16)";
}
if (type == Long.class || type == long.class) {
return "INTEGER";
}

View File

@ -0,0 +1,39 @@
package org.kar.archidata.dataAccess;
import java.sql.PreparedStatement;
import java.util.List;
public class GroupBy extends QueryOption {
protected final List<String> childs;
public GroupBy(final List<String> childs) {
this.childs = childs;
}
public GroupBy(final String... childs) {
this.childs = List.of(childs);
}
public void generateQuerry(final StringBuilder query, final String tableName) {
if (this.childs.size() == 0) {
return;
}
query.append(" GROUP BY ");
boolean first = true;
for (final String elem : this.childs) {
if (first) {
first = false;
} else {
query.append(", ");
}
// query.append("`");
query.append(elem);
// query.append("` ");
}
query.append("\n");
}
public void injectQuerry(final PreparedStatement ps, final CountInOut iii) throws Exception {
// nothing to add.
}
}

View File

@ -10,7 +10,7 @@ public class Limit extends QueryOption {
}
public void generateQuerry(final StringBuilder query, final String tableName) {
query.append(" LIMIT ? ");
query.append(" LIMIT ? \n");
}
public void injectQuerry(final PreparedStatement ps, final CountInOut iii) throws Exception {

View File

@ -15,9 +15,10 @@ public class OrderBy extends QueryOption {
}
public void generateQuerry(final StringBuilder query, final String tableName) {
if (this.childs.size() >= 1) {
query.append(" ORDER BY ");
if (this.childs.size() == 0) {
return;
}
query.append(" ORDER BY ");
boolean first = true;
for (final OrderItem elem : this.childs) {
if (first) {
@ -25,14 +26,13 @@ public class OrderBy extends QueryOption {
} else {
query.append(", ");
}
query.append("`");
// query.append("`");
query.append(elem.value);
query.append("` ");
// query.append("`");
query.append(" ");
query.append(elem.order.toString());
}
if (this.childs.size() >= 1) {
query.append(")");
}
query.append("\n");
}
public void injectQuerry(final PreparedStatement ps, final CountInOut iii) throws Exception {

View File

@ -0,0 +1,14 @@
package org.kar.archidata.dataAccess.exportTools;
import java.util.ArrayList;
import java.util.List;
public class TableQuery {
public final List<TableQueryTypes> headers;
public final List<List<Object>> values = new ArrayList<>();
public TableQuery(final List<TableQueryTypes> headers) {
this.headers = headers;
}
}

View File

@ -0,0 +1,20 @@
package org.kar.archidata.dataAccess.exportTools;
public class TableQueryTypes {
public Class<?> type;
public String name;
public String title;
public TableQueryTypes(final Class<?> type, final String name, final String title) {
this.type = type;
this.name = name;
this.title = title;
}
public TableQueryTypes(final Class<?> type, final String name) {
this.type = type;
this.name = name;
this.title = name;
}
}

View File

@ -43,13 +43,12 @@ public class Condition extends QueryOption {
query.append(tableName);
query.append(".");
query.append(deletedFieldName);
query.append(" = false ");
query.append(" = false \n");
}
return;
}
query.append(" WHERE (");
this.condition.generateQuerry(query, tableName);
query.append(") ");
if (exclude_deleted && deletedFieldName != null) {
query.append("AND ");
@ -58,5 +57,6 @@ public class Condition extends QueryOption {
query.append(deletedFieldName);
query.append(" = false ");
}
query.append("\n");
}
}

View File

@ -12,7 +12,6 @@ import jakarta.persistence.Table;
@DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Data extends GenericDataSoftDelete {
@Column(length = 128, nullable = false)
@Schema(description = "Sha512 of the data")
public String sha512;

View File

@ -1,38 +1,15 @@
package org.kar.archidata.model;
import java.util.Date;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.DataNotRead;
import org.kar.archidata.annotation.UpdateTimestamp;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.validation.constraints.NotNull;
public class GenericData {
public class GenericData extends GenericTiming {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, unique = true)
@Schema(description = "Unique Id of the object", required = false, readOnly = true, example = "123456")
public Long id = null;
@DataNotRead
@CreationTimestamp
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
@NotNull
@Schema(description = "Create time of the object", required = false, example = "2000-01-23T01:23:45.678+01:00", readOnly = true)
public Date createdAt = null;
@DataNotRead
@UpdateTimestamp
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
@NotNull
@Schema(description = "When update the object", required = false, example = "2000-01-23T00:23:45.678Z", readOnly = true)
public Date updatedAt = null;
}

View File

@ -0,0 +1,34 @@
package org.kar.archidata.model;
import java.time.Instant;
import java.util.Date;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.DataNotRead;
import org.kar.archidata.annotation.UpdateTimestamp;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.validation.constraints.NotNull;
public class GenericTiming {
@DataNotRead
@CreationTimestamp
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
@NotNull
@Schema(description = "Create time of the object", required = false, example = "2000-01-23T01:23:45.678+01:00", readOnly = true)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
public Date createdAt = null;
@DataNotRead
@UpdateTimestamp
@Column(nullable = false)
@NotNull
@Schema(description = "When update the object", required = false, example = "2000-01-23T00:23:45.678Z", readOnly = true)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
public Instant updatedAt = null;
}

View File

@ -0,0 +1,16 @@
package org.kar.archidata.model;
import java.util.UUID;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.persistence.Id;
import jakarta.ws.rs.DefaultValue;
public class UUIDGenericData extends GenericTiming {
@Id
@DefaultValue("UUID_TO_BIN(UUID())")
@Column(nullable = false, unique = true)
@Schema(description = "Unique UUID of the object", required = false, readOnly = true, example = "e6b33c1c-d24d-11ee-b616-02420a030102")
public UUID id = null;
}

View File

@ -0,0 +1,19 @@
package org.kar.archidata.model;
import org.kar.archidata.annotation.DataDefault;
import org.kar.archidata.annotation.DataDeleted;
import org.kar.archidata.annotation.DataNotRead;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull;
public class UUIDGenericDataSoftDelete extends UUIDGenericData {
@DataNotRead
@Column(nullable = false)
@DataDefault("'0'")
@DataDeleted
@NotNull
@Schema(description = "Deleted state", hidden = true, required = false, readOnly = true)
public Boolean deleted = null;
}

View File

@ -1,49 +0,0 @@
package org.kar.archidata.serializer;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.ext.MessageBodyWriter;
import jakarta.ws.rs.ext.Provider;
/** Body writer use in jersey with : In your main: ```java rc.register(new CSVMessageBodyWritter()); ```
*
* and in the produce element: ```java
* @GET
* @Produces(CSVMessageBodyWritter.CSV_TYPE) public List<Data> getData() {} ``` */
@Provider
@Produces("text/csv")
public class CSVMessageBodyWriter implements MessageBodyWriter<List<Object>> {
public static final String CSV_TYPE = "text/csv";
@Override
public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
return List.class.isAssignableFrom(type);
}
@Override
public long getSize(final List<Object> data, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
return 0;
}
@Override
public void writeTo(final List<Object> data, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType,
final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException, WebApplicationException {
if (data != null && data.size() > 0) {
final CsvMapper mapper = new CsvMapper();
final Object o = data.get(0);
final CsvSchema schema = mapper.schemaFor(o.getClass()).withHeader();
mapper.writer(schema).writeValue(entityStream, data);
}
}
}