Compare commits

..

2 Commits

  1. 33
      pom.xml
  2. 149
      pom.xml.versionsBackup
  3. 5
      src/main/java/de/kreth/property2java/Configuration.java
  4. 3
      src/main/java/de/kreth/property2java/Generator.java
  5. 5
      src/main/java/de/kreth/property2java/GeneratorOptions.java
  6. 8
      src/main/resources/template/enum_template_with_initializer.tpl
  7. 11
      src/main/resources/template/enum_template_with_inner_properties.tpl
  8. 8
      src/main/resources/template/enum_template_with_inner_propertyresourcebundle.tpl
  9. 70
      src/main/resources/template/parts/WithSubstitutors.tpl
  10. 7
      src/main/resources/template/parts/key_value_part.tpl
  11. 5
      src/main/resources/template/parts/withOptions.tpl
  12. 2
      src/test/java/de/kreth/property2java/GeneratorTests.java
  13. 4
      src/test/java/de/kreth/property2java/GeneratorWithInnerPropertiesTest.java
  14. 11
      src/test/java/de/kreth/property2java/TestPropertiesSource.java
  15. 47
      src/test/java/de/kreth/property2java/generated/GenerateTheTest.java
  16. 203
      src/test/java/de/kreth/property2java/generated/Property_Loader_Options_Properties.java
  17. 13
      src/test/java/de/kreth/property2java/generated/Property_Loader_Properties.java
  18. 11
      src/test/java/de/kreth/property2java/generated/Resource_Bundle_Properties.java
  19. 5
      src/test/java/de/kreth/property2java/generated/TestRealGenerated.java
  20. 8
      src/test/java/de/kreth/property2java/generated/Unary_Operator_Properties.java
  21. 65
      src/test/java/de/kreth/property2java/parts/ReplaceLogicForTemplate.java
  22. 82
      src/test/java/de/kreth/property2java/parts/ReplaceLogicForTemplateTest.java
  23. 1
      src/test/resources/property_loader.properties
  24. 25
      src/test/resources/property_loader_options.properties
  25. 1
      src/test/resources/resource_bundle.properties
  26. 1
      src/test/resources/unary_operator.properties

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.kreth.property2java</groupId>
<artifactId>PropertyToJavaGenerator</artifactId>
<version>2.0.3-SNAPSHOT</version>
<version>3.0.0-SNAPSHOT</version>
<properties>
@ -23,22 +23,22 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.10.0</version>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
<version>2.3.33</version>
</dependency>
<!-- LOGGING -->
@ -70,51 +70,58 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
<version>5.11.0-RC1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.2</version>
<version>5.11.0-RC1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.3.2</version>
<version>5.11.0-RC1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.5.0-M1</version>
<version>1.11.0-RC1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.5.0-M1</version>
<version>1.11.0-RC1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.24.5</version>
<version>5.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.24.5</version>
<version>5.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>2.1-rc4</version>
<version>3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.26.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.kreth.property2java</groupId>
<artifactId>PropertyToJavaGenerator</artifactId>
<version>2.0.3-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<org.junit.jupiter>5.3.0-M1</org.junit.jupiter>
<org.slf4j>1.7.36</org.slf4j>
<org.apache.logging.log4j>2.17.2</org.apache.logging.log4j>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<!-- LOGGING -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${org.apache.logging.log4j}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${org.apache.logging.log4j}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${org.apache.logging.log4j}</version>
<scope>runtime</scope>
</dependency>
<!-- TESTING -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.5.0-M1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.5.0-M1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.24.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.24.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>2.1-rc4</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<snapshotRepository>
<id>kreth.snapshots</id>
<url>https://nexus.kreth-development.de/repository/maven-snapshots/</url>
</snapshotRepository>
<repository>
<id>kreth.releases</id>
<url>https://nexus.kreth-development.de/repository/maven-releases/</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>${java.version}</release>
<compilerArgs>-proc:none</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
<scm>
<developerConnection>scm:git:https://gitea.kreth-development.de/markus/PropertyToJavaGenerator_migration.git</developerConnection>
<connection>scm:git:https://gitea.kreth-development.de/markus/PropertyToJavaGenerator_migration.git</connection>
<tag>HEAD</tag>
</scm>
</project>

@ -7,6 +7,7 @@ import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.Map;
import org.apache.commons.text.WordUtils;
@ -41,6 +42,10 @@ public interface Configuration {
*/
Path getRootPath();
default EnumSet<GeneratorOptions> getOptions() {
return EnumSet.noneOf(GeneratorOptions.class);
}
default Writer outWriter(String fileName) throws IOException {
return new FileWriter(new File(getRootPath().toFile(), mapFilenameToClassName(fileName) + ".java"),
outputCharset());

@ -64,6 +64,9 @@ public class Generator {
root.put("fileName", fileName);
root.put("bundle_base_name", fileName.substring(0, min(fileName.length(), fileName.lastIndexOf('.'))));
root.put("classname", config.mapFilenameToClassName(fileName));
if (config.getOptions().isEmpty() == false) {
root.put("options", config.getOptions());
}
List<Entry> entries = new ArrayList<>();

@ -0,0 +1,5 @@
package de.kreth.property2java;
public enum GeneratorOptions {
WithSubstitutors
}

@ -21,13 +21,7 @@ import javax.annotation.processing.Generated;
function = resourceFunction;
}
/**
* Represented Key in property File.
* @return key
*/
public String getValue() {
return value;
}
<#include "parts/key_value_part.tpl">
/**
* Resolves the value for this key.

@ -23,20 +23,15 @@ import javax.annotation.processing.Generated;
private final String value;
/**
* Represented Key in property File.
* @return key
*/
public String getValue() {
return value;
}
<#include "parts/key_value_part.tpl">
/**
* The Text for this Key from PropertyResourceBundle
* The text for this key from {@link Properties}
* @return human readable text
*/
public String getText() {
return properties.getProperty(value);
}
<#include "parts/withOptions.tpl">
}

@ -17,13 +17,7 @@ import javax.annotation.processing.Generated;
this.value = value;
}
/**
* Represented Key in property File.
* @return key
*/
public String getValue() {
return value;
}
<#include "parts/key_value_part.tpl">
/**
* The Text for this Key from PropertyResourceBundle

@ -0,0 +1,70 @@
/**
* The text for this key from {@link Properties} with args as replacements of placeholders.
* <p>Placeholder must be defined as {0}, {1} etc.
* @return human readable text
*/
public String getText(Object...objects) {
String property = properties.getProperty(value);
return doReplacements(property, objects);
}
<#-- From here tested substitution method -->
private String doReplacements(String property, Object...objects) {
StringBuilder text = new StringBuilder();
int index = property.indexOf('{');
text.append(property.substring(0, index));
while (index >= 0) {
index++;
int endIndex = withEndIndex(index, property);
if (endIndex >0) {
String theIndex = property.substring(index, endIndex);
int withIndex = Integer.valueOf(theIndex);
if (withIndex+1> objects.length) {
throw new IllegalStateException("No Argument for Index {" + theIndex
+ "}" + " at Position=" + (index - 1) + " in \"" + property + "\"");
}
text.append(objects[withIndex].toString());
index = property.indexOf('{', endIndex);
if (index <0) {
text.append(property.substring(endIndex + 1));
} else {
text.append(property.substring(endIndex + 1, index));
}
} else {
endIndex = index;
index = property.indexOf('{', index);
if (index <0) {
text.append('{');
text.append(property.substring(endIndex));
}
}
}
return text.toString();
}
/**
* extracts the end index, if (and only if) the closing } exists and
* between the indicee an integer value exists.
* @param index
* @param property
* @return -1 if invalid or not existing
*/
private int withEndIndex(int index, String property) {
int result = -1;
int endIndex = property.indexOf('}', index);
if (endIndex >index) {
String between = property.substring(index, endIndex);
if (between.length() > 0) {
result = endIndex;
for(int i=0; i<between.length(); i++) {
if (Character.isDigit(between.charAt(i)) == false) {
return -1;
}
}
}
}
return result;
}

@ -0,0 +1,7 @@
/**
* Represented Key in property File.
* @return key
*/
public String getKey() {
return value;
}

@ -0,0 +1,5 @@
<#if options??>
<#list options as option>
<#include "${option}.tpl">
</#list>
</#if>

@ -120,7 +120,7 @@ class GeneratorTests {
List<String> lines = out.toString().lines().filter(line -> line.contains(" (\"")).collect(Collectors.toList());
assertEquals(21, lines.size());
assertEquals(22, lines.size());
assertLineMatch(lines, "label", "label");
assertLineMatch(lines, "label_addarticle", "label.addarticle");
assertLineMatch(lines, "label_user_register", "label.user.register");

@ -20,6 +20,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
@ -121,6 +122,7 @@ public class GeneratorWithInnerPropertiesTest {
if (line.contains("Properties")
&& !line.contains("import")
&& !line.contains("enum")
&& !line.contains("@link")
&& !line.contains("class")) {
declaration = line;
} else if (line.contains(".load")) {
@ -159,7 +161,7 @@ public class GeneratorWithInnerPropertiesTest {
List<String> lines = out.toString().lines().filter(line -> line.contains(" (\"")).collect(Collectors.toList());
assertEquals(21, lines.size());
assertEquals(22, lines.size());
assertLineMatch(lines, "label", "label");
assertLineMatch(lines, "label_addarticle", "label.addarticle");
assertLineMatch(lines, "label_user_register", "label.user.register");

@ -25,7 +25,8 @@ public class TestPropertiesSource {
+ "message.invoiceitem.startbeforeend = End must be later than start.\r\n"
+ "message.user.create.success = Thanks {0} created!\r\n"
+ "message.user.loginfailure = Login Error! Wrong user or password?\r\n"
+ "message.user.passwordmissmatch = Passwords don't match.\r\n" + "");
+ "message.user.passwordmissmatch = Passwords don't match.\r\n"
+ "message.with.five.placeholders = Third is first{2}, then last \"{4}\", second={1}, fourth={3} and first is last={0}\r\n");
}
public static void main(String[] args) throws IOException {
@ -33,13 +34,21 @@ public class TestPropertiesSource {
try (FileWriter out = new FileWriter(new File(dir, GenerateTheTest.PROPERTY_LOADER_PROPERTIES))) {
testProperties().transferTo(out);
System.out.println("Generated: " + GenerateTheTest.PROPERTY_LOADER_PROPERTIES);
}
try (FileWriter out = new FileWriter(new File(dir, GenerateTheTest.UNARY_OPERATOR_PROPERTIES))) {
testProperties().transferTo(out);
System.out.println("Generated: " + GenerateTheTest.UNARY_OPERATOR_PROPERTIES);
}
try (FileWriter out = new FileWriter(new File(dir, GenerateTheTest.RESOURCE_BUNDLE))) {
testProperties().transferTo(out);
System.out.println("Generated: " + GenerateTheTest.RESOURCE_BUNDLE);
}
try (FileWriter out = new FileWriter(new File(dir, GenerateTheTest.PROPERTY_LOADER_OPTIONS_PROPERTIES))) {
testProperties().transferTo(out);
System.out.println("Generated: " + GenerateTheTest.PROPERTY_LOADER_OPTIONS_PROPERTIES);
}
}
}

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.Reader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
@ -11,11 +12,13 @@ import de.kreth.property2java.Configuration;
import de.kreth.property2java.Format;
import de.kreth.property2java.Generator;
import de.kreth.property2java.GeneratorException;
import de.kreth.property2java.GeneratorOptions;
import de.kreth.property2java.TestPropertiesSource;
public class GenerateTheTest {
public static final String PROPERTY_LOADER_PROPERTIES = "property_loader.properties";
public static final String PROPERTY_LOADER_OPTIONS_PROPERTIES = "property_loader_options.properties";
public static final String UNARY_OPERATOR_PROPERTIES = "unary_operator.properties";
public static final String RESOURCE_BUNDLE = "resource_bundle.properties";
@ -26,12 +29,14 @@ public class GenerateTheTest {
withUnaryOperatorParameter(current);
withInnerPropertyLoader(current);
withResourceBundle(current);
withInnerPropertyLoaderAndSubstitutors(current);
}
private static void withResourceBundle(Path current) throws IOException, GeneratorException {
Format format = Format.WithInnerPropertyResourceBundle;
Map<String, Reader> input = new HashMap<>();
input.put(RESOURCE_BUNDLE, TestPropertiesSource.testProperties());
System.out.println("Generating: " + RESOURCE_BUNDLE);
Configuration config = new Configuration() {
@ -64,6 +69,8 @@ public class GenerateTheTest {
Map<String, Reader> input = new HashMap<>();
input.put(UNARY_OPERATOR_PROPERTIES, TestPropertiesSource.testProperties());
System.out.println("Generating: " + UNARY_OPERATOR_PROPERTIES);
Configuration config = new Configuration() {
@Override
@ -95,6 +102,8 @@ public class GenerateTheTest {
Map<String, Reader> input = new HashMap<>();
input.put(PROPERTY_LOADER_PROPERTIES, TestPropertiesSource.testProperties());
System.out.println("Generating: " + PROPERTY_LOADER_PROPERTIES);
Configuration config = new Configuration() {
@Override
@ -121,4 +130,42 @@ public class GenerateTheTest {
generator.start();
}
private static void withInnerPropertyLoaderAndSubstitutors(Path current) throws IOException, GeneratorException {
Format format = Format.WithInnerPropertyLoader;
Map<String, Reader> input = new HashMap<>();
input.put(PROPERTY_LOADER_OPTIONS_PROPERTIES, TestPropertiesSource.testProperties());
System.out.println("Generating: " + PROPERTY_LOADER_OPTIONS_PROPERTIES);
Configuration config = new Configuration() {
@Override
public Path getRootPath() {
return current;
}
@Override
public String getPackage() {
return "de.kreth.property2java.generated";
}
@Override
public Format getFormat() {
return format;
}
@Override
public EnumSet<GeneratorOptions> getOptions() {
return EnumSet.allOf(GeneratorOptions.class);
}
@Override
public Map<String, Reader> getInput() {
return input;
}
};
Generator generator = new Generator(config);
generator.start();
}
}

@ -0,0 +1,203 @@
package de.kreth.property2java.generated;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Properties;
import javax.annotation.processing.Generated;
/**
* Property keys from property_loader_options.properties
*/
@Generated(date = "06.08.2024, 23:03:48", value = "de.kreth.property2java.Generator")
public enum Property_Loader_Options_Properties {
/**
* label = ""
*/
LABEL ("label"),
/**
* label.addarticle = "Add Article"
*/
LABEL_ADDARTICLE ("label.addarticle"),
/**
* label.cancel = "Cancel"
*/
LABEL_CANCEL ("label.cancel"),
/**
* label.close = "Close"
*/
LABEL_CLOSE ("label.close"),
/**
* label.delete = "Delete"
*/
LABEL_DELETE ("label.delete"),
/**
* label.discart = "Discart"
*/
LABEL_DISCART ("label.discart"),
/**
* label.loggedin = "Logged in:"
*/
LABEL_LOGGEDIN ("label.loggedin"),
/**
* label.logout = "Logout"
*/
LABEL_LOGOUT ("label.logout"),
/**
* label.ok = "OK"
*/
LABEL_OK ("label.ok"),
/**
* label.open = "Open"
*/
LABEL_OPEN ("label.open"),
/**
* label.preview = "Preview"
*/
LABEL_PREVIEW ("label.preview"),
/**
* label.store = "Store"
*/
LABEL_STORE ("label.store"),
/**
* label.user.register = "Register"
*/
LABEL_USER_REGISTER ("label.user.register"),
/**
* message.article.priceerror = "Please set the price."
*/
MESSAGE_ARTICLE_PRICEERROR ("message.article.priceerror"),
/**
* message.delete.text = "Delete {0}?"
*/
MESSAGE_DELETE_TEXT ("message.delete.text"),
/**
* message.delete.title = "Really delete?"
*/
MESSAGE_DELETE_TITLE ("message.delete.title"),
/**
* message.invoiceitem.allfieldsmustbeset = "Start, end and article must not be
empty!"
*/
MESSAGE_INVOICEITEM_ALLFIELDSMUSTBESET ("message.invoiceitem.allfieldsmustbeset"),
/**
* message.invoiceitem.startbeforeend = "End must be later than start."
*/
MESSAGE_INVOICEITEM_STARTBEFOREEND ("message.invoiceitem.startbeforeend"),
/**
* message.user.create.success = "Thanks {0} created!"
*/
MESSAGE_USER_CREATE_SUCCESS ("message.user.create.success"),
/**
* message.user.loginfailure = "Login Error! Wrong user or password?"
*/
MESSAGE_USER_LOGINFAILURE ("message.user.loginfailure"),
/**
* message.user.passwordmissmatch = "Passwords don't match."
*/
MESSAGE_USER_PASSWORDMISSMATCH ("message.user.passwordmissmatch"),
/**
* message.with.five.placeholders = "Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}"
*/
MESSAGE_WITH_FIVE_PLACEHOLDERS ("message.with.five.placeholders");
private Property_Loader_Options_Properties (String value) {
this.value = value;
}
private static Properties properties = new Properties();
static {
try {
properties.load(Property_Loader_Options_Properties.class.getResourceAsStream("/property_loader_options.properties"));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private final String value;
/**
* Represented Key in property File.
* @return key
*/
public String getKey() {
return value;
}
/**
* The text for this key from {@link Properties}
* @return human readable text
*/
public String getText() {
return properties.getProperty(value);
}
/**
* The text for this key from {@link Properties} with args as replacements of placeholders.
* <p>Placeholder must be defined as {0}, {1} etc.
* @return human readable text
*/
public String getText(Object...objects) {
String property = properties.getProperty(value);
return doReplacements(property, objects);
}
private String doReplacements(String property, Object...objects) {
StringBuilder text = new StringBuilder();
int index = property.indexOf('{');
text.append(property.substring(0, index));
while (index >= 0) {
index++;
int endIndex = withEndIndex(index, property);
if (endIndex >0) {
String theIndex = property.substring(index, endIndex);
int withIndex = Integer.valueOf(theIndex);
if (withIndex+1> objects.length) {
throw new IllegalStateException("No Argument for Index {" + theIndex
+ "}" + " at Position=" + (index - 1) + " in \"" + property + "\"");
}
text.append(objects[withIndex].toString());
index = property.indexOf('{', endIndex);
if (index <0) {
text.append(property.substring(endIndex + 1));
} else {
text.append(property.substring(endIndex + 1, index));
}
} else {
endIndex = index;
index = property.indexOf('{', index);
if (index <0) {
text.append('{');
text.append(property.substring(endIndex));
}
}
}
return text.toString();
}
/**
* extracts the end index, if (and only if) the closing } exists and
* between the indicee an integer value exists.
* @param index
* @param property
* @return -1 if invalid or not existing
*/
private int withEndIndex(int index, String property) {
int result = -1;
int endIndex = property.indexOf('}', index);
if (endIndex >index) {
String between = property.substring(index, endIndex);
if (between.length() > 0) {
result = endIndex;
for(int i=0; i<between.length(); i++) {
if (Character.isDigit(between.charAt(i)) == false) {
return -1;
}
}
}
}
return result;
}}

@ -10,7 +10,7 @@ import javax.annotation.processing.Generated;
* Property keys from property_loader.properties
*/
@Generated(date = "05.08.2024, 22:43:54", value = "de.kreth.property2java.Generator")
@Generated(date = "06.08.2024, 23:03:48", value = "de.kreth.property2java.Generator")
public enum Property_Loader_Properties {
/**
@ -97,7 +97,11 @@ public enum Property_Loader_Properties {
/**
* message.user.passwordmissmatch = "Passwords don't match."
*/
MESSAGE_USER_PASSWORDMISSMATCH ("message.user.passwordmissmatch");
MESSAGE_USER_PASSWORDMISSMATCH ("message.user.passwordmissmatch"),
/**
* message.with.five.placeholders = "Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}"
*/
MESSAGE_WITH_FIVE_PLACEHOLDERS ("message.with.five.placeholders");
private Property_Loader_Properties (String value) {
this.value = value;
}
@ -117,12 +121,11 @@ public enum Property_Loader_Properties {
* Represented Key in property File.
* @return key
*/
public String getValue() {
public String getKey() {
return value;
}
/**
* The Text for this Key from PropertyResourceBundle
* The text for this key from {@link Properties}
* @return human readable text
*/
public String getText() {

@ -11,7 +11,7 @@ import javax.annotation.processing.Generated;
* Initializationis generated also.
*/
@Generated(date = "05.08.2024, 22:43:54", value = "de.kreth.property2java.Generator")
@Generated(date = "06.08.2024, 23:03:48", value = "de.kreth.property2java.Generator")
public enum Resource_Bundle_Properties {
/**
@ -98,7 +98,11 @@ public enum Resource_Bundle_Properties {
/**
* message.user.passwordmissmatch = "Passwords don't match."
*/
MESSAGE_USER_PASSWORDMISSMATCH ("message.user.passwordmissmatch");
MESSAGE_USER_PASSWORDMISSMATCH ("message.user.passwordmissmatch"),
/**
* message.with.five.placeholders = "Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}"
*/
MESSAGE_WITH_FIVE_PLACEHOLDERS ("message.with.five.placeholders");
private static ResourceBundle bundle = PropertyResourceBundle.getBundle("resource_bundle");
private final String value;
@ -111,10 +115,9 @@ public enum Resource_Bundle_Properties {
* Represented Key in property File.
* @return key
*/
public String getValue() {
public String getKey() {
return value;
}
/**
* The Text for this Key from PropertyResourceBundle
* @return human readable text

@ -16,4 +16,9 @@ public class TestRealGenerated {
assertEquals("Login Error! Wrong user or password?", Resource_Bundle_Properties.MESSAGE_USER_LOGINFAILURE.getText());
}
@Test
void substitution() {
String text = Property_Loader_Options_Properties.MESSAGE_WITH_FIVE_PLACEHOLDERS.getText("|R1|", "|R2|", "|R3|", "|R4|", "|R5|");
assertEquals("Third is first|R3|, then last \"|R5|\", second=|R2|, fourth=|R4| and first is last=|R1|", text);
}
}

@ -12,7 +12,7 @@ import javax.annotation.processing.Generated;
* the value is given directly.
*/
@Generated(date = "05.08.2024, 22:43:54", value = "de.kreth.property2java.Generator")
@Generated(date = "06.08.2024, 23:03:48", value = "de.kreth.property2java.Generator")
public enum Unary_Operator_Properties {
/**
@ -99,7 +99,11 @@ public enum Unary_Operator_Properties {
/**
* message.user.passwordmissmatch = "Passwords don't match."
*/
MESSAGE_USER_PASSWORDMISSMATCH ("message.user.passwordmissmatch");
MESSAGE_USER_PASSWORDMISSMATCH ("message.user.passwordmissmatch"),
/**
* message.with.five.placeholders = "Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}"
*/
MESSAGE_WITH_FIVE_PLACEHOLDERS ("message.with.five.placeholders");
private final String value;
private Unary_Operator_Properties (String value) {

@ -0,0 +1,65 @@
package de.kreth.property2java.parts;
public class ReplaceLogicForTemplate {
static String doReplacements(String property, Object...objects) {
StringBuilder text = new StringBuilder();
int index = property.indexOf('{');
text.append(property.substring(0, index));
while (index >= 0) {
index++;
int endIndex = withEndIndex(index, property);
if (endIndex >0) {
String theIndex = property.substring(index, endIndex);
int withIndex = Integer.valueOf(theIndex);
if (withIndex+1> objects.length) {
throw new IllegalStateException("No Argument for Index {" + theIndex
+ "}" + " at Position=" + (index - 1) + " in \"" + property + "\"");
}
text.append(objects[withIndex].toString());
index = property.indexOf('{', endIndex);
if (index <0) {
text.append(property.substring(endIndex + 1));
} else {
text.append(property.substring(endIndex + 1, index));
}
} else {
endIndex = index;
index = property.indexOf('{', index);
if (index <0) {
text.append('{');
text.append(property.substring(endIndex));
}
}
}
return text.toString();
}
/**
* extracts the end index, if (and only if) the closing } exists and
* between the indicee an integer value exists.
* @param index
* @param property
* @return -1 if invalid or not existing
*/
private static int withEndIndex(int index, String property) {
int result = -1;
int endIndex = property.indexOf('}', index);
if (endIndex >index) {
String between = property.substring(index, endIndex);
if (between.length() > 0) {
result = endIndex;
for(int i=0; i<between.length(); i++) {
if (Character.isDigit(between.charAt(i)) == false) {
return -1;
}
}
}
}
return result;
}
}

@ -0,0 +1,82 @@
package de.kreth.property2java.parts;
import static org.assertj.core.api.Assertions.*;
import static de.kreth.property2java.parts.ReplaceLogicForTemplate.doReplacements;
import org.junit.jupiter.api.Test;
public class ReplaceLogicForTemplateTest {
@Test
void testPlaceholderOnly() {
String property = "{0}";
String replaced = doReplacements(property, "Replacement");
assertThat(replaced).isEqualTo("Replacement");
}
@Test
void testPlaceholderTrailing() {
String property = "|{0}";
String replaced = doReplacements(property, "Replacement");
assertThat(replaced).isEqualTo("|Replacement");
}
@Test
void testPlaceholderLeading() {
String property = "{0}|";
String replaced = doReplacements(property, "Replacement");
assertThat(replaced).isEqualTo("Replacement|");
}
@Test
void testPlaceholderOrdered() {
String property = "Start{0}|{1}|{2}End";
String replaced = doReplacements(property, "R1", "R2", "R3");
assertThat(replaced).isEqualTo("StartR1|R2|R3End");
}
@Test
void testPlaceholdersOrderedAtEdgesAndMissingIndex() {
String property = "{0}||{2}";
String replaced = doReplacements(property, "R1", "R2", "R3");
assertThat(replaced).isEqualTo("R1||R3");
}
@Test
void testSimpleReplacementWithEmpty() {
String property = "Start{0}End";
String replaced = doReplacements(property, "");
assertThat(replaced).isEqualTo("StartEnd");
}
@Test
void testSimpleReplacementToManyArguments() {
String property = "Start{0}End";
String replaced = doReplacements(property, "|0|", "notUsed");
assertThat(replaced).isEqualTo("Start|0|End");
}
@Test
void testNoReplacementWithoutIndex() {
String property = "Start{}End";
String replaced = doReplacements(property, "|0|", "notUsed");
assertThat(replaced).isEqualTo("Start{}End");
}
@Test
void testNoReplacementWithNoIntBetweenBraces() {
String property = "Start{xy}End";
String replaced = doReplacements(property, "|0|", "notUsed");
assertThat(replaced).isEqualTo("Start{xy}End");
}
@Test
void testMissingReplacement() {
String property = "Start{1}End";
assertThatThrownBy(() -> doReplacements(property, "|0|"))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("{1}") // Orignal Placeholder
.hasMessageContaining("Position=5") // Index of missing Placeholder
.hasMessageContaining(property); // Orignal Text
}
}

@ -22,3 +22,4 @@ message.invoiceitem.startbeforeend = End must be later than start.
message.user.create.success = Thanks {0} created!
message.user.loginfailure = Login Error! Wrong user or password?
message.user.passwordmissmatch = Passwords don't match.
message.with.five.placeholders = Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}

@ -0,0 +1,25 @@
label =
label.addarticle = Add Article
label.cancel = Cancel
label.close = Close
label.delete = Delete
label.discart = Discart
label.loggedin = Logged in:
label.logout = Logout
label.ok = OK
label.store = Store
label.preview = Preview
label.open = Open
label.user.register = Register
message.article.priceerror = Please set the price.
message.delete.text = Delete {0}?
message.delete.title = Really delete?
message.invoiceitem.allfieldsmustbeset = Start, end and article must not be \r\n empty!
message.invoiceitem.startbeforeend = End must be later than start.
message.user.create.success = Thanks {0} created!
message.user.loginfailure = Login Error! Wrong user or password?
message.user.passwordmissmatch = Passwords don't match.
message.with.five.placeholders = Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}

@ -22,3 +22,4 @@ message.invoiceitem.startbeforeend = End must be later than start.
message.user.create.success = Thanks {0} created!
message.user.loginfailure = Login Error! Wrong user or password?
message.user.passwordmissmatch = Passwords don't match.
message.with.five.placeholders = Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}

@ -22,3 +22,4 @@ message.invoiceitem.startbeforeend = End must be later than start.
message.user.create.success = Thanks {0} created!
message.user.loginfailure = Login Error! Wrong user or password?
message.user.passwordmissmatch = Passwords don't match.
message.with.five.placeholders = Third is first{2}, then last "{4}", second={1}, fourth={3} and first is last={0}

Loading…
Cancel
Save