Compare commits

..

7 Commits

40 changed files with 1503 additions and 615 deletions

View File

@@ -1,14 +1,4 @@
#!/bin/bash #!/bin/bash
version_file="version.txt"
# update the Maven version number mvn versions:set -DnewVersion=$(cat version.txt)
mvn versions:set -DnewVersion=$(sed 's/dev/SNAPSHOT/g' $version_file)
if grep -q "DEV" "$version_file"; then
# update all versions release of dependency
mvn versions:use-latest-releases
# update our manage dependency as snapshoot
mvn versions:use-latest-versions -Dincludes=kangaroo-and-rabbit
else
# update our manage dependency as release (must be done before)
mvn versions:use-latest-releases -Dincludes=kangaroo-and-rabbit
fi

14
pom.xml
View File

@@ -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.10.2</version> <version>0.8.10-SNAPSHOOT</version>
<properties> <properties>
<java.version>21</java.version> <java.version>21</java.version>
<maven.compiler.version>3.1</maven.compiler.version> <maven.compiler.version>3.1</maven.compiler.version>
@@ -136,24 +136,24 @@
<dependency> <dependency>
<groupId>org.xerial</groupId> <groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId> <artifactId>sqlite-jdbc</artifactId>
<version>3.45.3.0</version> <version>3.40.0.0</version>
</dependency> </dependency>
<!-- Interface for JWT token --> <!-- Interface for JWT token -->
<dependency> <dependency>
<groupId>com.nimbusds</groupId> <groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId> <artifactId>nimbus-jose-jwt</artifactId>
<version>9.39.1</version> <version>9.39</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>jakarta.persistence</groupId> <groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId> <artifactId>jakarta.persistence-api</artifactId>
<version>3.2.0</version> <version>3.2.0-M2</version>
</dependency> </dependency>
<!-- Swagger dependencies --> <!-- Swagger dependencies -->
<dependency> <dependency>
<groupId>io.swagger.core.v3</groupId> <groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2-jakarta</artifactId> <artifactId>swagger-jaxrs2-jakarta</artifactId>
<version>2.2.22</version> <version>2.2.21</version>
</dependency> </dependency>
<!-- <!--
************************************************************ ************************************************************
@@ -163,13 +163,13 @@
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>5.11.0-M2</version> <version>5.11.0-M1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId> <artifactId>junit-jupiter-engine</artifactId>
<version>5.11.0-M2</version> <version>5.11.0-M1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -11,7 +11,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType; import jakarta.persistence.GenerationType;
@@ -259,14 +258,6 @@ public class AnnotationTools {
return !((Column) annotation[0]).nullable(); return !((Column) annotation[0]).nullable();
} }
public static boolean getNullable(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Nullable.class);
if (annotation.length == 0) {
return false;
}
return true;
}
public static boolean getConstraintsNotNull(final Field element) throws Exception { public static boolean getConstraintsNotNull(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(NotNull.class); final Annotation[] annotation = element.getDeclaredAnnotationsByType(NotNull.class);
if (annotation.length == 0) { if (annotation.length == 0) {

View File

@@ -5,25 +5,21 @@ import java.util.UUID;
import org.kar.archidata.tools.UuidUtils; import org.kar.archidata.tools.UuidUtils;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
public class RestErrorResponse { public class RestErrorResponse {
@NotNull
public UUID uuid = UuidUtils.nextUUID(); public UUID uuid = UuidUtils.nextUUID();
@NotNull @NotNull
@Column(length = 0)
public String name; // Mandatory for TS generic error public String name; // Mandatory for TS generic error
@NotNull @NotNull
@Column(length = 0)
public String message; // Mandatory for TS generic error public String message; // Mandatory for TS generic error
@NotNull @NotNull
@Column(length = 0)
public String time; public String time;
@NotNull @NotNull
final public int status; final public int status;
@NotNull @NotNull
@Column(length = 0)
final public String statusMessage; final public String statusMessage;
public RestErrorResponse(final Response.Status status, final String time, final String error, public RestErrorResponse(final Response.Status status, final String time, final String error,

View File

@@ -796,7 +796,7 @@ public class DataAccess {
// External checker of data: // External checker of data:
final List<CheckFunction> checks = options.get(CheckFunction.class); final List<CheckFunction> checks = options.get(CheckFunction.class);
for (final CheckFunction check : checks) { for (final CheckFunction check : checks) {
check.getChecker().check("", data, AnnotationTools.getFieldsNames(clazz), options); check.getChecker().check("", data, AnnotationTools.getFieldsNames(clazz));
} }
final DBEntry entry = DBInterfaceOption.getAutoEntry(options); final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
@@ -1119,7 +1119,7 @@ public class DataAccess {
if (options != null) { if (options != null) {
final List<CheckFunction> checks = options.get(CheckFunction.class); final List<CheckFunction> checks = options.get(CheckFunction.class);
for (final CheckFunction check : checks) { for (final CheckFunction check : checks) {
check.getChecker().check("", data, filter.getValues(), options); check.getChecker().check("", data, filter.getValues());
} }
} }
final List<LazyGetter> asyncActions = new ArrayList<>(); final List<LazyGetter> asyncActions = new ArrayList<>();
@@ -1293,7 +1293,8 @@ public class DataAccess {
return stmt.execute(query); return stmt.execute(query);
} }
public static <T> T getWhere(final Class<T> clazz, final QueryOptions options) throws Exception { public static <T> T getWhere(final Class<T> clazz, final QueryOption... option) throws Exception {
final QueryOptions options = new QueryOptions(option);
options.add(new Limit(1)); options.add(new Limit(1));
final List<T> values = getsWhere(clazz, options); final List<T> values = getsWhere(clazz, options);
if (values.size() == 0) { if (values.size() == 0) {
@@ -1302,11 +1303,6 @@ public class DataAccess {
return values.get(0); return values.get(0);
} }
public static <T> T getWhere(final Class<T> clazz, final QueryOption... option) throws Exception {
final QueryOptions options = new QueryOptions(option);
return getWhere(clazz, options);
}
public static void generateSelectField(// public static void generateSelectField(//
final StringBuilder querySelect, // final StringBuilder querySelect, //
final StringBuilder query, // final StringBuilder query, //
@@ -1488,19 +1484,12 @@ public class DataAccess {
return data; return data;
} }
public static <ID_TYPE> long count(final Class<?> clazz, final ID_TYPE id, final QueryOption... option) public static <ID_TYPE> long count(final Class<?> clazz, final ID_TYPE id) throws Exception {
throws Exception { return DataAccess.countWhere(clazz, new Condition(getTableIdCondition(clazz, id)));
final QueryOptions options = new QueryOptions(option);
options.add(new Condition(getTableIdCondition(clazz, id)));
return DataAccess.countWhere(clazz, options);
} }
public static long countWhere(final Class<?> clazz, final QueryOption... option) throws Exception { public static long countWhere(final Class<?> clazz, final QueryOption... option) throws Exception {
final QueryOptions options = new QueryOptions(option); final QueryOptions options = new QueryOptions(option);
return countWhere(clazz, options);
}
public static long countWhere(final Class<?> clazz, final QueryOptions options) throws Exception {
final Condition condition = conditionFusionOrEmpty(options, false); final Condition condition = conditionFusionOrEmpty(options, false);
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz); final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
DBEntry entry = DBInterfaceOption.getAutoEntry(options); DBEntry entry = DBInterfaceOption.getAutoEntry(options);

View File

@@ -0,0 +1,524 @@
package org.kar.archidata.dataAccess;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.kar.archidata.catcher.RestErrorResponse;
import org.kar.archidata.dataAccess.DataFactoryZod.ClassElement;
import org.kar.archidata.dataAccess.DataFactoryZod.GeneratedTypes;
import org.kar.archidata.externalRestApi.model.ApiTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public class DataFactoryTsApi {
static final Logger LOGGER = LoggerFactory.getLogger(DataFactoryTsApi.class);
record APIModel(
String data,
String className) {}
/** Request the generation of the TypeScript file for the "Zod" export model
* @param classs List of class used in the model
* @throws Exception */
public static List<String> createApi(
final List<Class<?>> classs,
final GeneratedTypes previous,
final String pathPackage) throws Exception {
final List<String> apis = new ArrayList<>();
final String globalheader = """
/**
* API of the server (auto-generated code)
*/
import {
HTTPMimeType,
HTTPRequestModel,
ModelResponseHttp,
RESTCallbacks,
RESTConfig,
RESTRequestJson,
RESTRequestJsonArray,
RESTRequestVoid
} from "./rest-tools"
import {""";
for (final Class<?> clazz : classs) {
final Set<Class<?>> includeModel = new HashSet<>();
final Set<Class<?>> includeCheckerModel = new HashSet<>();
final APIModel api = createSingleApi(clazz, includeModel, includeCheckerModel, previous);
final StringBuilder generatedData = new StringBuilder();
generatedData.append(globalheader);
final List<String> includedElements = new ArrayList<>();
for (final Class<?> elem : includeModel) {
if (elem == null) {
continue;
}
final ClassElement classElement = DataFactoryZod.createTable(elem, previous);
if (classElement.nativeType) {
continue;
}
includedElements.add(classElement.tsTypeName);
}
Collections.sort(includedElements);
for (final String elem : includedElements) {
generatedData.append("\n ");
generatedData.append(elem);
generatedData.append(",");
}
for (final Class<?> elem : includeCheckerModel) {
if (elem == null) {
continue;
}
final ClassElement classElement = DataFactoryZod.createTable(elem, previous);
if (classElement.nativeType) {
continue;
}
generatedData.append("\n ");
generatedData.append(classElement.tsCheckType);
generatedData.append(",");
}
generatedData.append("\n} from \"./model\"\n");
generatedData.append(api.data());
String fileName = api.className();
fileName = fileName.replaceAll("([A-Z])", "-$1").toLowerCase();
fileName = fileName.replaceAll("^\\-*", "");
apis.add(fileName);
final FileWriter myWriter = new FileWriter(pathPackage + File.separator + fileName + ".ts");
myWriter.write(generatedData.toString());
myWriter.close();
}
return apis;
}
record OrderedElement(
String methodName,
Method method) {}
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();
// the basic path has no specific elements...
final String basicPath = ApiTool.apiAnnotationGetPath(clazz);
final String classSimpleName = clazz.getSimpleName();
builder.append("export namespace ");
builder.append(classSimpleName);
builder.append(" {\n");
LOGGER.info("Parse Class for path: {} => {}", classSimpleName, basicPath);
final List<OrderedElement> orderedElements = new ArrayList<>();
for (final Method method : clazz.getDeclaredMethods()) {
final String methodName = method.getName();
orderedElements.add(new OrderedElement(methodName, method));
}
final Comparator<OrderedElement> comparator = Comparator.comparing(OrderedElement::methodName);
Collections.sort(orderedElements, comparator);
for (final OrderedElement orderedElement : orderedElements) {
final Method method = orderedElement.method();
final String methodName = orderedElement.methodName();
final String methodPath = ApiTool.apiAnnotationGetPath(method);
final String methodType = ApiTool.apiAnnotationGetTypeRequest(method);
if (methodType == null) {
LOGGER.error(" [{}] {} => {}/{} ==> No methode type @PATH, @GET ...", methodType, methodName,
basicPath, methodPath);
continue;
}
final String methodDescription = ApiTool.apiAnnotationGetOperationDescription(method);
final List<String> consumes = ApiTool.apiAnnotationGetConsumes(clazz, method);
List<String> produces = ApiTool.apiAnnotationProduces(clazz, method);
LOGGER.trace(" [{}] {} => {}/{}", methodType, methodName, basicPath, methodPath);
if (methodDescription != null) {
LOGGER.trace(" description: {}", methodDescription);
}
final boolean needGenerateProgress = ApiTool.apiAnnotationTypeScriptProgress(method);
Class<?>[] returnTypeModel = ApiTool.apiAnnotationGetAsyncType(method);
boolean isUnmanagedReturnType = false;
boolean returnModelIsArray = false;
List<ClassElement> tmpReturn;
if (returnTypeModel == null) {
Class<?> returnTypeModelRaw = method.getReturnType();
LOGGER.info("Get type: {}", returnTypeModelRaw);
if (returnTypeModelRaw == Response.class) {
LOGGER.info("Get type: {}", returnTypeModelRaw);
}
if (returnTypeModelRaw == Response.class || returnTypeModelRaw == void.class
|| returnTypeModelRaw == Void.class) {
if (returnTypeModelRaw == Response.class) {
isUnmanagedReturnType = true;
}
returnTypeModel = new Class<?>[] { Void.class };
tmpReturn = new ArrayList<>();
produces = null;
} else if (returnTypeModelRaw == Map.class) {
LOGGER.warn("Not manage the Map Model ... set any");
returnTypeModel = new Class<?>[] { Map.class };
tmpReturn = DataFactoryZod.createTables(returnTypeModel, previous);
} 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 if (returnTypeModel.length >= 0 && (returnTypeModel[0] == Response.class
|| returnTypeModel[0] == Void.class || returnTypeModel[0] == void.class)) {
if (returnTypeModel[0] == Response.class) {
isUnmanagedReturnType = true;
}
returnTypeModel = new Class<?>[] { Void.class };
tmpReturn = new ArrayList<>();
produces = null;
} else if (returnTypeModel.length > 0 && returnTypeModel[0] == Map.class) {
LOGGER.warn("Not manage the Map Model ...");
returnTypeModel = new Class<?>[] { Map.class };
tmpReturn = DataFactoryZod.createTables(returnTypeModel, previous);
} else {
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);
}
final Map<String, String> queryParams = new HashMap<>();
final Map<String, String> pathParams = new HashMap<>();
final Map<String, String> formDataParams = new HashMap<>();
final List<String> emptyElement = new ArrayList<>();
// LOGGER.info(" Parameters:");
for (final Parameter parameter : method.getParameters()) {
// Security context are internal parameter (not available from API)
if (ApiTool.apiAnnotationIsContext(parameter)) {
continue;
}
final Class<?> parameterType = parameter.getType();
String parameterTypeString;
final Class<?>[] asyncType = ApiTool.apiAnnotationGetAsyncType(parameter);
if (parameterType == List.class) {
if (asyncType == null) {
LOGGER.warn("Detect List param ==> not managed type ==> any[] !!!");
parameterTypeString = "any[]";
} else {
final List<ClassElement> tmp = DataFactoryZod.createTables(asyncType, previous);
for (final ClassElement elem : tmp) {
includeModel.add(elem.model[0]);
}
parameterTypeString = ApiTool.convertInTypeScriptType(tmp, true);
}
} else if (asyncType == null) {
final ClassElement tmp = DataFactoryZod.createTable(parameterType, previous);
includeModel.add(tmp.model[0]);
parameterTypeString = tmp.tsTypeName;
} else {
final List<ClassElement> tmp = DataFactoryZod.createTables(asyncType, previous);
for (final ClassElement elem : tmp) {
includeModel.add(elem.model[0]);
}
parameterTypeString = ApiTool.convertInTypeScriptType(tmp, true);
}
final String pathParam = ApiTool.apiAnnotationGetPathParam(parameter);
final String queryParam = ApiTool.apiAnnotationGetQueryParam(parameter);
final String formDataParam = ApiTool.apiAnnotationGetFormDataParam(parameter);
if (queryParam != null) {
queryParams.put(queryParam, parameterTypeString);
} else if (pathParam != null) {
pathParams.put(pathParam, parameterTypeString);
} else if (formDataParam != null) {
formDataParams.put(formDataParam, parameterTypeString);
} else if (asyncType != null) {
final List<ClassElement> tmp = DataFactoryZod.createTables(asyncType, previous);
parameterTypeString = "";
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) {
parameterTypeString = "any[]";
final Class<?> plop = parameterType.arrayType();
LOGGER.info("ArrayType = {}", plop);
emptyElement.add(parameterTypeString);
} else {
final ClassElement tmp = DataFactoryZod.createTable(parameterType, previous);
includeModel.add(tmp.model[0]);
emptyElement.add(tmp.tsTypeName);
}
}
if (!queryParams.isEmpty()) {
LOGGER.trace(" Query parameter:");
for (final Entry<String, String> queryEntry : queryParams.entrySet()) {
LOGGER.trace(" - {}: {}", queryEntry.getKey(), queryEntry.getValue());
}
}
if (!pathParams.isEmpty()) {
LOGGER.trace(" Path parameter:");
for (final Entry<String, String> pathEntry : pathParams.entrySet()) {
LOGGER.trace(" - {}: {}", pathEntry.getKey(), pathEntry.getValue());
}
}
if (emptyElement.size() > 1) {
LOGGER.error(" Fail to parse: Too much element in the model for the data ...");
continue;
} else if (emptyElement.size() == 1 && formDataParams.size() != 0) {
LOGGER.error(" Fail to parse: Incompatible form data & direct data ...");
continue;
} else if (emptyElement.size() == 1) {
LOGGER.trace(" data type: {}", emptyElement.get(0));
}
// ALL is good can generate the Elements
if (methodDescription != null) {
builder.append("\n\t/**\n\t * ");
builder.append(methodDescription);
builder.append("\n\t */");
}
if (isUnmanagedReturnType) {
builder.append(
"\n\t// TODO: unmanaged \"Response\" type: please specify @AsyncType or considered as 'void'.");
}
builder.append("\n\texport function ");
builder.append(methodName);
builder.append("({\n\t\t\trestConfig,");
if (!queryParams.isEmpty()) {
builder.append("\n\t\t\tqueries,");
}
if (!pathParams.isEmpty()) {
builder.append("\n\t\t\tparams,");
}
if (produces != null && produces.size() > 1) {
builder.append("\n\t\t\tproduce,");
}
if (emptyElement.size() == 1 || formDataParams.size() != 0) {
builder.append("\n\t\t\tdata,");
}
if (needGenerateProgress) {
builder.append("\n\t\t\tcallback,");
}
builder.append("\n\t\t}: {");
builder.append("\n\t\trestConfig: RESTConfig,");
if (!queryParams.isEmpty()) {
builder.append("\n\t\tqueries: {");
for (final Entry<String, String> queryEntry : queryParams.entrySet()) {
builder.append("\n\t\t\t");
builder.append(queryEntry.getKey());
builder.append("?: ");
builder.append(queryEntry.getValue());
builder.append(",");
}
builder.append("\n\t\t},");
}
if (!pathParams.isEmpty()) {
builder.append("\n\t\tparams: {");
for (final Entry<String, String> pathEntry : pathParams.entrySet()) {
builder.append("\n\t\t\t");
builder.append(pathEntry.getKey());
builder.append(": ");
builder.append(pathEntry.getValue());
builder.append(",");
}
builder.append("\n\t\t},");
}
if (emptyElement.size() == 1) {
builder.append("\n\t\tdata: ");
builder.append(emptyElement.get(0));
builder.append(",");
} else if (formDataParams.size() != 0) {
builder.append("\n\t\tdata: {");
for (final Entry<String, String> pathEntry : formDataParams.entrySet()) {
builder.append("\n\t\t\t");
builder.append(pathEntry.getKey());
builder.append(": ");
builder.append(pathEntry.getValue());
builder.append(",");
}
builder.append("\n\t\t},");
}
if (produces != null && produces.size() > 1) {
builder.append("\n\t\tproduce: ");
String isFist = null;
for (final String elem : produces) {
String lastElement = null;
if (MediaType.APPLICATION_JSON.equals(elem)) {
lastElement = "HTTPMimeType.JSON";
}
if (MediaType.MULTIPART_FORM_DATA.equals(elem)) {
lastElement = "HTTPMimeType.MULTIPART";
}
if (DataExport.CSV_TYPE.equals(elem)) {
lastElement = "HTTPMimeType.CSV";
}
if (lastElement != null) {
if (isFist == null) {
isFist = lastElement;
} else {
builder.append(" | ");
}
builder.append(lastElement);
} else {
LOGGER.error("Unmanaged model type: {}", elem);
}
}
builder.append(",");
}
if (needGenerateProgress) {
builder.append("\n\t\tcallback?: RESTCallbacks,");
}
builder.append("\n\t}): Promise<");
if (tmpReturn.size() == 0 //
|| tmpReturn.get(0).tsTypeName == null //
|| tmpReturn.get(0).tsTypeName.equals("void")) {
builder.append("void");
} else {
builder.append(ApiTool.convertInTypeScriptType(tmpReturn, returnModelIsArray));
}
builder.append("> {");
if (tmpReturn.size() == 0 //
|| tmpReturn.get(0).tsTypeName == null //
|| tmpReturn.get(0).tsTypeName.equals("void")) {
builder.append("\n\t\treturn RESTRequestVoid({");
} else if (returnModelIsArray) {
builder.append("\n\t\treturn RESTRequestJsonArray({");
} else {
builder.append("\n\t\treturn RESTRequestJson({");
}
builder.append("\n\t\t\trestModel: {");
builder.append("\n\t\t\t\tendPoint: \"");
builder.append(basicPath);
if (methodPath != null) {
builder.append("/");
builder.append(methodPath);
}
builder.append("\",");
builder.append("\n\t\t\t\trequestType: HTTPRequestModel.");
builder.append(methodType);
builder.append(",");
if (consumes != null) {
for (final String elem : consumes) {
if (MediaType.APPLICATION_JSON.equals(elem)) {
builder.append("\n\t\t\t\tcontentType: HTTPMimeType.JSON,");
break;
} else if (MediaType.MULTIPART_FORM_DATA.equals(elem)) {
builder.append("\n\t\t\t\tcontentType: HTTPMimeType.MULTIPART,");
break;
} else if (MediaType.TEXT_PLAIN.equals(elem)) {
builder.append("\n\t\t\t\tcontentType: HTTPMimeType.TEXT_PLAIN,");
break;
}
}
} else if ("DELETE".equals(methodType)) {
builder.append("\n\t\t\t\tcontentType: HTTPMimeType.TEXT_PLAIN,");
}
if (produces != null) {
if (produces.size() > 1) {
builder.append("\n\t\t\t\taccept: produce,");
} else {
for (final String elem : produces) {
if (MediaType.APPLICATION_JSON.equals(elem)) {
builder.append("\n\t\t\t\taccept: HTTPMimeType.JSON,");
break;
}
}
}
}
builder.append("\n\t\t\t},");
builder.append("\n\t\t\trestConfig,");
if (!pathParams.isEmpty()) {
builder.append("\n\t\t\tparams,");
}
if (!queryParams.isEmpty()) {
builder.append("\n\t\t\tqueries,");
}
if (emptyElement.size() == 1) {
builder.append("\n\t\t\tdata,");
} else if (formDataParams.size() != 0) {
builder.append("\n\t\t\tdata,");
}
if (needGenerateProgress) {
builder.append("\n\t\t\tcallback,");
}
builder.append("\n\t\t}");
if (tmpReturn.size() != 0 && tmpReturn.get(0).tsTypeName != null
&& !tmpReturn.get(0).tsTypeName.equals("void")) {
builder.append(", ");
// TODO: correct this it is really bad ...
builder.append(ApiTool.convertInTypeScriptCheckType(tmpReturn));
}
builder.append(");");
builder.append("\n\t};");
}
builder.append("\n}\n");
return new APIModel(builder.toString(), classSimpleName);
}
public static void generatePackage(
final List<Class<?>> classApi,
final List<Class<?>> classModel,
final String pathPackage) throws Exception {
final GeneratedTypes previous = DataFactoryZod.createBasicType();
DataFactoryZod.createTable(RestErrorResponse.class, previous);
final List<String> listApi = createApi(classApi, previous, pathPackage);
final String packageApi = DataFactoryZod.createTables(new ArrayList<>(classModel), previous);
FileWriter myWriter = new FileWriter(pathPackage + File.separator + "model.ts");
myWriter.write(packageApi.toString());
myWriter.close();
final StringBuilder index = new StringBuilder("""
/**
* Global import of the package
*/
export * from "./model";
""");
for (final String api : listApi) {
index.append("export * from \"./").append(api).append("\";\n");
}
myWriter = new FileWriter(pathPackage + File.separator + "index.ts");
myWriter.write(index.toString());
myWriter.close();
final InputStream ioStream = DataFactoryTsApi.class.getClassLoader().getResourceAsStream("rest-tools.ts");
if (ioStream == null) {
throw new IllegalArgumentException("rest-tools.ts is not found");
}
final BufferedReader buffer = new BufferedReader(new InputStreamReader(ioStream));
myWriter = new FileWriter(pathPackage + File.separator + "rest-tools.ts");
String line;
while ((line = buffer.readLine()) != null) {
myWriter.write(line);
myWriter.write("\n");
}
ioStream.close();
myWriter.close();
return;
}
}

View File

@@ -0,0 +1,471 @@
package org.kar.archidata.dataAccess;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.exception.DataAccessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.Response;
public class DataFactoryZod {
static final Logger LOGGER = LoggerFactory.getLogger(DataFactoryZod.class);
static public class ClassElement {
public Class<?>[] model;
public String zodName;
public String tsTypeName;
public String tsCheckType;
public String declaration;
public String comment = null;
public boolean isEnum = false;
public boolean nativeType;
public ClassElement(final Class<?> model[], final String zodName, final String tsTypeName,
final String tsCheckType, final String declaration, final boolean nativeType) {
this.model = model;
this.zodName = zodName;
this.tsTypeName = tsTypeName;
this.tsCheckType = tsCheckType;
this.declaration = declaration;
this.nativeType = nativeType;
}
public ClassElement(final Class<?> model) {
this(new Class<?>[] { model });
}
public ClassElement(final Class<?> model[]) {
this.model = model;
this.zodName = "Zod" + model[0].getSimpleName();
this.tsTypeName = model[0].getSimpleName();
this.tsCheckType = "is" + model[0].getSimpleName();
this.declaration = null;
this.nativeType = false;
}
}
public static class GeneratedTypes {
final List<ClassElement> previousGeneration = new ArrayList<>();
final List<Class<?>> order = new ArrayList<>();
public ClassElement find(final Class<?> clazz) {
for (final ClassElement elem : this.previousGeneration) {
for (final Class<?> elemClass : elem.model) {
if (elemClass == clazz) {
return elem;
}
}
}
return null;
}
public void add(final ClassElement elem) {
this.previousGeneration.add(elem);
}
public void add(final ClassElement elem, final boolean addOrder) {
this.previousGeneration.add(elem);
if (addOrder) {
this.order.add(elem.model[0]);
}
}
public void addOrder(final ClassElement elem) {
this.order.add(elem.model[0]);
}
}
public static ClassElement convertTypeZodEnum(final Class<?> clazz, final GeneratedTypes previous)
throws Exception {
final ClassElement element = new ClassElement(clazz);
previous.add(element);
final Object[] arr = clazz.getEnumConstants();
final StringBuilder out = new StringBuilder();
if (System.getenv("ARCHIDATA_GENERATE_ZOD_ENUM") != null) {
boolean first = true;
out.append("zod.enum([");
for (final Object elem : arr) {
if (!first) {
out.append(",\n\t");
} else {
out.append("\n\t");
first = false;
}
out.append("'");
out.append(elem.toString());
out.append("'");
}
if (first) {
out.append("]}");
} else {
out.append("\n\t])");
}
} else {
element.isEnum = true;
boolean first = true;
out.append("{");
for (final Object elem : arr) {
if (!first) {
out.append(",\n\t");
} else {
out.append("\n\t");
first = false;
}
out.append(elem.toString());
out.append(" = '");
out.append(elem.toString());
out.append("'");
}
if (first) {
out.append("}");
} else {
out.append(",\n\t}");
}
}
element.declaration = out.toString();
previous.addOrder(element);
return element;
}
public static String convertTypeZod(final Class<?> type, final GeneratedTypes previous) throws Exception {
final ClassElement previousType = previous.find(type);
if (previousType != null) {
return previousType.zodName;
}
if (type.isEnum()) {
return convertTypeZodEnum(type, previous).zodName;
}
if (type == List.class) {
throw new DataAccessException("Imcompatible type of element in object for: " + type.getCanonicalName()
+ " Unmanaged List of List ... ");
}
final ClassElement elemCreated = createTable(type, previous);
if (elemCreated != null) {
return elemCreated.zodName;
}
throw new DataAccessException("Imcompatible type of element in object for: " + type.getCanonicalName());
}
public static String convertTypeZod(final Field field, final GeneratedTypes previous) throws Exception {
final Class<?> type = field.getType();
final ClassElement previousType = previous.find(type);
if (previousType != null) {
return previousType.zodName;
}
if (type.isEnum()) {
return convertTypeZodEnum(type, previous).zodName;
}
if (type == List.class) {
final ParameterizedType listType = (ParameterizedType) field.getGenericType();
final Class<?> listClass = (Class<?>) listType.getActualTypeArguments()[0];
final String simpleSubType = convertTypeZod(listClass, previous);
return "zod.array(" + simpleSubType + ")";
}
final ClassElement elemCreated = createTable(type, previous);
if (elemCreated != null) {
return elemCreated.zodName;
}
throw new DataAccessException("Imcompatible type of element in object for: " + type.getCanonicalName());
}
public static String optionalTypeZod(final Class<?> type) throws Exception {
if (type.isPrimitive()) {
return "";
}
return ".optional()";
}
public static void createTablesSpecificType(
final Field elem,
final int fieldId,
final StringBuilder builder,
final GeneratedTypes previous) throws Exception {
final String name = elem.getName();
final Class<?> classModel = elem.getType();
final int limitSize = AnnotationTools.getLimitSize(elem);
final String comment = AnnotationTools.getComment(elem);
if (fieldId != 0) {
builder.append(",");
}
if (comment != null) {
builder.append("\n\t// ");
builder.append(comment);
}
builder.append("\n\t");
builder.append(name);
builder.append(": ");
builder.append(convertTypeZod(elem, previous));
if (limitSize > 0 && classModel == String.class) {
builder.append(".max(");
builder.append(limitSize);
builder.append(")");
}
if (AnnotationTools.getSchemaReadOnly(elem)) {
builder.append(".readonly()");
}
builder.append(optionalTypeZod(classModel));
}
private static boolean isFieldFromSuperClass(final Class<?> model, final String filedName) {
final Class<?> superClass = model.getSuperclass();
if (superClass == null) {
return false;
}
for (final Field field : superClass.getFields()) {
String name;
try {
name = AnnotationTools.getFieldName(field);
if (filedName.equals(name)) {
return true;
}
} catch (final Exception e) {
// TODO Auto-generated catch block
LOGGER.trace("Catch error field name in parent create data table: {}", e.getMessage());
}
}
return false;
}
public static GeneratedTypes createBasicType() throws Exception {
final GeneratedTypes previous = new GeneratedTypes();
previous.add(new ClassElement(new Class<?>[] { Void.class, void.class }, "void", "void", null, null, true));
// Map is binded to any ==> can not determine this complex model for now
previous.add(new ClassElement(new Class<?>[] { Map.class }, "any", "any", null, null, true));
previous.add(new ClassElement(new Class<?>[] { String.class }, "zod.string()", "string", null, "zod.string()",
true));
previous.add(new ClassElement(new Class<?>[] { InputStream.class, FormDataContentDisposition.class },
"z.instanceof(File)", "File", null, "z.instanceof(File)", true));
previous.add(new ClassElement(new Class<?>[] { Boolean.class, boolean.class }, "zod.boolean()", "boolean", null,
"zod.boolean()", true));
previous.add(new ClassElement(new Class<?>[] { UUID.class }, "ZodUUID", "UUID", "isUUID", "zod.string().uuid()",
false), true);
previous.add(new ClassElement(new Class<?>[] { Long.class, long.class }, "ZodLong", "Long", "isLong",
// "zod.bigint()",
"zod.number()", false), true);
previous.add(new ClassElement(new Class<?>[] { Integer.class, int.class }, "ZodInteger", "Integer", "isInteger",
"zod.number().safe()", false), true);
previous.add(new ClassElement(new Class<?>[] { Double.class, double.class }, "ZodDouble", "Double", "isDouble",
"zod.number()", true), true);
previous.add(new ClassElement(new Class<?>[] { Float.class, float.class }, "ZodFloat", "Float", "isFloat",
"zod.number()", false), true);
previous.add(new ClassElement(new Class<?>[] { Instant.class }, "ZodInstant", "Instant", "isInstant",
"zod.string()", false), true);
previous.add(new ClassElement(new Class<?>[] { Date.class }, "ZodDate", "Date", "isDate",
"zod.string().datetime({ precision: 3 })", false), true);
previous.add(new ClassElement(new Class<?>[] { Timestamp.class }, "ZodTimestamp", "Timestamp", "isTimestamp",
"zod.string().datetime({ precision: 3 })", false), true);
previous.add(new ClassElement(new Class<?>[] { LocalDate.class }, "ZodLocalDate", "LocalDate", "isLocalDate",
"zod.string().date()", false), true);
previous.add(new ClassElement(new Class<?>[] { LocalTime.class }, "ZodLocalTime", "LocalTime", "isLocalTime",
"zod.string().time()", false), true);
return previous;
}
/** Request the generation of the TypeScript file for the "Zod" export model
* @param classs List of class used in the model
* @return A string representing the Server models
* @throws Exception */
public static String createTables(final List<Class<?>> classs) throws Exception {
return createTables(classs, createBasicType());
}
public static String createTables(final List<Class<?>> classs, final GeneratedTypes previous) throws Exception {
for (final Class<?> clazz : classs) {
createTable(clazz, previous);
}
final StringBuilder generatedData = new StringBuilder();
generatedData.append("""
/**
* Interface of the server (auto-generated code)
*/
import { z as zod } from \"zod\";
""");
for (final Class<?> elem : previous.order) {
final ClassElement data = previous.find(elem);
if (!data.nativeType) {
if (data.comment != null) {
generatedData.append(data.comment);
}
generatedData.append(createDeclaration(data));
generatedData.append("\n\n");
}
}
LOGGER.info("generated: {}", 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 {
if (clazz == 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);
if (previous.find(clazz) != null) {
return alreadyExist;
}
if (clazz.isPrimitive()) {
return null;
}
if (clazz.isEnum()) {
return convertTypeZodEnum(clazz, previous);
}
// add the current class to prevent multiple creation
final ClassElement curentElementClass = new ClassElement(clazz);
previous.add(curentElementClass);
// Local generation of class:
final StringBuilder internalBuilder = new StringBuilder();
final List<String> alreadyAdded = new ArrayList<>();
LOGGER.trace("parse class: '{}'", clazz.getCanonicalName());
int fieldId = 0;
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
final String dataName = elem.getName();
if (isFieldFromSuperClass(clazz, dataName)) {
LOGGER.trace(" SKIP: '{}'", elem.getName());
continue;
}
if (alreadyAdded.contains(dataName)) {
LOGGER.trace(" SKIP2: '{}'", elem.getName());
continue;
}
alreadyAdded.add(dataName);
LOGGER.trace(" + '{}'", elem.getName());
if (false && DataAccess.isAddOnField(elem)) {
final DataAccessAddOn addOn = DataAccess.findAddOnforField(elem);
LOGGER.error("Create type for: {} ==> {} (ADD-ON) ==> Not managed now ....",
AnnotationTools.getFieldName(elem), elem.getType());
/* LOGGER.trace("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType()); if (addOn != null) { addOn.createTables(tableName, elem, tmpOut,
* preActionList, postActionList, createIfNotExist, createDrop, fieldId); } else { throw new DataAccessException( "Element matked as add-on but add-on does not loaded: table:" +
* tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType()); } fieldId++; */
} else {
LOGGER.trace("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType());
DataFactoryZod.createTablesSpecificType(elem, fieldId, internalBuilder, previous);
fieldId++;
}
}
final String description = AnnotationTools.getSchemaDescription(clazz);
final String example = AnnotationTools.getSchemaExample(clazz);
final StringBuilder generatedCommentedData = new StringBuilder();
if (description != null || example != null) {
generatedCommentedData.append("/**\n");
if (description != null) {
for (final String elem : description.split("\n")) {
generatedCommentedData.append(" * ");
generatedCommentedData.append(elem);
generatedCommentedData.append("\n");
}
}
if (example != null) {
generatedCommentedData.append(" * Example:\n");
generatedCommentedData.append(" * ```\n");
for (final String elem : example.split("\n")) {
generatedCommentedData.append(" * ");
generatedCommentedData.append(elem);
generatedCommentedData.append("\n");
}
generatedCommentedData.append(" * ```\n");
}
generatedCommentedData.append(" */\n");
}
curentElementClass.comment = generatedCommentedData.toString();
final StringBuilder generatedData = new StringBuilder();
final Class<?> parentClass = clazz.getSuperclass();
if (parentClass != null && parentClass != Object.class && parentClass != Record.class) {
final ClassElement parentDeclaration = createTable(parentClass, previous);
generatedData.append(parentDeclaration.zodName);
generatedData.append(".extend({");
} else {
generatedData.append("zod.object({");
}
generatedData.append(internalBuilder.toString());
generatedData.append("\n})");
// Remove the previous to reorder the map ==> parent must be inserted before us.
curentElementClass.declaration = generatedData.toString();
previous.addOrder(curentElementClass);
return curentElementClass;
}
public static String createDeclaration(final ClassElement elem) {
final StringBuilder generatedData = new StringBuilder();
if (elem.isEnum) {
generatedData.append("export enum ");
generatedData.append(elem.tsTypeName);
generatedData.append(" ");
generatedData.append(elem.declaration);
generatedData.append(";");
generatedData.append("\nexport const ");
generatedData.append(elem.zodName);
generatedData.append(" = zod.nativeEnum(");
generatedData.append(elem.tsTypeName);
generatedData.append(");");
} else {
generatedData.append("export const ");
generatedData.append(elem.zodName);
generatedData.append(" = ");
generatedData.append(elem.declaration);
generatedData.append(";");
generatedData.append("\nexport type ");
generatedData.append(elem.tsTypeName);
generatedData.append(" = zod.infer<typeof ");
generatedData.append(elem.zodName);
generatedData.append(">;");
}
// declare generic isXXX:
generatedData.append("\nexport function ");
generatedData.append(elem.tsCheckType);
generatedData.append("(data: any): data is ");
generatedData.append(elem.tsTypeName);
generatedData.append(" {\n\ttry {\n\t\t");
generatedData.append(elem.zodName);
generatedData.append("""
.parse(data);
return true;
} catch (e: any) {
console.log(`Fail to parse data ${e}`);
return false;
}
}
""");
return generatedData.toString();
}
}

View File

@@ -1,6 +1,7 @@
package org.kar.archidata.dataAccess; package org.kar.archidata.dataAccess;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.kar.archidata.dataAccess.options.AccessDeletedItems; import org.kar.archidata.dataAccess.options.AccessDeletedItems;
@@ -24,16 +25,10 @@ public class QueryOptions {
if (elems == null || elems.length == 0) { if (elems == null || elems.length == 0) {
return; return;
} }
for (final QueryOption elem : elems) { Collections.addAll(this.options, elems);
add(elem);
}
} }
public void add(final QueryOption option) { public void add(final QueryOption option) {
if (option == null) {
return;
}
this.options.add(option); this.options.add(option);
} }

View File

@@ -3,7 +3,6 @@ package org.kar.archidata.dataAccess.options;
import java.util.List; import java.util.List;
import org.kar.archidata.annotation.AnnotationTools; import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.dataAccess.QueryOptions;
/** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */ /** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */
public interface CheckFunctionInterface { public interface CheckFunctionInterface {
@@ -12,11 +11,10 @@ public interface CheckFunctionInterface {
* @param data The object that might be injected. * @param data The object that might be injected.
* @param filterValue List of fields that might be check. If null, then all column must be checked. * @param filterValue List of fields that might be check. If null, then all column must be checked.
* @throws Exception Exception is generate if the data are incorrect. */ * @throws Exception Exception is generate if the data are incorrect. */
void check(final String baseName, Object data, List<String> filterValue, final QueryOptions options) void check(final String baseName, Object data, List<String> filterValue) throws Exception;
throws Exception;
default void checkAll(final String baseName, final Object data, final QueryOptions options) throws Exception { default void checkAll(final String baseName, final Object data) throws Exception {
check(baseName, data, AnnotationTools.getAllFieldsNames(data.getClass()), options); check(baseName, data, AnnotationTools.getAllFieldsNames(data.getClass()));
} }
} }

View File

@@ -2,16 +2,10 @@ package org.kar.archidata.dataAccess.options;
import java.util.List; import java.util.List;
import org.kar.archidata.dataAccess.QueryOptions;
/** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */ /** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */
public class CheckFunctionVoid implements CheckFunctionInterface { public class CheckFunctionVoid implements CheckFunctionInterface {
@Override @Override
public void check( public void check(final String baseName, Object data, List<String> filterValue) {
final String baseName,
final Object data,
final List<String> filterValue,
final QueryOptions options) {
} }

View File

@@ -16,7 +16,6 @@ import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.DataJson; import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.DataAccess; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.QueryCondition; import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.exception.DataAccessException; import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.exception.InputException; import org.kar.archidata.exception.InputException;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -38,7 +37,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
* @param data The object that might be injected. * @param data The object that might be injected.
* @param filterValue List of fields that might be check. If null, then all column must be checked. * @param filterValue List of fields that might be check. If null, then all column must be checked.
* @throws Exception Exception is generate if the data are incorrect. */ * @throws Exception Exception is generate if the data are incorrect. */
void check(final String baseName, final K data, final QueryOptions options) throws Exception; void check(final String baseName, final K data) throws Exception;
} }
protected Map<String, List<CheckInterface<T>>> checking = null; protected Map<String, List<CheckInterface<T>>> checking = null;
@@ -67,20 +66,20 @@ public class CheckJPA<T> implements CheckFunctionInterface {
for (final Field field : this.clazz.getFields()) { for (final Field field : this.clazz.getFields()) {
final String fieldName = field.getName(); // AnnotationTools.getFieldName(field); final String fieldName = field.getName(); // AnnotationTools.getFieldName(field);
if (AnnotationTools.isPrimaryKey(field)) { if (AnnotationTools.isPrimaryKey(field)) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
throw new InputException(baseName + fieldName, throw new InputException(baseName + fieldName,
"This is a '@Id' (primaryKey) ==> can not be change"); "This is a '@Id' (primaryKey) ==> can not be change");
}); });
} }
if (AnnotationTools.getConstraintsNotNull(field)) { if (AnnotationTools.getConstraintsNotNull(field)) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
if (field.get(data) == null) { if (field.get(data) == null) {
throw new InputException(baseName + fieldName, "Can not be null"); throw new InputException(baseName + fieldName, "Can not be null");
} }
}); });
} }
if (AnnotationTools.isCreatedAtField(field) || AnnotationTools.isUpdateAtField(field)) { if (AnnotationTools.isCreatedAtField(field) || AnnotationTools.isUpdateAtField(field)) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
throw new InputException(baseName + fieldName, "It is forbidden to change this field"); throw new InputException(baseName + fieldName, "It is forbidden to change this field");
}); });
} }
@@ -89,7 +88,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
if (type == Long.class || type == long.class) { if (type == Long.class || type == long.class) {
final Long maxValue = AnnotationTools.getConstraintsMax(field); final Long maxValue = AnnotationTools.getConstraintsMax(field);
if (maxValue != null) { if (maxValue != null) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -102,7 +101,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
final Long minValue = AnnotationTools.getConstraintsMin(field); final Long minValue = AnnotationTools.getConstraintsMin(field);
if (minValue != null) { if (minValue != null) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -115,19 +114,12 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
} }
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class); final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
long count = 0;
if (condCheckers.isEmpty()) {
count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
} else {
count = DataAccess.count(annotationManyToOne.targetEntity(), elem,
condCheckers.get(0).toCondition());
}
if (count == 0) { if (count == 0) {
throw new InputException(baseName + fieldName, throw new InputException(baseName + fieldName,
"Foreign element does not exist in the DB:" + elem); "Foreign element does not exist in the DB:" + elem);
@@ -139,7 +131,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
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();
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -153,7 +145,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
final Long minValueRoot = AnnotationTools.getConstraintsMin(field); final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) { if (minValueRoot != null) {
final int minValue = minValueRoot.intValue(); final int minValue = minValueRoot.intValue();
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -166,7 +158,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -181,7 +173,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} else if (type == UUID.class) { } else if (type == UUID.class) {
final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field); final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) { if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -199,7 +191,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) { if (maxValueRoot != null) {
final float maxValue = maxValueRoot.floatValue(); final float maxValue = maxValueRoot.floatValue();
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -213,7 +205,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
final Long minValueRoot = AnnotationTools.getConstraintsMin(field); final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) { if (minValueRoot != null) {
final float minValue = minValueRoot.floatValue(); final float minValue = minValueRoot.floatValue();
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -228,7 +220,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
final Long maxValueRoot = AnnotationTools.getConstraintsMax(field); final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
if (maxValueRoot != null) { if (maxValueRoot != null) {
final double maxValue = maxValueRoot.doubleValue(); final double maxValue = maxValueRoot.doubleValue();
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -242,7 +234,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
final Long minValueRoot = AnnotationTools.getConstraintsMin(field); final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
if (minValueRoot != null) { if (minValueRoot != null) {
final double minValue = minValueRoot.doubleValue(); final double minValue = minValueRoot.doubleValue();
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -262,7 +254,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} else if (type == String.class) { } else if (type == String.class) {
final int maxSizeString = AnnotationTools.getLimitSize(field); final int maxSizeString = AnnotationTools.getLimitSize(field);
if (maxSizeString > 0) { if (maxSizeString > 0) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -276,7 +268,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
final Size limitSize = AnnotationTools.getConstraintsSize(field); final Size limitSize = AnnotationTools.getConstraintsSize(field);
if (limitSize != null) { if (limitSize != null) {
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -288,14 +280,14 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
if (elemTyped.length() < limitSize.min()) { if (elemTyped.length() < limitSize.min()) {
throw new InputException(baseName + fieldName, throw new InputException(baseName + fieldName,
"Too small size (constraints) must be >= " + limitSize.min()); "Too small size (constraints) must be >= " + limitSize.max());
} }
}); });
} }
final String patternString = AnnotationTools.getConstraintsPattern(field); final String patternString = AnnotationTools.getConstraintsPattern(field);
if (patternString != null) { if (patternString != null) {
final Pattern pattern = Pattern.compile(patternString); final Pattern pattern = Pattern.compile(patternString);
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final Object elem = field.get(data); final Object elem = field.get(data);
if (elem == null) { if (elem == null) {
return; return;
@@ -314,8 +306,8 @@ public class CheckJPA<T> implements CheckFunctionInterface {
// Here if we have an error it crash at start and no new instance after creation... // Here if we have an error it crash at start and no new instance after creation...
final CheckFunctionInterface instance = jsonAnnotation.checker().getDeclaredConstructor() final CheckFunctionInterface instance = jsonAnnotation.checker().getDeclaredConstructor()
.newInstance(); .newInstance();
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
instance.checkAll(baseName + fieldName + ".", field.get(data), options); instance.checkAll(baseName + fieldName + ".", field.get(data));
}); });
} }
} else if (type.isEnum()) { } else if (type.isEnum()) {
@@ -324,17 +316,9 @@ public class CheckJPA<T> implements CheckFunctionInterface {
// keep this is last ==> take more time... // keep this is last ==> take more time...
if (AnnotationTools.isUnique(field)) { if (AnnotationTools.isUnique(field)) {
// Create the request ... // Create the request ...
add(fieldName, (final String baseName, final T data, final QueryOptions options) -> { add(fieldName, (final String baseName, final T data) -> {
final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class); final Object other = DataAccess.getWhere(this.clazz,
Object other = null;
if (condCheckers.isEmpty()) {
other = DataAccess.getWhere(this.clazz,
new Condition(new QueryCondition(fieldName, "==", field.get(data)))); new Condition(new QueryCondition(fieldName, "==", field.get(data))));
} else {
other = DataAccess.getWhere(this.clazz,
new Condition(new QueryCondition(fieldName, "==", field.get(data))),
condCheckers.get(0).toCondition());
}
if (other != null) { if (other != null) {
throw new InputException(baseName + fieldName, "Name already exist in the DB"); throw new InputException(baseName + fieldName, "Name already exist in the DB");
} }
@@ -349,11 +333,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
} }
@Override @Override
public void check( public void check(final String baseName, final Object data, final List<String> filterValue) throws Exception {
final String baseName,
final Object data,
final List<String> filterValue,
final QueryOptions options) throws Exception {
if (this.checking == null) { if (this.checking == null) {
initialize(); initialize();
} }
@@ -368,13 +348,13 @@ public class CheckJPA<T> implements CheckFunctionInterface {
continue; continue;
} }
for (final CheckInterface<T> action : actions) { for (final CheckInterface<T> action : actions) {
action.check(baseName, dataCasted, options); action.check(baseName, dataCasted);
} }
} }
checkTyped(dataCasted, filterValue, options); checkTyped(dataCasted, filterValue);
} }
public void checkTyped(final T data, final List<String> filterValue, final QueryOptions options) throws Exception { public void checkTyped(final T data, final List<String> filterValue) throws Exception {
// nothing to do ... // nothing to do ...
} }
} }

View File

@@ -1,21 +0,0 @@
package org.kar.archidata.dataAccess.options;
import org.kar.archidata.dataAccess.QueryItem;
/** Condition model apply to the check models. */
public class ConditionChecker extends QueryOption {
public final QueryItem condition;
public ConditionChecker(final QueryItem items) {
this.condition = items;
}
public ConditionChecker() {
this.condition = null;
}
public Condition toCondition() {
return new Condition(this.condition);
}
}

View File

@@ -55,7 +55,7 @@ public class TsApiGeneration {
if (tsModel.nativeType != DefinedPosition.NATIVE) { if (tsModel.nativeType != DefinedPosition.NATIVE) {
imports.add(model); imports.add(model);
} }
if (tsModel.nativeType != DefinedPosition.NORMAL) { if (tsModel.nativeType == DefinedPosition.BASIC) {
return tsModel.tsTypeName; return tsModel.tsTypeName;
} }
if (writeMode) { if (writeMode) {
@@ -348,11 +348,11 @@ public class TsApiGeneration {
data.append(", is"); data.append(", is");
data.append(returnModelNameIfComplex); data.append(returnModelNameIfComplex);
} else { } else {
final TsClassElement retType = tsGroup.find(interfaceElement.returnTypes.get(0)); final String returnType = generateClassModelsTypescript(interfaceElement.returnTypes, tsGroup, imports,
if (retType.tsCheckType != null) { false);
data.append(", "); if (!"void".equals(returnType)) {
data.append(retType.tsCheckType); data.append(", is");
imports.add(interfaceElement.returnTypes.get(0)); data.append(returnType);
} }
} }
data.append(");"); data.append(");");
@@ -393,9 +393,7 @@ public class TsApiGeneration {
if (tsModel.nativeType == DefinedPosition.NATIVE) { if (tsModel.nativeType == DefinedPosition.NATIVE) {
continue; continue;
} }
if (tsModel.tsCheckType != null) { finalImportList.add("is" + tsModel.tsTypeName);
finalImportList.add(tsModel.tsCheckType);
}
} }
for (final ClassModel model : zodImports) { for (final ClassModel model : zodImports) {
final TsClassElement tsModel = tsGroup.find(model); final TsClassElement tsModel = tsGroup.find(model);

View File

@@ -7,7 +7,6 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import org.kar.archidata.externalRestApi.model.ClassEnumModel; import org.kar.archidata.externalRestApi.model.ClassEnumModel;
import org.kar.archidata.externalRestApi.model.ClassListModel; import org.kar.archidata.externalRestApi.model.ClassListModel;
@@ -86,7 +85,7 @@ public class TsClassElement {
out.append(this.tsTypeName); out.append(this.tsTypeName);
out.append(" = "); out.append(" = ");
out.append("zod.enum(["); out.append("zod.enum([");
for (final Entry<String, Object> elem : model.getListOfValues().entrySet()) { for (final String elem : model.getListOfValues()) {
if (!first) { if (!first) {
out.append(",\n\t"); out.append(",\n\t");
} else { } else {
@@ -94,7 +93,7 @@ public class TsClassElement {
first = false; first = false;
} }
out.append("'"); out.append("'");
out.append(elem.getKey()); out.append(elem);
out.append("'"); out.append("'");
} }
if (first) { if (first) {
@@ -109,22 +108,17 @@ public class TsClassElement {
out.append("export enum "); out.append("export enum ");
out.append(this.tsTypeName); out.append(this.tsTypeName);
out.append(" {"); out.append(" {");
for (final Entry<String, Object> elem : model.getListOfValues().entrySet()) { for (final String elem : model.getListOfValues()) {
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;
} }
out.append(elem.getKey()); out.append(elem);
out.append(" = "); out.append(" = '");
if (elem.getValue() instanceof final Integer value) { out.append(elem);
out.append(value);
} else {
out.append("'"); out.append("'");
out.append(elem.getValue());
out.append("'");
}
} }
if (first) { if (first) {
out.append("}"); out.append("}");
@@ -216,18 +210,10 @@ public class TsClassElement {
} }
public String optionalTypeZod(final FieldProperty field) { public String optionalTypeZod(final FieldProperty field) {
// Common checking element (apply to List, Map, ...)
if (field.nullable()) {
return ".optional()";
}
if (field.notNull()) {
return "";
}
// Other object:
if (field.model().getOriginClasses() == null || field.model().getOriginClasses().isPrimitive()) { if (field.model().getOriginClasses() == null || field.model().getOriginClasses().isPrimitive()) {
return ""; return "";
} }
if (field.columnNotNull()) { if (field.notNull()) {
return ""; return "";
} }
return ".optional()"; return ".optional()";

View File

@@ -17,9 +17,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.glassfish.jersey.media.multipart.ContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.kar.archidata.catcher.RestErrorResponse; import org.kar.archidata.catcher.RestErrorResponse;
import org.kar.archidata.dataAccess.DataFactoryTsApi;
import org.kar.archidata.externalRestApi.TsClassElement.DefinedPosition; import org.kar.archidata.externalRestApi.TsClassElement.DefinedPosition;
import org.kar.archidata.externalRestApi.model.ApiGroupModel; import org.kar.archidata.externalRestApi.model.ApiGroupModel;
import org.kar.archidata.externalRestApi.model.ClassModel; import org.kar.archidata.externalRestApi.model.ClassModel;
@@ -130,8 +129,7 @@ public class TsGenerateApi {
tsModels.add( tsModels.add(
new TsClassElement(models, "zod.string()", "string", null, "zod.string()", DefinedPosition.NATIVE)); new TsClassElement(models, "zod.string()", "string", null, "zod.string()", DefinedPosition.NATIVE));
} }
models = api.getCompatibleModels( models = api.getCompatibleModels(List.of(InputStream.class));
List.of(InputStream.class, FormDataContentDisposition.class, ContentDisposition.class));
if (models != null) { if (models != null) {
tsModels.add(new TsClassElement(models, "z.instanceof(File)", "File", null, "z.instanceof(File)", tsModels.add(new TsClassElement(models, "z.instanceof(File)", "File", null, "z.instanceof(File)",
DefinedPosition.NATIVE)); DefinedPosition.NATIVE));
@@ -216,7 +214,7 @@ public class TsGenerateApi {
} }
public static void copyResourceFile(final String name, final String destinationPath) throws IOException { public static void copyResourceFile(final String name, final String destinationPath) throws IOException {
final InputStream ioStream = TsGenerateApi.class.getClassLoader().getResourceAsStream(name); final InputStream ioStream = DataFactoryTsApi.class.getClassLoader().getResourceAsStream(name);
if (ioStream == null) { if (ioStream == null) {
throw new IllegalArgumentException("rest-tools.ts is not found"); throw new IllegalArgumentException("rest-tools.ts is not found");
} }

View File

@@ -129,8 +129,7 @@ public class ApiModel {
final Class<?>[] asyncType = ApiTool.apiAnnotationGetAsyncType(parameter); final Class<?>[] asyncType = ApiTool.apiAnnotationGetAsyncType(parameter);
if (asyncType != null) { if (asyncType != null) {
for (final Class<?> elem : asyncType) { for (final Class<?> elem : asyncType) {
final ClassModel modelGenerated = ClassModel.getModel(elem, previousModel); parameterModel.add(new ClassListModel(elem, previousModel));
parameterModel.add(modelGenerated);
} }
} else if (parameterType == List.class) { } else if (parameterType == List.class) {
final Type parameterrizedType = parameter.getParameterizedType(); final Type parameterrizedType = parameter.getParameterizedType();
@@ -148,17 +147,11 @@ public class ApiModel {
final String queryParam = ApiTool.apiAnnotationGetQueryParam(parameter); final String queryParam = ApiTool.apiAnnotationGetQueryParam(parameter);
final String formDataParam = ApiTool.apiAnnotationGetFormDataParam(parameter); final String formDataParam = ApiTool.apiAnnotationGetFormDataParam(parameter);
if (queryParam != null) { if (queryParam != null) {
if (!this.queries.containsKey(queryParam)) {
this.queries.put(queryParam, parameterModel); this.queries.put(queryParam, parameterModel);
}
} else if (pathParam != null) { } else if (pathParam != null) {
if (!this.parameters.containsKey(pathParam)) {
this.parameters.put(pathParam, parameterModel); this.parameters.put(pathParam, parameterModel);
}
} else if (formDataParam != null) { } else if (formDataParam != null) {
if (!this.multiPartParameters.containsKey(formDataParam)) {
this.multiPartParameters.put(formDataParam, parameterModel); this.multiPartParameters.put(formDataParam, parameterModel);
}
} else { } else {
this.unnamedElement.addAll(parameterModel); this.unnamedElement.addAll(parameterModel);
} }

View File

@@ -9,6 +9,7 @@ import java.util.List;
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.annotation.TypeScriptProgress;
import org.kar.archidata.dataAccess.DataFactoryZod.ClassElement;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
@@ -205,4 +206,28 @@ public class ApiTool {
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;
}
} }

View File

@@ -1,9 +1,8 @@
package org.kar.archidata.externalRestApi.model; package org.kar.archidata.externalRestApi.model;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.util.ArrayList;
import java.util.HashMap; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
public class ClassEnumModel extends ClassModel { public class ClassEnumModel extends ClassModel {
@@ -21,7 +20,7 @@ public class ClassEnumModel extends ClassModel {
return out.toString(); return out.toString();
} }
final Map<String, Object> listOfValues = new HashMap<>(); final List<String> listOfValues = new ArrayList<>();
@Override @Override
public void analyze(final ModelGroup group) throws IOException { public void analyze(final ModelGroup group) throws IOException {
@@ -29,28 +28,16 @@ public class ClassEnumModel extends ClassModel {
return; return;
} }
this.analyzeDone = true; this.analyzeDone = true;
// TODO: check if we really need to have multiple type for enums ???
// TODO: manage enum with int, String and bitField ...
final Class<?> clazz = this.originClasses; final Class<?> clazz = this.originClasses;
final Object[] constants = clazz.getEnumConstants(); final Object[] arr = clazz.getEnumConstants();
for (final Object elem : arr) {
// Try to get a get Value element to serialize: this.listOfValues.add(elem.toString());
try {
final Method getValueMethod = clazz.getMethod("getValue");
for (final Object constant : constants) {
final String name = constant.toString();
final Object value = getValueMethod.invoke(constant);
this.listOfValues.put(name, value);
}
return;
} catch (final Exception e) {
//e.printStackTrace();
}
for (final Object elem : constants) {
this.listOfValues.put(elem.toString(), elem.toString());
} }
} }
public Map<String, Object> getListOfValues() { public List<String> getListOfValues() {
return this.listOfValues; return this.listOfValues;
} }

View File

@@ -54,20 +54,18 @@ public class ClassObjectModel extends ClassModel {
ClassModel model, ClassModel model,
String comment, String comment,
int limitSize, int limitSize,
Boolean readOnly, boolean readOnly,
Boolean notNull, boolean notNull,
Boolean columnNotNull, boolean nullable) {
Boolean nullable) {
public FieldProperty(final String name, final ClassModel model, final String comment, final int limitSize, public FieldProperty(final String name, final ClassModel model, final String comment, final int limitSize,
final Boolean readOnly, final Boolean notNull, final Boolean columnNotNull, final Boolean nullable) { final boolean readOnly, final boolean notNull, final boolean nullable) {
this.name = name; this.name = name;
this.model = model; this.model = model;
this.comment = comment; this.comment = comment;
this.limitSize = limitSize; this.limitSize = limitSize;
this.readOnly = readOnly; this.readOnly = readOnly;
this.notNull = notNull; this.notNull = notNull;
this.columnNotNull = columnNotNull;
this.nullable = nullable; this.nullable = nullable;
} }
@@ -79,8 +77,7 @@ public class ClassObjectModel extends ClassModel {
AnnotationTools.getLimitSize(field), // AnnotationTools.getLimitSize(field), //
AnnotationTools.getSchemaReadOnly(field), // AnnotationTools.getSchemaReadOnly(field), //
AnnotationTools.getConstraintsNotNull(field), // AnnotationTools.getConstraintsNotNull(field), //
AnnotationTools.getColumnNotNull(field), // AnnotationTools.getColumnNotNull(field));
AnnotationTools.getNullable(field));
} }
} }

View File

@@ -4,7 +4,6 @@ import org.kar.archidata.annotation.DataDeleted;
import org.kar.archidata.annotation.DataNotRead; import org.kar.archidata.annotation.DataNotRead;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.DefaultValue;
@@ -14,6 +13,5 @@ public class GenericDataSoftDelete extends GenericData {
@DefaultValue("'0'") @DefaultValue("'0'")
@DataDeleted @DataDeleted
@Schema(description = "Deleted state", hidden = true, required = false, readOnly = true) @Schema(description = "Deleted state", hidden = true, required = false, readOnly = true)
@Nullable
public Boolean deleted = null; public Boolean deleted = null;
} }

View File

@@ -9,7 +9,6 @@ import org.kar.archidata.annotation.UpdateTimestamp;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import jakarta.persistence.Column; import jakarta.persistence.Column;
public class GenericTiming { public class GenericTiming {
@@ -18,7 +17,6 @@ public class GenericTiming {
@Column(nullable = false) @Column(nullable = false)
@Schema(description = "Create time of the object", required = false, example = "2000-01-23T01:23:45.678+01:00", readOnly = true) @Schema(description = "Create time of the object", required = false, example = "2000-01-23T01:23:45.678+01:00", readOnly = true)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
@Nullable
public Date createdAt = null; public Date createdAt = null;
@DataNotRead @DataNotRead
@UpdateTimestamp @UpdateTimestamp
@@ -26,6 +24,5 @@ public class GenericTiming {
@Schema(description = "When update the object", required = false, example = "2000-01-23T00:23:45.678Z", readOnly = true) @Schema(description = "When update the object", required = false, example = "2000-01-23T00:23:45.678Z", readOnly = true)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
// public Instant updatedAt = null; // public Instant updatedAt = null;
@Nullable
public Date updatedAt = null; public Date updatedAt = null;
} }

View File

@@ -4,7 +4,6 @@ import org.kar.archidata.annotation.DataDeleted;
import org.kar.archidata.annotation.DataNotRead; import org.kar.archidata.annotation.DataNotRead;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.DefaultValue;
@@ -14,6 +13,5 @@ public class UUIDGenericDataSoftDelete extends UUIDGenericData {
@DefaultValue("'0'") @DefaultValue("'0'")
@DataDeleted @DataDeleted
@Schema(description = "Deleted state", hidden = true, required = false, readOnly = true) @Schema(description = "Deleted state", hidden = true, required = false, readOnly = true)
@Nullable
public Boolean deleted = null; public Boolean deleted = null;
} }

View File

@@ -4,25 +4,25 @@
* @license MPL-2 * @license MPL-2
*/ */
import { RestErrorResponse } from "./model"; import { RestErrorResponse } from "./model"
export enum HTTPRequestModel { export enum HTTPRequestModel {
DELETE = "DELETE", DELETE = 'DELETE',
GET = "GET", GET = 'GET',
PATCH = "PATCH", PATCH = 'PATCH',
POST = "POST", POST = 'POST',
PUT = "PUT", PUT = 'PUT',
} }
export enum HTTPMimeType { export enum HTTPMimeType {
ALL = "*/*", ALL = '*/*',
CSV = "text/csv", CSV = 'text/csv',
IMAGE = "image/*", IMAGE = 'image/*',
IMAGE_JPEG = "image/jpeg", IMAGE_JPEG = 'image/jpeg',
IMAGE_PNG = "image/png", IMAGE_PNG = 'image/png',
JSON = "application/json", JSON = 'application/json',
MULTIPART = "multipart/form-data", MULTIPART = 'multipart/form-data',
OCTET_STREAM = "application/octet-stream", OCTET_STREAM = 'application/octet-stream',
TEXT_PLAIN = "text/plain", TEXT_PLAIN = 'text/plain',
} }
export interface RESTConfig { export interface RESTConfig {
@@ -58,24 +58,25 @@ function isNullOrUndefined(data: any): data is undefined | null {
export type ProgressCallback = (count: number, total: number) => void; export type ProgressCallback = (count: number, total: number) => void;
export interface RESTAbort { export interface RESTAbort {
abort?: () => boolean; abort?: () => boolean
} }
// Rest generic callback have a basic model to upload and download advancement. // Rest generic callback have a basic model to upload and download advancement.
export interface RESTCallbacks { export interface RESTCallbacks {
progressUpload?: ProgressCallback; progressUpload?: ProgressCallback,
progressDownload?: ProgressCallback; progressDownload?: ProgressCallback,
abortHandle?: RESTAbort; abortHandle?: RESTAbort,
} };
export interface RESTRequestType { 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; callback?: RESTCallbacks,
} };
function replaceAll(input, searchValue, replaceValue) { function replaceAll(input, searchValue, replaceValue) {
return input.split(searchValue).join(replaceValue); return input.split(searchValue).join(replaceValue);
@@ -85,34 +86,24 @@ function removeTrailingSlashes(input: string): string {
if (isNullOrUndefined(input)) { if (isNullOrUndefined(input)) {
return "undefined"; return "undefined";
} }
return input.replace(/\/+$/, ""); return input.replace(/\/+$/, '');
} }
function removeLeadingSlashes(input: string): string { function removeLeadingSlashes(input: string): string {
if (isNullOrUndefined(input)) { if (isNullOrUndefined(input)) {
return ""; return "";
} }
return input.replace(/^\/+/, ""); return input.replace(/^\/+/, '');
} }
export function RESTUrl({ export function RESTUrl({ restModel, restConfig, params, queries }: RESTRequestType): string {
restModel,
restConfig,
params,
queries,
}: RESTRequestType): string {
// Create the URL PATH: // Create the URL PATH:
let generateUrl = `${removeTrailingSlashes( let generateUrl = `${removeTrailingSlashes(restConfig.server)}/${removeLeadingSlashes(restModel.endPoint)}`;
restConfig.server
)}/${removeLeadingSlashes(restModel.endPoint)}`;
if (params !== undefined) { if (params !== undefined) {
for (let key of Object.keys(params)) { for (let key of Object.keys(params)) {
generateUrl = replaceAll(generateUrl, `{${key}}`, `${params[key]}`); generateUrl = replaceAll(generateUrl, `{${key}}`, `${params[key]}`);
} }
} }
if ( if (queries === undefined && (restConfig.token === undefined || restModel.tokenInUrl !== true)) {
queries === undefined &&
(restConfig.token === undefined || restModel.tokenInUrl !== true)
) {
return generateUrl; return generateUrl;
} }
const searchParams = new URLSearchParams(); const searchParams = new URLSearchParams();
@@ -120,8 +111,8 @@ export function RESTUrl({
for (let key of Object.keys(queries)) { for (let key of Object.keys(queries)) {
const value = queries[key]; const value = queries[key];
if (Array.isArray(value)) { if (Array.isArray(value)) {
for (const element of value) { for (let iii = 0; iii < value.length; iii++) {
searchParams.append(`${key}`, `${element}`); searchParams.append(`${key}`, `${value[iii]}`);
} }
} else { } else {
searchParams.append(`${key}`, `${value}`); searchParams.append(`${key}`, `${value}`);
@@ -129,43 +120,36 @@ export function RESTUrl({
} }
} }
if (restConfig.token !== undefined && restModel.tokenInUrl === true) { if (restConfig.token !== undefined && restModel.tokenInUrl === true) {
searchParams.append("Authorization", `Bearer ${restConfig.token}`); searchParams.append('Authorization', `Bearer ${restConfig.token}`);
} }
return generateUrl + "?" + searchParams.toString(); return generateUrl + "?" + searchParams.toString();
} }
export function fetchProgress(
generateUrl: string, export function fetchProgress(generateUrl: string, { method, headers, body }: {
{ method: HTTPRequestModel,
method, headers: any,
headers, body: any,
body, }, { progressUpload, progressDownload, abortHandle }: RESTCallbacks): Promise<Response> {
}: { const xhr = {
method: HTTPRequestModel; io: new XMLHttpRequest()
headers: any; }
body: any;
},
{ progressUpload, progressDownload, abortHandle }: RESTCallbacks
): Promise<Response> {
const xhr: {
io?: XMLHttpRequest;
} = {
io: new XMLHttpRequest(),
};
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Stream the upload progress // Stream the upload progress
if (progressUpload) { if (progressUpload) {
xhr.io?.upload.addEventListener("progress", (dataEvent) => { xhr.io.upload.addEventListener("progress", (dataEvent) => {
if (dataEvent.lengthComputable) { if (dataEvent.lengthComputable) {
//console.log(` ==> has a progress event: ${dataEvent.loaded} / ${dataEvent.total}`);
progressUpload(dataEvent.loaded, dataEvent.total); progressUpload(dataEvent.loaded, dataEvent.total);
} }
}); });
} }
// Stream the download progress // Stream the download progress
if (progressDownload) { if (progressDownload) {
xhr.io?.addEventListener("progress", (dataEvent) => { xhr.io.addEventListener("progress", (dataEvent) => {
if (dataEvent.lengthComputable) { if (dataEvent.lengthComputable) {
progressDownload(dataEvent.loaded, dataEvent.total); //console.log(` ==> download progress:: ${dataEvent.loaded} / ${dataEvent.total}`);
progressUpload(dataEvent.loaded, dataEvent.total);
} }
}); });
} }
@@ -176,43 +160,38 @@ export function fetchProgress(
xhr.io.abort(); xhr.io.abort();
return true; return true;
} }
console.log( console.log(`Request abort (FAIL) on the XMLHttpRequest: ${generateUrl}`);
`Request abort (FAIL) on the XMLHttpRequest: ${generateUrl}`
);
return false; return false;
}; }
} }
// Check if we have an internal Fail: // Check if we have an internal Fail:
xhr.io?.addEventListener("error", () => { xhr.io.addEventListener('error', () => {
xhr.io = undefined; xhr.io = undefined;
reject(new TypeError("Failed to fetch")); reject(new TypeError('Failed to fetch'))
}); });
// Capture the end of the stream // Capture the end of the stream
xhr.io?.addEventListener("loadend", () => { xhr.io.addEventListener("loadend", () => {
if (xhr.io?.readyState !== XMLHttpRequest.DONE) { if (xhr.io.readyState !== XMLHttpRequest.DONE) {
//console.log(` ==> READY state`);
return; return;
} }
if (xhr.io?.status === 0) { if (xhr.io.status === 0) {
//the stream has been aborted //the stream has been aborted
reject(new TypeError("Fetch has been aborted")); reject(new TypeError('Fetch has been aborted'));
return; return;
} }
// Stream is ended, transform in a generic response: // Stream is ended, transform in a generic response:
const response = new Response(xhr.io.response, { const response = new Response(xhr.io.response, {
status: xhr.io.status, status: xhr.io.status,
statusText: xhr.io.statusText, statusText: xhr.io.statusText
}); });
const headersArray = replaceAll( const headersArray = replaceAll(xhr.io.getAllResponseHeaders().trim(), "\r\n", "\n").split('\n');
xhr.io.getAllResponseHeaders().trim(),
"\r\n",
"\n"
).split("\n");
headersArray.forEach(function (header) { headersArray.forEach(function (header) {
const firstColonIndex = header.indexOf(":"); const firstColonIndex = header.indexOf(':');
if (firstColonIndex !== -1) { if (firstColonIndex !== -1) {
const key = header.substring(0, firstColonIndex).trim(); var key = header.substring(0, firstColonIndex).trim();
const value = header.substring(firstColonIndex + 1).trim(); var value = header.substring(firstColonIndex + 1).trim();
response.headers.set(key, value); response.headers.set(key, value);
} else { } else {
response.headers.set(header, ""); response.headers.set(header, "");
@@ -221,38 +200,31 @@ export function fetchProgress(
xhr.io = undefined; xhr.io = undefined;
resolve(response); resolve(response);
}); });
xhr.io?.open(method, generateUrl, true); xhr.io.open(method, generateUrl, true);
if (!isNullOrUndefined(headers)) { if (!isNullOrUndefined(headers)) {
for (const [key, value] of Object.entries(headers)) { for (const [key, value] of Object.entries(headers)) {
xhr.io?.setRequestHeader(key, value as string); xhr.io.setRequestHeader(key, value as string);
} }
} }
xhr.io?.send(body); xhr.io.send(body);
}); });
} }
export function RESTRequest({ export function RESTRequest({ restModel, restConfig, data, params, queries, callback }: RESTRequestType): Promise<ModelResponseHttp> {
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 = {};
if (restConfig.token !== undefined && restModel.tokenInUrl !== true) { if (restConfig.token !== undefined && restModel.tokenInUrl !== true) {
headers["Authorization"] = `Bearer ${restConfig.token}`; headers['Authorization'] = `Bearer ${restConfig.token}`;
} }
if (restModel.accept !== undefined) { if (restModel.accept !== undefined) {
headers["Accept"] = restModel.accept; headers['Accept'] = restModel.accept;
} }
if (restModel.requestType !== HTTPRequestModel.GET) { if (restModel.requestType !== HTTPRequestModel.GET) {
// if Get we have not a content type, the body is empty // if Get we have not a content type, the body is empty
if (restModel.contentType !== HTTPMimeType.MULTIPART) { if (restModel.contentType !== HTTPMimeType.MULTIPART) {
// special case of multi-part ==> no content type otherwise the browser does not set the ";bundary=--****" // special case of multi-part ==> no content type otherwise the browser does not set the ";bundary=--****"
headers["Content-Type"] = restModel.contentType; headers['Content-Type'] = restModel.contentType;
} }
} }
let body = data; let body = data;
@@ -263,16 +235,14 @@ export function RESTRequest({
for (const name in data) { for (const name in data) {
formData.append(name, data[name]); formData.append(name, data[name]);
} }
body = formData; body = formData
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let action: undefined | Promise<Response> = undefined; let action: undefined | Promise<Response> = undefined;
if ( if (isNullOrUndefined(callback)
isNullOrUndefined(callback) || || (isNullOrUndefined(callback.progressDownload)
(isNullOrUndefined(callback.progressDownload) && && isNullOrUndefined(callback.progressUpload)
isNullOrUndefined(callback.progressUpload) && && isNullOrUndefined(callback.abortHandle))) {
isNullOrUndefined(callback.abortHandle))
) {
// No information needed: call the generic fetch interface // No information needed: call the generic fetch interface
action = fetch(generateUrl, { action = fetch(generateUrl, {
method: restModel.requestType, method: restModel.requestType,
@@ -281,46 +251,37 @@ export function RESTRequest({
}); });
} else { } else {
// need progression information: call old fetch model (XMLHttpRequest) that permit to keep % upload and % download for HTTP1.x // need progression information: call old fetch model (XMLHttpRequest) that permit to keep % upload and % download for HTTP1.x
action = fetchProgress( action = fetchProgress(generateUrl, {
generateUrl,
{
method: restModel.requestType ?? HTTPRequestModel.GET, method: restModel.requestType ?? HTTPRequestModel.GET,
headers, headers,
body, body,
}, }, callback);
callback
);
} }
action action.then((response: Response) => {
.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 ( if (!isNullOrUndefined(restModel.accept) && restModel.accept !== contentType) {
!isNullOrUndefined(restModel.accept) &&
restModel.accept !== contentType
) {
reject({ reject({
name: "Model accept type incompatible",
time: Date().toString(), time: Date().toString(),
status: 901, status: 901,
error: `REST check wrong type: ${restModel.accept} != ${contentType}`, error: `REST check wrong type: ${restModel.accept} != ${contentType}`,
statusMessage: "Fetch error", statusMessage: "Fetch error",
message: "rest-tools.ts Wrong type in the message return type", message: "rest-tools.ts Wrong type in the message return type"
} as RestErrorResponse); } as RestErrorResponse);
} else if (contentType === HTTPMimeType.JSON) { } else if (contentType === HTTPMimeType.JSON) {
response response
.json() .json()
.then((value: any) => { .then((value: any) => {
//console.log(`RECEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
resolve({ status: response.status, data: value }); resolve({ status: response.status, data: value });
}) })
.catch((reason: any) => { .catch((reason: any) => {
reject({ reject({
name: "API serialization error",
time: Date().toString(), time: Date().toString(),
status: 902, status: 902,
error: `REST parse json fail: ${reason}`, error: `REST parse json fail: ${reason}`,
statusMessage: "Fetch parse error", statusMessage: "Fetch parse error",
message: "rest-tools.ts Wrong message model to parse", message: "rest-tools.ts Wrong message model to parse"
} as RestErrorResponse); } as RestErrorResponse);
}); });
} else { } else {
@@ -328,52 +289,43 @@ export function RESTRequest({
} }
} else { } else {
reject({ reject({
name: "REST return no OK status",
time: Date().toString(), time: Date().toString(),
status: response.status, status: response.status,
error: `${response.body}`, error: `${response.body}`,
statusMessage: "Fetch code error", statusMessage: "Fetch code error",
message: "rest-tools.ts Wrong return code", message: "rest-tools.ts Wrong return code"
} as RestErrorResponse); } as RestErrorResponse);
} }
}) }).catch((error: any) => {
.catch((error: any) => {
reject({ reject({
name: "Request fail",
time: Date(), time: Date(),
status: 999, status: 999,
error: error, error: error,
statusMessage: "Fetch catch error", statusMessage: "Fetch catch error",
message: "rest-tools.ts detect an error in the fetch request", message: "rest-tools.ts detect an error in the fetch request"
}); });
}); });
}); });
} }
export function RESTRequestJson<TYPE>( export function RESTRequestJson<TYPE>(request: RESTRequestType, checker: (data: any) => data is TYPE): Promise<TYPE> {
request: RESTRequestType,
checker?: (data: any) => data is TYPE
): Promise<TYPE> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
RESTRequest(request) RESTRequest(request).then((value: ModelResponseHttp) => {
.then((value: ModelResponseHttp) => {
if (isNullOrUndefined(checker)) { if (isNullOrUndefined(checker)) {
console.log(`Have no check of MODEL in API: ${RESTUrl(request)}`); console.log(`Have no check of MODEL in API: ${RESTUrl(request)}`);
resolve(value.data); resolve(value.data);
} else if (checker === undefined || checker(value.data)) { } else if (checker(value.data)) {
resolve(value.data); resolve(value.data);
} else { } else {
reject({ reject({
name: "Model check fail",
time: Date().toString(), time: Date().toString(),
status: 950, status: 950,
error: "REST Fail to verify the data", error: "REST Fail to verify the data",
statusMessage: "API cast ERROR", statusMessage: "API cast ERROR",
message: "api.ts Check type as fail", message: "api.ts Check type as fail"
} as RestErrorResponse); } as RestErrorResponse);
} }
}) }).catch((reason: RestErrorResponse) => {
.catch((reason: RestErrorResponse) => {
reject(reason); reject(reason);
}); });
}); });
@@ -381,11 +333,9 @@ export function RESTRequestJson<TYPE>(
export function RESTRequestVoid(request: RESTRequestType): Promise<void> { export function RESTRequestVoid(request: RESTRequestType): Promise<void> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
RESTRequest(request) RESTRequest(request).then((value: ModelResponseHttp) => {
.then((value: ModelResponseHttp) => {
resolve(); resolve();
}) }).catch((reason: RestErrorResponse) => {
.catch((reason: RestErrorResponse) => {
reject(reason); reject(reason);
}); });
}); });

View File

@@ -31,15 +31,15 @@ public class TestAnalyzeApiName {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ApiName.class)); api.addAllApi(List.of(ApiName.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals("ApiName", api.getAllApi().get(0).name); Assertions.assertEquals("ApiName", api.apiModels.get(0).name);
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("firstName"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("firstName");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("SecondName"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("SecondName");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
} }
} }

View File

@@ -0,0 +1,17 @@
package test.kar.archidata.externalRestApi;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestAnalyzeApiParameterParamQuery {
final static private Logger LOGGER = LoggerFactory.getLogger(TestAnalyzeApiParameterParamQuery.class);
@Test
public void testNotImplemented() throws Exception {
Assertions.assertEquals(1, 0);
}
}

View File

@@ -49,10 +49,10 @@ public class TestAnalyzeApiParameterType {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(BasicParameter.class)); api.addAllApi(List.of(BasicParameter.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(5, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(5, api.apiModels.get(0).interfaces.size());
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("setInteger1"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("setInteger1");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.unnamedElement.size()); Assertions.assertEquals(1, model.unnamedElement.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -60,7 +60,7 @@ public class TestAnalyzeApiParameterType {
Assertions.assertEquals(int.class, classModel.getOriginClasses()); Assertions.assertEquals(int.class, classModel.getOriginClasses());
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("setInteger2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("setInteger2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.unnamedElement.size()); Assertions.assertEquals(1, model.unnamedElement.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -68,7 +68,7 @@ public class TestAnalyzeApiParameterType {
Assertions.assertEquals(Integer.class, classModel.getOriginClasses()); Assertions.assertEquals(Integer.class, classModel.getOriginClasses());
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("setString"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("setString");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.unnamedElement.size()); Assertions.assertEquals(1, model.unnamedElement.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -76,7 +76,7 @@ public class TestAnalyzeApiParameterType {
Assertions.assertEquals(String.class, classModel.getOriginClasses()); Assertions.assertEquals(String.class, classModel.getOriginClasses());
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("setObject"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("setObject");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.unnamedElement.size()); Assertions.assertEquals(1, model.unnamedElement.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -84,7 +84,7 @@ public class TestAnalyzeApiParameterType {
Assertions.assertEquals(TestObject.class, classModel.getOriginClasses()); Assertions.assertEquals(TestObject.class, classModel.getOriginClasses());
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("setEnum"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("setEnum");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.unnamedElement.size()); Assertions.assertEquals(1, model.unnamedElement.size());
final ClassEnumModel classModel = Assertions.assertInstanceOf(ClassEnumModel.class, final ClassEnumModel classModel = Assertions.assertInstanceOf(ClassEnumModel.class,
@@ -104,9 +104,9 @@ public class TestAnalyzeApiParameterType {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ListParameter.class)); api.addAllApi(List.of(ListParameter.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(1, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(1, api.apiModels.get(0).interfaces.size());
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("setList"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("setList");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.unnamedElement.size()); Assertions.assertEquals(1, model.unnamedElement.size());
final ClassListModel classModel = Assertions.assertInstanceOf(ClassListModel.class, final ClassListModel classModel = Assertions.assertInstanceOf(ClassListModel.class,
@@ -127,9 +127,9 @@ public class TestAnalyzeApiParameterType {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(MapParameter.class)); api.addAllApi(List.of(MapParameter.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(1, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(1, api.apiModels.get(0).interfaces.size());
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("setMap"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("setMap");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.unnamedElement.size()); Assertions.assertEquals(1, model.unnamedElement.size());
final ClassMapModel classModel = Assertions.assertInstanceOf(ClassMapModel.class, model.unnamedElement.get(0)); final ClassMapModel classModel = Assertions.assertInstanceOf(ClassMapModel.class, model.unnamedElement.get(0));

View File

@@ -0,0 +1,17 @@
package test.kar.archidata.externalRestApi;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestAnalyzeApiParameterTypeAsync {
final static private Logger LOGGER = LoggerFactory.getLogger(TestAnalyzeApiParameterTypeAsync.class);
@Test
public void testNotImplemented() throws Exception {
Assertions.assertEquals(1, 0);
}
}

View File

@@ -39,21 +39,21 @@ public class TestAnalyzeApiPath {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(NoPath.class)); api.addAllApi(List.of(NoPath.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals("", api.getAllApi().get(0).restEndPoint); Assertions.assertEquals("", api.apiModels.get(0).restEndPoint);
Assertions.assertEquals(3, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(3, api.apiModels.get(0).interfaces.size());
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("noPath"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("noPath");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals("/", model.restEndPoint); Assertions.assertEquals("/", model.restEndPoint);
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("withPath"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("withPath");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals("/plop", model.restEndPoint); Assertions.assertEquals("/plop", model.restEndPoint);
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("withPath2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("withPath2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals("//plop", model.restEndPoint); Assertions.assertEquals("//plop", model.restEndPoint);
} }
@@ -84,21 +84,21 @@ public class TestAnalyzeApiPath {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(WithPath.class)); api.addAllApi(List.of(WithPath.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals("/kaboom", api.getAllApi().get(0).restEndPoint); Assertions.assertEquals("/kaboom", api.apiModels.get(0).restEndPoint);
Assertions.assertEquals(3, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(3, api.apiModels.get(0).interfaces.size());
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("noPath"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("noPath");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals("/kaboom/", model.restEndPoint); Assertions.assertEquals("/kaboom/", model.restEndPoint);
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("withPath"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("withPath");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals("/kaboom/plop", model.restEndPoint); Assertions.assertEquals("/kaboom/plop", model.restEndPoint);
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("withPath2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("withPath2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals("/kaboom//plop", model.restEndPoint); Assertions.assertEquals("/kaboom//plop", model.restEndPoint);
} }

View File

@@ -43,10 +43,10 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueVoid.class)); api.addAllApi(List.of(ReturnValueVoid.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getVoid1"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getVoid1");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -54,7 +54,7 @@ public class TestAnalyzeApiReturn {
Assertions.assertEquals(void.class, classModel.getOriginClasses()); Assertions.assertEquals(void.class, classModel.getOriginClasses());
} }
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getVoid2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getVoid2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -82,11 +82,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueInteger.class)); api.addAllApi(List.of(ReturnValueInteger.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
// Check int // Check int
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getInteger1"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getInteger1");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -95,7 +95,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Integer // Check Integer
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getInteger2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getInteger2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -123,11 +123,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueShort.class)); api.addAllApi(List.of(ReturnValueShort.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
// Check short // Check short
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getShort1"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getShort1");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -136,7 +136,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Short // Check Short
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getShort2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getShort2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -164,11 +164,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueLong.class)); api.addAllApi(List.of(ReturnValueLong.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
// Check long // Check long
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getLong1"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getLong1");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -177,7 +177,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Long // Check Long
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getLong2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getLong2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
Assertions.assertInstanceOf(ClassObjectModel.class, model.returnTypes.get(0)); Assertions.assertInstanceOf(ClassObjectModel.class, model.returnTypes.get(0));
@@ -206,11 +206,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueFloat.class)); api.addAllApi(List.of(ReturnValueFloat.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
// Check float // Check float
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getFloat1"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getFloat1");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -219,7 +219,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Float // Check Float
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getFloat2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getFloat2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -247,11 +247,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueDouble.class)); api.addAllApi(List.of(ReturnValueDouble.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
// Check double // Check double
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getDouble1"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getDouble1");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -260,7 +260,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Double // Check Double
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getDouble2"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getDouble2");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -283,11 +283,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueString.class)); api.addAllApi(List.of(ReturnValueString.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(1, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(1, api.apiModels.get(0).interfaces.size());
// Check String // Check String
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getString"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getString");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -314,11 +314,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueAny.class)); api.addAllApi(List.of(ReturnValueAny.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(2, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(2, api.apiModels.get(0).interfaces.size());
// Check Response ==> represent a Any value then it wrapped as Object // Check Response ==> represent a Any value then it wrapped as Object
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getResponse"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getResponse");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -327,7 +327,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Object // Check Object
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getObject"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getObject");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModel = Assertions.assertInstanceOf(ClassObjectModel.class,
@@ -350,11 +350,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueEnum.class)); api.addAllApi(List.of(ReturnValueEnum.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(1, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(1, api.apiModels.get(0).interfaces.size());
// Check Enum // Check Enum
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getEnum"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getEnum");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
final ClassEnumModel classModel = Assertions.assertInstanceOf(ClassEnumModel.class, final ClassEnumModel classModel = Assertions.assertInstanceOf(ClassEnumModel.class,
@@ -396,11 +396,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueList.class)); api.addAllApi(List.of(ReturnValueList.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(5, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(5, api.apiModels.get(0).interfaces.size());
// Check List<Integer> // Check List<Integer>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getListInteger"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getListInteger");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -413,7 +413,7 @@ public class TestAnalyzeApiReturn {
} }
// Check List<TestEnum> // Check List<TestEnum>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getListEnum"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getListEnum");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -426,7 +426,7 @@ public class TestAnalyzeApiReturn {
} }
// Check List<TestObject> // Check List<TestObject>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getListObject"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getListObject");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -435,11 +435,11 @@ public class TestAnalyzeApiReturn {
// Level 1 // Level 1
final ClassObjectModel classModelOfValue = Assertions.assertInstanceOf(ClassObjectModel.class, final ClassObjectModel classModelOfValue = Assertions.assertInstanceOf(ClassObjectModel.class,
classListModel.valueModel); classListModel.valueModel);
Assertions.assertEquals(TestObject.class, classModelOfValue.getOriginClasses()); Assertions.assertEquals(Integer.class, classModelOfValue.getOriginClasses());
} }
// Check List<List<Integer>> // Check List<List<Integer>>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getListListInteger"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getListListInteger");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -455,7 +455,7 @@ public class TestAnalyzeApiReturn {
} }
// Check List<Map<String, Integer>> // Check List<Map<String, Integer>>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getListMapInteger"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getListMapInteger");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -509,11 +509,11 @@ public class TestAnalyzeApiReturn {
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(List.of(ReturnValueMap.class)); api.addAllApi(List.of(ReturnValueMap.class));
Assertions.assertEquals(1, api.getAllApi().size()); Assertions.assertEquals(1, api.apiModels.size());
Assertions.assertEquals(5, api.getAllApi().get(0).interfaces.size()); Assertions.assertEquals(5, api.apiModels.get(0).interfaces.size());
// Check Map<String, Integer> // Check Map<String, Integer>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getMapInteger"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getMapInteger");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -529,7 +529,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Map<String, TestEnum> // Check Map<String, TestEnum>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getMapEnum"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getMapEnum");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -545,7 +545,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Map<String, TestObject> // Check Map<String, TestObject>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getMapObject"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getMapObject");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -561,7 +561,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Map<String, Map<String, Integer>> // Check Map<String, Map<String, Integer>>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getMapMap"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getMapMap");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0
@@ -583,7 +583,7 @@ public class TestAnalyzeApiReturn {
} }
// Check Map<String, List<Integer>> // Check Map<String, List<Integer>>
{ {
final ApiModel model = api.getAllApi().get(0).getInterfaceNamed("getMapList"); final ApiModel model = api.apiModels.get(0).getInterfaceNamed("getMapList");
Assertions.assertNotNull(model); Assertions.assertNotNull(model);
Assertions.assertEquals(1, model.returnTypes.size()); Assertions.assertEquals(1, model.returnTypes.size());
// Level 0 // Level 0

View File

@@ -0,0 +1,17 @@
package test.kar.archidata.externalRestApi;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestAnalyzeApiReturnAsync {
final static private Logger LOGGER = LoggerFactory.getLogger(TestAnalyzeApiReturnAsync.class);
@Test
public void testNotImplemented() throws Exception {
Assertions.assertEquals(1, 0);
}
}

View File

@@ -1,8 +1,12 @@
package test.kar.archidata.externalRestApi; package test.kar.archidata.externalRestApi;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.kar.archidata.externalRestApi.AnalyzeApi; import org.kar.archidata.externalRestApi.AnalyzeModel;
import org.kar.archidata.externalRestApi.model.ClassModel;
import org.kar.archidata.externalRestApi.model.ClassObjectModel; import org.kar.archidata.externalRestApi.model.ClassObjectModel;
import org.kar.archidata.externalRestApi.model.ClassObjectModel.FieldProperty; import org.kar.archidata.externalRestApi.model.ClassObjectModel.FieldProperty;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -17,11 +21,10 @@ public class TestAnalyzeModel {
@Test @Test
public void testNames() throws Exception { public void testNames() throws Exception {
final AnalyzeApi apiInterface = new AnalyzeApi(); final ClassObjectModel model = new ClassObjectModel(TestObject.class);
apiInterface.addModel(TestObject.class); final List<ClassModel> models = new ArrayList<>();
Assertions.assertEquals(2, apiInterface.getAllModel().size()); models.add(model);
final ClassObjectModel model = Assertions.assertInstanceOf(ClassObjectModel.class, AnalyzeModel.fillModel(models);
apiInterface.getAllModel().get(0));
Assertions.assertEquals("TestObject", model.getName()); Assertions.assertEquals("TestObject", model.getName());
Assertions.assertEquals(false, model.isPrimitive()); Assertions.assertEquals(false, model.isPrimitive());

View File

@@ -1 +1 @@
0.10.2 0.8.9