From 69402d314c3b3dc8bf44d0a730706e96ebc3ccff Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Tue, 5 Jul 2022 15:15:31 +0200
Subject: [PATCH] 1.2.0

- add support for PDF (requires additional dependencies)
- avoid parametrized attributes
- avoid computing NTAs before checking whether to include them
- cleanup of DumpBuilder
---
 .../src/main/jastadd/GenerationBackend.jadd   | 21 +++---
 .../st/jastadd/dumpAst/ast/DumpBuilder.java   | 65 +++++++++++++------
 .../main/resources/dumpAstVersion.properties  |  4 +-
 .../jastadd/featureTest/FeatureTestMain.java  |  4 ++
 pages/docs/adding.md                          |  2 +-
 5 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/dumpAst/src/main/jastadd/GenerationBackend.jadd b/dumpAst/src/main/jastadd/GenerationBackend.jadd
index 1c2a06f..bf3ccf3 100644
--- a/dumpAst/src/main/jastadd/GenerationBackend.jadd
+++ b/dumpAst/src/main/jastadd/GenerationBackend.jadd
@@ -164,16 +164,15 @@ aspect GenerationBackend {
     for (AnalysedMethod otherMethod : car.getOtherMethodList()) {
       if (otherMethod.isSingleChildMethod()) {
         // -- singleChild --
-        Object target = otherMethod.getMethod().invoke(obj);
         String childName = otherMethod.getName();
         boolean computed = otherMethod.asSingleChildMethod().isNTASingleChildMethod();
         boolean shouldInclude = computed ?
             getBuildConfig().getIncludeAttributeMethod().shouldInclude(obj, childName, true, () -> catchedInvoke(otherMethod.getMethod(), obj)) :
-            getBuildConfig().getIncludeChildMethod().shouldInclude(obj, target, childName);
+            getBuildConfig().getIncludeChildMethod().shouldInclude(obj, otherMethod.getMethod().invoke(obj), childName);
         if (!shouldInclude) {
           continue;
         }
-        DumpNode targetNode = transform(tti, target, options.asNormal(false).computed(computed).allowNullObjectsOnce());
+        DumpNode targetNode = transform(tti, otherMethod.getMethod().invoke(obj), options.asNormal(false).computed(computed).allowNullObjectsOnce());
         if (targetNode != null) {
           DumpNormalChildNode normalChild = new DumpNormalChildNode();
           normalChild.setName(childName);
@@ -183,19 +182,17 @@ aspect GenerationBackend {
         }
       } else if (otherMethod.isListChildMethod()) {
         // -- listChild --
+        // it is always a NTAListChildMethod
+        String childName = otherMethod.getName();
+        if (!getBuildConfig().getIncludeAttributeMethod().shouldInclude(obj, childName, true, () -> catchedInvoke(otherMethod.getMethod(), obj))) {
+          continue;
+        }
         Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj);
         DumpListChildNode listChild = new DumpListChildNode();
         boolean computed = otherMethod.asListChildMethod().isNTAListChildMethod();
         listChild.setComputed(computed);
-        String childName = otherMethod.getName();
         listChild.setName(childName);
         for (Object target : targetList) {
-          boolean shouldInclude = computed ?
-              getBuildConfig().getIncludeAttributeMethod().shouldInclude(obj, childName, true, () -> catchedInvoke(otherMethod.getMethod(), obj)) :
-              getBuildConfig().getIncludeChildMethod().shouldInclude(obj, target, childName);
-          if (!shouldInclude) {
-            continue;
-          }
           DumpNode targetNode = transform(tti, target, options.asNormal(false).computed(computed));
           if (target != null && targetNode != null) {
             listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
@@ -385,6 +382,10 @@ aspect GenerationBackend {
               result.addOtherMethod(tokenMethod);
               break;
             case "Attribute":
+              if (method.getParameterCount() > 0) {
+                // ignore parametrized attributes
+                continue;
+              }
               String attributeName = method.getName();
               boolean isNTA = (boolean) invokeMethod("isNTA", annotation);
               if (isNTA) {
diff --git a/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java b/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java
index 9fdc7b0..18bd976 100644
--- a/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java
+++ b/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java
@@ -1,6 +1,17 @@
 package de.tudresden.inf.st.jastadd.dumpAst.ast;
 
+import net.sourceforge.plantuml.FileFormat;
+import net.sourceforge.plantuml.FileFormatOption;
+import net.sourceforge.plantuml.SourceStringReader;
+
+import java.io.IOException;
+import java.io.Writer;
 import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ResourceBundle;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 import static de.tudresden.inf.st.jastadd.dumpAst.ast.ASTNode.matches;
 
@@ -661,11 +672,11 @@ public class DumpBuilder {
    *
    * @param destination path of destination file
    * @return this
-   * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+   * @throws java.io.IOException if an I/O error happened during opening or writing in that file
    */
-  public DumpBuilder dumpAsSource(java.nio.file.Path destination) throws java.io.IOException {
+  public DumpBuilder dumpAsSource(Path destination) throws java.io.IOException {
     String content = build().toPlantUml();
-    try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
+    try (Writer writer = Files.newBufferedWriter(destination)) {
       writer.write(content);
     }
     return this;
@@ -677,11 +688,11 @@ public class DumpBuilder {
    * @param destination path of destination file
    * @param prependCreationComment whether to add the creation date as first line
    * @return this
-   * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+   * @throws java.io.IOException if an I/O error happened during opening or writing in that file
    */
-  public DumpBuilder dumpAsYaml(java.nio.file.Path destination, boolean prependCreationComment) throws java.io.IOException {
+  public DumpBuilder dumpAsYaml(Path destination, boolean prependCreationComment) throws java.io.IOException {
     String content = build().printYaml(prependCreationComment);
-    try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
+    try (Writer writer = Files.newBufferedWriter(destination)) {
       writer.write(content);
     }
     return this;
@@ -692,12 +703,10 @@ public class DumpBuilder {
    *
    * @param destination path of destination file
    * @return this
-   * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+   * @throws java.io.IOException if an I/O error happened during opening or writing in that file
    */
-  public DumpBuilder dumpAsPNG(java.nio.file.Path destination) throws java.io.IOException {
-    String content = build().toPlantUml();
-    net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
-    reader.outputImage(java.nio.file.Files.newOutputStream(destination));
+  public DumpBuilder dumpAsPNG(Path destination) throws java.io.IOException {
+    dumpAs(destination, FileFormat.PNG);
     return this;
   }
 
@@ -706,16 +715,34 @@ public class DumpBuilder {
    *
    * @param destination path of destination file
    * @return this
-   * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+   * @throws java.io.IOException if an I/O error happened during opening or writing in that file
    */
-  public DumpBuilder dumpAsSVG(java.nio.file.Path destination) throws java.io.IOException {
-    String content = build().toPlantUml();
-    net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
-    reader.outputImage(java.nio.file.Files.newOutputStream(destination),
-        new net.sourceforge.plantuml.FileFormatOption(net.sourceforge.plantuml.FileFormat.SVG));
+  public DumpBuilder dumpAsSVG(Path destination) throws java.io.IOException {
+    dumpAs(destination, FileFormat.SVG);
+    return this;
+  }
+
+  /**
+   * Write out content as PDF generated by plantuml.
+   *
+   * <br>
+   * <b>Note:</b> This requires additional dependencies, see <a href="https://plantuml.com/pdf">https://plantuml.com/pdf</a>
+   *
+   * @param destination path of destination file
+   * @return this
+   * @throws java.io.IOException if an I/O error happened during opening or writing in that file
+   */
+  public DumpBuilder dumpAsPDF(Path destination) throws java.io.IOException {
+    dumpAs(destination, FileFormat.PDF);
     return this;
   }
 
+  private void dumpAs(Path destination, FileFormat fileFormat) throws IOException {
+    String content = build().toPlantUml();
+    SourceStringReader reader = new SourceStringReader(content);
+    reader.outputImage(Files.newOutputStream(destination), new FileFormatOption(fileFormat));
+  }
+
   // --- Helper methods ---
 
   protected DumpAst build() {
@@ -767,7 +794,7 @@ public class DumpBuilder {
     return result;
   }
 
-  private void updateRegexes(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String regex, String... moreRegexes) {
+  private void updateRegexes(Supplier<String> getter, Consumer<String> setter, String regex, String... moreRegexes) {
     if (getter.get().isEmpty()) {
       setter.accept(regex);
     } else {
@@ -780,7 +807,7 @@ public class DumpBuilder {
 
   private String readVersion() {
     try {
-      java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion");
+      ResourceBundle resources = ResourceBundle.getBundle("dumpAstVersion");
       return resources.getString("version");
     } catch (java.util.MissingResourceException e) {
       return "version ?";
diff --git a/dumpAst/src/main/resources/dumpAstVersion.properties b/dumpAst/src/main/resources/dumpAstVersion.properties
index 086530a..25bac21 100644
--- a/dumpAst/src/main/resources/dumpAstVersion.properties
+++ b/dumpAst/src/main/resources/dumpAstVersion.properties
@@ -1,2 +1,2 @@
-#Thu Jun 23 16:13:20 CEST 2022
-version=1.1.0
+#Tue Jul 05 15:14:22 CEST 2022
+version=1.2.0
diff --git a/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java b/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java
index 99cd85d..cd6436b 100644
--- a/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java
+++ b/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java
@@ -40,6 +40,8 @@ public class FeatureTestMain {
 
     Path pathToYaml = Paths.get("featureTest.yml");
     Path pathToPng = Paths.get("featureTest.png");
+    Path pathToSvg = Paths.get("featureTest.svg");
+    Path pathToPdf = Paths.get("featureTest.pdf");
     Dumper
 //        .read(null)
         .read(root)
@@ -68,6 +70,8 @@ public class FeatureTestMain {
 //        .enableRelationWithRank()
         .dumpAsYaml(pathToYaml, true)
         .dumpAsPNG(pathToPng)
+        .dumpAsSVG(pathToSvg)
+        .dumpAsPDF(pathToPdf)
         .dumpAsSource(Paths.get("featureTest.puml"))
     ;
   }
diff --git a/pages/docs/adding.md b/pages/docs/adding.md
index cca2cbf..6b5c91c 100644
--- a/pages/docs/adding.md
+++ b/pages/docs/adding.md
@@ -19,7 +19,7 @@ Add `dumpAst` as a dependency:
 
 ```
 dependencies {
-    implementation group: 'de.tudresden.inf.st', name: 'dumpAst', version: '1.0.1'
+    implementation group: 'de.tudresden.inf.st', name: 'dumpAst', version: '1.2.0'
 }
 ```
 
-- 
GitLab