[FEAT] add link of List<UUID> that is decorate with @ManyToOne, or @ManyToMany or @OneToMany

This commit is contained in:
Edouard DUPIN 2024-06-20 00:09:37 +02:00
parent 7e81bfef28
commit cdb4581799
6 changed files with 206 additions and 172 deletions

View File

@ -17,7 +17,9 @@ import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
@ -136,18 +138,30 @@ public class AnnotationTools {
return ((DefaultValue) annotation[0]).value();
}
public static ManyToOne getManyToOne(final Field element) throws DataAccessException {
public static ManyToOne getManyToOne(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(ManyToOne.class);
if (annotation.length == 0) {
return null;
}
if (annotation.length > 1) {
throw new DataAccessException(
"Must not have more than 1 element @ManyToOne on " + element.getClass().getCanonicalName());
}
return (ManyToOne) annotation[0];
}
public static ManyToMany getManyToMany(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(ManyToMany.class);
if (annotation.length == 0) {
return null;
}
return (ManyToMany) annotation[0];
}
public static OneToMany getOneToMany(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(OneToMany.class);
if (annotation.length == 0) {
return null;
}
return (OneToMany) annotation[0];
}
public static DataJson getDataJson(final Field element) throws DataAccessException {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DataJson.class);
if (annotation.length == 0) {

View File

@ -64,6 +64,7 @@ public class DotGenerateApi {
myWriter.write("\n");
}
// create an invisible link to force all element to be link together:
if (false) {
String previous = null;
for (final ApiGroupModel element : api.apiModels) {
if (previous == null) {
@ -77,6 +78,7 @@ public class DotGenerateApi {
myWriter.write(previous);
myWriter.write(":n [style=invis]}\n");
}
}
/*
myWriter.write("""
}

View File

@ -1,6 +1,7 @@
package org.kar.archidata.externalRestApi.dot;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
@ -88,45 +89,45 @@ public class DotApiGeneration {
public static String generateClassModelsTypescript(
final List<ClassModel> models,
final DotClassElementGroup dotGroup,
final Set<ClassModel> imports) throws IOException {
final DotClassElementGroup dotGroup) throws IOException {
if (models.size() == 0) {
return "void";
}
final StringBuilder out = new StringBuilder();
if (models.size() > 1) {
out.append("Union&lt;");
}
boolean isFirst = true;
for (final ClassModel model : models) {
if (isFirst) {
isFirst = false;
} else {
out.append(" | ");
out.append(", ");
}
final String data = generateClassModelTypescript(model, dotGroup, imports);
final String data = DotClassElement.generateClassModelTypescript(model, dotGroup);
out.append(data);
}
if (models.size() > 1) {
out.append("&gt;");
}
return out.toString();
}
public static List<String> generateClassModelsLinks(
final List<ClassModel> models,
final DotClassElementGroup dotGroup) throws IOException {
// a ce point ca fait les union et tout et tou, mais il vas faloir fusionner avec les class ...
ICI CA PLANTE !!!
if (models.size() == 0) {
return null;
}
final StringBuilder out = new StringBuilder();
boolean isFirst = true;
final List<String> out = new ArrayList<>();
final boolean isFirst = true;
for (final ClassModel model : models) {
if (isFirst) {
isFirst = false;
} else {
out.append(" | ");
final String data = DotClassElement.generateClassModelTypescriptLink(model, dotGroup);
if (data != null) {
out.add(data);
}
final String data = generateClassModelTypescript(model, dotGroup, imports);
out.append(data);
}
return out.toString();
return out;
}
public static String capitalizeFirstLetter(final String str) {
@ -139,34 +140,7 @@ public class DotApiGeneration {
public static String generateApiFile(final ApiGroupModel element, final DotClassElementGroup dotGroup)
throws IOException {
final StringBuilder data = new StringBuilder();
final String polkop = """
API_REST_PLOP [
shape=plain
label=<<table color="#FF3333" border="2" cellborder="1" cellspacing="0" cellpadding="4">
<tr>
<td><b>MY_CLASS_NAME</b><br/>(REST)</td>
</tr>
<tr>
<td>
<table border="0" cellborder="0" cellspacing="0" >
<tr>
<td align="left" port="PROPERTY_1_REF" >
+ plop(xxx: Kaboom) : KataPloof<br/>
&nbsp;&nbsp;&nbsp;&nbsp;/qsdqds/{id}/
</td>
</tr>
<tr>
<td align="left" port="PROPERTY_2_REF" >
+ plop(xxx: Kaboom) : KataPloof<br/>
&nbsp;&nbsp;&nbsp;&nbsp;/qsdqds/{id}/
</td>
</tr>
</table>
</td>
</tr>
</table>>
]
""";
final StringBuilder outLinks = new StringBuilder();
data.append("""
%s [
shape=plain
@ -195,7 +169,9 @@ public class DotApiGeneration {
}
}
*/
data.append("\t\t\t\t\t<tr><td align=\"left\"><b> + ");
data.append("\t\t\t\t\t<tr><td align=\"left\" port=\"");
data.append(interfaceElement.name);
data.append("\"><b> + ");
data.append(interfaceElement.name);
data.append("(");
boolean hasParam = false;
@ -248,7 +224,7 @@ public class DotApiGeneration {
hasParam2 = true;
data.append(pathEntry.getKey());
data.append(": ");
data.append(generateClassModelsTypescript(pathEntry.getValue(), dotGroup, writeImports));
data.append(generateClassModelsTypescript(pathEntry.getValue(), dotGroup));
}
data.append("}");
}
@ -263,26 +239,18 @@ public class DotApiGeneration {
final DotClassElementGroup dotGroup,
final Set<ClassModel> imports) throws IOException {
*/
/*if (returnComplexModel != null) {
data.append(returnModelNameIfComplex);
} else*/ {
if (interfaceElement.returnTypes instanceof ClassEnumModel) {
final DotClassElement dotFieldModel = dotGroup.find(interfaceElement.returnTypes);
data.append(dotFieldModel.dotTypeName);
outLinks.append("\t");
outLinks.append(this.dotTypeName);
outLinks.append(":");
outLinks.append(field.name());
outLinks.append(":e -> ");
outLinks.append(dotFieldModel.dotTypeName);
outLinks.append(":NAME:w\n");
} else {
final String returnType = generateClassModelsTypescript(interfaceElement.returnTypes, dotGroup,
imports);
final String returnType = generateClassModelsTypescript(interfaceElement.returnTypes, dotGroup);
data.append(returnType);
final List<String> returnLinks = generateClassModelsLinks(interfaceElement.returnTypes, dotGroup);
for (final String link : returnLinks) {
outLinks.append("\t");
outLinks.append(element.name);
outLinks.append(":");
outLinks.append(interfaceElement.name);
outLinks.append(":e -> ");
outLinks.append(link);
outLinks.append(":NAME:w\n");
}
}
data.append("</b>");
//data.append("<br align=\"left\"/>&nbsp;&nbsp;&nbsp;&nbsp;");
data.append("</td></tr>\n\t\t\t\t\t\t\t<tr><td align=\"left\"> ");
@ -439,6 +407,7 @@ public class DotApiGeneration {
</table>>
]
""");
data.append(outLinks.toString());
return data.toString();
}

View File

@ -199,6 +199,46 @@ public class DotClassElement {
return data.replace("<", "&lt;").replace(">", "&gt;");
}
public static String generateClassModelTypescript(final ClassModel model, final DotClassElementGroup dotGroup)
throws IOException {
if (model instanceof ClassEnumModel) {
final DotClassElement dotFieldModel = dotGroup.find(model);
return dotFieldModel.dotTypeName;
} else if (model instanceof ClassObjectModel) {
final DotClassElement dotFieldModel = dotGroup.find(model);
return dotFieldModel.dotTypeName;
} else if (model instanceof final ClassListModel fieldListModel) {
return generateDotList(fieldListModel, dotGroup);
} else if (model instanceof final ClassMapModel fieldMapModel) {
return generateDotMap(fieldMapModel, dotGroup);
}
throw new IOException("Impossible model:" + model);
}
public static String generateClassModelTypescriptLink(final ClassModel model, final DotClassElementGroup dotGroup)
throws IOException {
if (model instanceof ClassEnumModel) {
final DotClassElement dotFieldModel = dotGroup.find(model);
return dotFieldModel.dotTypeName;
} else if (model instanceof ClassObjectModel) {
final DotClassElement dotFieldModel = dotGroup.find(model);
if (dotFieldModel.nativeType == DefinedPosition.NORMAL) {
return dotFieldModel.dotTypeName;
}
} else if (model instanceof final ClassListModel fieldListModel) {
final String className = generateDotListClassName(fieldListModel, dotGroup);
if (className != null) {
return className;
}
} else if (model instanceof final ClassMapModel fieldMapModel) {
final String className = generateDotMapClassName(fieldMapModel, dotGroup);
if (className != null) {
return className;
}
}
return null;
}
public String generateObject(final ClassObjectModel model, final DotClassElementGroup dotGroup) throws IOException {
final StringBuilder out = new StringBuilder();
final StringBuilder outLinks = new StringBuilder();
@ -236,57 +276,28 @@ public class DotClassElement {
out.append(field.name());
out.append("</b>: ");
if (fieldModel instanceof ClassEnumModel) {
final DotClassElement dotFieldModel = dotGroup.find(fieldModel);
out.append(dotFieldModel.dotTypeName);
out.append(generateClassModelTypescript(fieldModel, dotGroup));
final String remoteType = generateClassModelTypescriptLink(fieldModel, dotGroup);
if (remoteType != null) {
outLinks.append("\t");
outLinks.append(this.dotTypeName);
outLinks.append(":");
outLinks.append(field.name());
outLinks.append(":e -> ");
outLinks.append(dotFieldModel.dotTypeName);
outLinks.append(remoteType);
outLinks.append(":NAME:w\n");
} else if (fieldModel instanceof ClassObjectModel) {
final DotClassElement dotFieldModel = dotGroup.find(fieldModel);
out.append(dotFieldModel.dotTypeName);
if (dotFieldModel.nativeType == DefinedPosition.NORMAL) {
} else if (field.linkClass() != null) {
final String remoteLinkType = generateClassModelTypescriptLink(field.linkClass(), dotGroup);
if (remoteLinkType != null) {
outLinks.append("\t");
outLinks.append(this.dotTypeName);
outLinks.append(":");
outLinks.append(field.name());
outLinks.append(":e -> ");
outLinks.append(dotFieldModel.dotTypeName);
outLinks.append(remoteLinkType);
outLinks.append(":NAME:w\n");
}
} else if (fieldModel instanceof final ClassListModel fieldListModel) {
final String data = generateDotList(fieldListModel, dotGroup);
out.append(data);
final String className = generateDotListClassName(fieldListModel, dotGroup);
if (className != null) {
outLinks.append(this.dotTypeName);
outLinks.append(":");
outLinks.append(field.name());
outLinks.append(":e -> ");
outLinks.append(className);
outLinks.append(":NAME:w\n");
}
} else if (fieldModel instanceof final ClassMapModel fieldMapModel) {
final String data = generateDotMap(fieldMapModel, dotGroup);
out.append(data);
final String className = generateDotMapClassName(fieldMapModel, dotGroup);
if (className != null) {
outLinks.append(this.dotTypeName);
outLinks.append(":");
outLinks.append(field.name());
outLinks.append(":e -> ");
outLinks.append(className);
outLinks.append(":NAME:w\n");
}
} /*
out.append(maxSizeZod(field));
out.append(readOnlyZod(field));
out.append(optionalTypeZod(field));
out.append(",\n");
*/
out.append("</td></tr>\n");
}
out.append("""

View File

@ -15,6 +15,9 @@ import org.kar.archidata.exception.DataAccessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.validation.constraints.Size;
public class ClassObjectModel extends ClassModel {
@ -56,6 +59,7 @@ public class ClassObjectModel extends ClassModel {
public record FieldProperty(
String name,
ClassModel model,
ClassModel linkClass, // link class when use remote ID (ex: list<UUID>)
String comment,
int sizeMin, // String SizeMin
int sizeMax, // String SizeMax
@ -66,11 +70,12 @@ public class ClassObjectModel extends ClassModel {
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 ClassModel linkClass,
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) {
this.name = name;
this.model = model;
this.linkClass = linkClass;
this.comment = comment;
this.sizeMin = sizeMin;
this.sizeMax = sizeMax;
@ -85,7 +90,6 @@ 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;
}
@ -95,9 +99,43 @@ public class ClassObjectModel extends ClassModel {
return size == null ? colomnLimitSize : colomnLimitSize < size.max() ? colomnLimitSize : size.max();
}
private static Class<?> getSubModelIfExist2(final Field field) {
final ManyToOne manyToOne = AnnotationTools.getManyToOne(field);
if (manyToOne != null) {
if (manyToOne.targetEntity() != null && manyToOne.targetEntity() != void.class) {
return manyToOne.targetEntity();
}
return null;
}
final ManyToMany manyToMany = AnnotationTools.getManyToMany(field);
if (manyToMany != null) {
if (manyToMany.targetEntity() != null && manyToMany.targetEntity() != void.class) {
return manyToMany.targetEntity();
}
return null;
}
final OneToMany oneToMany = AnnotationTools.getOneToMany(field);
if (oneToMany != null) {
if (oneToMany.targetEntity() != null && oneToMany.targetEntity() != void.class) {
return oneToMany.targetEntity();
}
return null;
}
return null;
}
private static ClassModel getSubModelIfExist(final Field field, final ModelGroup previous) throws IOException {
final Class<?> tmp = getSubModelIfExist2(field);
if (tmp == null) {
return null;
}
return ClassModel.getModel(tmp, previous);
}
public FieldProperty(final Field field, final ModelGroup previous) throws DataAccessException, IOException {
this(field.getName(), //
ClassModel.getModel(field.getGenericType(), previous), //
getSubModelIfExist(field, previous), //
AnnotationTools.getComment(field), //
getStringMinSize(field), //
getStringMaxSize(field), //