Compare commits
2 Commits
84525fd7aa
...
cdb4581799
Author | SHA1 | Date | |
---|---|---|---|
cdb4581799 | |||
7e81bfef28 |
@ -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) {
|
||||
|
232
src/org/kar/archidata/externalRestApi/DotGenerateApi.java
Normal file
232
src/org/kar/archidata/externalRestApi/DotGenerateApi.java
Normal file
@ -0,0 +1,232 @@
|
||||
package org.kar.archidata.externalRestApi;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.InputStream;
|
||||
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.ContentDisposition;
|
||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||
import org.kar.archidata.catcher.RestErrorResponse;
|
||||
import org.kar.archidata.externalRestApi.dot.DotApiGeneration;
|
||||
import org.kar.archidata.externalRestApi.dot.DotClassElement;
|
||||
import org.kar.archidata.externalRestApi.dot.DotClassElement.DefinedPosition;
|
||||
import org.kar.archidata.externalRestApi.dot.DotClassElementGroup;
|
||||
import org.kar.archidata.externalRestApi.model.ApiGroupModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassModel;
|
||||
|
||||
public class DotGenerateApi {
|
||||
|
||||
public static void generateApi(final AnalyzeApi api, final String pathDotFile) throws Exception {
|
||||
final List<DotClassElement> localModel = generateApiModel(api);
|
||||
final DotClassElementGroup dotGroup = new DotClassElementGroup(localModel);
|
||||
|
||||
try (final FileWriter myWriter = new FileWriter(pathDotFile)) {
|
||||
myWriter.write("""
|
||||
# Architecture auto-generated file
|
||||
digraph UML_Class_diagram {
|
||||
#rankdir=NS;
|
||||
graph [
|
||||
pad="0.5"
|
||||
nodesep="1"
|
||||
#ranksep="2"
|
||||
label="Rest API server Model"
|
||||
labelloc="t"
|
||||
fontname="FreeMono,Sans-Mono,Helvetica,Arial,sans-serif"
|
||||
]
|
||||
node [
|
||||
fontname="FreeMono,Sans-Mono,Helvetica,Arial,sans-serif"
|
||||
shape=record
|
||||
style=filled
|
||||
fillcolor=gray95
|
||||
]
|
||||
edge [fontname="FreeMono,Sans-Mono,Helvetica,Arial,sans-serif"]
|
||||
""");
|
||||
/*
|
||||
myWriter.write("""
|
||||
subgraph REST_API {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
label="REST API";
|
||||
rankdir=LR;
|
||||
""");
|
||||
*/
|
||||
for (final ApiGroupModel element : api.apiModels) {
|
||||
final String tmp = DotApiGeneration.generateApiFile(element, dotGroup);
|
||||
myWriter.write(tmp);
|
||||
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) {
|
||||
previous = element.name;
|
||||
continue;
|
||||
}
|
||||
myWriter.write("\t{ ");
|
||||
myWriter.write(previous);
|
||||
myWriter.write(":s -> ");
|
||||
previous = element.name;
|
||||
myWriter.write(previous);
|
||||
myWriter.write(":n [style=invis]}\n");
|
||||
}
|
||||
}
|
||||
/*
|
||||
myWriter.write("""
|
||||
}
|
||||
""");
|
||||
myWriter.write("""
|
||||
subgraph Models {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
label="Models";
|
||||
rankdir=NS;
|
||||
""");
|
||||
*/
|
||||
// Generates all MODEL files
|
||||
for (final DotClassElement element : localModel) {
|
||||
final String tmp = element.generateFile(dotGroup);
|
||||
myWriter.write(tmp);
|
||||
myWriter.write("\n");
|
||||
}
|
||||
/*
|
||||
myWriter.write("""
|
||||
}
|
||||
""");
|
||||
*/
|
||||
myWriter.write("""
|
||||
}
|
||||
""");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<DotClassElement> generateApiModel(final AnalyzeApi api) throws Exception {
|
||||
// First step is to add all specific basic elements the wrap correctly the model
|
||||
final List<DotClassElement> dotModels = new ArrayList<>();
|
||||
List<ClassModel> models = api.getCompatibleModels(List.of(Void.class, void.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "void", "void", null, null, DefinedPosition.NATIVE));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Object.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Object", "object", null, "Object", DefinedPosition.NATIVE));
|
||||
}
|
||||
// Map is binded to any ==> can not determine this complex model for now
|
||||
models = api.getCompatibleModels(List.of(Map.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Object", "any", null, null, DefinedPosition.NATIVE));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(String.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "String", "string", null, "String", DefinedPosition.NATIVE));
|
||||
}
|
||||
models = api.getCompatibleModels(
|
||||
List.of(InputStream.class, FormDataContentDisposition.class, ContentDisposition.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "File", "File", null, "File", DefinedPosition.NATIVE));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Boolean.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Boolean", "boolean", null, "Boolean", DefinedPosition.NATIVE));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(boolean.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "boolean", "boolean", null, "boolean", DefinedPosition.NATIVE));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(UUID.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "UUID", "UUID", "isUUID", "UUID", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(long.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "long", "Long", "isLong", "long", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Long.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Long", "Long", "isLong", "Long", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(short.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "short", "Short", "isShort", "short", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Short.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Short", "Short", "isShort", "Short", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(int.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "int", "Integer", "isInteger", "int", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Integer.class));
|
||||
if (models != null) {
|
||||
dotModels.add(
|
||||
new DotClassElement(models, "Integer", "Integer", "isInteger", "Integer", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(double.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Double", "Double", "isDouble", "double", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Double.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Double", "Double", "isDouble", "Double", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(float.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "float", "Float", "isFloat", "float", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Float.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Float", "Float", "isFloat", "Float", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Instant.class));
|
||||
if (models != null) {
|
||||
dotModels.add(
|
||||
new DotClassElement(models, "Instant", "Instant", "isInstant", "Instant", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Date.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Date", "IsoDate", "isIsoDate", "Date", DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(Timestamp.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "Timestamp", "Timestamp", "isTimestamp", "Timestamp",
|
||||
DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(LocalDate.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "LocalDate", "LocalDate", "isLocalDate", "LocalDate",
|
||||
DefinedPosition.BASIC));
|
||||
}
|
||||
models = api.getCompatibleModels(List.of(LocalTime.class));
|
||||
if (models != null) {
|
||||
dotModels.add(new DotClassElement(models, "LocalTime", "LocalTime", "isLocalTime", "LocalTime",
|
||||
DefinedPosition.BASIC));
|
||||
}
|
||||
// needed for Rest interface
|
||||
api.addModel(RestErrorResponse.class);
|
||||
for (final ClassModel model : api.getAllModel()) {
|
||||
boolean alreadyExist = false;
|
||||
for (final DotClassElement elem : dotModels) {
|
||||
if (elem.isCompatible(model)) {
|
||||
alreadyExist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alreadyExist) {
|
||||
continue;
|
||||
}
|
||||
dotModels.add(new DotClassElement(model));
|
||||
}
|
||||
return dotModels;
|
||||
|
||||
}
|
||||
|
||||
}
|
414
src/org/kar/archidata/externalRestApi/dot/DotApiGeneration.java
Normal file
414
src/org/kar/archidata/externalRestApi/dot/DotApiGeneration.java
Normal file
@ -0,0 +1,414 @@
|
||||
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;
|
||||
import java.util.Set;
|
||||
|
||||
import org.kar.archidata.externalRestApi.dot.DotClassElement.DefinedPosition;
|
||||
import org.kar.archidata.externalRestApi.model.ApiGroupModel;
|
||||
import org.kar.archidata.externalRestApi.model.ApiModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassEnumModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassListModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassMapModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassObjectModel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DotApiGeneration {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(DotApiGeneration.class);
|
||||
|
||||
public static String generateClassEnumModelTypescript(
|
||||
final ClassEnumModel model,
|
||||
final DotClassElementGroup dotGroup,
|
||||
final Set<ClassModel> imports) throws IOException {
|
||||
imports.add(model);
|
||||
final DotClassElement dotModel = dotGroup.find(model);
|
||||
return dotModel.dotTypeName;
|
||||
}
|
||||
|
||||
public static String generateClassObjectModelTypescript(
|
||||
final ClassObjectModel model,
|
||||
final DotClassElementGroup dotGroup,
|
||||
final Set<ClassModel> imports) throws IOException {
|
||||
final DotClassElement dotModel = dotGroup.find(model);
|
||||
if (dotModel.nativeType != DefinedPosition.NATIVE) {
|
||||
imports.add(model);
|
||||
}
|
||||
if (dotModel.nativeType != DefinedPosition.NORMAL) {
|
||||
return dotModel.dotTypeName;
|
||||
}
|
||||
return dotModel.dotTypeName;
|
||||
}
|
||||
|
||||
public static String generateClassMapModelTypescript(
|
||||
final ClassMapModel model,
|
||||
final DotClassElementGroup dotGroup,
|
||||
final Set<ClassModel> imports) throws IOException {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
out.append("Map<");
|
||||
out.append(generateClassModelTypescript(model.keyModel, dotGroup, imports));
|
||||
out.append(", ");
|
||||
out.append(generateClassModelTypescript(model.valueModel, dotGroup, imports));
|
||||
out.append(">");
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static String generateClassListModelTypescript(
|
||||
final ClassListModel model,
|
||||
final DotClassElementGroup dotGroup,
|
||||
final Set<ClassModel> imports) throws IOException {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
out.append("List<");
|
||||
out.append(generateClassModelTypescript(model.valueModel, dotGroup, imports));
|
||||
out.append(">");
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static String generateClassModelTypescript(
|
||||
final ClassModel model,
|
||||
final DotClassElementGroup dotGroup,
|
||||
final Set<ClassModel> imports) throws IOException {
|
||||
if (model instanceof final ClassObjectModel objectModel) {
|
||||
return generateClassObjectModelTypescript(objectModel, dotGroup, imports);
|
||||
}
|
||||
if (model instanceof final ClassListModel listModel) {
|
||||
return generateClassListModelTypescript(listModel, dotGroup, imports);
|
||||
}
|
||||
if (model instanceof final ClassMapModel mapModel) {
|
||||
return generateClassMapModelTypescript(mapModel, dotGroup, imports);
|
||||
}
|
||||
if (model instanceof final ClassEnumModel enumModel) {
|
||||
return generateClassEnumModelTypescript(enumModel, dotGroup, imports);
|
||||
}
|
||||
throw new IOException("Impossible model:" + model);
|
||||
}
|
||||
|
||||
public static String generateClassModelsTypescript(
|
||||
final List<ClassModel> models,
|
||||
final DotClassElementGroup dotGroup) throws IOException {
|
||||
if (models.size() == 0) {
|
||||
return "void";
|
||||
}
|
||||
final StringBuilder out = new StringBuilder();
|
||||
if (models.size() > 1) {
|
||||
out.append("Union<");
|
||||
}
|
||||
boolean isFirst = true;
|
||||
for (final ClassModel model : models) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
out.append(", ");
|
||||
}
|
||||
final String data = DotClassElement.generateClassModelTypescript(model, dotGroup);
|
||||
out.append(data);
|
||||
}
|
||||
if (models.size() > 1) {
|
||||
out.append(">");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static List<String> generateClassModelsLinks(
|
||||
final List<ClassModel> models,
|
||||
final DotClassElementGroup dotGroup) throws IOException {
|
||||
if (models.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
final List<String> out = new ArrayList<>();
|
||||
final boolean isFirst = true;
|
||||
for (final ClassModel model : models) {
|
||||
final String data = DotClassElement.generateClassModelTypescriptLink(model, dotGroup);
|
||||
if (data != null) {
|
||||
out.add(data);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public static String capitalizeFirstLetter(final String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||
}
|
||||
|
||||
public static String generateApiFile(final ApiGroupModel element, final DotClassElementGroup dotGroup)
|
||||
throws IOException {
|
||||
final StringBuilder data = new StringBuilder();
|
||||
final StringBuilder outLinks = new StringBuilder();
|
||||
data.append("""
|
||||
%s [
|
||||
shape=plain
|
||||
label=<<table color="#FF3333" border="2" cellborder="1" cellspacing="0" cellpadding="4">
|
||||
<tr>
|
||||
<td><b>%s</b><br/>(REST)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0" cellborder="0" cellspacing="0" >
|
||||
""".formatted(element.name, element.name));
|
||||
final Set<ClassModel> imports = new HashSet<>();
|
||||
final Set<ClassModel> zodImports = new HashSet<>();
|
||||
final Set<ClassModel> isImports = new HashSet<>();
|
||||
final Set<ClassModel> writeImports = new HashSet<>();
|
||||
final Set<String> toolImports = new HashSet<>();
|
||||
for (final ApiModel interfaceElement : element.interfaces) {
|
||||
final List<String> consumes = interfaceElement.consumes;
|
||||
final List<String> produces = interfaceElement.produces;
|
||||
final boolean needGenerateProgress = interfaceElement.needGenerateProgress;
|
||||
/*
|
||||
if (returnComplexModel != null) {
|
||||
data.append(returnComplexModel.replaceAll("(?m)^", "\t"));
|
||||
for (final ClassModel elem : interfaceElement.returnTypes) {
|
||||
zodImports.addAll(elem.getDependencyGroupModels());
|
||||
}
|
||||
}
|
||||
*/
|
||||
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;
|
||||
/*
|
||||
if (!interfaceElement.queries.isEmpty()) {
|
||||
data.append("\n\t\tqueries: {");
|
||||
for (final Entry<String, List<ClassModel>> queryEntry : interfaceElement.queries.entrySet()) {
|
||||
data.append("\n\t\t\t");
|
||||
data.append(queryEntry.getKey());
|
||||
data.append("?: ");
|
||||
data.append(generateClassModelsTypescript(queryEntry.getValue(), dotGroup, imports, false));
|
||||
data.append(",");
|
||||
}
|
||||
data.append("\n\t\t},");
|
||||
}
|
||||
*/
|
||||
/* fonctionnel mais trop de donnée
|
||||
if (!interfaceElement.parameters.isEmpty()) {
|
||||
//data.append("params: {");
|
||||
for (final Entry<String, List<ClassModel>> paramEntry : interfaceElement.parameters.entrySet()) {
|
||||
data.append("");
|
||||
data.append(paramEntry.getKey());
|
||||
data.append(": ");
|
||||
data.append(generateClassModelsTypescript(paramEntry.getValue(), dotGroup, imports, false));
|
||||
data.append(",");
|
||||
}
|
||||
//data.append("},");
|
||||
}
|
||||
*/
|
||||
if (interfaceElement.unnamedElement.size() == 1) {
|
||||
if (hasParam) {
|
||||
data.append(", ");
|
||||
}
|
||||
hasParam = true;
|
||||
data.append("data: ");
|
||||
data.append(
|
||||
generateClassModelTypescript(interfaceElement.unnamedElement.get(0), dotGroup, writeImports));
|
||||
} else if (interfaceElement.multiPartParameters.size() != 0) {
|
||||
if (hasParam) {
|
||||
data.append(", ");
|
||||
}
|
||||
hasParam = true;
|
||||
boolean hasParam2 = false;
|
||||
data.append("data: {");
|
||||
for (final Entry<String, List<ClassModel>> pathEntry : interfaceElement.multiPartParameters
|
||||
.entrySet()) {
|
||||
if (hasParam2) {
|
||||
data.append(", ");
|
||||
}
|
||||
hasParam2 = true;
|
||||
data.append(pathEntry.getKey());
|
||||
data.append(": ");
|
||||
data.append(generateClassModelsTypescript(pathEntry.getValue(), dotGroup));
|
||||
}
|
||||
data.append("}");
|
||||
}
|
||||
data.append("): ");
|
||||
/*
|
||||
String tmp = DotClassElement.generateLocalModel(
|
||||
final String ModelName,
|
||||
final List<ClassModel> models,
|
||||
final DotClassElementGroup dotGroup)
|
||||
public static String generateClassModelsTypescript(
|
||||
final List<ClassModel> models,
|
||||
final DotClassElementGroup dotGroup,
|
||||
final Set<ClassModel> imports) throws IOException {
|
||||
*/
|
||||
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\"/> ");
|
||||
data.append("</td></tr>\n\t\t\t\t\t\t\t<tr><td align=\"left\"> ");
|
||||
/*
|
||||
data.append("\n\t\t\trestModel: {");
|
||||
data.append("\n\t\t\t\tendPoint: \"");
|
||||
*/
|
||||
data.append(interfaceElement.restEndPoint);
|
||||
/*
|
||||
data.append("\",");
|
||||
data.append("\n\t\t\t\trequestType: HTTPRequestModel.");
|
||||
toolImports.add("HTTPRequestModel");
|
||||
data.append(interfaceElement.restTypeRequest);
|
||||
data.append(",");
|
||||
if (consumes != null) {
|
||||
for (final String elem : consumes) {
|
||||
if (MediaType.APPLICATION_JSON.equals(elem)) {
|
||||
data.append("\n\t\t\t\tcontentType: HTTPMimeType.JSON,");
|
||||
toolImports.add("HTTPMimeType");
|
||||
break;
|
||||
} else if (MediaType.MULTIPART_FORM_DATA.equals(elem)) {
|
||||
data.append("\n\t\t\t\tcontentType: HTTPMimeType.MULTIPART,");
|
||||
toolImports.add("HTTPMimeType");
|
||||
break;
|
||||
} else if (MediaType.TEXT_PLAIN.equals(elem)) {
|
||||
data.append("\n\t\t\t\tcontentType: HTTPMimeType.TEXT_PLAIN,");
|
||||
toolImports.add("HTTPMimeType");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (RestTypeRequest.DELETE.equals(interfaceElement.restTypeRequest)) {
|
||||
data.append("\n\t\t\t\tcontentType: HTTPMimeType.TEXT_PLAIN,");
|
||||
toolImports.add("HTTPMimeType");
|
||||
}
|
||||
if (produces != null) {
|
||||
if (produces.size() > 1) {
|
||||
data.append("\n\t\t\t\taccept: produce,");
|
||||
} else {
|
||||
final String returnType = generateClassModelsTypescript(interfaceElement.returnTypes, dotGroup,
|
||||
imports, false);
|
||||
if (!"void".equals(returnType)) {
|
||||
for (final String elem : produces) {
|
||||
if (MediaType.APPLICATION_JSON.equals(elem)) {
|
||||
data.append("\n\t\t\t\taccept: HTTPMimeType.JSON,");
|
||||
toolImports.add("HTTPMimeType");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
data.append("\n\t\t\t},");
|
||||
data.append("\n\t\t\trestConfig,");
|
||||
if (!interfaceElement.parameters.isEmpty()) {
|
||||
data.append("\n\t\t\tparams,");
|
||||
}
|
||||
if (!interfaceElement.queries.isEmpty()) {
|
||||
data.append("\n\t\t\tqueries,");
|
||||
}
|
||||
if (interfaceElement.unnamedElement.size() == 1) {
|
||||
data.append("\n\t\t\tdata,");
|
||||
} else if (interfaceElement.multiPartParameters.size() != 0) {
|
||||
data.append("\n\t\t\tdata,");
|
||||
}
|
||||
if (needGenerateProgress) {
|
||||
data.append("\n\t\t\tcallback,");
|
||||
}
|
||||
data.append("\n\t\t}");
|
||||
if (returnComplexModel != null) {
|
||||
data.append(", is");
|
||||
data.append(returnModelNameIfComplex);
|
||||
} else {
|
||||
final DotClassElement retType = dotGroup.find(interfaceElement.returnTypes.get(0));
|
||||
if (retType.dotCheckType != null) {
|
||||
data.append(", ");
|
||||
data.append(retType.dotCheckType);
|
||||
imports.add(interfaceElement.returnTypes.get(0));
|
||||
}
|
||||
}
|
||||
*/
|
||||
data.append("</td></tr>\n");
|
||||
}
|
||||
/*
|
||||
data.append("\n}\n");
|
||||
|
||||
final StringBuilder out = new StringBuilder();
|
||||
|
||||
final List<String> toolImportsList = new ArrayList<>(toolImports);
|
||||
Collections.sort(toolImportsList);
|
||||
if (toolImportsList.size() != 0) {
|
||||
out.append("import {");
|
||||
for (final String elem : toolImportsList) {
|
||||
out.append("\n\t");
|
||||
out.append(elem);
|
||||
out.append(",");
|
||||
}
|
||||
out.append("\n} from \"../rest-tools\";\n\n");
|
||||
}
|
||||
|
||||
if (zodImports.size() != 0) {
|
||||
out.append("import { z as zod } from \"zod\"\n");
|
||||
}
|
||||
|
||||
final Set<String> finalImportSet = new TreeSet<>();
|
||||
|
||||
for (final ClassModel model : imports) {
|
||||
final DotClassElement dotModel = dotGroup.find(model);
|
||||
if (dotModel.nativeType == DefinedPosition.NATIVE) {
|
||||
continue;
|
||||
}
|
||||
finalImportSet.add(dotModel.dotTypeName);
|
||||
}
|
||||
for (final ClassModel model : isImports) {
|
||||
final DotClassElement dotModel = dotGroup.find(model);
|
||||
if (dotModel.nativeType == DefinedPosition.NATIVE) {
|
||||
continue;
|
||||
}
|
||||
if (dotModel.dotCheckType != null) {
|
||||
finalImportSet.add(dotModel.dotCheckType);
|
||||
}
|
||||
}
|
||||
for (final ClassModel model : zodImports) {
|
||||
final DotClassElement dotModel = dotGroup.find(model);
|
||||
if (dotModel.nativeType == DefinedPosition.NATIVE) {
|
||||
continue;
|
||||
}
|
||||
finalImportSet.add("Zod" + dotModel.dotTypeName);
|
||||
}
|
||||
for (final ClassModel model : writeImports) {
|
||||
final DotClassElement dotModel = dotGroup.find(model);
|
||||
if (dotModel.nativeType == DefinedPosition.NATIVE) {
|
||||
continue;
|
||||
}
|
||||
finalImportSet.add(dotModel.dotTypeName + "Write");
|
||||
}
|
||||
|
||||
if (finalImportSet.size() != 0) {
|
||||
out.append("import {");
|
||||
for (final String elem : finalImportSet) {
|
||||
out.append("\n\t");
|
||||
out.append(elem);
|
||||
out.append(",");
|
||||
}
|
||||
out.append("\n} from \"../model\";\n\n");
|
||||
}
|
||||
|
||||
out.append(data.toString());
|
||||
*/
|
||||
|
||||
data.append("""
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>>
|
||||
]
|
||||
""");
|
||||
data.append(outLinks.toString());
|
||||
return data.toString();
|
||||
}
|
||||
|
||||
}
|
485
src/org/kar/archidata/externalRestApi/dot/DotClassElement.java
Normal file
485
src/org/kar/archidata/externalRestApi/dot/DotClassElement.java
Normal file
@ -0,0 +1,485 @@
|
||||
package org.kar.archidata.externalRestApi.dot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.kar.archidata.externalRestApi.model.ClassEnumModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassListModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassMapModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassObjectModel;
|
||||
import org.kar.archidata.externalRestApi.model.ClassObjectModel.FieldProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DotClassElement {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(DotClassElement.class);
|
||||
|
||||
public enum DefinedPosition {
|
||||
NATIVE, // Native element of dot language.
|
||||
BASIC, // basic wrapping for JAVA type.
|
||||
NORMAL // Normal Object to interpret.
|
||||
}
|
||||
|
||||
public List<ClassModel> models;
|
||||
public String zodName;
|
||||
public String dotTypeName;
|
||||
public String dotCheckType;
|
||||
public String declaration;
|
||||
public String fileName = null;
|
||||
public String comment = null;
|
||||
public DefinedPosition nativeType = DefinedPosition.NORMAL;
|
||||
|
||||
public static String determineFileName(final String className) {
|
||||
return className.replaceAll("([a-z])([A-Z])", "$1-$2").replaceAll("([A-Z])([A-Z][a-z])", "$1-$2").toLowerCase();
|
||||
}
|
||||
|
||||
public DotClassElement(final List<ClassModel> model, final String zodName, final String dotTypeName,
|
||||
final String dotCheckType, final String declaration, final DefinedPosition nativeType) {
|
||||
this.models = model;
|
||||
this.zodName = zodName;
|
||||
this.dotTypeName = dotTypeName;
|
||||
this.declaration = declaration;
|
||||
this.nativeType = nativeType;
|
||||
}
|
||||
|
||||
public DotClassElement(final ClassModel model) {
|
||||
this.models = List.of(model);
|
||||
this.dotTypeName = model.getOriginClasses().getSimpleName();
|
||||
this.declaration = null;
|
||||
}
|
||||
|
||||
public boolean isCompatible(final ClassModel model) {
|
||||
return this.models.contains(model);
|
||||
}
|
||||
|
||||
public String generateEnum(final ClassEnumModel model, final DotClassElementGroup dotGroup) throws IOException {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
out.append("""
|
||||
%s [
|
||||
shape=plain
|
||||
label=<<table color="#33FF33" border="2" cellborder="1" cellspacing="0" cellpadding="4">
|
||||
<tr>
|
||||
<td port="NAME"><b>%s</b><br/>(ENUM)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0" cellborder="0" cellspacing="0" >
|
||||
""".formatted(this.dotTypeName, this.dotTypeName));
|
||||
final boolean first = true;
|
||||
for (final Entry<String, Object> elem : model.getListOfValues().entrySet()) {
|
||||
out.append("\t\t\t\t\t\t<tr><td align=\"left\"><b> + ");
|
||||
out.append(elem.getKey());
|
||||
out.append("</b> = ");
|
||||
if (elem.getValue() instanceof final Integer value) {
|
||||
out.append(value);
|
||||
} else {
|
||||
out.append("'");
|
||||
out.append(elem.getValue());
|
||||
out.append("'");
|
||||
}
|
||||
out.append("</td></tr>\n");
|
||||
}
|
||||
out.append("""
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>>
|
||||
]
|
||||
""");
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public String generateImporDot(final List<ClassModel> depModels, final DotClassElementGroup dotGroup)
|
||||
throws IOException {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
for (final ClassModel depModel : depModels) {
|
||||
final DotClassElement dotModel = dotGroup.find(depModel);
|
||||
if (dotModel.nativeType != DefinedPosition.NATIVE) {
|
||||
out.append("import {");
|
||||
out.append(dotModel.zodName);
|
||||
out.append("} from \"./");
|
||||
out.append(dotModel.fileName);
|
||||
out.append("\";\n");
|
||||
}
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private Object generateComment(final ClassObjectModel model) {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
if (model.getDescription() != null || model.getExample() != null) {
|
||||
out.append("/**\n");
|
||||
if (model.getDescription() != null) {
|
||||
for (final String elem : model.getDescription().split("\n")) {
|
||||
out.append(" * ");
|
||||
out.append(elem);
|
||||
out.append("\n");
|
||||
}
|
||||
}
|
||||
if (model.getExample() != null) {
|
||||
out.append(" * Example:\n");
|
||||
out.append(" * ```\n");
|
||||
for (final String elem : model.getExample().split("\n")) {
|
||||
out.append(" * ");
|
||||
out.append(elem);
|
||||
out.append("\n");
|
||||
}
|
||||
out.append(" * ```\n");
|
||||
}
|
||||
out.append(" */\n");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
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()) {
|
||||
return "";
|
||||
}
|
||||
if (field.columnNotNull()) {
|
||||
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(")");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public String readOnlyZod(final FieldProperty field) {
|
||||
if (field.readOnly()) {
|
||||
return ".readonly()";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String generateBaseObject() {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public String convertHtml(final String data) {
|
||||
return data.replace("<", "<").replace(">", ">");
|
||||
}
|
||||
|
||||
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();
|
||||
out.append("""
|
||||
%s [
|
||||
shape=plain
|
||||
ranksep="2"
|
||||
label=<<table color="#000000" border="2" cellborder="1" cellspacing="0" cellpadding="4">
|
||||
<tr>
|
||||
<td port="NAME"><b>%s</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0" cellborder="0" cellspacing="0" >
|
||||
""".formatted(this.dotTypeName, this.dotTypeName));
|
||||
String inheritence = null;
|
||||
if (model.getExtendsClass() != null) {
|
||||
final ClassModel parentClass = model.getExtendsClass();
|
||||
final DotClassElement dotParentModel = dotGroup.find(parentClass);
|
||||
inheritence = dotParentModel.dotTypeName;
|
||||
}
|
||||
if (model.getFields().size() == 0) {
|
||||
out.append("\t\t\t\t\t\t<tr><td> <i>(empty)</i> </td></tr>");
|
||||
}
|
||||
for (final FieldProperty field : model.getFields()) {
|
||||
final ClassModel fieldModel = field.model();
|
||||
if (field.comment() != null) {
|
||||
out.append("\t\t\t\t\t\t<tr><td align=\"left\"><i> // ");
|
||||
out.append(convertHtml(field.comment()));
|
||||
out.append("</i></td></tr>\n");
|
||||
}
|
||||
out.append("\t\t\t\t\t\t<tr><td align=\"left\" port=\"");
|
||||
out.append(field.name());
|
||||
out.append("\"><b> + ");
|
||||
out.append(field.name());
|
||||
out.append("</b>: ");
|
||||
|
||||
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(remoteType);
|
||||
outLinks.append(":NAME:w\n");
|
||||
} 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(remoteLinkType);
|
||||
outLinks.append(":NAME:w\n");
|
||||
}
|
||||
}
|
||||
out.append("</td></tr>\n");
|
||||
}
|
||||
out.append("""
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>>
|
||||
]
|
||||
""");
|
||||
if (inheritence != null) {
|
||||
out.append("\tedge [dir=back arrowtail=empty arrowsize=2]\n");
|
||||
out.append("\t");
|
||||
out.append(inheritence);
|
||||
// heritage stop link on the "s" South
|
||||
out.append(":s -> ");
|
||||
out.append(this.dotTypeName);
|
||||
// heritage start link on the "n" North
|
||||
out.append(":n\n");
|
||||
}
|
||||
if (!outLinks.isEmpty()) {
|
||||
out.append("\tedge [dir=back arrowtail=diamond arrowsize=2]\n");
|
||||
//out.append("\tedge [arrowhead=diamond arrowsize=2]\n");
|
||||
out.append(outLinks.toString());
|
||||
|
||||
}
|
||||
return out.toString();
|
||||
|
||||
}
|
||||
|
||||
private static String generateDotMap(final ClassMapModel model, final DotClassElementGroup dotGroup) {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
out.append("Map<");
|
||||
if (model.keyModel instanceof final ClassListModel fieldListModel) {
|
||||
final String tmp = generateDotList(fieldListModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.keyModel instanceof final ClassMapModel fieldMapModel) {
|
||||
final String tmp = generateDotMap(fieldMapModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.keyModel instanceof final ClassObjectModel fieldObjectModel) {
|
||||
final String tmp = generateDotObject(fieldObjectModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.keyModel instanceof final ClassEnumModel fieldEnumModel) {
|
||||
final String tmp = generateDotEnum(fieldEnumModel, dotGroup);
|
||||
out.append(tmp);
|
||||
}
|
||||
out.append(", ");
|
||||
if (model.valueModel instanceof final ClassListModel fieldListModel) {
|
||||
final String tmp = generateDotList(fieldListModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.valueModel instanceof final ClassMapModel fieldMapModel) {
|
||||
final String tmp = generateDotMap(fieldMapModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.valueModel instanceof final ClassObjectModel fieldObjectModel) {
|
||||
final String tmp = generateDotObject(fieldObjectModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.valueModel instanceof final ClassEnumModel fieldEnumModel) {
|
||||
final String tmp = generateDotEnum(fieldEnumModel, dotGroup);
|
||||
out.append(tmp);
|
||||
}
|
||||
out.append(">");
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static String generateDotEnum(final ClassEnumModel model, final DotClassElementGroup dotGroup) {
|
||||
final DotClassElement dotParentModel = dotGroup.find(model);
|
||||
return dotParentModel.dotTypeName;
|
||||
}
|
||||
|
||||
private static String generateDotObject(final ClassObjectModel model, final DotClassElementGroup dotGroup) {
|
||||
final DotClassElement dotParentModel = dotGroup.find(model);
|
||||
return dotParentModel.dotTypeName;
|
||||
}
|
||||
|
||||
private static String generateDotObjectClassName(
|
||||
final ClassObjectModel model,
|
||||
final DotClassElementGroup dotGroup) {
|
||||
final DotClassElement dotParentModel = dotGroup.find(model);
|
||||
if (dotParentModel.nativeType == DefinedPosition.NORMAL) {
|
||||
return dotParentModel.dotTypeName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String generateDotListClassName(final ClassListModel model, final DotClassElementGroup dotGroup) {
|
||||
if (model.valueModel instanceof final ClassListModel fieldListModel) {
|
||||
return generateDotListClassName(fieldListModel, dotGroup);
|
||||
} else if (model.valueModel instanceof final ClassMapModel fieldMapModel) {
|
||||
return generateDotMapClassName(fieldMapModel, dotGroup);
|
||||
} else if (model.valueModel instanceof final ClassObjectModel fieldObjectModel) {
|
||||
return generateDotObjectClassName(fieldObjectModel, dotGroup);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String generateDotMapClassName(final ClassMapModel model, final DotClassElementGroup dotGroup) {
|
||||
if (model.valueModel instanceof final ClassListModel fieldListModel) {
|
||||
return generateDotListClassName(fieldListModel, dotGroup);
|
||||
} else if (model.valueModel instanceof final ClassMapModel fieldMapModel) {
|
||||
return generateDotMapClassName(fieldMapModel, dotGroup);
|
||||
} else if (model.valueModel instanceof final ClassObjectModel fieldObjectModel) {
|
||||
return generateDotObjectClassName(fieldObjectModel, dotGroup);
|
||||
} else if (model.valueModel instanceof final ClassEnumModel fieldEnumModel) {
|
||||
return generateDotEnum(fieldEnumModel, dotGroup);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String generateDotList(final ClassListModel model, final DotClassElementGroup dotGroup) {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
out.append("List<");
|
||||
if (model.valueModel instanceof final ClassListModel fieldListModel) {
|
||||
final String tmp = generateDotList(fieldListModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.valueModel instanceof final ClassMapModel fieldMapModel) {
|
||||
final String tmp = generateDotMap(fieldMapModel, dotGroup);
|
||||
out.append(tmp);
|
||||
} else if (model.valueModel instanceof final ClassObjectModel fieldObjectModel) {
|
||||
final String tmp = generateDotObject(fieldObjectModel, dotGroup);
|
||||
out.append(tmp);
|
||||
}
|
||||
out.append(">");
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public String generateFile(final DotClassElementGroup dotGroup) throws IOException {
|
||||
if (this.nativeType == DefinedPosition.NATIVE) {
|
||||
return "";
|
||||
}
|
||||
final ClassModel model = this.models.get(0);
|
||||
String data = "";
|
||||
if (this.nativeType == DefinedPosition.BASIC && model instanceof ClassObjectModel) {
|
||||
// nothing to do___ data = generateBaseObject();
|
||||
} else if (model instanceof final ClassEnumModel modelEnum) {
|
||||
data = generateEnum(modelEnum, dotGroup);
|
||||
} else if (model instanceof final ClassObjectModel modelObject) {
|
||||
data = generateObject(modelObject, dotGroup);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private static String generateLocalModelBase(final ClassModel model, final DotClassElementGroup dotGroup)
|
||||
throws IOException {
|
||||
if (model instanceof final ClassObjectModel objectModel) {
|
||||
return generateDotObject(objectModel, dotGroup);
|
||||
}
|
||||
if (model instanceof final ClassEnumModel enumModel) {
|
||||
return generateDotEnum(enumModel, dotGroup);
|
||||
}
|
||||
if (model instanceof final ClassListModel listModel) {
|
||||
return generateDotList(listModel, dotGroup);
|
||||
}
|
||||
if (model instanceof final ClassMapModel mapModel) {
|
||||
return generateDotMap(mapModel, dotGroup);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String generateLocalModel(
|
||||
final String ModelName,
|
||||
final List<ClassModel> models,
|
||||
final DotClassElementGroup dotGroup) throws IOException {
|
||||
if (models.size() == 1) {
|
||||
if (models.get(0) instanceof ClassObjectModel) {
|
||||
return null;
|
||||
}
|
||||
if (models.get(0) instanceof ClassEnumModel) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final StringBuilder out = new StringBuilder();
|
||||
if (models.size() == 1) {
|
||||
out.append(generateLocalModelBase(models.get(0), dotGroup));
|
||||
} else {
|
||||
out.append("Union<");
|
||||
for (final ClassModel model : models) {
|
||||
out.append("\t");
|
||||
out.append(generateLocalModelBase(models.get(0), dotGroup));
|
||||
out.append(",\n");
|
||||
}
|
||||
out.append(">");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package org.kar.archidata.externalRestApi.dot;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.kar.archidata.externalRestApi.model.ClassModel;
|
||||
|
||||
public class DotClassElementGroup {
|
||||
private final List<DotClassElement> dotElements;
|
||||
|
||||
public List<DotClassElement> getDotElements() {
|
||||
return this.dotElements;
|
||||
}
|
||||
|
||||
public DotClassElementGroup(final List<DotClassElement> tsElements) {
|
||||
this.dotElements = tsElements;
|
||||
}
|
||||
|
||||
public DotClassElement find(final ClassModel model) {
|
||||
for (final DotClassElement elem : this.dotElements) {
|
||||
if (elem.isCompatible(model)) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -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), //
|
||||
|
Loading…
Reference in New Issue
Block a user