Compare commits

..

No commits in common. "483c41914a806bfb9e3b56aff4711f8405ca4c45" and "e4c56a4da56c769fe6dca8cf87a0364885a6cc07" have entirely different histories.

13 changed files with 64 additions and 217 deletions

View File

@ -25,7 +25,7 @@
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>

View File

@ -11,12 +11,12 @@
</arguments>
</buildCommand>
<buildCommand>
<name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name>
<arguments>
</arguments>
</buildCommand>

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId>
<version>0.12.0</version>
<version>0.11.0</version>
<properties>
<java.version>21</java.version>
<maven.compiler.version>3.1</maven.compiler.version>

View File

@ -80,14 +80,6 @@ public class AnnotationTools {
return ((Schema) annotation[0]).example();
}
public static boolean getNoWriteSpecificMode(final Class<?> element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(NoWriteSpecificMode.class);
if (annotation.length == 0) {
return false;
}
return true;
}
public static String getSchemaDescription(final Class<?> element) throws DataAccessException {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
if (annotation.length == 0) {

View File

@ -5,9 +5,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** When we wend to have only One type for read and write mode (Wrapping API). */
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface NoWriteSpecificMode {
public @interface SQLWhere {
String clause();
}

View File

@ -3,14 +3,12 @@ package org.kar.archidata.catcher;
import java.time.Instant;
import java.util.UUID;
import org.kar.archidata.annotation.NoWriteSpecificMode;
import org.kar.archidata.tools.UuidUtils;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.core.Response;
@NoWriteSpecificMode
public class RestErrorResponse {
public UUID uuid = UuidUtils.nextUUID();
@NotNull

View File

@ -10,7 +10,6 @@ public class ClassEnumModel extends ClassModel {
protected ClassEnumModel(final Class<?> clazz) {
this.originClasses = clazz;
this.noWriteSpecificMode = true;
}
@Override

View File

@ -11,17 +11,12 @@ import java.util.Set;
public abstract class ClassModel {
protected boolean analyzeDone = false;
protected Class<?> originClasses = null;
protected boolean noWriteSpecificMode = false;
protected List<ClassModel> dependencyModels = new ArrayList<>();
public Class<?> getOriginClasses() {
return this.originClasses;
}
public boolean isNoWriteSpecificMode() {
return this.noWriteSpecificMode;
}
protected boolean isCompatible(final Class<?> clazz) {
return this.originClasses == clazz;
}

View File

@ -1,6 +1,5 @@
package org.kar.archidata.externalRestApi.model;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.time.LocalDate;
@ -11,12 +10,9 @@ import java.util.List;
import java.util.Set;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.exception.DataAccessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.validation.constraints.Size;
public class ClassObjectModel extends ClassModel {
static final Logger LOGGER = LoggerFactory.getLogger(ClassObjectModel.class);
@ -57,25 +53,18 @@ public class ClassObjectModel extends ClassModel {
String name,
ClassModel model,
String comment,
int sizeMin, // String SizeMin
int sizeMax, // String SizeMax
Long min, // number min value
Long max, // number max value
int limitSize,
Boolean readOnly,
Boolean notNull,
Boolean columnNotNull,
Boolean nullable) {
public FieldProperty(final String name, final ClassModel model, final String comment, final int sizeMin,
final int sizeMax, final Long min, final Long max, final Boolean readOnly, final Boolean notNull,
final Boolean columnNotNull, final Boolean nullable) {
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) {
this.name = name;
this.model = model;
this.comment = comment;
this.sizeMin = sizeMin;
this.sizeMax = sizeMax;
this.min = min;
this.max = max;
this.limitSize = limitSize;
this.readOnly = readOnly;
this.notNull = notNull;
this.columnNotNull = columnNotNull;
@ -83,26 +72,11 @@ public class ClassObjectModel extends ClassModel {
}
private static int getStringMinSize(final Field field) throws DataAccessException {
final Size size = AnnotationTools.getConstraintsSize(field);
final int colomnLimitSize = AnnotationTools.getLimitSize(field);
return size != null ? size.min() : 0;
}
private static int getStringMaxSize(final Field field) throws DataAccessException {
final Size size = AnnotationTools.getConstraintsSize(field);
final int colomnLimitSize = AnnotationTools.getLimitSize(field);
return size == null ? colomnLimitSize : colomnLimitSize < size.max() ? colomnLimitSize : size.max();
}
public FieldProperty(final Field field, final ModelGroup previous) throws DataAccessException, IOException {
public FieldProperty(final Field field, final ModelGroup previous) throws Exception {
this(field.getName(), //
ClassModel.getModel(field.getGenericType(), previous), //
AnnotationTools.getComment(field), //
getStringMinSize(field), //
getStringMaxSize(field), //
AnnotationTools.getConstraintsMin(field), //
AnnotationTools.getConstraintsMax(field), //
AnnotationTools.getLimitSize(field), //
AnnotationTools.getSchemaReadOnly(field), //
AnnotationTools.getConstraintsNotNull(field), //
AnnotationTools.getColumnNotNull(field), //
@ -149,7 +123,6 @@ public class ClassObjectModel extends ClassModel {
}
this.analyzeDone = true;
final Class<?> clazz = this.originClasses;
this.noWriteSpecificMode = AnnotationTools.getNoWriteSpecificMode(clazz);
this.isPrimitive = clazz.isPrimitive();
if (this.isPrimitive) {
return;

View File

@ -41,7 +41,7 @@ public class TsApiGeneration {
final ClassEnumModel model,
final TsClassElementGroup tsGroup,
final Set<ClassModel> imports,
final Set<ClassModel> importWrite) throws IOException {
final boolean writeMode) throws IOException {
imports.add(model);
final TsClassElement tsModel = tsGroup.find(model);
return tsModel.tsTypeName;
@ -51,19 +51,15 @@ public class TsApiGeneration {
final ClassObjectModel model,
final TsClassElementGroup tsGroup,
final Set<ClassModel> imports,
final Set<ClassModel> importWrite) throws IOException {
final boolean writeMode) throws IOException {
final TsClassElement tsModel = tsGroup.find(model);
if (tsModel.nativeType != DefinedPosition.NATIVE) {
if (importWrite == null || tsModel.models.get(0).isNoWriteSpecificMode()) {
imports.add(model);
} else {
importWrite.add(model);
}
imports.add(model);
}
if (tsModel.nativeType != DefinedPosition.NORMAL) {
return tsModel.tsTypeName;
}
if (importWrite != null && !tsModel.models.get(0).isNoWriteSpecificMode()) {
if (writeMode) {
return tsModel.tsTypeName + "Write";
}
return tsModel.tsTypeName;
@ -73,12 +69,12 @@ public class TsApiGeneration {
final ClassMapModel model,
final TsClassElementGroup tsGroup,
final Set<ClassModel> imports,
final Set<ClassModel> importWrite) throws IOException {
final boolean writeMode) throws IOException {
final StringBuilder out = new StringBuilder();
out.append("{[key: ");
out.append(generateClassModelTypescript(model.keyModel, tsGroup, imports, importWrite));
out.append(generateClassModelTypescript(model.keyModel, tsGroup, imports, writeMode));
out.append("]: ");
out.append(generateClassModelTypescript(model.valueModel, tsGroup, imports, importWrite));
out.append(generateClassModelTypescript(model.valueModel, tsGroup, imports, writeMode));
out.append(";}");
return out.toString();
}
@ -87,9 +83,9 @@ public class TsApiGeneration {
final ClassListModel model,
final TsClassElementGroup tsGroup,
final Set<ClassModel> imports,
final Set<ClassModel> importWrite) throws IOException {
final boolean writeMode) throws IOException {
final StringBuilder out = new StringBuilder();
out.append(generateClassModelTypescript(model.valueModel, tsGroup, imports, importWrite));
out.append(generateClassModelTypescript(model.valueModel, tsGroup, imports, writeMode));
out.append("[]");
return out.toString();
}
@ -98,18 +94,18 @@ public class TsApiGeneration {
final ClassModel model,
final TsClassElementGroup tsGroup,
final Set<ClassModel> imports,
final Set<ClassModel> importWrite) throws IOException {
final boolean writeMode) throws IOException {
if (model instanceof final ClassObjectModel objectModel) {
return generateClassObjectModelTypescript(objectModel, tsGroup, imports, importWrite);
return generateClassObjectModelTypescript(objectModel, tsGroup, imports, writeMode);
}
if (model instanceof final ClassListModel listModel) {
return generateClassListModelTypescript(listModel, tsGroup, imports, importWrite);
return generateClassListModelTypescript(listModel, tsGroup, imports, writeMode);
}
if (model instanceof final ClassMapModel mapModel) {
return generateClassMapModelTypescript(mapModel, tsGroup, imports, importWrite);
return generateClassMapModelTypescript(mapModel, tsGroup, imports, writeMode);
}
if (model instanceof final ClassEnumModel enumModel) {
return generateClassEnumModelTypescript(enumModel, tsGroup, imports, importWrite);
return generateClassEnumModelTypescript(enumModel, tsGroup, imports, writeMode);
}
throw new IOException("Impossible model:" + model);
}
@ -118,7 +114,7 @@ public class TsApiGeneration {
final List<ClassModel> models,
final TsClassElementGroup tsGroup,
final Set<ClassModel> imports,
final Set<ClassModel> importWrite) throws IOException {
final boolean writeMode) throws IOException {
if (models.size() == 0) {
return "void";
}
@ -130,7 +126,7 @@ public class TsApiGeneration {
} else {
out.append(" | ");
}
final String data = generateClassModelTypescript(model, tsGroup, imports, importWrite);
final String data = generateClassModelTypescript(model, tsGroup, imports, writeMode);
out.append(data);
}
return out.toString();
@ -203,7 +199,7 @@ public class TsApiGeneration {
data.append("\n\t\t\t");
data.append(queryEntry.getKey());
data.append("?: ");
data.append(generateClassModelsTypescript(queryEntry.getValue(), tsGroup, imports, null));
data.append(generateClassModelsTypescript(queryEntry.getValue(), tsGroup, imports, false));
data.append(",");
}
data.append("\n\t\t},");
@ -214,15 +210,15 @@ public class TsApiGeneration {
data.append("\n\t\t\t");
data.append(paramEntry.getKey());
data.append(": ");
data.append(generateClassModelsTypescript(paramEntry.getValue(), tsGroup, imports, null));
data.append(generateClassModelsTypescript(paramEntry.getValue(), tsGroup, imports, false));
data.append(",");
}
data.append("\n\t\t},");
}
if (interfaceElement.unnamedElement.size() == 1) {
data.append("\n\t\tdata: ");
data.append(generateClassModelTypescript(interfaceElement.unnamedElement.get(0), tsGroup, imports,
writeImports));
data.append(generateClassModelTypescript(interfaceElement.unnamedElement.get(0), tsGroup, writeImports,
true));
data.append(",");
} else if (interfaceElement.multiPartParameters.size() != 0) {
data.append("\n\t\tdata: {");
@ -231,7 +227,7 @@ public class TsApiGeneration {
data.append("\n\t\t\t");
data.append(pathEntry.getKey());
data.append(": ");
data.append(generateClassModelsTypescript(pathEntry.getValue(), tsGroup, imports, writeImports));
data.append(generateClassModelsTypescript(pathEntry.getValue(), tsGroup, writeImports, true));
data.append(",");
}
data.append("\n\t\t},");
@ -279,7 +275,7 @@ public class TsApiGeneration {
toolImports.add("RESTRequestJson");
} else {
final String returnType = generateClassModelsTypescript(interfaceElement.returnTypes, tsGroup, imports,
null);
false);
data.append(returnType);
data.append("> {");
if ("void".equals(returnType)) {
@ -324,7 +320,7 @@ public class TsApiGeneration {
data.append("\n\t\t\t\taccept: produce,");
} else {
final String returnType = generateClassModelsTypescript(interfaceElement.returnTypes, tsGroup,
imports, null);
imports, false);
if (!"void".equals(returnType)) {
for (final String elem : produces) {
if (MediaType.APPLICATION_JSON.equals(elem)) {

View File

@ -181,18 +181,12 @@ public class TsClassElement {
if (tsModel.nativeType != DefinedPosition.NATIVE) {
out.append("import {");
out.append(tsModel.zodName);
if (tsModel.nativeType == DefinedPosition.NORMAL && !(tsModel.models.get(0).isNoWriteSpecificMode())) {
out.append(", ");
out.append(tsModel.zodName);
out.append("Write ");
}
out.append("} from \"./");
out.append(tsModel.fileName);
out.append("\";\n");
}
}
return out.toString();
}
private Object generateComment(final ClassObjectModel model) {
@ -221,68 +215,31 @@ public class TsClassElement {
return out.toString();
}
public boolean isOptionalTypeZod(final FieldProperty field) {
public String optionalTypeZod(final FieldProperty field) {
// Common checking element (apply to List, Map, ...)
if (field.nullable()) {
return true;
return ".optional()";
}
if (field.notNull()) {
return false;
return "";
}
// Other object:
if (field.model().getOriginClasses() == null || field.model().getOriginClasses().isPrimitive()) {
return false;
return "";
}
if (field.columnNotNull()) {
return false;
return "";
}
return true;
}
public String optionalTypeZod(final FieldProperty field) {
// Common checking element (apply to List, Map, ...)
if (isOptionalTypeZod(field)) {
return ".optional()";
}
return "";
}
public String optionalWriteTypeZod(final FieldProperty field) {
// Common checking element (apply to List, Map, ...)
if (isOptionalTypeZod(field)) {
return ".nullable()";
}
return "";
return ".optional()";
}
public String maxSizeZod(final FieldProperty field) {
final StringBuilder builder = new StringBuilder();
final Class<?> clazz = field.model().getOriginClasses();
if (clazz == String.class) {
if (field.sizeMin() > 0) {
builder.append(".min(");
builder.append(field.sizeMin());
builder.append(")");
}
if (field.sizeMax() > 0) {
builder.append(".max(");
builder.append(field.sizeMax());
builder.append(")");
}
}
if (clazz == short.class || clazz == Short.class || clazz == int.class || clazz == Integer.class
|| clazz == long.class || clazz == Long.class || clazz == float.class || clazz == Float.class
|| clazz == double.class || clazz == Double.class) {
if (field.min() != null && field.min() > 0) {
builder.append(".min(");
builder.append(field.min());
builder.append(")");
}
if (field.max() != null && field.max() > 0) {
builder.append(".max(");
builder.append(field.max());
builder.append(")");
}
if (field.limitSize() > 0 && clazz == String.class) {
builder.append(".max(");
builder.append(field.limitSize());
builder.append(")");
}
return builder.toString();
}
@ -313,9 +270,7 @@ public class TsClassElement {
out.append(getBaseHeader());
out.append(generateImports(model.getDependencyModels(), tsGroup));
out.append("\n");
// ------------------------------------------------------------------------
// -- Generate read mode
// ------------------------------------------------------------------------
out.append(generateComment(model));
out.append("export const ");
out.append(this.zodName);
@ -360,85 +315,27 @@ public class TsClassElement {
out.append("\n});\n");
out.append(generateZodInfer(this.tsTypeName, this.zodName));
out.append(generateExportCheckFunctionWrite(""));
// check if we need to generate write mode :
if (!model.isNoWriteSpecificMode()) {
// ------------------------------------------------------------------------
// -- Generate write mode
// ------------------------------------------------------------------------
//out.append(generateComment(model));
out.append("export const ");
out.append(this.zodName);
out.append("Write = ");
if (model.getExtendsClass() != null) {
final ClassModel parentClass = model.getExtendsClass();
final TsClassElement tsParentModel = tsGroup.find(parentClass);
out.append(tsParentModel.zodName);
out.append("Write");
out.append(".extend({");
} else {
out.append("zod.object({");
}
out.append("\n");
for (final FieldProperty field : model.getFields()) {
// remove all readOnly field
if (field.readOnly()) {
continue;
}
final ClassModel fieldModel = field.model();
if (field.comment() != null) {
out.append("\t/**\n");
out.append("\t * ");
out.append(field.comment());
out.append("\n\t */\n");
}
// Generate the Write Type associated.
out.append("\nexport const ");
out.append(this.zodName);
out.append("Write = ");
out.append(this.zodName);
if (omitField.size() != 0) {
out.append(".omit({\n");
for (final String elem : omitField) {
out.append("\t");
out.append(field.name());
out.append(": ");
if (fieldModel instanceof ClassEnumModel || fieldModel instanceof ClassObjectModel) {
final TsClassElement tsFieldModel = tsGroup.find(fieldModel);
out.append(tsFieldModel.zodName);
} else if (fieldModel instanceof final ClassListModel fieldListModel) {
final String data = generateTsList(fieldListModel, tsGroup);
out.append(data);
} else if (fieldModel instanceof final ClassMapModel fieldMapModel) {
final String data = generateTsMap(fieldMapModel, tsGroup);
out.append(data);
}
out.append(maxSizeZod(field));
out.append(optionalWriteTypeZod(field));
// all write field are optional
if (field.model() instanceof final ClassObjectModel plop) {
if (!plop.isPrimitive()) {
out.append(".optional()");
}
} else {
out.append(".optional()");
}
out.append(",\n");
out.append(elem);
out.append(": true,\n");
}
out.append("\n});\n");
out.append(generateZodInfer(this.tsTypeName + "Write", this.zodName + "Write"));
// Check only the input value ==> no need of the output
out.append(generateExportCheckFunctionWrite("Write"));
// Generate the Write Type associated.
/*
out.append("\nexport const ");
out.append(this.zodName);
out.append("Write = ");
out.append(this.zodName);
if (omitField.size() != 0) {
out.append(".omit({\n");
for (final String elem : omitField) {
out.append("\t");
out.append(elem);
out.append(": true,\n");
}
out.append("\n})");
}
out.append(".partial();\n");
*/
out.append("\n})");
}
out.append(".partial();\n");
out.append(generateZodInfer(this.tsTypeName + "Write", this.zodName + "Write"));
// Check only the input value ==> no need of the output
out.append(generateExportCheckFunctionWrite("Write"));
return out.toString();
}

View File

@ -120,7 +120,6 @@ public class RESTApi {
}
}
@SuppressWarnings("unchecked")
protected <T, U> T modelSendJson(final String model, final Class<T> clazz, final String urlOffset, String body)
throws RESTErrorResponseExeption, IOException, InterruptedException {
final HttpClient client = HttpClient.newHttpClient();
@ -165,7 +164,6 @@ public class RESTApi {
return this.mapper.readValue(httpResponse.body(), clazz);
}
@SuppressWarnings("unchecked")
protected <T> T modelSendMap(
final String model,
final Class<T> clazz,

View File

@ -1 +1 @@
0.12.0
0.11.0