Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
cb0ee69820 | |||
cfc7ec2ff1 | |||
0605ef0824 | |||
3309abe053 | |||
f069ce7cc3 | |||
a82c3e725d | |||
08124f212a | |||
631999e135 | |||
7674d9a299 | |||
9cd71ab601 | |||
4cb8c84312 | |||
5acdbfb0c7 | |||
d35c83fcbf | |||
0fe769a203 | |||
dbe1b469f6 |
2
pom.xml
2
pom.xml
@@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.7.0</version>
|
<version>0.8.0</version>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.version>3.1</maven.compiler.version>
|
<maven.compiler.version>3.1</maven.compiler.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
@@ -257,6 +257,19 @@ public class AnnotationTools {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Field getPrimaryKeyField(final Class<?> clazz) throws Exception {
|
||||||
|
for (final Field field : clazz.getFields()) {
|
||||||
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
|
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (AnnotationTools.isPrimaryKey(field)) {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isPrimaryKey(final Field element) throws Exception {
|
public static boolean isPrimaryKey(final Field element) throws Exception {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Id.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Id.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
|
@@ -6,8 +6,12 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/** In case of the update parameter with String input to detect null element. */
|
/** In case of the update parameter with String input to detect null element. */
|
||||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
@Target({ ElementType.PARAMETER, ElementType.METHOD })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface AsyncType {
|
public @interface AsyncType {
|
||||||
Class<?> value();
|
// Possible class values.
|
||||||
|
Class<?>[] value();
|
||||||
|
|
||||||
|
// direct copy value in the TypeScript (separate with type by a |
|
||||||
|
String[] tsComplement() default {};
|
||||||
}
|
}
|
||||||
|
11
src/org/kar/archidata/annotation/TypeScriptProgress.java
Normal file
11
src/org/kar/archidata/annotation/TypeScriptProgress.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package org.kar.archidata.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/** In case of the update parameter with String input to detect null element. */
|
||||||
|
@Target({ ElementType.PARAMETER, ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface TypeScriptProgress {}
|
@@ -93,6 +93,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileData(final UUID uuid) {
|
public static String getFileData(final UUID uuid) {
|
||||||
final String stringUUID = uuid.toString();
|
final String stringUUID = uuid.toString();
|
||||||
final String part1 = stringUUID.substring(0, 2);
|
final String part1 = stringUUID.substring(0, 2);
|
||||||
@@ -108,6 +109,7 @@ public class DataResource {
|
|||||||
filePath += part3;
|
filePath += part3;
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileMetaData(final UUID uuid) {
|
public static String getFileMetaData(final UUID uuid) {
|
||||||
return getFileData(uuid) + ".json";
|
return getFileData(uuid) + ".json";
|
||||||
}
|
}
|
||||||
@@ -317,8 +319,8 @@ public class DataResource {
|
|||||||
return Response.status(404).entity("{\"error\":\"media Does not exist: " + id + "\"}").type("application/json").build();
|
return Response.status(404).entity("{\"error\":\"media Does not exist: " + id + "\"}").type("application/json").build();
|
||||||
}
|
}
|
||||||
if (value.mimeType.contentEquals("image/jpeg") || value.mimeType.contentEquals("image/png")
|
if (value.mimeType.contentEquals("image/jpeg") || value.mimeType.contentEquals("image/png")
|
||||||
// || value.mimeType.contentEquals("image/webp")
|
// || value.mimeType.contentEquals("image/webp")
|
||||||
) {
|
) {
|
||||||
// reads input image
|
// reads input image
|
||||||
final BufferedImage inputImage = ImageIO.read(inputFile);
|
final BufferedImage inputImage = ImageIO.read(inputFile);
|
||||||
final int scaledWidth = 250;
|
final int scaledWidth = 250;
|
||||||
@@ -353,13 +355,12 @@ public class DataResource {
|
|||||||
return buildStream(filePathName, range, value.mimeType);
|
return buildStream(filePathName, range, value.mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Secured
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/{name}")
|
@Path("{id}/{name}")
|
||||||
@PermitTokenInURI
|
@PermitTokenInURI
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
@Operation(description = "Get back some data from the data environment (with a beautifull name (permit download with basic name)", tags = "SYSTEM")
|
@Operation(description = "Get back some data from the data environment (with a beautiful name (permit download with basic name)", tags = "SYSTEM")
|
||||||
public Response retrieveDataFull(@Context final SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) final String token, @HeaderParam("Range") final String range,
|
public Response retrieveDataFull(@Context final SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) final String token, @HeaderParam("Range") final String range,
|
||||||
@PathParam("id") final UUID id, @PathParam("name") final String name) throws Exception {
|
@PathParam("id") final UUID id, @PathParam("name") final String name) throws Exception {
|
||||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
@@ -3,19 +3,21 @@ package org.kar.archidata.catcher;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.kar.archidata.tools.UuidUtils;
|
||||||
|
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
public class RestErrorResponse {
|
public class RestErrorResponse {
|
||||||
public UUID uuid = UUID.randomUUID();
|
public UUID uuid = UuidUtils.nextUUID();
|
||||||
|
public String name; // Mandatory for TS generic error
|
||||||
|
public String message; // Mandatory for TS generic error
|
||||||
public String time;
|
public String time;
|
||||||
public String error;
|
|
||||||
public String message;
|
|
||||||
final public int status;
|
final public int status;
|
||||||
final public String statusMessage;
|
final public String statusMessage;
|
||||||
|
|
||||||
public RestErrorResponse(final Response.Status status, final String time, final String error, final String message) {
|
public RestErrorResponse(final Response.Status status, final String time, final String error, final String message) {
|
||||||
this.time = time;
|
this.time = time;
|
||||||
this.error = error;
|
this.name = error;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.status = status.getStatusCode();
|
this.status = status.getStatusCode();
|
||||||
this.statusMessage = status.getReasonPhrase();
|
this.statusMessage = status.getReasonPhrase();
|
||||||
@@ -23,13 +25,15 @@ public class RestErrorResponse {
|
|||||||
|
|
||||||
public RestErrorResponse(final Response.Status status, final String error, final String message) {
|
public RestErrorResponse(final Response.Status status, final String error, final String message) {
|
||||||
this.time = Instant.now().toString();
|
this.time = Instant.now().toString();
|
||||||
this.error = error;
|
this.name = error;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.status = status.getStatusCode();
|
this.status = status.getStatusCode();
|
||||||
this.statusMessage = status.getReasonPhrase();
|
this.statusMessage = status.getReasonPhrase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestErrorResponse(final Response.Status status) {
|
public RestErrorResponse(final Response.Status status) {
|
||||||
|
this.name = "generic";
|
||||||
|
this.message = "";
|
||||||
this.time = Instant.now().toString();
|
this.time = Instant.now().toString();
|
||||||
this.status = status.getStatusCode();
|
this.status = status.getStatusCode();
|
||||||
this.statusMessage = status.getReasonPhrase();
|
this.statusMessage = status.getReasonPhrase();
|
||||||
|
@@ -174,7 +174,7 @@ public class DataAccess {
|
|||||||
throw new InternalServerErrorException("Can Not manage the DB-access");
|
throw new InternalServerErrorException("Can Not manage the DB-access");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** extract a list of "-" separated element from a SQL input data.
|
/** Extract a list of Long with "-" separated element from a SQL input data.
|
||||||
* @param rs Result Set of the BDD
|
* @param rs Result Set of the BDD
|
||||||
* @param iii Id in the result set
|
* @param iii Id in the result set
|
||||||
* @return The list of Long value
|
* @return The list of Long value
|
||||||
@@ -185,7 +185,7 @@ public class DataAccess {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final List<Long> out = new ArrayList<>();
|
final List<Long> out = new ArrayList<>();
|
||||||
final String[] elements = trackString.split("-");
|
final String[] elements = trackString.split(separator);
|
||||||
for (final String elem : elements) {
|
for (final String elem : elements) {
|
||||||
final Long tmp = Long.parseLong(elem);
|
final Long tmp = Long.parseLong(elem);
|
||||||
out.add(tmp);
|
out.add(tmp);
|
||||||
@@ -193,6 +193,25 @@ public class DataAccess {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Extract a list of UUID with "-" separated element from a SQL input data.
|
||||||
|
* @param rs Result Set of the BDD
|
||||||
|
* @param iii Id in the result set
|
||||||
|
* @return The list of Long value
|
||||||
|
* @throws SQLException if an error is generated in the SQL request. */
|
||||||
|
public static List<UUID> getListOfUUIDs(final ResultSet rs, final int iii, final String separator) throws SQLException {
|
||||||
|
final String trackString = rs.getString(iii);
|
||||||
|
if (rs.wasNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final List<UUID> out = new ArrayList<>();
|
||||||
|
final String[] elements = trackString.split(separator);
|
||||||
|
for (final String elem : elements) {
|
||||||
|
final UUID tmp = UUID.fromString(elem);
|
||||||
|
out.add(tmp);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
protected static <T> void setValuedb(final Class<?> type, final T data, final CountInOut iii, final Field field, final PreparedStatement ps) throws Exception {
|
protected static <T> void setValuedb(final Class<?> type, final T data, final CountInOut iii, final Field field, final PreparedStatement ps) throws Exception {
|
||||||
if (type == UUID.class) {
|
if (type == UUID.class) {
|
||||||
final Object tmp = field.get(data);
|
final Object tmp = field.get(data);
|
||||||
@@ -835,7 +854,8 @@ public class DataAccess {
|
|||||||
UUID uuid = null;
|
UUID uuid = null;
|
||||||
if (generateUUID) {
|
if (generateUUID) {
|
||||||
firstField = false;
|
firstField = false;
|
||||||
uuid = UUID.randomUUID();
|
// uuid = UUID.randomUUID();
|
||||||
|
uuid = UuidUtils.nextUUID();
|
||||||
addElement(ps, uuid, iii);
|
addElement(ps, uuid, iii);
|
||||||
iii.inc();
|
iii.inc();
|
||||||
}
|
}
|
||||||
@@ -889,13 +909,8 @@ public class DataAccess {
|
|||||||
if (generatedKeys.next()) {
|
if (generatedKeys.next()) {
|
||||||
if (primaryKeyField.getType() == UUID.class) {
|
if (primaryKeyField.getType() == UUID.class) {
|
||||||
// uniqueSQLUUID = generatedKeys.getObject(1, UUID.class);
|
// uniqueSQLUUID = generatedKeys.getObject(1, UUID.class);
|
||||||
/*
|
/* final Object obj = generatedKeys.getObject(1); final BigInteger bigint = (BigInteger) generatedKeys.getObject(1); uniqueSQLUUID = UuidUtils.asUuid(bigint); final UUID
|
||||||
final Object obj = generatedKeys.getObject(1);
|
* generatedUUID = (UUID) generatedKeys.getObject(1); System.out.println("UUID généré: " + generatedUUID); */
|
||||||
final BigInteger bigint = (BigInteger) generatedKeys.getObject(1);
|
|
||||||
uniqueSQLUUID = UuidUtils.asUuid(bigint);
|
|
||||||
final UUID generatedUUID = (UUID) generatedKeys.getObject(1);
|
|
||||||
System.out.println("UUID généré: " + generatedUUID);
|
|
||||||
*/
|
|
||||||
final Object obj = generatedKeys.getObject(1);
|
final Object obj = generatedKeys.getObject(1);
|
||||||
final byte[] tmpid = generatedKeys.getBytes(1);
|
final byte[] tmpid = generatedKeys.getBytes(1);
|
||||||
uniqueSQLUUID = UuidUtils.asUuid(tmpid);
|
uniqueSQLUUID = UuidUtils.asUuid(tmpid);
|
||||||
@@ -925,14 +940,20 @@ public class DataAccess {
|
|||||||
}
|
}
|
||||||
// ps.execute();
|
// ps.execute();
|
||||||
} catch (final SQLException ex) {
|
} catch (final SQLException ex) {
|
||||||
|
LOGGER.error("Fail SQL request: {}", ex.getMessage());
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
throw new DataAccessException("Fail to Insert data in DB : " + ex.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
entry.close();
|
entry.close();
|
||||||
}
|
}
|
||||||
final List<LazyGetter> asyncActions = new ArrayList<>();
|
final List<LazyGetter> asyncActions = new ArrayList<>();
|
||||||
for (final Field field : asyncFieldUpdate) {
|
for (final Field field : asyncFieldUpdate) {
|
||||||
final DataAccessAddOn addOn = findAddOnforField(field);
|
final DataAccessAddOn addOn = findAddOnforField(field);
|
||||||
addOn.asyncInsert(tableName, uniqueSQLID, field, field.get(data), asyncActions);
|
if (uniqueSQLID != null) {
|
||||||
|
addOn.asyncInsert(tableName, uniqueSQLID, field, field.get(data), asyncActions);
|
||||||
|
} else if (uniqueSQLUUID != null) {
|
||||||
|
addOn.asyncInsert(tableName, uniqueSQLUUID, field, field.get(data), asyncActions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (final LazyGetter action : asyncActions) {
|
for (final LazyGetter action : asyncActions) {
|
||||||
action.doRequest();
|
action.doRequest();
|
||||||
|
@@ -61,8 +61,17 @@ public interface DataAccessAddOn {
|
|||||||
* @param createDrop
|
* @param createDrop
|
||||||
* @param fieldId
|
* @param fieldId
|
||||||
* @throws Exception */
|
* @throws Exception */
|
||||||
void createTables(String tableName, Field field, StringBuilder mainTableBuilder, List<String> preActionList, List<String> postActionList, boolean createIfNotExist, boolean createDrop, int fieldId)
|
void createTables(//
|
||||||
throws Exception;
|
String tableName, //
|
||||||
|
final Field primaryField, //
|
||||||
|
Field field, //
|
||||||
|
StringBuilder mainTableBuilder, //
|
||||||
|
List<String> preActionList, //
|
||||||
|
List<String> postActionList, //
|
||||||
|
boolean createIfNotExist, //
|
||||||
|
boolean createDrop, //
|
||||||
|
int fieldId //
|
||||||
|
) throws Exception;
|
||||||
|
|
||||||
/** Some action must be done asynchronously for update or remove element
|
/** Some action must be done asynchronously for update or remove element
|
||||||
* @param field
|
* @param field
|
||||||
|
@@ -339,6 +339,7 @@ public class DataFactory {
|
|||||||
LOGGER.debug("===> TABLE `{}`", tableName);
|
LOGGER.debug("===> TABLE `{}`", tableName);
|
||||||
final List<String> primaryKeys = new ArrayList<>();
|
final List<String> primaryKeys = new ArrayList<>();
|
||||||
|
|
||||||
|
final Field primaryField = AnnotationTools.getPrimaryKeyField(clazz);
|
||||||
for (final Field elem : clazz.getFields()) {
|
for (final Field elem : clazz.getFields()) {
|
||||||
// DEtect the primary key (support only one primary key right now...
|
// DEtect the primary key (support only one primary key right now...
|
||||||
if (AnnotationTools.isPrimaryKey(elem)) {
|
if (AnnotationTools.isPrimaryKey(elem)) {
|
||||||
@@ -373,7 +374,7 @@ public class DataFactory {
|
|||||||
final DataAccessAddOn addOn = DataAccess.findAddOnforField(elem);
|
final DataAccessAddOn addOn = DataAccess.findAddOnforField(elem);
|
||||||
LOGGER.trace("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType());
|
LOGGER.trace("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType());
|
||||||
if (addOn != null) {
|
if (addOn != null) {
|
||||||
addOn.createTables(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId);
|
addOn.createTables(tableName, primaryField, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId);
|
||||||
} else {
|
} else {
|
||||||
throw new DataAccessException(
|
throw new DataAccessException(
|
||||||
"Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType());
|
"Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType());
|
||||||
|
@@ -20,6 +20,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.kar.archidata.annotation.AsyncType;
|
import org.kar.archidata.annotation.AsyncType;
|
||||||
|
import org.kar.archidata.annotation.TypeScriptProgress;
|
||||||
import org.kar.archidata.catcher.RestErrorResponse;
|
import org.kar.archidata.catcher.RestErrorResponse;
|
||||||
import org.kar.archidata.dataAccess.DataFactoryZod.ClassElement;
|
import org.kar.archidata.dataAccess.DataFactoryZod.ClassElement;
|
||||||
import org.kar.archidata.dataAccess.DataFactoryZod.GeneratedTypes;
|
import org.kar.archidata.dataAccess.DataFactoryZod.GeneratedTypes;
|
||||||
@@ -56,8 +57,17 @@ public class DataFactoryTsApi {
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import {
|
||||||
import { """;
|
HTTPMimeType,
|
||||||
|
HTTPRequestModel,
|
||||||
|
ModelResponseHttp,
|
||||||
|
RESTCallbacks,
|
||||||
|
RESTConfig,
|
||||||
|
RESTRequestJson,
|
||||||
|
RESTRequestJsonArray,
|
||||||
|
RESTRequestVoid
|
||||||
|
} from "./rest-tools"
|
||||||
|
import {""";
|
||||||
|
|
||||||
for (final Class<?> clazz : classs) {
|
for (final Class<?> clazz : classs) {
|
||||||
final Set<Class<?>> includeModel = new HashSet<>();
|
final Set<Class<?>> includeModel = new HashSet<>();
|
||||||
@@ -73,8 +83,9 @@ public class DataFactoryTsApi {
|
|||||||
if (classElement.nativeType) {
|
if (classElement.nativeType) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
generatedData.append("\n ");
|
||||||
generatedData.append(classElement.tsTypeName);
|
generatedData.append(classElement.tsTypeName);
|
||||||
generatedData.append(", ");
|
generatedData.append(",");
|
||||||
}
|
}
|
||||||
for (final Class<?> elem : includeCheckerModel) {
|
for (final Class<?> elem : includeCheckerModel) {
|
||||||
if (elem == null) {
|
if (elem == null) {
|
||||||
@@ -84,10 +95,11 @@ public class DataFactoryTsApi {
|
|||||||
if (classElement.nativeType) {
|
if (classElement.nativeType) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
generatedData.append("\n ");
|
||||||
generatedData.append(classElement.tsCheckType);
|
generatedData.append(classElement.tsCheckType);
|
||||||
generatedData.append(", ");
|
generatedData.append(",");
|
||||||
}
|
}
|
||||||
generatedData.append("} from \"./model\"\n");
|
generatedData.append("\n} from \"./model\"\n");
|
||||||
generatedData.append(api.data());
|
generatedData.append(api.data());
|
||||||
|
|
||||||
String fileName = api.className();
|
String fileName = api.className();
|
||||||
@@ -125,6 +137,14 @@ public class DataFactoryTsApi {
|
|||||||
return Arrays.asList(((Produces) annotation[0]).value());
|
return Arrays.asList(((Produces) annotation[0]).value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean apiAnnotationTypeScriptProgress(final Method element) throws Exception {
|
||||||
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(TypeScriptProgress.class);
|
||||||
|
if (annotation.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<String> apiAnnotationProduces(final Class<?> clazz, final Method method) throws Exception {
|
public static List<String> apiAnnotationProduces(final Class<?> clazz, final Method method) throws Exception {
|
||||||
final List<String> data = apiAnnotationProduces(method);
|
final List<String> data = apiAnnotationProduces(method);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
@@ -192,14 +212,15 @@ public class DataFactoryTsApi {
|
|||||||
return ((FormDataParam) annotation[0]).value();
|
return ((FormDataParam) annotation[0]).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?> apiAnnotationGetAsyncType(final Parameter element) throws Exception {
|
public static Class<?>[] apiAnnotationGetAsyncType(final Parameter element) throws Exception {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(AsyncType.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(AsyncType.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ((AsyncType) annotation[0]).value();
|
return ((AsyncType) annotation[0]).value();
|
||||||
}
|
}
|
||||||
public static Class<?> apiAnnotationGetAsyncType(final Method element) throws Exception {
|
|
||||||
|
public static Class<?>[] apiAnnotationGetAsyncType(final Method element) throws Exception {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(AsyncType.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(AsyncType.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
@@ -235,6 +256,30 @@ public class DataFactoryTsApi {
|
|||||||
return element.getDeclaredAnnotationsByType(Context.class).length != 0;
|
return element.getDeclaredAnnotationsByType(Context.class).length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String convertInTypeScriptType(final List<ClassElement> tmp, final boolean isList) {
|
||||||
|
String out = "";
|
||||||
|
for (final ClassElement elem : tmp) {
|
||||||
|
if (out.length() != 0) {
|
||||||
|
out += " | ";
|
||||||
|
}
|
||||||
|
out += elem.tsTypeName;
|
||||||
|
if (isList) {
|
||||||
|
out += "[]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
public static String convertInTypeScriptCheckType(final List<ClassElement> tmp) {
|
||||||
|
String out = "";
|
||||||
|
for (final ClassElement elem : tmp) {
|
||||||
|
if (out.length() != 0) {
|
||||||
|
out += " | ";
|
||||||
|
}
|
||||||
|
out += elem.tsCheckType;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
public static APIModel createSingleApi(final Class<?> clazz, final Set<Class<?>> includeModel, final Set<Class<?>> includeCheckerModel, final GeneratedTypes previous) throws Exception {
|
public static APIModel createSingleApi(final Class<?> clazz, final Set<Class<?>> includeModel, final Set<Class<?>> includeCheckerModel, final GeneratedTypes previous) throws Exception {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
// the basic path has no specific elements...
|
// the basic path has no specific elements...
|
||||||
@@ -260,30 +305,42 @@ public class DataFactoryTsApi {
|
|||||||
if (methodDescription != null) {
|
if (methodDescription != null) {
|
||||||
LOGGER.trace(" description: {}", methodDescription);
|
LOGGER.trace(" description: {}", methodDescription);
|
||||||
}
|
}
|
||||||
Class<?> returnTypeModel = apiAnnotationGetAsyncType(method);
|
final boolean needGenerateProgress = apiAnnotationTypeScriptProgress(method);
|
||||||
if (returnTypeModel == null) {
|
Class<?>[] returnTypeModel = apiAnnotationGetAsyncType(method);
|
||||||
returnTypeModel = method.getReturnType();
|
|
||||||
}
|
|
||||||
boolean isUnmanagedReturnType = false;
|
boolean isUnmanagedReturnType = false;
|
||||||
if (returnTypeModel == Response.class ) {
|
|
||||||
isUnmanagedReturnType = true;
|
|
||||||
returnTypeModel = Void.class;
|
|
||||||
}
|
|
||||||
boolean returnModelIsArray = false;
|
boolean returnModelIsArray = false;
|
||||||
ClassElement tmpReturn;
|
List<ClassElement> tmpReturn;
|
||||||
if (returnTypeModel == List.class) {
|
if (returnTypeModel == null) {
|
||||||
final ParameterizedType listType = (ParameterizedType) method.getGenericReturnType();
|
Class<?> returnTypeModelRaw = method.getReturnType();
|
||||||
returnTypeModel = (Class<?>) listType.getActualTypeArguments()[0];
|
LOGGER.info("Get type: {}", returnTypeModelRaw);
|
||||||
tmpReturn = DataFactoryZod.createTable(returnTypeModel, previous);
|
if (returnTypeModelRaw == Response.class) {
|
||||||
returnModelIsArray = true;
|
LOGGER.info("Get type: {}", returnTypeModelRaw);
|
||||||
includeModel.add(tmpReturn.model[0]);
|
}
|
||||||
|
if (returnTypeModelRaw == Response.class) {
|
||||||
|
isUnmanagedReturnType = true;
|
||||||
|
returnTypeModel = new Class<?>[] { Void.class };
|
||||||
|
tmpReturn = new ArrayList<>();
|
||||||
|
} else if (returnTypeModelRaw == List.class) {
|
||||||
|
final ParameterizedType listType = (ParameterizedType) method.getGenericReturnType();
|
||||||
|
returnTypeModelRaw = (Class<?>) listType.getActualTypeArguments()[0];
|
||||||
|
returnModelIsArray = true;
|
||||||
|
returnTypeModel = new Class<?>[] { returnTypeModelRaw };
|
||||||
|
tmpReturn = DataFactoryZod.createTables(returnTypeModel, previous);
|
||||||
|
} else {
|
||||||
|
returnTypeModel = new Class<?>[] { returnTypeModelRaw };
|
||||||
|
tmpReturn = DataFactoryZod.createTables(returnTypeModel, previous);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tmpReturn = DataFactoryZod.createTable(returnTypeModel, previous);
|
tmpReturn = DataFactoryZod.createTables(returnTypeModel, previous);
|
||||||
|
}
|
||||||
|
for (final ClassElement elem : tmpReturn) {
|
||||||
|
includeModel.add(elem.model[0]);
|
||||||
|
includeCheckerModel.add(elem.model[0]);
|
||||||
|
}
|
||||||
|
LOGGER.trace(" return: {}", tmpReturn.size());
|
||||||
|
for (final ClassElement elem : tmpReturn) {
|
||||||
|
LOGGER.trace(" - {}", elem.tsTypeName);
|
||||||
}
|
}
|
||||||
includeModel.add(tmpReturn.model[0]);
|
|
||||||
includeCheckerModel.add(tmpReturn.model[0]);
|
|
||||||
LOGGER.trace(" return: {}", tmpReturn.tsTypeName);
|
|
||||||
final Map<String, String> queryParams = new HashMap<>();
|
final Map<String, String> queryParams = new HashMap<>();
|
||||||
final Map<String, String> pathParams = new HashMap<>();
|
final Map<String, String> pathParams = new HashMap<>();
|
||||||
final Map<String, String> formDataParams = new HashMap<>();
|
final Map<String, String> formDataParams = new HashMap<>();
|
||||||
@@ -296,24 +353,28 @@ public class DataFactoryTsApi {
|
|||||||
}
|
}
|
||||||
final Class<?> parameterType = parameter.getType();
|
final Class<?> parameterType = parameter.getType();
|
||||||
String parameterTypeString;
|
String parameterTypeString;
|
||||||
final Class<?> asyncType = apiAnnotationGetAsyncType(parameter);
|
final Class<?>[] asyncType = apiAnnotationGetAsyncType(parameter);
|
||||||
if (parameterType == List.class) {
|
if (parameterType == List.class) {
|
||||||
if (asyncType == null) {
|
if (asyncType == null) {
|
||||||
LOGGER.warn("Detext List param ==> not managed type ==> any[] !!!");
|
LOGGER.warn("Detect List param ==> not managed type ==> any[] !!!");
|
||||||
parameterTypeString = "any[]";
|
parameterTypeString = "any[]";
|
||||||
} else {
|
} else {
|
||||||
final ClassElement tmp = DataFactoryZod.createTable(asyncType, previous);
|
final List<ClassElement> tmp = DataFactoryZod.createTables(asyncType, previous);
|
||||||
includeModel.add(tmp.model[0]);
|
for (final ClassElement elem : tmp) {
|
||||||
parameterTypeString = tmp.tsTypeName + "[]";
|
includeModel.add(elem.model[0]);
|
||||||
|
}
|
||||||
|
parameterTypeString = convertInTypeScriptType(tmp, true);
|
||||||
}
|
}
|
||||||
} else if (asyncType == null) {
|
} else if (asyncType == null) {
|
||||||
final ClassElement tmp = DataFactoryZod.createTable(parameterType, previous);
|
final ClassElement tmp = DataFactoryZod.createTable(parameterType, previous);
|
||||||
includeModel.add(tmp.model[0]);
|
includeModel.add(tmp.model[0]);
|
||||||
parameterTypeString = tmp.tsTypeName;
|
parameterTypeString = tmp.tsTypeName;
|
||||||
} else {
|
} else {
|
||||||
final ClassElement tmp = DataFactoryZod.createTable(asyncType, previous);
|
final List<ClassElement> tmp = DataFactoryZod.createTables(asyncType, previous);
|
||||||
includeModel.add(tmp.model[0]);
|
for (final ClassElement elem : tmp) {
|
||||||
parameterTypeString = tmp.tsTypeName;
|
includeModel.add(elem.model[0]);
|
||||||
|
}
|
||||||
|
parameterTypeString = convertInTypeScriptType(tmp, true);
|
||||||
}
|
}
|
||||||
final String pathParam = apiAnnotationGetPathParam(parameter);
|
final String pathParam = apiAnnotationGetPathParam(parameter);
|
||||||
final String queryParam = apiAnnotationGetQueryParam(parameter);
|
final String queryParam = apiAnnotationGetQueryParam(parameter);
|
||||||
@@ -325,13 +386,21 @@ public class DataFactoryTsApi {
|
|||||||
} else if (formDataParam != null) {
|
} else if (formDataParam != null) {
|
||||||
formDataParams.put(formDataParam, parameterTypeString);
|
formDataParams.put(formDataParam, parameterTypeString);
|
||||||
} else if (asyncType != null) {
|
} else if (asyncType != null) {
|
||||||
final ClassElement tmp = DataFactoryZod.createTable(asyncType, previous);
|
final List<ClassElement> tmp = DataFactoryZod.createTables(asyncType, previous);
|
||||||
includeModel.add(tmp.model[0]);
|
parameterTypeString = "";
|
||||||
emptyElement.add(tmp.tsTypeName);
|
for (final ClassElement elem : tmp) {
|
||||||
|
includeModel.add(elem.model[0]);
|
||||||
|
if (parameterTypeString.length() != 0) {
|
||||||
|
parameterTypeString += " | ";
|
||||||
|
}
|
||||||
|
parameterTypeString += elem.tsTypeName;
|
||||||
|
}
|
||||||
|
emptyElement.add(parameterTypeString);
|
||||||
} else if (parameterType == List.class) {
|
} else if (parameterType == List.class) {
|
||||||
parameterTypeString = "any[]";
|
parameterTypeString = "any[]";
|
||||||
final Class<?> plop = parameterType.arrayType();
|
final Class<?> plop = parameterType.arrayType();
|
||||||
LOGGER.info("ArrayType = {}", plop);
|
LOGGER.info("ArrayType = {}", plop);
|
||||||
|
emptyElement.add(parameterTypeString);
|
||||||
} else {
|
} else {
|
||||||
final ClassElement tmp = DataFactoryZod.createTable(parameterType, previous);
|
final ClassElement tmp = DataFactoryZod.createTable(parameterType, previous);
|
||||||
includeModel.add(tmp.model[0]);
|
includeModel.add(tmp.model[0]);
|
||||||
@@ -371,29 +440,30 @@ public class DataFactoryTsApi {
|
|||||||
}
|
}
|
||||||
builder.append("\n\texport function ");
|
builder.append("\n\texport function ");
|
||||||
builder.append(methodName);
|
builder.append(methodName);
|
||||||
builder.append("({ restConfig,");
|
builder.append("({\n\t\t\trestConfig,");
|
||||||
if (!queryParams.isEmpty()) {
|
if (!queryParams.isEmpty()) {
|
||||||
builder.append(" queries,");
|
builder.append("\n\t\t\tqueries,");
|
||||||
}
|
}
|
||||||
if (!pathParams.isEmpty()) {
|
if (!pathParams.isEmpty()) {
|
||||||
builder.append(" params,");
|
builder.append("\n\t\t\tparams,");
|
||||||
}
|
}
|
||||||
if (produces.size() > 1) {
|
if (produces.size() > 1) {
|
||||||
builder.append(" produce,");
|
builder.append("\n\t\t\tproduce,");
|
||||||
}
|
}
|
||||||
if (emptyElement.size() == 1) {
|
if (emptyElement.size() == 1 || formDataParams.size() != 0) {
|
||||||
builder.append(" data,");
|
builder.append("\n\t\t\tdata,");
|
||||||
} else if (formDataParams.size() != 0) {
|
|
||||||
builder.append(" data,");
|
|
||||||
}
|
}
|
||||||
builder.append(" }: {");
|
if (needGenerateProgress) {
|
||||||
|
builder.append("\n\t\t\tcallback,");
|
||||||
|
}
|
||||||
|
builder.append("\n\t\t}: {");
|
||||||
builder.append("\n\t\trestConfig: RESTConfig,");
|
builder.append("\n\t\trestConfig: RESTConfig,");
|
||||||
if (!queryParams.isEmpty()) {
|
if (!queryParams.isEmpty()) {
|
||||||
builder.append("\n\t\tqueries: {");
|
builder.append("\n\t\tqueries: {");
|
||||||
for (final Entry<String, String> queryEntry : queryParams.entrySet()) {
|
for (final Entry<String, String> queryEntry : queryParams.entrySet()) {
|
||||||
builder.append("\n\t\t\t");
|
builder.append("\n\t\t\t");
|
||||||
builder.append(queryEntry.getKey());
|
builder.append(queryEntry.getKey());
|
||||||
builder.append(": ");
|
builder.append("?: ");
|
||||||
builder.append(queryEntry.getValue());
|
builder.append(queryEntry.getValue());
|
||||||
builder.append(",");
|
builder.append(",");
|
||||||
}
|
}
|
||||||
@@ -453,13 +523,21 @@ public class DataFactoryTsApi {
|
|||||||
}
|
}
|
||||||
builder.append(",");
|
builder.append(",");
|
||||||
}
|
}
|
||||||
|
if (needGenerateProgress) {
|
||||||
|
builder.append("\n\t\tcallback?: RESTCallbacks,");
|
||||||
|
}
|
||||||
builder.append("\n\t}): Promise<");
|
builder.append("\n\t}): Promise<");
|
||||||
builder.append(tmpReturn.tsTypeName);
|
if (tmpReturn.size() == 0 //
|
||||||
if (returnModelIsArray) {
|
|| tmpReturn.get(0).tsTypeName == null //
|
||||||
builder.append("[]");
|
|| tmpReturn.get(0).tsTypeName.equals("void")) {
|
||||||
|
builder.append("void");
|
||||||
|
} else {
|
||||||
|
builder.append(convertInTypeScriptType(tmpReturn, returnModelIsArray));
|
||||||
}
|
}
|
||||||
builder.append("> {");
|
builder.append("> {");
|
||||||
if (tmpReturn.tsTypeName.equals("void")) {
|
if (tmpReturn.size() == 0 //
|
||||||
|
|| tmpReturn.get(0).tsTypeName == null //
|
||||||
|
|| tmpReturn.get(0).tsTypeName.equals("void")) {
|
||||||
builder.append("\n\t\treturn RESTRequestVoid({");
|
builder.append("\n\t\treturn RESTRequestVoid({");
|
||||||
} else if (returnModelIsArray) {
|
} else if (returnModelIsArray) {
|
||||||
builder.append("\n\t\treturn RESTRequestJsonArray({");
|
builder.append("\n\t\treturn RESTRequestJsonArray({");
|
||||||
@@ -518,10 +596,14 @@ public class DataFactoryTsApi {
|
|||||||
} else if (formDataParams.size() != 0) {
|
} else if (formDataParams.size() != 0) {
|
||||||
builder.append("\n\t\t\tdata,");
|
builder.append("\n\t\t\tdata,");
|
||||||
}
|
}
|
||||||
|
if (needGenerateProgress) {
|
||||||
|
builder.append("\n\t\t\tcallback,");
|
||||||
|
}
|
||||||
builder.append("\n\t\t}");
|
builder.append("\n\t\t}");
|
||||||
if (tmpReturn.tsCheckType != null) {
|
if (tmpReturn.size() != 0 && tmpReturn.get(0).tsTypeName != null && !tmpReturn.get(0).tsTypeName.equals("void")) {
|
||||||
builder.append(", ");
|
builder.append(", ");
|
||||||
builder.append(tmpReturn.tsCheckType);
|
// TODO: correct this it is really bad ...
|
||||||
|
builder.append(convertInTypeScriptCheckType(tmpReturn));
|
||||||
}
|
}
|
||||||
builder.append(");");
|
builder.append(");");
|
||||||
builder.append("\n\t};");
|
builder.append("\n\t};");
|
||||||
@@ -551,16 +633,14 @@ public class DataFactoryTsApi {
|
|||||||
myWriter = new FileWriter(pathPackage + File.separator + "index.ts");
|
myWriter = new FileWriter(pathPackage + File.separator + "index.ts");
|
||||||
myWriter.write(index.toString());
|
myWriter.write(index.toString());
|
||||||
myWriter.close();
|
myWriter.close();
|
||||||
final InputStream ioStream = DataFactoryTsApi.class
|
final InputStream ioStream = DataFactoryTsApi.class.getClassLoader().getResourceAsStream("rest-tools.ts");
|
||||||
.getClassLoader()
|
|
||||||
.getResourceAsStream("rest-tools.ts");
|
|
||||||
if (ioStream == null) {
|
if (ioStream == null) {
|
||||||
throw new IllegalArgumentException("rest-tools.ts is not found");
|
throw new IllegalArgumentException("rest-tools.ts is not found");
|
||||||
}
|
}
|
||||||
final BufferedReader buffer = new BufferedReader(new InputStreamReader(ioStream));
|
final BufferedReader buffer = new BufferedReader(new InputStreamReader(ioStream));
|
||||||
myWriter = new FileWriter(pathPackage + File.separator + "rest-tools.ts");
|
myWriter = new FileWriter(pathPackage + File.separator + "rest-tools.ts");
|
||||||
String line;
|
String line;
|
||||||
while( (line = buffer.readLine()) != null) {
|
while ((line = buffer.readLine()) != null) {
|
||||||
myWriter.write(line);
|
myWriter.write(line);
|
||||||
myWriter.write("\n");
|
myWriter.write("\n");
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package org.kar.archidata.dataAccess;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
@@ -20,6 +21,8 @@ import org.kar.archidata.exception.DataAccessException;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
public class DataFactoryZod {
|
public class DataFactoryZod {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(DataFactoryZod.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(DataFactoryZod.class);
|
||||||
|
|
||||||
@@ -97,7 +100,7 @@ public class DataFactoryZod {
|
|||||||
out.append("zod.enum([");
|
out.append("zod.enum([");
|
||||||
for (final Object elem : arr) {
|
for (final Object elem : arr) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
out.append(", \n\t");
|
out.append(",\n\t");
|
||||||
} else {
|
} else {
|
||||||
out.append("\n\t");
|
out.append("\n\t");
|
||||||
first = false;
|
first = false;
|
||||||
@@ -106,14 +109,18 @@ public class DataFactoryZod {
|
|||||||
out.append(elem.toString());
|
out.append(elem.toString());
|
||||||
out.append("'");
|
out.append("'");
|
||||||
}
|
}
|
||||||
out.append("\n\t])");
|
if (first) {
|
||||||
|
out.append("]}");
|
||||||
|
} else {
|
||||||
|
out.append("\n\t])");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
element.isEnum = true;
|
element.isEnum = true;
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
out.append("{");
|
out.append("{");
|
||||||
for (final Object elem : arr) {
|
for (final Object elem : arr) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
out.append(", \n\t");
|
out.append(",\n\t");
|
||||||
} else {
|
} else {
|
||||||
out.append("\n\t");
|
out.append("\n\t");
|
||||||
first = false;
|
first = false;
|
||||||
@@ -123,7 +130,11 @@ public class DataFactoryZod {
|
|||||||
out.append(elem.toString());
|
out.append(elem.toString());
|
||||||
out.append("'");
|
out.append("'");
|
||||||
}
|
}
|
||||||
out.append("}");
|
if (first) {
|
||||||
|
out.append("}");
|
||||||
|
} else {
|
||||||
|
out.append(",\n\t}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
element.declaration = out.toString();
|
element.declaration = out.toString();
|
||||||
previous.addOrder(element);
|
previous.addOrder(element);
|
||||||
@@ -282,10 +293,24 @@ public class DataFactoryZod {
|
|||||||
return generatedData.toString();
|
return generatedData.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<ClassElement> createTables(final Class<?>[] classs, final GeneratedTypes previous) throws Exception {
|
||||||
|
final List<ClassElement> out = new ArrayList<>();
|
||||||
|
for (final Class<?> clazz : classs) {
|
||||||
|
if (clazz == Response.class) {
|
||||||
|
throw new IOException("Can not generate a Zod element for an unknow type Response");
|
||||||
|
}
|
||||||
|
out.add(createTable(clazz, previous));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
public static ClassElement createTable(final Class<?> clazz, final GeneratedTypes previous) throws Exception {
|
public static ClassElement createTable(final Class<?> clazz, final GeneratedTypes previous) throws Exception {
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (clazz == Response.class) {
|
||||||
|
throw new IOException("Can not generate a Zod element for an unknow type Response");
|
||||||
|
}
|
||||||
final ClassElement alreadyExist = previous.find(clazz);
|
final ClassElement alreadyExist = previous.find(clazz);
|
||||||
if (previous.find(clazz) != null) {
|
if (previous.find(clazz) != null) {
|
||||||
return alreadyExist;
|
return alreadyExist;
|
||||||
|
@@ -141,10 +141,20 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createTables(final String tableName, final Field field, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> postActionList,
|
public void createTables(//
|
||||||
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
final String tableName, //
|
||||||
|
final Field primaryField, //
|
||||||
|
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 {
|
||||||
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, JsonValue.class);
|
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, JsonValue.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addLink(final Class<?> clazz, final Long id, final String column, final Long remoteKey) throws Exception {
|
public static void addLink(final Class<?> clazz, final Long id, final String column, final Long remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
final TableCoversLongLong data = DataAccess.get(TableCoversLongLong.class, id, new OverrideTableName(tableName));
|
final TableCoversLongLong data = DataAccess.get(TableCoversLongLong.class, id, new OverrideTableName(tableName));
|
||||||
@@ -174,6 +184,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
data.covers.add(remoteKey);
|
data.covers.add(remoteKey);
|
||||||
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addLink(final Class<?> clazz, final UUID id, final String column, final UUID remoteKey) throws Exception {
|
public static void addLink(final Class<?> clazz, final UUID id, final String column, final UUID remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
final TableCoversUUIDUUID data = DataAccess.get(TableCoversUUIDUUID.class, id, new OverrideTableName(tableName));
|
final TableCoversUUIDUUID data = DataAccess.get(TableCoversUUIDUUID.class, id, new OverrideTableName(tableName));
|
||||||
@@ -188,6 +199,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
data.covers.add(remoteKey);
|
data.covers.add(remoteKey);
|
||||||
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addLink(final Class<?> clazz, final UUID id, final String column, final Long remoteKey) throws Exception {
|
public static void addLink(final Class<?> clazz, final UUID id, final String column, final Long remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
final TableCoversUUIDLong data = DataAccess.get(TableCoversUUIDLong.class, id, new OverrideTableName(tableName));
|
final TableCoversUUIDLong data = DataAccess.get(TableCoversUUIDLong.class, id, new OverrideTableName(tableName));
|
||||||
@@ -202,6 +214,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
data.covers.add(remoteKey);
|
data.covers.add(remoteKey);
|
||||||
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeLink(final Class<?> clazz, final UUID id, final String column, final Long remoteKey) throws Exception {
|
public static void removeLink(final Class<?> clazz, final UUID id, final String column, final Long remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
final TableCoversUUIDLong data = DataAccess.get(TableCoversUUIDLong.class, id, new OverrideTableName(tableName));
|
final TableCoversUUIDLong data = DataAccess.get(TableCoversUUIDLong.class, id, new OverrideTableName(tableName));
|
||||||
@@ -218,6 +231,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
data.covers = newList;
|
data.covers = newList;
|
||||||
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeLink(final Class<?> clazz, final UUID id, final String column, final UUID remoteKey) throws Exception {
|
public static void removeLink(final Class<?> clazz, final UUID id, final String column, final UUID remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
final TableCoversUUIDUUID data = DataAccess.get(TableCoversUUIDUUID.class, id, new OverrideTableName(tableName));
|
final TableCoversUUIDUUID data = DataAccess.get(TableCoversUUIDUUID.class, id, new OverrideTableName(tableName));
|
||||||
@@ -234,6 +248,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
data.covers = newList;
|
data.covers = newList;
|
||||||
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeLink(final Class<?> clazz, final Long id, final String column, final Long remoteKey) throws Exception {
|
public static void removeLink(final Class<?> clazz, final Long id, final String column, final Long remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
final TableCoversLongLong data = DataAccess.get(TableCoversLongLong.class, id, new OverrideTableName(tableName));
|
final TableCoversLongLong data = DataAccess.get(TableCoversLongLong.class, id, new OverrideTableName(tableName));
|
||||||
@@ -250,6 +265,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
data.covers = newList;
|
data.covers = newList;
|
||||||
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeLink(final Class<?> clazz, final Long id, final String column, final UUID remoteKey) throws Exception {
|
public static void removeLink(final Class<?> clazz, final Long id, final String column, final UUID remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
final TableCoversLongUUID data = DataAccess.get(TableCoversLongUUID.class, id, new OverrideTableName(tableName));
|
final TableCoversLongUUID data = DataAccess.get(TableCoversLongUUID.class, id, new OverrideTableName(tableName));
|
||||||
@@ -266,22 +282,9 @@ public class AddOnDataJson implements DataAccessAddOn {
|
|||||||
data.covers = newList;
|
data.covers = newList;
|
||||||
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
DataAccess.update(data, data.id, List.of("covers"), new OverrideTableName(tableName));
|
||||||
}
|
}
|
||||||
/*
|
/* public static <TYPE> void addLink(final Class<TYPE> clazz, final Object localKey, final String column, final Object remoteKey) throws Exception { final String tableName =
|
||||||
public static <TYPE> void addLink(final Class<TYPE> clazz, final Object localKey, final String column, final Object remoteKey) throws Exception {
|
* AnnotationTools.getTableName(clazz); final TYPE data = DataAccess.get(clazz, localKey); // TODO: add filter of the "column" // find the field column: // add the remoteKey in the list: // post
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
* new data in the DB final String linkTableName = generateLinkTableName(this.tableName, this.column); final LinkTable insertElement = new LinkTable(this.localKey, this.remoteKey);
|
||||||
final TYPE data = DataAccess.get(clazz, localKey); // TODO: add filter of the "column"
|
* DataAccess.insert(insertElement, new OverrideTableName(linkTableName)); } */
|
||||||
|
|
||||||
// find the field column:
|
|
||||||
|
|
||||||
// add the remoteKey in the list:
|
|
||||||
|
|
||||||
|
|
||||||
// post new data in the DB
|
|
||||||
|
|
||||||
final String linkTableName = generateLinkTableName(this.tableName, this.column);
|
|
||||||
final LinkTable insertElement = new LinkTable(this.localKey, this.remoteKey);
|
|
||||||
DataAccess.insert(insertElement, new OverrideTableName(linkTableName));
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.AnnotationTools;
|
import org.kar.archidata.annotation.AnnotationTools;
|
||||||
import org.kar.archidata.dataAccess.CountInOut;
|
import org.kar.archidata.dataAccess.CountInOut;
|
||||||
@@ -18,7 +19,10 @@ import org.kar.archidata.dataAccess.QueryAnd;
|
|||||||
import org.kar.archidata.dataAccess.QueryCondition;
|
import org.kar.archidata.dataAccess.QueryCondition;
|
||||||
import org.kar.archidata.dataAccess.QueryInList;
|
import org.kar.archidata.dataAccess.QueryInList;
|
||||||
import org.kar.archidata.dataAccess.QueryOptions;
|
import org.kar.archidata.dataAccess.QueryOptions;
|
||||||
import org.kar.archidata.dataAccess.addOn.model.LinkTable;
|
import org.kar.archidata.dataAccess.addOn.model.LinkTableLongLong;
|
||||||
|
import org.kar.archidata.dataAccess.addOn.model.LinkTableLongUUID;
|
||||||
|
import org.kar.archidata.dataAccess.addOn.model.LinkTableUUIDLong;
|
||||||
|
import org.kar.archidata.dataAccess.addOn.model.LinkTableUUIDUUID;
|
||||||
import org.kar.archidata.dataAccess.options.Condition;
|
import org.kar.archidata.dataAccess.options.Condition;
|
||||||
import org.kar.archidata.dataAccess.options.OverrideTableName;
|
import org.kar.archidata.dataAccess.options.OverrideTableName;
|
||||||
import org.kar.archidata.exception.DataAccessException;
|
import org.kar.archidata.exception.DataAccessException;
|
||||||
@@ -32,7 +36,8 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
|
|
||||||
public class AddOnManyToMany implements DataAccessAddOn {
|
public class AddOnManyToMany implements DataAccessAddOn {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class);
|
||||||
static final String SEPARATOR = "-";
|
static final String SEPARATOR_LONG = "-";
|
||||||
|
static final String SEPARATOR_UUID = "_";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getAnnotationClass() {
|
public Class<?> getAnnotationClass() {
|
||||||
@@ -62,7 +67,15 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canRetrieve(final Field field) {
|
public boolean canRetrieve(final Field field) {
|
||||||
return true;
|
if (field.getType() != List.class) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
|
if (objectClass == Long.class || objectClass == UUID.class) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateLinkTableNameField(final String tableName, final Field field) throws Exception {
|
public static String generateLinkTableNameField(final String tableName, final Field field) throws Exception {
|
||||||
@@ -78,21 +91,39 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
return tableName + "_link_" + localName;
|
return tableName + "_link_" + localName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateConcatQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry,
|
public void generateConcatQuerry( //
|
||||||
@NotNull final String name, @NotNull final CountInOut elemCount, final QueryOptions options) {
|
@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 linkTableName = generateLinkTableName(tableName, name);
|
||||||
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
final String tmpVariable = "tmp_" + Integer.toString(elemCount.value);
|
final String tmpVariable = "tmp_" + Integer.toString(elemCount.value);
|
||||||
querrySelect.append(" (SELECT GROUP_CONCAT(");
|
querrySelect.append(" (SELECT GROUP_CONCAT(");
|
||||||
querrySelect.append(tmpVariable);
|
if (objectClass == Long.class) {
|
||||||
querrySelect.append(".object2Id ");
|
querrySelect.append(tmpVariable);
|
||||||
|
querrySelect.append(".object2Id ");
|
||||||
|
} else {
|
||||||
|
querrySelect.append("BIN_TO_UUID(");
|
||||||
|
querrySelect.append(tmpVariable);
|
||||||
|
querrySelect.append(".object2Id) ");
|
||||||
|
}
|
||||||
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
|
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
|
||||||
querrySelect.append(", ");
|
querrySelect.append(", ");
|
||||||
} else {
|
} else {
|
||||||
querrySelect.append("SEPARATOR ");
|
querrySelect.append("SEPARATOR ");
|
||||||
}
|
}
|
||||||
querrySelect.append("'");
|
querrySelect.append("'");
|
||||||
querrySelect.append(SEPARATOR);
|
if (objectClass == Long.class) {
|
||||||
|
querrySelect.append(SEPARATOR_LONG);
|
||||||
|
} else {
|
||||||
|
querrySelect.append(SEPARATOR_UUID);
|
||||||
|
|
||||||
|
}
|
||||||
querrySelect.append("') FROM ");
|
querrySelect.append("') FROM ");
|
||||||
querrySelect.append(linkTableName);
|
querrySelect.append(linkTableName);
|
||||||
querrySelect.append(" ");
|
querrySelect.append(" ");
|
||||||
@@ -118,13 +149,20 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry, @NotNull final String name,
|
public void generateQuerry( //
|
||||||
@NotNull final CountInOut elemCount, final QueryOptions options) throws Exception {
|
@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 {
|
||||||
if (field.getType() != List.class) {
|
if (field.getType() != List.class) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
if (objectClass == Long.class) {
|
if (objectClass == Long.class || objectClass == UUID.class) {
|
||||||
generateConcatQuerry(tableName, field, querrySelect, querry, name, elemCount, options);
|
generateConcatQuerry(tableName, field, querrySelect, querry, name, elemCount, options);
|
||||||
}
|
}
|
||||||
final ManyToMany decorators = field.getDeclaredAnnotation(ManyToMany.class);
|
final ManyToMany decorators = field.getDeclaredAnnotation(ManyToMany.class);
|
||||||
@@ -141,20 +179,29 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
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) {
|
if (field.getType() != List.class) {
|
||||||
LOGGER.error("Can not ManyToMany with other than List Model: {}", field.getType().getCanonicalName());
|
LOGGER.error("Can not ManyToMany with other than List Model: {}", field.getType().getCanonicalName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
if (objectClass == Long.class) {
|
if (objectClass == Long.class) {
|
||||||
final List<Long> idList = DataAccess.getListOfIds(rs, count.value, SEPARATOR);
|
final List<Long> idList = DataAccess.getListOfIds(rs, count.value, SEPARATOR_LONG);
|
||||||
|
field.set(data, idList);
|
||||||
|
count.inc();
|
||||||
|
return;
|
||||||
|
} else if (objectClass == UUID.class) {
|
||||||
|
final List<UUID> idList = DataAccess.getListOfUUIDs(rs, count.value, SEPARATOR_UUID);
|
||||||
field.set(data, idList);
|
field.set(data, idList);
|
||||||
count.inc();
|
count.inc();
|
||||||
return;
|
return;
|
||||||
// } else {
|
|
||||||
// LOGGER.error("Can not ManyToMany with other than List<Long> Model: List<{}>", objectClass.getCanonicalName());
|
|
||||||
// return;
|
|
||||||
}
|
}
|
||||||
final ManyToMany decorators = field.getDeclaredAnnotation(ManyToMany.class);
|
final ManyToMany decorators = field.getDeclaredAnnotation(ManyToMany.class);
|
||||||
if (decorators == null) {
|
if (decorators == null) {
|
||||||
@@ -163,8 +210,8 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
if (objectClass == decorators.targetEntity()) {
|
if (objectClass == decorators.targetEntity()) {
|
||||||
if (decorators.fetch() == FetchType.EAGER) {
|
if (decorators.fetch() == FetchType.EAGER) {
|
||||||
throw new DataAccessException("EAGER is not supported for list of element...");
|
throw new DataAccessException("EAGER is not supported for list of element...");
|
||||||
} else {
|
} else if (objectClass == Long.class) {
|
||||||
final List<Long> idList = DataAccess.getListOfIds(rs, count.value, SEPARATOR);
|
final List<Long> idList = DataAccess.getListOfIds(rs, count.value, SEPARATOR_LONG);
|
||||||
// field.set(data, idList);
|
// field.set(data, idList);
|
||||||
count.inc();
|
count.inc();
|
||||||
if (idList != null && idList.size() > 0) {
|
if (idList != null && idList.size() > 0) {
|
||||||
@@ -182,6 +229,25 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
};
|
};
|
||||||
lazyCall.add(lambda);
|
lazyCall.add(lambda);
|
||||||
}
|
}
|
||||||
|
} else if (objectClass == UUID.class) {
|
||||||
|
final List<UUID> idList = DataAccess.getListOfUUIDs(rs, count.value, SEPARATOR_UUID);
|
||||||
|
// field.set(data, idList);
|
||||||
|
count.inc();
|
||||||
|
if (idList != null && idList.size() > 0) {
|
||||||
|
final String idField = AnnotationTools.getFieldName(AnnotationTools.getIdField(objectClass));
|
||||||
|
// In the lazy mode, the request is done in asynchronous mode, they will be done after...
|
||||||
|
final LazyGetter lambda = () -> {
|
||||||
|
final List<UUID> childs = new ArrayList<>(idList);
|
||||||
|
// TODO: update to have get with abstract types ....
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Object foreignData = DataAccess.getsWhere(decorators.targetEntity(), new Condition(new QueryInList<>(idField, childs)));
|
||||||
|
if (foreignData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
field.set(data, foreignData);
|
||||||
|
};
|
||||||
|
lazyCall.add(lambda);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,12 +263,38 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
LOGGER.error("Can not ManyToMany with other than List Model: {}", field.getType().getCanonicalName());
|
LOGGER.error("Can not ManyToMany with other than List Model: {}", field.getType().getCanonicalName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
|
if (objectClass != Long.class && objectClass != UUID.class) {
|
||||||
|
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">");
|
||||||
|
}
|
||||||
final String columnName = AnnotationTools.getFieldName(field);
|
final String columnName = AnnotationTools.getFieldName(field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName);
|
final String linkTableName = generateLinkTableName(tableName, columnName);
|
||||||
actions.add(() -> {
|
|
||||||
DataAccess.deleteWhere(LinkTable.class, new OverrideTableName(linkTableName), new Condition(new QueryCondition("object1Id", "=", localKey)));
|
if (localKey instanceof final Long localKeyLong) {
|
||||||
});
|
if (objectClass == Long.class) {
|
||||||
asyncInsert(tableName, localKey, field, data, actions);
|
actions.add(() -> {
|
||||||
|
DataAccess.deleteWhere(LinkTableLongLong.class, new OverrideTableName(linkTableName), new Condition(new QueryCondition("object1Id", "=", localKeyLong)));
|
||||||
|
});
|
||||||
|
asyncInsert(tableName, localKey, field, data, actions);
|
||||||
|
} else {
|
||||||
|
actions.add(() -> {
|
||||||
|
DataAccess.deleteWhere(LinkTableLongUUID.class, new OverrideTableName(linkTableName), new Condition(new QueryCondition("object1Id", "=", localKeyLong)));
|
||||||
|
});
|
||||||
|
asyncInsert(tableName, localKey, field, data, actions);
|
||||||
|
}
|
||||||
|
} else if (localKey instanceof final UUID localKeyUUID) {
|
||||||
|
if (objectClass == Long.class) {
|
||||||
|
actions.add(() -> {
|
||||||
|
DataAccess.deleteWhere(LinkTableUUIDLong.class, new OverrideTableName(linkTableName), new Condition(new QueryCondition("object1Id", "=", localKeyUUID)));
|
||||||
|
});
|
||||||
|
asyncInsert(tableName, localKey, field, data, actions);
|
||||||
|
} else {
|
||||||
|
actions.add(() -> {
|
||||||
|
DataAccess.deleteWhere(LinkTableUUIDUUID.class, new OverrideTableName(linkTableName), new Condition(new QueryCondition("object1Id", "=", localKeyUUID)));
|
||||||
|
});
|
||||||
|
asyncInsert(tableName, localKey, field, data, actions);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -219,56 +311,142 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
LOGGER.error("Can not ManyToMany with other than List Model: {}", field.getType().getCanonicalName());
|
LOGGER.error("Can not ManyToMany with other than List Model: {}", field.getType().getCanonicalName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
|
if (objectClass != Long.class && objectClass != UUID.class) {
|
||||||
|
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">");
|
||||||
|
}
|
||||||
final String columnName = AnnotationTools.getFieldName(field);
|
final String columnName = AnnotationTools.getFieldName(field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName);
|
final String linkTableName = generateLinkTableName(tableName, columnName);
|
||||||
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
if (localKey instanceof final Long localKeyLong) {
|
||||||
if (objectClass != Long.class) {
|
if (objectClass == Long.class) {
|
||||||
LOGGER.error("Can not ManyToMany with other than List<Long> Model: List<{}>", objectClass.getCanonicalName());
|
// ========================================================
|
||||||
return;
|
// == Link a "Long" primary Key with List<Long>
|
||||||
}
|
// ========================================================
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final List<Long> dataCasted = (List<Long>) data;
|
final List<Long> dataCasted = (List<Long>) data;
|
||||||
if (dataCasted.size() == 0) {
|
if (dataCasted.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final List<LinkTable> insertElements = new ArrayList<>();
|
final List<LinkTableLongLong> insertElements = new ArrayList<>();
|
||||||
for (final Long remoteKey : dataCasted) {
|
for (final Long remoteKey : dataCasted) {
|
||||||
if (remoteKey == null) {
|
if (remoteKey == null) {
|
||||||
throw new DataAccessException("Try to insert remote key with null value");
|
throw new DataAccessException("Try to insert remote key with null value");
|
||||||
}
|
}
|
||||||
if (localKey instanceof final Long localKeyLong) {
|
insertElements.add(new LinkTableLongLong(localKeyLong, remoteKey));
|
||||||
insertElements.add(new LinkTable(localKeyLong, remoteKey));
|
}
|
||||||
|
if (insertElements.size() == 0) {
|
||||||
|
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
actions.add(() -> {
|
||||||
|
DataAccess.insertMultiple(insertElements, new OverrideTableName(linkTableName));
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new DataAccessException("Not manage access of remte key like ManyToMany other than Long: " + localKey.getClass().getCanonicalName());
|
// ========================================================
|
||||||
|
// == Link a "Long" primary Key with List<UUID>
|
||||||
|
// ========================================================
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<UUID> dataCasted = (List<UUID>) data;
|
||||||
|
if (dataCasted.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final List<LinkTableLongUUID> insertElements = new ArrayList<>();
|
||||||
|
for (final UUID remoteKey : dataCasted) {
|
||||||
|
if (remoteKey == null) {
|
||||||
|
throw new DataAccessException("Try to insert remote key with null value");
|
||||||
|
}
|
||||||
|
insertElements.add(new LinkTableLongUUID(localKeyLong, remoteKey));
|
||||||
|
}
|
||||||
|
if (insertElements.size() == 0) {
|
||||||
|
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
actions.add(() -> {
|
||||||
|
DataAccess.insertMultiple(insertElements, new OverrideTableName(linkTableName));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
} else if (localKey instanceof final UUID localKeyUUID) {
|
||||||
|
if (objectClass == Long.class) {
|
||||||
|
// ========================================================
|
||||||
|
// == Link a "UUID" primary Key with List<Long>
|
||||||
|
// ========================================================
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<Long> dataCasted = (List<Long>) data;
|
||||||
|
if (dataCasted.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final List<LinkTableUUIDLong> insertElements = new ArrayList<>();
|
||||||
|
for (final Long remoteKey : dataCasted) {
|
||||||
|
if (remoteKey == null) {
|
||||||
|
throw new DataAccessException("Try to insert remote key with null value");
|
||||||
|
}
|
||||||
|
insertElements.add(new LinkTableUUIDLong(localKeyUUID, remoteKey));
|
||||||
|
}
|
||||||
|
if (insertElements.size() == 0) {
|
||||||
|
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
actions.add(() -> {
|
||||||
|
DataAccess.insertMultiple(insertElements, new OverrideTableName(linkTableName));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// ========================================================
|
||||||
|
// == Link a "UUID" primary Key with List<UUID>
|
||||||
|
// ========================================================
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<UUID> dataCasted = (List<UUID>) data;
|
||||||
|
if (dataCasted.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final List<LinkTableUUIDUUID> insertElements = new ArrayList<>();
|
||||||
|
for (final UUID remoteKey : dataCasted) {
|
||||||
|
if (remoteKey == null) {
|
||||||
|
throw new DataAccessException("Try to insert remote key with null value");
|
||||||
|
}
|
||||||
|
insertElements.add(new LinkTableUUIDUUID(localKeyUUID, remoteKey));
|
||||||
|
}
|
||||||
|
if (insertElements.size() == 0) {
|
||||||
|
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
actions.add(() -> {
|
||||||
|
DataAccess.insertMultiple(insertElements, new OverrideTableName(linkTableName));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new DataAccessException("Not manage access of remte key like ManyToMany other than Long or UUID: " + localKey.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
if (insertElements.size() == 0) {
|
|
||||||
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
actions.add(() -> {
|
|
||||||
DataAccess.insertMultiple(insertElements, new OverrideTableName(linkTableName));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drop(final String tableName, final Field field) throws Exception {
|
public void drop(final String tableName, final Field field) throws Exception {
|
||||||
final String columnName = AnnotationTools.getFieldName(field);
|
final String columnName = AnnotationTools.getFieldName(field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName);
|
final String linkTableName = generateLinkTableName(tableName, columnName);
|
||||||
DataAccess.drop(LinkTable.class, new OverrideTableName(linkTableName));
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
|
if (objectClass != Long.class && objectClass != UUID.class) {
|
||||||
|
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">");
|
||||||
|
}
|
||||||
|
DataAccess.drop(LinkTableLongLong.class, new OverrideTableName(linkTableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanAll(final String tableName, final Field field) throws Exception {
|
public void cleanAll(final String tableName, final Field field) throws Exception {
|
||||||
final String columnName = AnnotationTools.getFieldName(field);
|
final String columnName = AnnotationTools.getFieldName(field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName);
|
final String linkTableName = generateLinkTableName(tableName, columnName);
|
||||||
DataAccess.cleanAll(LinkTable.class, new OverrideTableName(linkTableName));
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
|
if (objectClass != Long.class && objectClass != UUID.class) {
|
||||||
|
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">");
|
||||||
|
}
|
||||||
|
DataAccess.cleanAll(LinkTableLongLong.class, new OverrideTableName(linkTableName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addLink(final Class<?> clazz, final long localKey, final String column, final long remoteKey) throws Exception {
|
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 tableName = AnnotationTools.getTableName(clazz);
|
||||||
final String linkTableName = generateLinkTableName(tableName, column);
|
final String linkTableName = generateLinkTableName(tableName, column);
|
||||||
final LinkTable insertElement = new LinkTable(localKey, remoteKey);
|
/* final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; if (objectClass != Long.class && objectClass != UUID.class) { throw new
|
||||||
|
* DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">"); } */
|
||||||
|
final LinkTableLongLong insertElement = new LinkTableLongLong(localKey, remoteKey);
|
||||||
DataAccess.insert(insertElement, new OverrideTableName(linkTableName));
|
DataAccess.insert(insertElement, new OverrideTableName(linkTableName));
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -276,16 +454,48 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
public static int removeLink(final Class<?> clazz, final long localKey, final String column, final long remoteKey) throws Exception {
|
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 tableName = AnnotationTools.getTableName(clazz);
|
||||||
final String linkTableName = generateLinkTableName(tableName, column);
|
final String linkTableName = generateLinkTableName(tableName, column);
|
||||||
return DataAccess.deleteWhere(LinkTable.class, new OverrideTableName(linkTableName),
|
return DataAccess.deleteWhere(LinkTableLongLong.class, new OverrideTableName(linkTableName),
|
||||||
new Condition(new QueryAnd(new QueryCondition("object1Id", "=", localKey), new QueryCondition("object2Id", "=", remoteKey))));
|
new Condition(new QueryAnd(new QueryCondition("object1Id", "=", localKey), new QueryCondition("object2Id", "=", remoteKey))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createTables(final String tableName, final Field field, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> postActionList,
|
public void createTables( //
|
||||||
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
final String tableName, //
|
||||||
|
final Field primaryField, //
|
||||||
|
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 {
|
||||||
final String linkTableName = generateLinkTableNameField(tableName, field);
|
final String linkTableName = generateLinkTableNameField(tableName, field);
|
||||||
final QueryOptions options = new QueryOptions(new OverrideTableName(linkTableName));
|
final QueryOptions options = new QueryOptions(new OverrideTableName(linkTableName));
|
||||||
final List<String> sqlCommand = DataFactory.createTable(LinkTable.class, options);
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
postActionList.addAll(sqlCommand);
|
if (objectClass != Long.class && objectClass != UUID.class) {
|
||||||
|
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">");
|
||||||
|
}
|
||||||
|
final Class<?> primaryType = primaryField.getType();
|
||||||
|
if (primaryType == Long.class) {
|
||||||
|
if (objectClass == Long.class) {
|
||||||
|
final List<String> sqlCommand = DataFactory.createTable(LinkTableLongLong.class, options);
|
||||||
|
postActionList.addAll(sqlCommand);
|
||||||
|
} else {
|
||||||
|
final List<String> sqlCommand = DataFactory.createTable(LinkTableLongUUID.class, options);
|
||||||
|
postActionList.addAll(sqlCommand);
|
||||||
|
}
|
||||||
|
} else if (primaryType == UUID.class) {
|
||||||
|
|
||||||
|
if (objectClass == Long.class) {
|
||||||
|
final List<String> sqlCommand = DataFactory.createTable(LinkTableUUIDLong.class, options);
|
||||||
|
postActionList.addAll(sqlCommand);
|
||||||
|
} else {
|
||||||
|
final List<String> sqlCommand = DataFactory.createTable(LinkTableUUIDUUID.class, options);
|
||||||
|
postActionList.addAll(sqlCommand);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new DataAccessException("Can not ManyToMany with other than primary key type Long or UUID Model: " + primaryType.getCanonicalName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.AnnotationTools;
|
import org.kar.archidata.annotation.AnnotationTools;
|
||||||
import org.kar.archidata.dataAccess.CountInOut;
|
import org.kar.archidata.dataAccess.CountInOut;
|
||||||
@@ -14,6 +15,7 @@ import org.kar.archidata.dataAccess.DataFactory;
|
|||||||
import org.kar.archidata.dataAccess.LazyGetter;
|
import org.kar.archidata.dataAccess.LazyGetter;
|
||||||
import org.kar.archidata.dataAccess.QueryOptions;
|
import org.kar.archidata.dataAccess.QueryOptions;
|
||||||
import org.kar.archidata.exception.DataAccessException;
|
import org.kar.archidata.exception.DataAccessException;
|
||||||
|
import org.kar.archidata.tools.UuidUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -30,12 +32,11 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQLFieldType(final Field elem) throws Exception {
|
public String getSQLFieldType(final Field field) throws Exception {
|
||||||
final String fieldName = AnnotationTools.getFieldName(elem);
|
final String fieldName = AnnotationTools.getFieldName(field);
|
||||||
try {
|
try {
|
||||||
return DataFactory.convertTypeInSQL(Long.class, fieldName);
|
return DataFactory.convertTypeInSQL(field.getType(), fieldName);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -43,18 +44,41 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCompatibleField(final Field elem) {
|
public boolean isCompatibleField(final Field elem) {
|
||||||
final ManyToOne decorators = elem.getDeclaredAnnotation(ManyToOne.class);
|
return elem.getDeclaredAnnotation(ManyToOne.class) != null;
|
||||||
return decorators != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void insertData(final PreparedStatement ps, final Field field, final Object rootObject, final CountInOut iii) throws Exception {
|
public void insertData(final PreparedStatement ps, final Field field, final Object rootObject, final CountInOut iii) throws Exception {
|
||||||
final Object data = field.get(rootObject);
|
final Object data = field.get(rootObject);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
ps.setNull(iii.value, Types.BIGINT);
|
if (field.getType() == Long.class) {
|
||||||
|
ps.setNull(iii.value, Types.BIGINT);
|
||||||
|
} else if (field.getType() == Integer.class) {
|
||||||
|
ps.setNull(iii.value, Types.INTEGER);
|
||||||
|
} else if (field.getType() == Short.class) {
|
||||||
|
ps.setNull(iii.value, Types.INTEGER);
|
||||||
|
} else if (field.getType() == String.class) {
|
||||||
|
ps.setNull(iii.value, Types.VARCHAR);
|
||||||
|
} else if (field.getType() == UUID.class) {
|
||||||
|
ps.setNull(iii.value, Types.BINARY);
|
||||||
|
}
|
||||||
} else if (field.getType() == Long.class) {
|
} else if (field.getType() == Long.class) {
|
||||||
final Long dataLong = (Long) data;
|
final Long dataTyped = (Long) data;
|
||||||
ps.setLong(iii.value, dataLong);
|
ps.setLong(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == Integer.class) {
|
||||||
|
final Integer dataTyped = (Integer) data;
|
||||||
|
ps.setInt(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == Short.class) {
|
||||||
|
final Short dataTyped = (Short) data;
|
||||||
|
ps.setShort(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == String.class) {
|
||||||
|
final String dataTyped = (String) data;
|
||||||
|
ps.setString(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == UUID.class) {
|
||||||
|
final UUID dataTyped = (UUID) data;
|
||||||
|
LOGGER.info("Generate UUTD for DB: {}", dataTyped);
|
||||||
|
final byte[] dataByte = UuidUtils.asBytes(dataTyped);
|
||||||
|
ps.setBytes(iii.value, dataByte);
|
||||||
} else {
|
} else {
|
||||||
final Field idField = AnnotationTools.getFieldOfId(field.getType());
|
final Field idField = AnnotationTools.getFieldOfId(field.getType());
|
||||||
final Object uid = idField.get(data);
|
final Object uid = idField.get(data);
|
||||||
@@ -71,7 +95,11 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canInsert(final Field field) {
|
public boolean canInsert(final Field field) {
|
||||||
if (field.getType() == Long.class) {
|
if (field.getType() == Long.class //
|
||||||
|
|| field.getType() == Integer.class //
|
||||||
|
|| field.getType() == Short.class //
|
||||||
|
|| field.getType() == String.class //
|
||||||
|
|| field.getType() == UUID.class) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
||||||
@@ -88,7 +116,12 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canRetrieve(final Field field) {
|
public boolean canRetrieve(final Field field) {
|
||||||
if (field.getType() == Long.class) {
|
final Class<?> classType = field.getType();
|
||||||
|
if (classType == Long.class //
|
||||||
|
|| classType == Integer.class //
|
||||||
|
|| classType == Short.class //
|
||||||
|
|| classType == String.class //
|
||||||
|
|| classType == UUID.class) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
||||||
@@ -99,9 +132,20 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry, @NotNull final String name,
|
public void generateQuerry( //
|
||||||
@NotNull final CountInOut elemCount, final QueryOptions options) throws Exception {
|
@NotNull final String tableName, //
|
||||||
if (field.getType() == Long.class) {
|
@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 {
|
||||||
|
if (field.getType() == Long.class //
|
||||||
|
|| field.getType() == Integer.class //
|
||||||
|
|| field.getType() == Short.class //
|
||||||
|
|| field.getType() == String.class //
|
||||||
|
|| field.getType() == UUID.class) {
|
||||||
querrySelect.append(" ");
|
querrySelect.append(" ");
|
||||||
querrySelect.append(tableName);
|
querrySelect.append(tableName);
|
||||||
querrySelect.append(".");
|
querrySelect.append(".");
|
||||||
@@ -150,6 +194,39 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (field.getType() == Integer.class) {
|
||||||
|
final Integer foreignKey = rs.getInt(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field.getType() == Short.class) {
|
||||||
|
final Short foreignKey = rs.getShort(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field.getType() == String.class) {
|
||||||
|
final String foreignKey = rs.getString(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field.getType() == UUID.class) {
|
||||||
|
final byte[] tmp = rs.getBytes(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
final UUID foreignKey = UuidUtils.asUuid(tmp);
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
final Class<?> objectClass = field.getType();
|
final Class<?> objectClass = field.getType();
|
||||||
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
||||||
if (decorators == null) {
|
if (decorators == null) {
|
||||||
@@ -184,8 +261,27 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
|
|
||||||
// TODO : refacto this table to manage a generic table with dynamic name to be serialisable with the default system
|
// TODO : refacto this table to manage a generic table with dynamic name to be serialisable with the default system
|
||||||
@Override
|
@Override
|
||||||
public void createTables(final String tableName, final Field field, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> postActionList,
|
public void createTables(//
|
||||||
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
final String tableName, //
|
||||||
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, Long.class);
|
final Field primaryField, //
|
||||||
|
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 {
|
||||||
|
final Class<?> classType = field.getType();
|
||||||
|
if (classType == Long.class //
|
||||||
|
|| classType == Integer.class //
|
||||||
|
|| classType == Short.class //
|
||||||
|
|| classType == String.class //
|
||||||
|
|| classType == UUID.class) {
|
||||||
|
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, classType);
|
||||||
|
} else {
|
||||||
|
LOGGER.error("Support only the Long remote field of ecternal primary keys...");
|
||||||
|
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, Long.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -125,8 +125,17 @@ public class AddOnOneToMany implements DataAccessAddOn {
|
|||||||
|
|
||||||
// TODO : refacto this table to manage a generic table with dynamic name to be serializable with the default system
|
// TODO : refacto this table to manage a generic table with dynamic name to be serializable with the default system
|
||||||
@Override
|
@Override
|
||||||
public void createTables(final String tableName, final Field field, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> postActionList,
|
public void createTables(//
|
||||||
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
final String tableName, //
|
||||||
|
final Field primaryField, //
|
||||||
|
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 {
|
||||||
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, Long.class);
|
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, Long.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -105,8 +105,17 @@ public class AddOnSQLTableExternalForeinKeyAsList implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createTables(final String tableName, final Field field, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> postActionList,
|
public void createTables(//
|
||||||
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
final String tableName, //
|
||||||
|
final Field primaryField, //
|
||||||
|
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 {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, String.class);
|
DataFactory.createTablesSpecificType(tableName, field, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, String.class);
|
||||||
|
@@ -5,12 +5,12 @@ import org.kar.archidata.model.GenericData;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
|
|
||||||
public class LinkTable extends GenericData {
|
public class LinkTableLongLong extends GenericData {
|
||||||
public LinkTable() {
|
public LinkTableLongLong() {
|
||||||
// nothing to do...
|
// nothing to do...
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkTable(final long object1Id, final long object2Id) {
|
public LinkTableLongLong(final long object1Id, final long object2Id) {
|
||||||
this.object1Id = object1Id;
|
this.object1Id = object1Id;
|
||||||
this.object2Id = object2Id;
|
this.object2Id = object2Id;
|
||||||
}
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
package org.kar.archidata.dataAccess.addOn.model;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.kar.archidata.model.GenericData;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
|
||||||
|
public class LinkTableLongUUID extends GenericData {
|
||||||
|
public LinkTableLongUUID() {
|
||||||
|
// nothing to do...
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkTableLongUUID(final long object1Id, final UUID object2Id) {
|
||||||
|
this.object1Id = object1Id;
|
||||||
|
this.object2Id = object2Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "Object reference 1")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public Long object1Id;
|
||||||
|
@Schema(description = "Object reference 2")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public UUID object2Id;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
package org.kar.archidata.dataAccess.addOn.model;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.kar.archidata.model.GenericData;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
|
||||||
|
public class LinkTableUUIDLong extends GenericData {
|
||||||
|
public LinkTableUUIDLong() {
|
||||||
|
// nothing to do...
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkTableUUIDLong(final UUID object1Id, final long object2Id) {
|
||||||
|
this.object1Id = object1Id;
|
||||||
|
this.object2Id = object2Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "Object reference 1")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public UUID object1Id;
|
||||||
|
@Schema(description = "Object reference 2")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public Long object2Id;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
package org.kar.archidata.dataAccess.addOn.model;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.kar.archidata.model.GenericData;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
|
||||||
|
public class LinkTableUUIDUUID extends GenericData {
|
||||||
|
public LinkTableUUIDUUID() {
|
||||||
|
// nothing to do...
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkTableUUIDUUID(final UUID object1Id, final UUID object2Id) {
|
||||||
|
this.object1Id = object1Id;
|
||||||
|
this.object2Id = object2Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "Object reference 1")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public UUID object1Id;
|
||||||
|
@Schema(description = "Object reference 2")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public UUID object2Id;
|
||||||
|
|
||||||
|
}
|
@@ -9,6 +9,7 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.AnnotationTools;
|
import org.kar.archidata.annotation.AnnotationTools;
|
||||||
@@ -125,7 +126,6 @@ public class CheckJPA<T> implements CheckFunctionInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (type == Integer.class || type == int.class) {
|
} else if (type == Integer.class || type == int.class) {
|
||||||
|
|
||||||
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
|
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
|
||||||
if (maxValueRoot != null) {
|
if (maxValueRoot != null) {
|
||||||
final int maxValue = maxValueRoot.intValue();
|
final int maxValue = maxValueRoot.intValue();
|
||||||
@@ -167,6 +167,20 @@ public class CheckJPA<T> 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) -> {
|
||||||
|
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 == Boolean.class || type == boolean.class) {
|
||||||
|
|
||||||
} else if (type == Float.class || type == float.class) {
|
} else if (type == Float.class || type == float.class) {
|
||||||
|
@@ -5,7 +5,7 @@ import java.util.UUID;
|
|||||||
public class RESTErrorResponseExeption extends Exception {
|
public class RESTErrorResponseExeption extends Exception {
|
||||||
public UUID uuid;
|
public UUID uuid;
|
||||||
public String time;
|
public String time;
|
||||||
public String error;
|
public String name;
|
||||||
public String message;
|
public String message;
|
||||||
public int status;
|
public int status;
|
||||||
public String statusMessage;
|
public String statusMessage;
|
||||||
@@ -13,16 +13,16 @@ public class RESTErrorResponseExeption extends Exception {
|
|||||||
public RESTErrorResponseExeption() {
|
public RESTErrorResponseExeption() {
|
||||||
this.uuid = null;
|
this.uuid = null;
|
||||||
this.time = null;
|
this.time = null;
|
||||||
this.error = null;
|
this.name = null;
|
||||||
this.message = null;
|
this.message = null;
|
||||||
this.status = 0;
|
this.status = 0;
|
||||||
this.statusMessage = null;
|
this.statusMessage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RESTErrorResponseExeption(final UUID uuid, final String time, final String error, final String message, final int status, final String statusMessage) {
|
public RESTErrorResponseExeption(final UUID uuid, final String time, final String name, final String message, final int status, final String statusMessage) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
this.error = error;
|
this.name = name;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.statusMessage = statusMessage;
|
this.statusMessage = statusMessage;
|
||||||
@@ -30,7 +30,7 @@ public class RESTErrorResponseExeption extends Exception {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RESTErrorResponseExeption [uuid=" + this.uuid + ", time=" + this.time + ", error=" + this.error + ", message=" + this.message + ", status=" + this.status + ", statusMessage="
|
return "RESTErrorResponseExeption [uuid=" + this.uuid + ", time=" + this.time + ", name=" + this.name + ", message=" + this.message + ", status=" + this.status + ", statusMessage="
|
||||||
+ this.statusMessage + "]";
|
+ this.statusMessage + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -211,7 +211,8 @@ public class DataTools {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <CLASS_TYPE, ID_TYPE> Response uploadCover(final Class<CLASS_TYPE> clazz, final ID_TYPE id, String fileName, final InputStream fileInputStream, final FormDataContentDisposition fileMetaData) {
|
public static <CLASS_TYPE, ID_TYPE> Response uploadCover(final Class<CLASS_TYPE> clazz, final ID_TYPE id, String fileName, final InputStream fileInputStream,
|
||||||
|
final FormDataContentDisposition fileMetaData) {
|
||||||
try {
|
try {
|
||||||
// correct input string stream :
|
// correct input string stream :
|
||||||
fileName = multipartCorrection(fileName);
|
fileName = multipartCorrection(fileName);
|
||||||
|
@@ -47,7 +47,7 @@ public class RESTApi {
|
|||||||
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
||||||
try {
|
try {
|
||||||
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
||||||
throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status, out.statusMessage);
|
throw out;
|
||||||
} catch (final MismatchedInputException ex) {
|
} catch (final MismatchedInputException ex) {
|
||||||
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ public class RESTApi {
|
|||||||
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
||||||
try {
|
try {
|
||||||
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
||||||
throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status, out.statusMessage);
|
throw out;
|
||||||
} catch (final MismatchedInputException ex) {
|
} catch (final MismatchedInputException ex) {
|
||||||
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||||
} catch (final JsonParseException ex) {
|
} catch (final JsonParseException ex) {
|
||||||
@@ -156,7 +156,7 @@ public class RESTApi {
|
|||||||
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
||||||
try {
|
try {
|
||||||
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
||||||
throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status, out.statusMessage);
|
throw out;
|
||||||
} catch (final MismatchedInputException ex) {
|
} catch (final MismatchedInputException ex) {
|
||||||
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ public class RESTApi {
|
|||||||
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
||||||
try {
|
try {
|
||||||
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
final RESTErrorResponseExeption out = this.mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
||||||
throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status, out.statusMessage);
|
throw out;
|
||||||
} catch (final MismatchedInputException ex) {
|
} catch (final MismatchedInputException ex) {
|
||||||
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,10 @@ package org.kar.archidata.tools;
|
|||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class UuidUtils {
|
public class UuidUtils {
|
||||||
@@ -25,4 +29,41 @@ public class UuidUtils {
|
|||||||
bb.putLong(uuid.getLeastSignificantBits());
|
bb.putLong(uuid.getLeastSignificantBits());
|
||||||
return bb.array();
|
return bb.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Generator {
|
||||||
|
private long base;
|
||||||
|
private final long offset;
|
||||||
|
private long previous;
|
||||||
|
|
||||||
|
public Generator() {
|
||||||
|
this.offset = System.currentTimeMillis();
|
||||||
|
// The local method never generate new UUID in the past, then we use the creation function time to prevent 2038 error
|
||||||
|
final Instant startingUUID = LocalDate.of(2024, 03, 19).atStartOfDay(ZoneOffset.UTC).toInstant();
|
||||||
|
this.base = startingUUID.until(Instant.now(), ChronoUnit.SECONDS);
|
||||||
|
final String serveurBaseUUID = System.getenv("UUID_SERVER_ID");
|
||||||
|
if (serveurBaseUUID != null) {
|
||||||
|
long serverId = Long.valueOf(serveurBaseUUID);
|
||||||
|
serverId %= 0xFFFF;
|
||||||
|
this.base += (serverId << (64 - 16));
|
||||||
|
} else {
|
||||||
|
this.base += (1L << (64 - 16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized UUID next() {
|
||||||
|
long tmp = System.currentTimeMillis();
|
||||||
|
if (this.previous >= tmp) {
|
||||||
|
tmp = this.previous + 1;
|
||||||
|
}
|
||||||
|
this.previous = tmp;
|
||||||
|
tmp -= this.offset;
|
||||||
|
return new UUID(Long.reverseBytes(tmp), this.base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Generator generator = new Generator();
|
||||||
|
|
||||||
|
public static UUID nextUUID() {
|
||||||
|
return generator.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,7 @@ export interface RESTModel {
|
|||||||
accept?: HTTPMimeType;
|
accept?: HTTPMimeType;
|
||||||
// Content of the local data.
|
// Content of the local data.
|
||||||
contentType?: HTTPMimeType;
|
contentType?: HTTPMimeType;
|
||||||
// Mode of the TOKEN in urk or Header
|
// Mode of the TOKEN in URL or Header (?token:${tokenInUrl})
|
||||||
tokenInUrl?: boolean;
|
tokenInUrl?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,22 +67,48 @@ export function isArrayOf<TYPE>(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RESTRequestType = {
|
function isNullOrUndefined(data: any): data is undefined | null {
|
||||||
|
return data === undefined || data === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic progression callback
|
||||||
|
export type ProgressCallback = (count: number, total: number) => void;
|
||||||
|
|
||||||
|
export interface RESTAbort {
|
||||||
|
abort?: () => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Rest generic callback have a basic model to upload and download advancement.
|
||||||
|
export interface RESTCallbacks {
|
||||||
|
progressUpload?: ProgressCallback,
|
||||||
|
progressDownload?: ProgressCallback,
|
||||||
|
abortHandle?: RESTAbort,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface RESTRequestType {
|
||||||
restModel: RESTModel,
|
restModel: RESTModel,
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data?: any,
|
data?: any,
|
||||||
params?: object,
|
params?: object,
|
||||||
queries?: object,
|
queries?: object,
|
||||||
|
callback?: RESTCallbacks,
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeTrailingSlashes(input: string): string {
|
function removeTrailingSlashes(input: string): string {
|
||||||
|
if (isNullOrUndefined(input)) {
|
||||||
|
return "undefined";
|
||||||
|
}
|
||||||
return input.replace(/\/+$/, '');
|
return input.replace(/\/+$/, '');
|
||||||
}
|
}
|
||||||
function removeLeadingSlashes(input: string): string {
|
function removeLeadingSlashes(input: string): string {
|
||||||
|
if (isNullOrUndefined(input)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return input.replace(/^\/+/, '');
|
return input.replace(/^\/+/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RESTUrl({ restModel, restConfig, data, params, queries }: RESTRequestType): string {
|
export function RESTUrl({ restModel, restConfig, params, queries }: RESTRequestType): string {
|
||||||
// Create the URL PATH:
|
// Create the URL PATH:
|
||||||
let generateUrl = `${removeTrailingSlashes(restConfig.server)}/${removeLeadingSlashes(restModel.endPoint)}`;
|
let generateUrl = `${removeTrailingSlashes(restConfig.server)}/${removeLeadingSlashes(restModel.endPoint)}`;
|
||||||
if (params !== undefined) {
|
if (params !== undefined) {
|
||||||
@@ -91,7 +117,7 @@ export function RESTUrl({ restModel, restConfig, data, params, queries }: RESTRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (queries === undefined && (restConfig.token === undefined || restModel.tokenInUrl !== true)) {
|
if (queries === undefined && (restConfig.token === undefined || restModel.tokenInUrl !== true)) {
|
||||||
return generateUrl;
|
return generateUrl;
|
||||||
}
|
}
|
||||||
const searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
if (queries !== undefined) {
|
if (queries !== undefined) {
|
||||||
@@ -112,7 +138,92 @@ export function RESTUrl({ restModel, restConfig, data, params, queries }: RESTRe
|
|||||||
return generateUrl + "?" + searchParams.toString();
|
return generateUrl + "?" + searchParams.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RESTRequest({ restModel, restConfig, data, params, queries }: RESTRequestType): Promise<ModelResponseHttp> {
|
|
||||||
|
export function fetchProgress(generateUrl: string, { method, headers, body }: {
|
||||||
|
method: HTTPRequestModel,
|
||||||
|
headers: any,
|
||||||
|
body: any,
|
||||||
|
}, { progressUpload, progressDownload, abortHandle }: RESTCallbacks): Promise<Response> {
|
||||||
|
const xhr = {
|
||||||
|
io: new XMLHttpRequest()
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Stream the upload progress
|
||||||
|
if (progressUpload) {
|
||||||
|
xhr.io.upload.addEventListener("progress", (dataEvent) => {
|
||||||
|
if (dataEvent.lengthComputable) {
|
||||||
|
//console.log(` ==> has a progress event: ${dataEvent.loaded} / ${dataEvent.total}`);
|
||||||
|
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Stream the download progress
|
||||||
|
if (progressDownload) {
|
||||||
|
xhr.io.addEventListener("progress", (dataEvent) => {
|
||||||
|
if (dataEvent.lengthComputable) {
|
||||||
|
//console.log(` ==> download progress:: ${dataEvent.loaded} / ${dataEvent.total}`);
|
||||||
|
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (abortHandle) {
|
||||||
|
abortHandle.abort = () => {
|
||||||
|
if (xhr.io) {
|
||||||
|
console.log(`Request abort on the XMLHttpRequest: ${generateUrl}`);
|
||||||
|
xhr.io.abort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(`Request abort (FAIL) on the XMLHttpRequest: ${generateUrl}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if we have an internal Fail:
|
||||||
|
xhr.io.addEventListener('error', () => {
|
||||||
|
xhr.io = undefined;
|
||||||
|
reject(new TypeError('Failed to fetch'))
|
||||||
|
});
|
||||||
|
|
||||||
|
// Capture the end of the stream
|
||||||
|
xhr.io.addEventListener("loadend", () => {
|
||||||
|
if (xhr.io.readyState !== XMLHttpRequest.DONE) {
|
||||||
|
//console.log(` ==> READY state`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (xhr.io.status === 0) {
|
||||||
|
//the stream has been aborted
|
||||||
|
reject(new TypeError('Fetch has been aborted'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Stream is ended, transform in a generic response:
|
||||||
|
const response = new Response(xhr.io.response, {
|
||||||
|
status: xhr.io.status,
|
||||||
|
statusText: xhr.io.statusText
|
||||||
|
});
|
||||||
|
const headersArray = xhr.io.getAllResponseHeaders().trim().replaceAll("\r\n", "\n").split('\n');
|
||||||
|
headersArray.forEach(function (header) {
|
||||||
|
const firstColonIndex = header.indexOf(':');
|
||||||
|
if (firstColonIndex !== -1) {
|
||||||
|
var key = header.substring(0, firstColonIndex).trim();
|
||||||
|
var value = header.substring(firstColonIndex + 1).trim();
|
||||||
|
response.headers.set(key, value);
|
||||||
|
} else {
|
||||||
|
response.headers.set(header, "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
xhr.io = undefined;
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
xhr.io.open(method, generateUrl, true);
|
||||||
|
if (!isNullOrUndefined(headers)) {
|
||||||
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
|
xhr.io.setRequestHeader(key, value as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.io.send(body);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RESTRequest({ restModel, restConfig, data, params, queries, callback }: RESTRequestType): Promise<ModelResponseHttp> {
|
||||||
// Create the URL PATH:
|
// Create the URL PATH:
|
||||||
let generateUrl = RESTUrl({ restModel, restConfig, data, params, queries });
|
let generateUrl = RESTUrl({ restModel, restConfig, data, params, queries });
|
||||||
let headers: any = {};
|
let headers: any = {};
|
||||||
@@ -139,13 +250,27 @@ export function RESTRequest({ restModel, restConfig, data, params, queries }: RE
|
|||||||
}
|
}
|
||||||
body = formData
|
body = formData
|
||||||
}
|
}
|
||||||
console.log(`Call ${generateUrl}`)
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fetch(generateUrl, {
|
let action: undefined | Promise<Response> = undefined;
|
||||||
method: restModel.requestType,
|
if (isNullOrUndefined(callback)
|
||||||
headers,
|
|| (isNullOrUndefined(callback.progressDownload)
|
||||||
body,
|
&& isNullOrUndefined(callback.progressUpload)
|
||||||
}).then((response: Response) => {
|
&& isNullOrUndefined(callback.abortHandle))) {
|
||||||
|
// No information needed: call the generic fetch interface
|
||||||
|
action = fetch(generateUrl, {
|
||||||
|
method: restModel.requestType,
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// need progression information: call old fetch model (XMLHttpRequest) that permit to keep % upload and % download for HTTP1.x
|
||||||
|
action = fetchProgress(generateUrl, {
|
||||||
|
method: restModel.requestType ?? HTTPRequestModel.GET,
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
action.then((response: Response) => {
|
||||||
if (response.status >= 200 && response.status <= 299) {
|
if (response.status >= 200 && response.status <= 299) {
|
||||||
const contentType = response.headers.get('Content-Type');
|
const contentType = response.headers.get('Content-Type');
|
||||||
if (restModel.accept !== contentType) {
|
if (restModel.accept !== contentType) {
|
||||||
@@ -190,12 +315,14 @@ export function RESTRequest({ restModel, restConfig, data, params, queries }: RE
|
|||||||
status: 999,
|
status: 999,
|
||||||
error: error,
|
error: error,
|
||||||
statusMessage: "Fetch catch error",
|
statusMessage: "Fetch catch error",
|
||||||
message: "http-wrapper.ts detect an error in the fetch request"
|
message: "rest-tools.ts detect an error in the fetch request"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function RESTRequestJson<TYPE>(request: RESTRequestType, checker: (data: any) => data is TYPE): Promise<TYPE> {
|
export function RESTRequestJson<TYPE>(request: RESTRequestType, checker: (data: any) => data is TYPE): Promise<TYPE> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
RESTRequest(request).then((value: ModelResponseHttp) => {
|
RESTRequest(request).then((value: ModelResponseHttp) => {
|
||||||
|
@@ -1 +1 @@
|
|||||||
0.7.0
|
0.8.0
|
||||||
|
Reference in New Issue
Block a user