From 57e9749d7cd157a41b81806389e5cc504e3f2b3a Mon Sep 17 00:00:00 2001 From: Mohamed ENNAHDI EL IDRISSI Date: Fri, 17 Jan 2025 22:03:30 +0000 Subject: [PATCH] Supporting Enum + Applying SonarCloud recommendations (#38) * Supporting Enum + Applying SonarCloud recommendations * Rectification + redimentioning --- .../app/exception/ValidationException.java | 5 ++ .../app/service/ObjectmorphService.java | 24 +++---- .../src/main/resources/public/client.html | 17 +++-- .../src/main/resources/public/index.html | 6 +- .../logic/JavaClassInterpreter.java | 62 +++++++++++++++---- .../objectmorph/renderer/HTMLGenerator.java | 28 +++++---- .../renderer/HTMLIndividualGenerator.java | 33 +++++++--- .../renderer/relation/Relation.java | 12 ++-- 8 files changed, 122 insertions(+), 65 deletions(-) diff --git a/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/exception/ValidationException.java b/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/exception/ValidationException.java index 316278b..1e167a4 100644 --- a/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/exception/ValidationException.java +++ b/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/exception/ValidationException.java @@ -1,6 +1,11 @@ package com.github.mohamedennahdi.objectmorph.app.exception; public class ValidationException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + public ValidationException() { } diff --git a/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/service/ObjectmorphService.java b/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/service/ObjectmorphService.java index dd102b6..2524c70 100644 --- a/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/service/ObjectmorphService.java +++ b/objectmorph-app/src/main/java/com/github/mohamedennahdi/objectmorph/app/service/ObjectmorphService.java @@ -2,9 +2,10 @@ import java.io.File; import java.io.FileWriter; +import java.io.IOException; import java.io.Writer; import java.net.URLDecoder; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; @@ -36,20 +37,13 @@ public String generateHTML(SourceCodeDto[] sourceCodes) throws Exception { validateFilenames(sourceCodes); String path = System.getProperty("user.home"); for (SourceCodeDto sourceCode: sourceCodes) { - sourceCode.setSourceCode(URLDecoder.decode(sourceCode.getSourceCode(), Charset.forName("UTF-8"))); + sourceCode.setSourceCode(URLDecoder.decode(sourceCode.getSourceCode(), StandardCharsets.UTF_8)); String fileName = sourceCode.getFilename(); log.info("Filename: " + fileName); - File file = new File(path + File.separator + fileName); - try (Writer fileWriter = new FileWriter(file, false)) { - fileWriter.write(sourceCode.getSourceCode()); - } catch (Exception e) { - throw e; - } + File file = saveFile(path + File.separator + fileName, sourceCode); files.add(file); } return objectmorphLogic.getHtmlGenerator(files.toArray(new File[0])).generateFullHTML(); - } catch (Exception e) { - throw e; } finally { log.info("Files removal."); for (File file : files) { @@ -60,9 +54,17 @@ public String generateHTML(SourceCodeDto[] sourceCodes) throws Exception { private void validateFilenames(SourceCodeDto[] sourceCodes) throws ValidationException { List filenames = Arrays.asList(sourceCodes).stream().map(n -> n.getFilename()).collect(Collectors.toList()); - Set uniqueFilenames = new HashSet(filenames); + Set uniqueFilenames = new HashSet<>(filenames); if (uniqueFilenames.size() != filenames.size()) { throw new ValidationException("File names must be unique."); } } + + private File saveFile(String path, SourceCodeDto sourceCode) throws IOException { + File file = new File(path); + try (Writer fileWriter = new FileWriter(file, false)) { + fileWriter.write(sourceCode.getSourceCode()); + } + return file; + } } diff --git a/objectmorph-app/src/main/resources/public/client.html b/objectmorph-app/src/main/resources/public/client.html index bfc7749..8c314de 100644 --- a/objectmorph-app/src/main/resources/public/client.html +++ b/objectmorph-app/src/main/resources/public/client.html @@ -1,5 +1,5 @@ - + Objectmorph-Sample-Client @@ -20,14 +20,14 @@

Executable locally.

-
+
-
-

- Version: +

+

+ Version:

@@ -66,18 +66,17 @@

if (this.status == 200) { console.log(this.responseText); const winUrl = URL.createObjectURL(new Blob([this.responseText], { type: "text/html" })); - const win = window.open(winUrl, "win", `width=512,height=512`); + window.open(winUrl, "win", `width=512,height=768`); } else { alert('Error: ' + this.status + " " + this.responseText); console.log('Error: ' + this.status + " " + this.responseText); } }; } - var url = location.protocol + '//' + location.host + "/html"; + let url = location.protocol + '//' + location.host + "/html"; xhttp.open("POST", url, true); xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); - var data = new FormData(); - data = JSON.stringify(file); + var data = JSON.stringify(file); xhttp.send(data); } diff --git a/objectmorph-app/src/main/resources/public/index.html b/objectmorph-app/src/main/resources/public/index.html index 3674fee..0184978 100644 --- a/objectmorph-app/src/main/resources/public/index.html +++ b/objectmorph-app/src/main/resources/public/index.html @@ -24,9 +24,9 @@

ObjectMorph application (Beta version)

-
-

- Version: +

+

+ Version:

diff --git a/objectmorph-logic/src/main/java/com/github/mohamedennahdi/objectmorph/logic/JavaClassInterpreter.java b/objectmorph-logic/src/main/java/com/github/mohamedennahdi/objectmorph/logic/JavaClassInterpreter.java index 311fa27..6870598 100644 --- a/objectmorph-logic/src/main/java/com/github/mohamedennahdi/objectmorph/logic/JavaClassInterpreter.java +++ b/objectmorph-logic/src/main/java/com/github/mohamedennahdi/objectmorph/logic/JavaClassInterpreter.java @@ -3,14 +3,19 @@ import java.io.File; import java.io.FileNotFoundException; import java.text.ParseException; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import com.github.javaparser.JavaParser; import com.github.javaparser.ParseResult; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.ast.body.EnumConstantDeclaration; +import com.github.javaparser.ast.body.EnumDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; @@ -21,19 +26,16 @@ public class JavaClassInterpreter { private ClassOrInterfaceDeclaration decl; + private EnumDeclaration enumDecl; private String className; private String packageName; - private static int INSTANCE_ID = 0; - - private int instanceId; + private static int instanceId = 0; public JavaClassInterpreter(File myClassSourceFile) throws FileNotFoundException, ParseException { - INSTANCE_ID ++; - - this.instanceId = INSTANCE_ID; + instanceId ++; JavaParser parser = new JavaParser(); @@ -56,6 +58,13 @@ public JavaClassInterpreter(File myClassSourceFile) throws FileNotFoundException optional = cu.getInterfaceByName(this.className); if (optional.isPresent()) { this.decl = optional.get(); + } else { + Optional enumOptional = cu.getEnumByName(this.className); + if (enumOptional.isPresent()) { + this.enumDecl = enumOptional.get(); + } else { + throw new UnsupportedOperationException(); + } } } } @@ -70,36 +79,67 @@ public String getClassName() { } public List getFields() { - return decl.getFields(); + if (Objects.isNull(this.decl)) { + return new ArrayList<>(); + } else { + return decl.getFields(); + } + } + + public NodeList getEntries() { + if (Objects.isNull(this.enumDecl)) { + return new NodeList<>(); + } else { + return enumDecl.getEntries(); + } } public List getConstructors() { + if (Objects.isNull(this.decl)) { + return new ArrayList<>(); + } return decl.getConstructors(); } public List getMethods() { + if (Objects.isNull(this.decl)) { + return new ArrayList<>(); + } return decl.getMethods(); } public String getSuperClassName() { - if (decl.getExtendedTypes().size() > 0) + if (Objects.isNull(this.decl)) { + return ""; + } + if (decl.getExtendedTypes().isNonEmpty()) return decl.getExtendedTypes(0).getNameAsString(); else return ""; } public boolean isInterface() { + if (Objects.isNull(decl)) { + return false; + } return decl.isInterface(); } + + public boolean isEnum() { + if (Objects.isNull(enumDecl)) { + return false; + } + return enumDecl.isEnumDeclaration(); + } public String getPackageName() { return packageName; } public int getInstanceId() { - return this.instanceId; + return instanceId; } - public void resetInstanceId() { - INSTANCE_ID = 0; + public static void resetInstanceId() { + instanceId = 0; } } diff --git a/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLGenerator.java b/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLGenerator.java index da06680..c658a06 100644 --- a/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLGenerator.java +++ b/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLGenerator.java @@ -44,12 +44,13 @@ public HTMLGenerator(File... sourceCodeClasses) throws Exception { } } - public String generateFullHTML() throws FileNotFoundException, URISyntaxException { - String draggableScript = ""; + public String generateFullHTML() { + StringBuilder draggableScript = new StringBuilder(); short top = 0; for (JavaClassInterpreter interpreter : interpreters) { - draggableScript += "\n var draggable" + interpreter.getInstanceId() +" = new PlainDraggable(document.getElementById('"+ interpreter.getClassName() +"'), {onMove: fixLine});"; - draggableScript += "\n draggable" + interpreter.getInstanceId() +".top = "+ (top += 128) +";"; + draggableScript.append("\n var draggable").append(interpreter.getInstanceId()).append(" = new PlainDraggable(document.getElementById('").append(interpreter.getClassName()).append("'), {onMove: fixLine});"); + draggableScript.append("\n draggable").append(interpreter.getInstanceId()).append(".top = ").append(top).append(";"); + top += 128; } List relations = new ArrayList<>(); @@ -64,26 +65,27 @@ public String generateFullHTML() throws FileNotFoundException, URISyntaxExceptio relations = new ArrayList<>(set); - String lineScript = ""; - String fixeLineScript = "function fixLine() {"; + StringBuilder lineScript = new StringBuilder(); + StringBuilder fixeLineScript = new StringBuilder("function fixLine() {"); for (Relation relation : relations) { String varName = "line" + relation.getInstanceId(); - lineScript += "\n var " + varName + " = new LeaderLine(document.getElementById('" + relation.getFrom() + "'), document.getElementById('" + relation.getTo() + "'), " + + lineScript.append("\n var ").append(varName).append(" = new LeaderLine(document.getElementById('").append(relation.getFrom()).append("'), document.getElementById('").append(relation.getTo()).append("'), "); + lineScript.append( (switch (relation.getLinkType()) { case GENERALIZATION -> Relation.GENERALIZATION_PROPERTIES_SCRIPT; case ASSOCIATION -> Relation.ASSOCIATION_PROPERTIES_SCRIPT; case UNARY -> Relation.UNARY_PROPERTIES_SCRIPT; default -> throw new IllegalArgumentException("Unexpected value: " + relation.getLinkType()); - }); - fixeLineScript += varName + ".position(); "; + })); + fixeLineScript.append(varName).append(".position(); "); } - fixeLineScript += " } "; + fixeLineScript.append(" } "); if (!relations.isEmpty()) { - relations.get(0).resetInstanceId(); + Relation.resetInstanceId(); } if (!interpreters.isEmpty()) { - interpreters.get(0).resetInstanceId(); + JavaClassInterpreter.resetInstanceId(); } return html( @@ -95,7 +97,7 @@ public String generateFullHTML() throws FileNotFoundException, URISyntaxExceptio body( div( tables.toArray(new TableTag[0]) - ).withStyle("background-color: gray; margin:0 auto; width: 1080px; height: 768px; border:1px solid black;"), + ).withStyle("background-color: gray; margin:0 auto; width: 1536px; height: 768px; border:1px solid black;"), script( draggableScript + " \n" + lineScript + "\n " + fixeLineScript ) diff --git a/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLIndividualGenerator.java b/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLIndividualGenerator.java index e1345d1..53f86b3 100644 --- a/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLIndividualGenerator.java +++ b/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/HTMLIndividualGenerator.java @@ -14,7 +14,9 @@ import java.util.List; import java.util.stream.Collectors; +import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.ast.body.EnumConstantDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; @@ -36,7 +38,7 @@ public HTMLIndividualGenerator(File srcCodeJavaClass) throws URISyntaxException, private TrTag generateClassNameHTML() { return tr( td( - img().withSrc(RESOURCES_PATH + (interpreter.isInterface() ? "/int_obj.svg" : "/class_obj.svg")).withStyle("top: 4px;position: relative;"), + img().withSrc(RESOURCES_PATH + (interpreter.isInterface() ? "/int_obj.svg" : interpreter.isEnum() ? "/enum_obj.svg" : "/class_obj.svg")).withStyle("top: 4px;position: relative;"), b(this.interpreter.getClassName()) ).attr("valign", "top").attr("align", "center") @@ -57,18 +59,29 @@ private TableTag generateClassHeaderHTML() { ).withStyle("width: 100%"); } - private TableTag generateAttributesHTML() throws FileNotFoundException { + private TableTag generateAttributesHTML() { List fields = interpreter.getFields(); + NodeList nodes = interpreter.getEntries(); return table( each(fields, field -> tr( td( - img().withSrc(RESOURCES_PATH + "/field_" + ("none".equals(field.getAccessSpecifier().name().toLowerCase()) ? "default" : field.getAccessSpecifier().name().toLowerCase() ) + "_obj.svg") + img().withSrc(RESOURCES_PATH + "/field_" + ("none".equalsIgnoreCase(field.getAccessSpecifier().name()) ? "default" : field.getAccessSpecifier().name().toLowerCase() ) + "_obj.svg") ).withStyle("width: 6%"), td( field.getVariables().stream().map(v -> v.getName().asString()).collect(Collectors.joining(", ")) + ": " + field.getVariable(0).getTypeAsString() ) - )) - ).withStyle("width: 100%").attr("width", "6%"); + )), + each(nodes, field -> tr( + td( + img().withSrc(RESOURCES_PATH + "/field_public_obj.svg"), + img().withSrc(RESOURCES_PATH_SPEC + "/static_co.svg").withStyle("position: relative; left: -17px; top: -8px;"), + img().withSrc(RESOURCES_PATH_SPEC + "/final_co.svg").withStyle("position: relative; left: -26px; top: -8px;") + ), + td( + + field.toString() + ))) + ); } private TableTag generateConstructorsHTML() { @@ -76,7 +89,7 @@ private TableTag generateConstructorsHTML() { return table( each(constructors, constructor -> tr( td( - img().withSrc(RESOURCES_PATH + "/meth" + ("none".equals(constructor.getAccessSpecifier().name().toLowerCase()) ? "def" : constructor.getAccessSpecifier().name().toLowerCase().substring(0, 3)) + "_obj.svg"), + img().withSrc(RESOURCES_PATH + "/meth" + ("none".equalsIgnoreCase(constructor.getAccessSpecifier().name()) ? "def" : constructor.getAccessSpecifier().name().toLowerCase().substring(0, 3)) + "_obj.svg"), img().withSrc(RESOURCES_PATH_SPEC + "/constr_ovr.svg").withStyle("position: relative; left: -13px; top: -4px;") ), td( constructor.getName().asString() + "(" + constructor.getParameters().stream().map(p -> p.getTypeAsString()).collect(Collectors.joining(",")) + ")") @@ -90,7 +103,7 @@ private TableTag generateMethodsHTML() { return table( each(methods, method -> tr( td( - img().withSrc(RESOURCES_PATH + "/meth" + ("none".equals(method.getAccessSpecifier().name().toLowerCase()) ? "def" : method.getAccessSpecifier().name().toLowerCase().substring(0, 3) ) + "_obj.svg") + img().withSrc(RESOURCES_PATH + "/meth" + ("none".equalsIgnoreCase(method.getAccessSpecifier().name()) ? "def" : method.getAccessSpecifier().name().toLowerCase().substring(0, 3) ) + "_obj.svg") ), td( method.getName().asString() + "(" + method.getParameters().stream().map(p -> p.getTypeAsString()).collect(Collectors.joining(",")) + "): " + method.getTypeAsString() ) @@ -99,7 +112,7 @@ private TableTag generateMethodsHTML() { ); } - public TableTag generateFullClassHTML() throws URISyntaxException, FileNotFoundException { + public TableTag generateFullClassHTML() { return table( tr( @@ -117,14 +130,14 @@ public TableTag generateFullClassHTML() throws URISyntaxException, FileNotFoundE td( this.generateConstructorsHTML() ) - ).withStyle("outline: thin solid; display: " + (interpreter.getConstructors().size() == 0 ? "none" : "visible")), + ).withStyle("outline: thin solid; display: " + (interpreter.getConstructors().isEmpty() ? "none" : "visible")), tr( td( this.generateMethodsHTML() ) ).withStyle("outline: thin solid") ) - .withStyle("background-color: white;").attr("cellspacing", "0").withId(this.interpreter.getClassName()); + .withStyle("background-color: white;width: 20%").attr("cellspacing", "0").withId(this.interpreter.getClassName()); } public JavaClassInterpreter getInterpreter() { diff --git a/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/relation/Relation.java b/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/relation/Relation.java index f38b123..d475165 100644 --- a/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/relation/Relation.java +++ b/objectmorph-renderer/src/main/java/com/github/mohamedennahdi/objectmorph/renderer/relation/Relation.java @@ -7,9 +7,7 @@ public class Relation { String to; LinkTypes linkType; - private int instanceId; - - private static int INSTANCE_ID = 0; + private static int instanceId = 0; public static final String GENERALIZATION_PROPERTIES_SCRIPT = " {" + "endPlug: 'arrow3'," + @@ -42,9 +40,7 @@ public class Relation { public Relation(String from, String to, LinkTypes linkType) { super(); - INSTANCE_ID ++; - - this.instanceId = INSTANCE_ID; + instanceId ++; this.from = from; this.to = to; @@ -79,8 +75,8 @@ public int getInstanceId() { return instanceId; } - public void resetInstanceId() { - INSTANCE_ID = 0; + public static void resetInstanceId() { + instanceId = 0; } @Override