[FEAT] add generation of dot files
This commit is contained in:
parent
84525fd7aa
commit
7e81bfef28
230
src/org/kar/archidata/externalRestApi/DotGenerateApi.java
Normal file
230
src/org/kar/archidata/externalRestApi/DotGenerateApi.java
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
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:
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
445
src/org/kar/archidata/externalRestApi/dot/DotApiGeneration.java
Normal file
445
src/org/kar/archidata/externalRestApi/dot/DotApiGeneration.java
Normal file
@ -0,0 +1,445 @@
|
|||||||
|
package org.kar.archidata.externalRestApi.dot;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
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,
|
||||||
|
final Set<ClassModel> imports) throws IOException {
|
||||||
|
if (models.size() == 0) {
|
||||||
|
return "void";
|
||||||
|
}
|
||||||
|
final StringBuilder out = new StringBuilder();
|
||||||
|
boolean isFirst = true;
|
||||||
|
for (final ClassModel model : models) {
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
} else {
|
||||||
|
out.append(" | ");
|
||||||
|
}
|
||||||
|
final String data = generateClassModelTypescript(model, dotGroup, imports);
|
||||||
|
out.append(data);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
for (final ClassModel model : models) {
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
} else {
|
||||||
|
out.append(" | ");
|
||||||
|
}
|
||||||
|
final String data = generateClassModelTypescript(model, dotGroup, imports);
|
||||||
|
out.append(data);
|
||||||
|
}
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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/>
|
||||||
|
/qsdqds/{id}/
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="left" port="PROPERTY_2_REF" >
|
||||||
|
+ plop(xxx: Kaboom) : KataPloof<br/>
|
||||||
|
/qsdqds/{id}/
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>>
|
||||||
|
]
|
||||||
|
""";
|
||||||
|
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\"><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, writeImports));
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
*/
|
||||||
|
/*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);
|
||||||
|
data.append(returnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>>
|
||||||
|
]
|
||||||
|
""");
|
||||||
|
return data.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
474
src/org/kar/archidata/externalRestApi/dot/DotClassElement.java
Normal file
474
src/org/kar/archidata/externalRestApi/dot/DotClassElement.java
Normal file
@ -0,0 +1,474 @@
|
|||||||
|
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 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>: ");
|
||||||
|
|
||||||
|
if (fieldModel instanceof ClassEnumModel) {
|
||||||
|
final DotClassElement dotFieldModel = dotGroup.find(fieldModel);
|
||||||
|
out.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 if (fieldModel instanceof ClassObjectModel) {
|
||||||
|
final DotClassElement dotFieldModel = dotGroup.find(fieldModel);
|
||||||
|
out.append(dotFieldModel.dotTypeName);
|
||||||
|
if (dotFieldModel.nativeType == DefinedPosition.NORMAL) {
|
||||||
|
outLinks.append(this.dotTypeName);
|
||||||
|
outLinks.append(":");
|
||||||
|
outLinks.append(field.name());
|
||||||
|
outLinks.append(":e -> ");
|
||||||
|
outLinks.append(dotFieldModel.dotTypeName);
|
||||||
|
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("""
|
||||||
|
</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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user