From eee147a9a0966aa38c695d039239e68fd06e7e95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= <aurelien.mino@gmail.com>
Date: Sat, 14 Sep 2024 23:25:26 +0200
Subject: [PATCH] feat(module-builder): add a new API that allows to directly
 add a {Mandatory|Optional} replacer to the replacements This allows reusing
 replacers, and improves readability and maintainability of the code

---
 .../vue/core/domain/VueModulesFactory.java    | 23 +++++++++++--------
 .../domain/JHipsterModuleShortcuts.java       |  8 +++++--
 ...terModuleMandatoryReplacementsFactory.java |  6 +++++
 ...sterModuleOptionalReplacementsFactory.java |  6 +++++
 .../JHipsterModuleReplacementsFactory.java    |  8 +++++++
 .../domain/replacement/MandatoryReplacer.java |  5 ++++
 6 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java
index c0c15623802..da8c26dabe5 100644
--- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java
@@ -11,6 +11,7 @@
 import tech.jhipster.lite.module.domain.file.JHipsterDestination;
 import tech.jhipster.lite.module.domain.file.JHipsterSource;
 import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;
+import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer;
 import tech.jhipster.lite.module.domain.replacement.TextReplacer;
 import tech.jhipster.lite.shared.error.domain.Assert;
 
@@ -108,16 +109,17 @@ private Consumer<JHipsterModuleBuilder> patchTsConfig(JHipsterModuleProperties p
       .mandatoryReplacements()
         .in(path("tsconfig.json"))
           .add(text("@tsconfig/recommended/tsconfig.json"), "@vue/tsconfig/tsconfig.dom.json")
-          .add(lineAfterRegex("\"compilerOptions\":"), compilerOption("sourceMap", true, properties.indentation()))
-          .add(lineAfterRegex("\"compilerOptions\":"), compilerOption("allowJs", true, properties.indentation()))
+          .add(tsConfigCompilerOption("sourceMap", true, properties.indentation()))
+          .add(tsConfigCompilerOption("allowJs", true, properties.indentation()))
           .add(new TextReplacer(notContainingReplacement(), "\"types\": ["), "\"types\": [\"vite/client\", ")
           .and()
         .and();
     //@formatter:on
   }
 
-  private static String compilerOption(String optionName, boolean optionValue, Indentation indentation) {
-    return indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue);
+  private static MandatoryReplacer tsConfigCompilerOption(String optionName, boolean optionValue, Indentation indentation) {
+    String compilerOption = indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue);
+    return new MandatoryReplacer(lineAfterRegex("\"compilerOptions\":"), compilerOption);
   }
 
   private Consumer<JHipsterModuleBuilder> patchVitestConfig(JHipsterModuleProperties properties) {
@@ -128,16 +130,17 @@ private Consumer<JHipsterModuleBuilder> patchVitestConfig(JHipsterModuleProperti
           .add(lineAfterRegex("from 'vitest/config';"), "import vue from '@vitejs/plugin-vue';")
           .add(new TextReplacer(notContainingReplacement(), "plugins: ["), "plugins: [vue(), ")
           .add(text("environment: 'node',"), "environment: 'jsdom',")
-          .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/**/*.component.ts"))
-          .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/router.ts"))
-          .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/injections.ts"))
-          .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/main.ts"))
+          .add(vitestCoverageExclusion(properties,"src/main/webapp/**/*.component.ts"))
+          .add(vitestCoverageExclusion(properties,"src/main/webapp/app/router.ts"))
+          .add(vitestCoverageExclusion(properties,"src/main/webapp/app/injections.ts"))
+          .add(vitestCoverageExclusion(properties,"src/main/webapp/app/main.ts"))
         .and();
     //@formatter:on
   }
 
-  private static String vitestCoverageExclusion(Indentation indentation, String filePattern) {
-    return indentation.times(4) + "'" + filePattern + "',";
+  private static MandatoryReplacer vitestCoverageExclusion(JHipsterModuleProperties properties, String filePattern) {
+    Indentation indentation = properties.indentation();
+    return new MandatoryReplacer(lineAfterRegex("configDefaults.coverage.exclude"), indentation.times(4) + "'" + filePattern + "',");
   }
 
   public JHipsterModule buildPiniaModule(JHipsterModuleProperties properties) {
diff --git a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java
index 8addcf7a988..6fc7f3416ba 100644
--- a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java
+++ b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java
@@ -68,14 +68,18 @@ void springTestLogger(String name, LogLevel level) {
     Assert.notBlank("name", name);
     Assert.notNull("level", level);
 
-    builder.optionalReplacements().in(SPRING_TEST_LOG_FILE).add(JHIPSTER_LOGGER_NEEDLE, logger(name, level));
+    builder.optionalReplacements().in(SPRING_TEST_LOG_FILE).add(logConfigurationEntry(name, level));
   }
 
   void springMainLogger(String name, LogLevel level) {
     Assert.notBlank("name", name);
     Assert.notNull("level", level);
 
-    builder.optionalReplacements().in(SPRING_MAIN_LOG_FILE).add(JHIPSTER_LOGGER_NEEDLE, logger(name, level));
+    builder.optionalReplacements().in(SPRING_MAIN_LOG_FILE).add(logConfigurationEntry(name, level));
+  }
+
+  private OptionalReplacer logConfigurationEntry(String name, LogLevel level) {
+    return new OptionalReplacer(JHIPSTER_LOGGER_NEEDLE, logger(name, level));
   }
 
   private String logger(String name, LogLevel level) {
diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java
index 8f7c3550e43..35a31ffff05 100644
--- a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java
+++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java
@@ -52,6 +52,12 @@ private JHipsterModuleFileMandatoryReplacementsFactoryBuilder(
       super(replacements, file);
     }
 
+    public JHipsterModuleFileMandatoryReplacementsFactoryBuilder add(MandatoryReplacer mandatoryReplacer) {
+      replacements().add(buildReplacer(file(), mandatoryReplacer.replacer(), mandatoryReplacer.updatedValue()));
+
+      return this;
+    }
+
     @Override
     protected ContentReplacer buildReplacer(JHipsterProjectFilePath file, ElementReplacer toReplace, String replacement) {
       return new MandatoryFileReplacer(file, new MandatoryReplacer(toReplace, replacement));
diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java
index e5d3e3a8ebc..66df8a99bc9 100644
--- a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java
+++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java
@@ -80,6 +80,12 @@ private JHipsterModuleFileOptionalReplacementsFactoryBuilder(
       super(replacements, file);
     }
 
+    public JHipsterModuleFileOptionalReplacementsFactoryBuilder add(OptionalReplacer mandatoryReplacer) {
+      replacements().add(buildReplacer(file(), mandatoryReplacer.replacer(), mandatoryReplacer.updatedValue()));
+
+      return this;
+    }
+
     @Override
     protected ContentReplacer buildReplacer(JHipsterProjectFilePath file, ElementReplacer toReplace, String replacement) {
       return new OptionalFileReplacer(file, new OptionalReplacer(toReplace, replacement));
diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java
index 59f7957f5ee..ce4abf2b286 100644
--- a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java
+++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java
@@ -80,6 +80,14 @@ public Builder add(ElementReplacer elementToReplace, String replacement) {
       return self();
     }
 
+    protected ReplacementsBuilder replacements() {
+      return replacements;
+    }
+
+    protected JHipsterProjectFilePath file() {
+      return file;
+    }
+
     @SuppressWarnings("unchecked")
     private Builder self() {
       return (Builder) this;
diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/MandatoryReplacer.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/MandatoryReplacer.java
index f149504e877..403d08be600 100644
--- a/src/main/java/tech/jhipster/lite/module/domain/replacement/MandatoryReplacer.java
+++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/MandatoryReplacer.java
@@ -1,5 +1,7 @@
 package tech.jhipster.lite.module.domain.replacement;
 
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 import tech.jhipster.lite.shared.error.domain.Assert;
 
 public record MandatoryReplacer(ElementReplacer replacer, String updatedValue) {
@@ -9,6 +11,9 @@ public record MandatoryReplacer(ElementReplacer replacer, String updatedValue) {
   }
 
   public String apply(String content) {
+    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
+    builder.modules(new JavaTimeModule());
+
     if (replacer.dontNeedReplacement(content, updatedValue())) {
       return content;
     }