diff --git a/src/main/java/tech/jhipster/lite/module/domain/javaproperties/PropertyValue.java b/src/main/java/tech/jhipster/lite/module/domain/javaproperties/PropertyValue.java index 9630d6d8584..5b1d1f7ac39 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/javaproperties/PropertyValue.java +++ b/src/main/java/tech/jhipster/lite/module/domain/javaproperties/PropertyValue.java @@ -1,7 +1,7 @@ package tech.jhipster.lite.module.domain.javaproperties; -import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import tech.jhipster.lite.shared.collection.domain.JHipsterCollections; @@ -39,7 +39,7 @@ public Collection get() { } public static PropertyValue merge(PropertyValue v1, PropertyValue v2) { - Collection mergedValues = new ArrayList<>(); + Collection mergedValues = new LinkedHashSet<>(); mergedValues.addAll(v1.get()); mergedValues.addAll(v2.get()); diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandler.java b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandler.java index bb61078f0a4..405aa83b981 100644 --- a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandler.java +++ b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandler.java @@ -3,8 +3,10 @@ import static java.util.stream.Collectors.joining; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Properties; import tech.jhipster.lite.module.domain.javaproperties.PropertyKey; import tech.jhipster.lite.module.domain.javaproperties.PropertyValue; import tech.jhipster.lite.shared.error.domain.Assert; @@ -13,16 +15,36 @@ public class PropertiesFileSpringFactoriesHandler { - private static final String EQUAL = "="; private static final String COLLECTION_SEPARATOR = ","; - private static final String LINE_BREAK = System.lineSeparator(); private final Path file; + private final Properties properties; public PropertiesFileSpringFactoriesHandler(Path file) { Assert.notNull("file", file); - this.file = file; + this.properties = new Properties(); + createPropertiesIfNotExists(file); + loadPropertiesFromFile(file); + } + + private void loadPropertiesFromFile(Path file) { + try (InputStream inputStream = Files.newInputStream(file)) { + properties.load(inputStream); + } catch (IOException e) { + throw GeneratorException.technicalError("Error updating Spring Factories properties: " + e.getMessage(), e); + } + } + + private static void createPropertiesIfNotExists(Path file) { + try { + if (Files.notExists(file)) { + Files.createDirectories(file.getParent()); + Files.createFile(file); + } + } catch (IOException e) { + throw GeneratorException.technicalError("Error updating Spring Factories properties: " + e.getMessage(), e); + } } public void append(PropertyKey key, PropertyValue value) { @@ -35,61 +57,26 @@ public void append(PropertyKey key, PropertyValue value) { @ExcludeFromGeneratedCodeCoverage(reason = "Hard to cover IOException") private void updateFactories(PropertyKey key, PropertyValue value) { try { - String properties = buildFactories(key, value); + buildFactories(key, value); - Files.writeString(file, properties); + properties.store(Files.newOutputStream(file.toAbsolutePath()), null); } catch (IOException e) { throw GeneratorException.technicalError("Error updating Spring Factories properties: " + e.getMessage(), e); } } - private String buildFactories(PropertyKey key, PropertyValue value) throws IOException { - String currentProperties = readOrInitFactories(); - - int propertyIndex = currentProperties.indexOf(propertyId(key)); - if (propertyIndex != -1) { - return appendValuesToExistingPropertyKey(propertyIndex, value, currentProperties); - } - return addNewFactory(key, value, currentProperties); - } - - private String addNewFactory(PropertyKey key, PropertyValue value, String currentProperties) { - return currentProperties + propertyLine(key, value) + LINE_BREAK; - } - - private static String appendValuesToExistingPropertyKey(int propertyIndex, PropertyValue value, String currentProperties) { - StringBuilder newProperties = new StringBuilder(currentProperties); - int eolIndex = newProperties.indexOf(LINE_BREAK, propertyIndex); - - for (Object propertyValue : value.get()) { - if (!newProperties.substring(propertyIndex, eolIndex).contains(propertyValue.toString())) { - newProperties.insert(eolIndex, COLLECTION_SEPARATOR + propertyValue); - eolIndex = eolIndex + COLLECTION_SEPARATOR.length() + propertyValue.toString().length(); - } + private void buildFactories(PropertyKey key, PropertyValue value) throws IOException { + if (properties.containsKey(key.get())) { + properties.setProperty( + key.get(), + joinedPropertyValues(PropertyValue.merge(PropertyValue.of(new String[] { properties.getProperty(key.get()) }), value)) + ); + } else { + properties.setProperty(key.get(), joinedPropertyValues(value)); } - return newProperties.toString(); - } - - private String readOrInitFactories() throws IOException { - if (Files.notExists(file)) { - Files.createDirectories(file.getParent()); - Files.createFile(file); - - return ""; - } - - return Files.readString(file); - } - - private String propertyLine(PropertyKey key, PropertyValue value) { - return propertyId(key) + joinedPropertyValues(value); } private static String joinedPropertyValues(PropertyValue value) { return value.get().stream().map(Object::toString).collect(joining(COLLECTION_SEPARATOR)); } - - private String propertyId(PropertyKey key) { - return key.get() + EQUAL; - } } diff --git a/src/test/java/tech/jhipster/lite/TestFileUtils.java b/src/test/java/tech/jhipster/lite/TestFileUtils.java index 55d1de2f584..6c9f35aa585 100644 --- a/src/test/java/tech/jhipster/lite/TestFileUtils.java +++ b/src/test/java/tech/jhipster/lite/TestFileUtils.java @@ -1,12 +1,13 @@ package tech.jhipster.lite; -import static java.nio.file.StandardCopyOption.*; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.UUID; import java.util.stream.Stream; import tech.jhipster.lite.module.domain.properties.JHipsterProjectFolder; @@ -42,6 +43,14 @@ public static String contentNormalizingNewLines(Path path) { return content(path).replace("\r\n", "\n"); } + public static List fileLines(Path path) { + try { + return Files.readAllLines(path); + } catch (IOException e) { + throw new AssertionError(e); + } + } + public static void loadDefaultProperties(Path from, Path to) { try { Files.createDirectories(to.getParent()); diff --git a/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/domain/CassandraMigrationModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/domain/CassandraMigrationModuleFactoryTest.java index 19ce1428c95..b92a2925b81 100644 --- a/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/domain/CassandraMigrationModuleFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/domain/CassandraMigrationModuleFactoryTest.java @@ -57,7 +57,7 @@ void shouldBuildModule() { .hasPrefixedFiles("src/main/docker/cassandra/scripts", "autoMigrate.sh", "execute-cql.sh") .hasFiles("src/test/java/tech/jhipster/jhlitest/TestCassandraMigrationLoader.java") .hasFile("src/test/resources/META-INF/spring.factories") - .containing( + .containingInSequence( "org.springframework.context.ApplicationListener=tech.jhipster.jhlitest.TestCassandraManager,tech.jhipster.jhlitest.TestCassandraMigrationLoader" ) .and() diff --git a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandlerTest.java b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandlerTest.java index ddeb11ca08c..bf485c9c9b5 100644 --- a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandlerTest.java +++ b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/PropertiesFileSpringFactoriesHandlerTest.java @@ -24,7 +24,7 @@ void shouldCreateUnknownFile() { handler.append(propertyKey("o.s.c.ApplicationListener"), propertyValue("c.m.m.MyListener1", "c.m.m.MyListener2")); - assertThat(contentNormalizingNewLines(factoriesFile)).isEqualTo( + assertThat(contentNormalizingNewLines(factoriesFile)).contains( """ o.s.c.ApplicationListener=c.m.m.MyListener1,c.m.m.MyListener2 """ @@ -39,11 +39,9 @@ void shouldAppendPropertyToFileWithProperties() { handler.append(propertyKey("o.s.c.ApplicationListener"), propertyValue("c.m.m.MyListener1", "c.m.m.MyListener2")); - assertThat(contentNormalizingNewLines(factoriesFile)).isEqualTo( - """ - org.springframework.test.context.ContextCustomizerFactory=c.m.m.MyContextCustomizerFactory - o.s.c.ApplicationListener=c.m.m.MyListener1,c.m.m.MyListener2 - """ + assertThat(fileLines(factoriesFile)).contains( + "org.springframework.test.context.ContextCustomizerFactory=c.m.m.MyContextCustomizerFactory", + "o.s.c.ApplicationListener=c.m.m.MyListener1,c.m.m.MyListener2" ); } @@ -58,7 +56,7 @@ void shouldAppendToExistingProperty() { propertyValue("c.m.m.MyFactory", "c.m.m.MyFactory2") ); - assertThat(contentNormalizingNewLines(factoriesFile)).isEqualTo( + assertThat(contentNormalizingNewLines(factoriesFile)).contains( """ org.springframework.test.context.ContextCustomizerFactory=c.m.m.MyContextCustomizerFactory,c.m.m.MyFactory,c.m.m.MyFactory2 """ @@ -77,11 +75,9 @@ void shouldAppendNewAndExistingProperties() { ); handler.append(propertyKey("o.s.c.ApplicationListener"), propertyValue("c.m.m.MyListener1")); - assertThat(contentNormalizingNewLines(factoriesFile)).isEqualTo( - """ - org.springframework.test.context.ContextCustomizerFactory=c.m.m.MyContextCustomizerFactory,c.m.m.MyNewContextCustomizerFactory - o.s.c.ApplicationListener=c.m.m.MyListener1 - """ + assertThat(fileLines(factoriesFile)).contains( + "org.springframework.test.context.ContextCustomizerFactory=c.m.m.MyContextCustomizerFactory,c.m.m.MyNewContextCustomizerFactory", + "o.s.c.ApplicationListener=c.m.m.MyListener1" ); } @@ -100,7 +96,7 @@ void shouldNotAppendExistingValue() { propertyValue("c.m.m.MyContextCustomizerFactory") ); - assertThat(contentNormalizingNewLines(factoriesFile)).isEqualTo( + assertThat(contentNormalizingNewLines(factoriesFile)).contains( """ org.springframework.test.context.ContextCustomizerFactory=c.m.m.MyContextCustomizerFactory """