diff --git a/.classpath b/.classpath index 7fae055..6fe0074 100644 --- a/.classpath +++ b/.classpath @@ -1,37 +1,49 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/META-INF/services/javax.annotation.processing.Processor b/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..d22a1ba --- /dev/null +++ b/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +de.kreth.property2java.processor.Property2JavaGenerator \ No newline at end of file diff --git a/pom.xml b/pom.xml index 17e28ad..37b07c1 100644 --- a/pom.xml +++ b/pom.xml @@ -14,12 +14,14 @@ UTF-8 11 5.3.0-M1 - 1.7.21 - 2.17.1 + 1.7.36 + 2.17.2 ${maven.build.timestamp} yyyy-MM-dd HH:mm:ss + 1.0-rc2 + 3f3a1fa86ea83226b564895f3a8503f67e855440 target/surefire-reports jacoco @@ -51,7 +53,7 @@ freemarker 2.3.28 - + org.slf4j @@ -136,34 +138,9 @@ 3.8.0 ${java.version} + -proc:none - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M3 - - - - org.jacoco - jacoco-maven-plugin - 0.8.2 - - - default-jacoco-prepare-agent - - prepare-agent - - - - default-jacoco-report - prepare-package - - report - - - - diff --git a/src/main/java/de/kreth/property2java/Configuration.java b/src/main/java/de/kreth/property2java/Configuration.java index a0032d8..6c1c426 100644 --- a/src/main/java/de/kreth/property2java/Configuration.java +++ b/src/main/java/de/kreth/property2java/Configuration.java @@ -15,38 +15,46 @@ import de.kreth.property2java.config.Regex; public interface Configuration { - /** - * Package for generated Java Classes eg. "de.kreth.property2java". If null - no package line is generated. - * @return - */ - String getPackage(); - - /** - * Filename to InputReader Entries - * @return - */ - Map getInput(); - - /** - * Path of java source folder. - * @return - */ - Path getRootPath(); - - default Writer outWriter(String fileName) throws IOException { - return new FileWriter(new File(getRootPath().toFile(), mapFilenameToClassName(fileName) + ".java"), - outputCharset()); - } - - default Charset outputCharset() { - return Charset.defaultCharset(); - } - - default String mapFilenameToClassName(String fileName) { - - String path = Regex.PATTERN.matcher(fileName).replaceAll(".").replaceAll("\\.", "_").replaceAll(" ", "_"); - path = WordUtils.capitalize(path, '_'); - return path; - } + /** + * Package for generated Java Classes eg. "de.kreth.property2java". If null - no + * package line is generated. + * + * @return + */ + String getPackage(); + + /** + * Filename to InputReader Entries + * + * @return + */ + Map getInput(); + + /** + * Path of java source folder. + * + * @return + */ + Path getRootPath(); + + default Writer outWriter(String fileName) throws IOException { + return new FileWriter(new File(getRootPath().toFile(), mapFilenameToClassName(fileName) + ".java"), + outputCharset()); + } + + default Charset outputCharset() { + return Charset.defaultCharset(); + } + + default String mapFilenameToClassName(String fileName) { + + String path = Regex.PATTERN.matcher(fileName) + .replaceAll(".") + .replaceAll("\\.", "_") + .replaceAll(" ", "_") + .replaceAll("/", "_"); + path = WordUtils.capitalize(path, '_'); + return path; + } } diff --git a/src/main/java/de/kreth/property2java/Generator.java b/src/main/java/de/kreth/property2java/Generator.java index 7a8516d..38431aa 100644 --- a/src/main/java/de/kreth/property2java/Generator.java +++ b/src/main/java/de/kreth/property2java/Generator.java @@ -1,8 +1,10 @@ package de.kreth.property2java; +import java.io.File; import java.io.IOException; import java.io.Reader; import java.io.Writer; +import java.net.URL; import java.text.DateFormat; import java.util.ArrayList; import java.util.Collections; @@ -20,114 +22,134 @@ import freemarker.template.TemplateException; public class Generator { - private static final DateFormat dateTimeInstance = DateFormat.getDateTimeInstance(); + private static final DateFormat dateTimeInstance = DateFormat.getDateTimeInstance(); - private final Configuration config; + private final Configuration config; - private final Template template; + private final Template template; - public Generator(Configuration config) { - this.config = config; - try { - template = FreemarkerConfig.INSTANCE.getTemplate(); - } - catch (IOException e) { - throw new IllegalStateException("Unable to load freemarker template", e); - } + public Generator(Configuration config) { + this.config = config; + try { + template = FreemarkerConfig.INSTANCE.getTemplate(); + } catch (IOException e) { + throw new IllegalStateException("Unable to load freemarker template", e); } + } + + public void start() throws IOException, GeneratorException { - public void start() throws IOException, GeneratorException { - - for (Map.Entry entry : config.getInput().entrySet()) { - String fileName = entry.getKey(); - try (Writer out = config.outWriter(fileName)) { - - Properties properties = new Properties(); - properties.load(entry.getValue()); - try { - generate(properties, out, fileName, config); - } - catch (TemplateException e) { - throw new GeneratorException("Error configuring Engine", e); - } - } + for (Map.Entry entry : config.getInput().entrySet()) { + String fileName = entry.getKey(); + try (Writer out = config.outWriter(fileName)) { + + Properties properties = new Properties(); + properties.load(entry.getValue()); + try { + generate(properties, out, fileName, config); + } catch (TemplateException e) { + throw new GeneratorException("Error configuring Engine", e); } + } } + } - void generate(Properties properties, Writer out, String fileName, Configuration config) - throws IOException, TemplateException { + void generate(Properties properties, Writer out, String fileName, Configuration config) + throws IOException, TemplateException { - Map root = new HashMap<>(); - root.put("generator_name", getClass().getName()); - root.put("generation_date", dateTimeInstance.format(new Date())); - root.put("package", config.getPackage()); - root.put("fileName", fileName); - root.put("classname", config.mapFilenameToClassName(fileName)); + Map root = new HashMap<>(); + root.put("generator_name", getClass().getName()); + root.put("generation_date", dateTimeInstance.format(new Date())); + root.put("package", config.getPackage()); + root.put("fileName", fileName); + root.put("classname", config.mapFilenameToClassName(fileName)); - List entries = new ArrayList<>(); + List entries = new ArrayList<>(); - root.put("entries", entries); + root.put("entries", entries); - @SuppressWarnings("unchecked") - List propertyNames = Collections.list((Enumeration) properties.propertyNames()); - Collections.sort(propertyNames); + @SuppressWarnings("unchecked") + List propertyNames = Collections.list((Enumeration) properties.propertyNames()); + Collections.sort(propertyNames); - for (String propertyKeyString : propertyNames) { - final String propertyValue = properties.getProperty(propertyKeyString); + for (String propertyKeyString : propertyNames) { + final String propertyValue = properties.getProperty(propertyKeyString); - entries.add(new Entry(propertyKeyString.toUpperCase().replaceAll("[\\.-]", "_"), propertyKeyString, - propertyValue)); - } - template.process(root, out); + entries.add(new Entry(propertyKeyString.toUpperCase().replaceAll("[\\.-]", "_"), propertyKeyString, + propertyValue)); } + template.process(root, out); + } - public static void main(String[] args) throws IOException, GeneratorException { - Generator generator = new Generator(ArgumentConfiguration.parse(args)); - generator.start(); - } + public static void main(String[] args) throws IOException, GeneratorException { + Generator generator = new Generator(ArgumentConfiguration.parse(args)); + generator.start(); + } - /** - * Represents an Property Entry for the generated java class. - * @author markus - * - */ - public class Entry { + public static void generateFor(Class locationClass, List rescources, String relativeTargetDir) + throws IOException, GeneratorException { - public final String constant; + ArgumentConfiguration.Builder config = new ArgumentConfiguration.Builder(); - public final String key; + rescources + .stream() + .map(URL::getFile) + .map(File::new) + .map(File::getAbsolutePath) + .forEach(config::addPropFile); - public final String value; + config.setPackageName(locationClass.getPackageName()) + .setTarget(relativeTargetDir); - /** - * Creates Property Entry data for the generated java class. - * @param constant name for the created constant. - * @param key property key - * @param value property value - */ - public Entry(String constant, String key, String value) { - super(); - this.constant = constant; - this.key = key; - this.value = value; - } + Generator g = new Generator(config.build()); + g.start(); + } - public String getConstant() { - return constant; - } + /** + * Represents an Property Entry for the generated java class. + * + * @author markus + * + */ + public class Entry { - public String getKey() { - return key; - } + public final String constant; - public String getValue() { - return value; - } + public final String key; - @Override - public String toString() { - return "Entry [constant=" + constant + ", key=" + key + ", value=" + value + "]"; - } + public final String value; + + /** + * Creates Property Entry data for the generated java class. + * + * @param constant name for the created constant. + * @param key property key + * @param value property value + */ + public Entry(String constant, String key, String value) { + super(); + this.constant = constant; + this.key = key; + this.value = value; + } + + public String getConstant() { + return constant; + } + + public String getKey() { + return key; + } + public String getValue() { + return value; } + + @Override + public String toString() { + return "Entry [constant=" + constant + ", key=" + key + ", value=" + value + "]"; + } + + } + } diff --git a/src/main/java/de/kreth/property2java/cli/ArgumentConfiguration.java b/src/main/java/de/kreth/property2java/cli/ArgumentConfiguration.java index 88d5154..ce13603 100644 --- a/src/main/java/de/kreth/property2java/cli/ArgumentConfiguration.java +++ b/src/main/java/de/kreth/property2java/cli/ArgumentConfiguration.java @@ -16,82 +16,81 @@ import de.kreth.property2java.Configuration; public class ArgumentConfiguration implements Configuration { - private final String packageName; + private final String packageName; - private final Map files; + private final Map files; - private final Path rootPath; + private final Path rootPath; - private ArgumentConfiguration(Builder builder) throws IOException { - this.packageName = builder.packageName; - rootPath = new File(builder.target).toPath(); - files = new HashMap<>(); - for (String filePath : builder.propFiles) { - File f = new File(filePath); - files.put(f.getName(), new FileReader(f)); - } - - } - - @Override - public String getPackage() { - return packageName; + private ArgumentConfiguration(Builder builder) throws IOException { + this.packageName = builder.packageName; + rootPath = new File(builder.target).toPath(); + files = new HashMap<>(); + for (String filePath : builder.propFiles) { + File f = new File(filePath); + files.put(f.getName(), new FileReader(f)); } - @Override - public Map getInput() { - return files; + } + + @Override + public String getPackage() { + return packageName; + } + + @Override + public Map getInput() { + return files; + } + + @Override + public Path getRootPath() { + return rootPath; + } + + @Override + public Writer outWriter(String fileName) throws IOException { + File dir; + if (packageName != null && packageName.isBlank() == false) { + dir = new File(rootPath.toFile(), packageName.replace('.', File.separatorChar)); + } else { + dir = rootPath.toFile(); } + return new FileWriter(new File(dir, mapFilenameToClassName(fileName) + ".java"), false); + } - @Override - public Path getRootPath() { - return rootPath; - } + public static Configuration parse(String[] args) throws IOException { + CliConfig cliConfig = new CliConfig(); - @Override - public Writer outWriter(String fileName) throws IOException { - File dir; - if (packageName != null && packageName.isBlank() == false) { - dir = new File(rootPath.toFile(), packageName.replace('.', File.separatorChar)); - } - else { - dir = rootPath.toFile(); - } - return new FileWriter(new File(dir, mapFilenameToClassName(fileName) + ".java"), false); - } + Builder builder = new Builder(); + cliConfig.fill(builder, args); + return builder.build(); + } - public static Configuration parse(String[] args) throws IOException { - CliConfig cliConfig = new CliConfig(); + public static class Builder { + String target; - Builder builder = new Builder(); - cliConfig.fill(builder, args); - return builder.build(); - } + List propFiles = new ArrayList<>(); - static class Builder { - String target; + String packageName; - List propFiles = new ArrayList<>(); - - String packageName; - - public Builder setTarget(String target) { - this.target = target; - return this; - } + public Builder setTarget(String target) { + this.target = target; + return this; + } - public Builder addPropFile(String propFile) { - this.propFiles.add(propFile); - return this; - } + public Builder addPropFile(String propFile) { + this.propFiles.add(propFile); + return this; + } - public Builder setPackageName(String packageName) { - this.packageName = packageName; - return this; - } + public Builder setPackageName(String packageName) { + this.packageName = packageName; + return this; + } - public Configuration build() throws IOException { - return new ArgumentConfiguration(this); - } + public Configuration build() throws IOException { + return new ArgumentConfiguration(this); } + } } diff --git a/src/main/java/de/kreth/property2java/processor/GenerateProperty2Java.java b/src/main/java/de/kreth/property2java/processor/GenerateProperty2Java.java new file mode 100644 index 0000000..4d4862d --- /dev/null +++ b/src/main/java/de/kreth/property2java/processor/GenerateProperty2Java.java @@ -0,0 +1,40 @@ +package de.kreth.property2java.processor; + +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(TYPE) +@Retention(RetentionPolicy.SOURCE) +/** + * Für die konfigurierten Resourcen wird jeweils eine Java Klasse erzeugt. Es + * muss nur die Abhängigkeit eingebunden werden und die Annotation in einer + * Klasse verwendet werden, in deren Package die neuen Klassen generiert werden. + * + * Für die Ausgabe der Prozessornachrichten muss folgendes im maven compiler + * konfiguriert werden: + * + *
+<build>
+	<plugins>
+		<plugin>
+			<groupId>org.apache.maven.plugins</groupId>
+			<artifactId>maven-compiler-plugin</artifactId>
+			<version>3.8.0</version>
+			<configuration>
+				<release>${java.version}</release>
+				<showWarnings>true</showWarnings>
+			</configuration>
+		</plugin>
+	</plugins>
+</build>
+ * 
+ * + * @author Markus + * + */ +public @interface GenerateProperty2Java { + String[] resources(); +} diff --git a/src/main/java/de/kreth/property2java/processor/ProcessorConfiguration.java b/src/main/java/de/kreth/property2java/processor/ProcessorConfiguration.java new file mode 100644 index 0000000..13e59ce --- /dev/null +++ b/src/main/java/de/kreth/property2java/processor/ProcessorConfiguration.java @@ -0,0 +1,105 @@ +package de.kreth.property2java.processor; + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.processing.Filer; +import javax.lang.model.element.Element; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +import de.kreth.property2java.Configuration; +import de.kreth.property2java.Generator; +import de.kreth.property2java.GeneratorException; + +public class ProcessorConfiguration implements Configuration { + + private final Filer filer; + private final Element element; + private final Map input; + + ProcessorConfiguration(Builder builder) throws IOException { + this.filer = builder.filer; + this.element = builder.element; + this.input = new HashMap<>(); + for (String resource : builder.resourcenames) { + + FileObject ressource = filer.getResource(StandardLocation.CLASS_PATH, "", + resource); + String className = mapFilenameToClassName(resource); + input.put(className, ressource.openReader(false)); + } + } + + @Override + public String getPackage() { + + String packageName = ""; + if (element instanceof TypeElement) { + TypeElement typeElement = (TypeElement) element; + PackageElement packageElement = (PackageElement) typeElement.getEnclosingElement(); + packageName = packageElement.getQualifiedName().toString(); + } + return packageName; + } + + @Override + public Map getInput() { + return input; + } + + @Override + public Path getRootPath() { + throw new UnsupportedOperationException( + "For Annotation Processor this is not supported as outWriter is overwritten."); + } + + @Override + public Writer outWriter(String fileName) throws IOException { + String packageName = getPackage(); + if (packageName != null && !packageName.isBlank()) { + fileName = packageName + "." + fileName; + } + return filer.createSourceFile(fileName, element).openWriter(); + } + + static Builder builder(Filer filer, Element element) { + return new Builder(filer, element); + } + + static class Builder { + private final Filer filer; + private final Element element; + private final List resourcenames; + + private Builder(Filer filer, Element element) { + this.filer = filer; + this.element = element; + this.resourcenames = new ArrayList<>(); + } + + public Builder addAll(String[] resourceNames) { + this.resourcenames.addAll(Arrays.asList(resourceNames)); + return this; + } + + public Builder addAll(List resourceNames) { + this.resourcenames.addAll(resourceNames); + return this; + } + + public void startGeneration() throws IOException, GeneratorException { + Generator g = new Generator(new ProcessorConfiguration(this)); + g.start(); + } + } +} diff --git a/src/main/java/de/kreth/property2java/processor/Property2JavaGenerator.java b/src/main/java/de/kreth/property2java/processor/Property2JavaGenerator.java new file mode 100644 index 0000000..b89faf2 --- /dev/null +++ b/src/main/java/de/kreth/property2java/processor/Property2JavaGenerator.java @@ -0,0 +1,61 @@ +package de.kreth.property2java.processor; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic.Kind; + +import de.kreth.property2java.GeneratorException; + +@SupportedAnnotationTypes({ "de.kreth.property2java.processor.GenerateProperty2Java" }) +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class Property2JavaGenerator extends AbstractProcessor { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + + if (!roundEnv.processingOver()) { + processingEnv.getMessager().printMessage(Kind.NOTE, + "Processing annotation " + GenerateProperty2Java.class); + + Set elementsAnnotatedWith = roundEnv + .getElementsAnnotatedWith(GenerateProperty2Java.class); + + processElements(elementsAnnotatedWith); + } else { + processingEnv.getMessager().printMessage(Kind.NOTE, + "finished working on annotation " + GenerateProperty2Java.class); + } + return true; + } + + private void processElements(Set elementsAnnotatedWith) { + for (Element element : elementsAnnotatedWith) { + String[] resources = element.getAnnotation(GenerateProperty2Java.class).resources(); + processingEnv.getMessager().printMessage(Kind.NOTE, + "Generating Java for " + Arrays.asList(resources)); + try { + ProcessorConfiguration + .builder(processingEnv.getFiler(), element) + .addAll(resources) + .startGeneration(); + } catch (IOException | GeneratorException e) { + StringWriter out = new StringWriter(); + e.printStackTrace(new PrintWriter(out)); + out.flush(); + processingEnv.getMessager().printMessage(Kind.ERROR, "Exception " + e + "\n" + out.toString(), + element); + } + } + } +} diff --git a/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..d22a1ba --- /dev/null +++ b/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +de.kreth.property2java.processor.Property2JavaGenerator \ No newline at end of file diff --git a/src/test/java/de/kreth/property2java/GeneratorTests.java b/src/test/java/de/kreth/property2java/GeneratorTests.java index 12ece38..1229b38 100644 --- a/src/test/java/de/kreth/property2java/GeneratorTests.java +++ b/src/test/java/de/kreth/property2java/GeneratorTests.java @@ -29,149 +29,149 @@ import org.junit.jupiter.api.Test; class GeneratorTests { - private String path = "application.properties"; - - private Configuration config; - - private Generator generator; - - @BeforeEach - void setUp() throws Exception { - Map input = new HashMap<>(); - input.put(path, testProperties()); - - config = mock(Configuration.class); - when(config.getInput()).thenReturn(input); - when(config.mapFilenameToClassName(anyString())).thenCallRealMethod(); - when(config.outputCharset()).thenCallRealMethod(); - - generator = new Generator(config); + private String path = "application.properties"; + + private Configuration config; + + private Generator generator; + + @BeforeEach + void setUp() throws Exception { + Map input = new HashMap<>(); + input.put(path, testProperties()); + + config = mock(Configuration.class); + when(config.getInput()).thenReturn(input); + when(config.mapFilenameToClassName(anyString())).thenCallRealMethod(); + when(config.outputCharset()).thenCallRealMethod(); + + generator = new Generator(config); + } + + @Test + void testClassDefinition() throws IOException, GeneratorException { + + when(config.getPackage()).thenReturn("de.kreth.property2java"); + when(config.mapFilenameToClassName(anyString())).thenCallRealMethod(); + + StringWriter out = new StringWriter(); + when(config.outWriter(anyString())).thenReturn(out); + + generator.start(); + + String sourceCode = out.toString().trim(); + StringTokenizer sourceTokenizer = new StringTokenizer(sourceCode, "\n"); + String linePackage = null; + String lineClass = null; + int countOpenBaces = 0; + int countCloseBaces = 0; + while (sourceTokenizer.hasMoreTokens()) { + String line = sourceTokenizer.nextToken(); + if (line.trim().startsWith("package")) { + linePackage = line; + } else if (line.trim().startsWith("public enum")) { + lineClass = line; + } + if (line.contains("{")) { + countOpenBaces++; + } + if (line.contains("}")) { + countCloseBaces++; + } } - @Test - void testClassDefinition() throws IOException, GeneratorException { - - when(config.getPackage()).thenReturn("de.kreth.property2java"); - when(config.mapFilenameToClassName(anyString())).thenCallRealMethod(); - - StringWriter out = new StringWriter(); - when(config.outWriter(anyString())).thenReturn(out); - - generator.start(); - - String sourceCode = out.toString().trim(); - StringTokenizer sourceTokenizer = new StringTokenizer(sourceCode, "\n"); - String linePackage = null; - String lineClass = null; - int countOpenBaces = 0; - int countCloseBaces = 0; - while (sourceTokenizer.hasMoreTokens()) { - String line = sourceTokenizer.nextToken(); - if (line.trim().startsWith("package")) { - linePackage = line; - } - else if (line.trim().startsWith("public enum")) { - lineClass = line; - } - if (line.contains("{")) { - countOpenBaces++; - } - if (line.contains("}")) { - countCloseBaces++; - } - } - - assertEquals(countCloseBaces, countOpenBaces, - "Count of Braces doesn't match. Open = " + countOpenBaces + ", Close = " + countCloseBaces); - - assertNotNull(linePackage); - assertNotNull(lineClass); - - assertThat(linePackage, - Matchers.stringContainsInOrder(Arrays.asList("package", "de.kreth.property2java", ";"))); - - assertThat(lineClass, - Matchers.stringContainsInOrder(Arrays.asList("public", "enum", "Application_Properties"))); - - } - - @Test - void testOneInputGeneratesOneOutput() throws IOException, GeneratorException { - - Writer out = mock(Writer.class); - Writer nonOut = mock(Writer.class); - when(config.outWriter(anyString())).thenReturn(out, nonOut); - generator.start(); - verify(out).close(); - verify(nonOut, never()).close(); - verify(nonOut, never()).flush(); - } - - @Test - void testKeys() throws IOException, GeneratorException { - - StringWriter out = new StringWriter(); - when(config.outWriter(anyString())).thenReturn(out); - generator.start(); - - List lines = out.toString().lines().filter(line -> line.contains(" (\"")) - .collect(Collectors.toList()); - - assertEquals(21, lines.size()); - assertLineMatch(lines, "label", "label"); - assertLineMatch(lines, "label_addarticle", "label.addarticle"); - assertLineMatch(lines, "label_user_register", "label.user.register"); - assertLineMatch(lines, "message_article_priceerror", "message.article.priceerror"); - assertLineMatch(lines, "message_invoiceitem_startbeforeend", - "message.invoiceitem.startbeforeend"); - assertLineMatch(lines, "message_invoiceitem_allfieldsmustbeset", - "message.invoiceitem.allfieldsmustbeset"); - } - - private void assertLineMatch(List lines, String key, String expected) { - Optional found = lines.stream().filter(line -> keyMatches(line, key)) - .findFirst(); - assertTrue(found.isPresent(), "No line found with key = " + key); - final String line = found.get().trim(); - int indexEquals = line.indexOf('('); - String value = line.substring(indexEquals + 1).trim().substring(1); - value = value.substring(0, value.length() - 3); - assertEquals(expected, value, "Line \"" + line + "\" don't match expected Value \"" + expected + "\""); - - } - - private boolean keyMatches(String line, String key) { - line = line.toLowerCase(); - key = key.toLowerCase(); - return line.contains("\t" + key + " "); - } - - private StringReader testProperties() { - return new StringReader("\r\n" + - "label = \r\n" + - "\r\n" + - "label.addarticle = Add Article\r\n" + - "label.cancel = Cancel\r\n" + - "label.close = Close\r\n" + - "label.delete = Delete\r\n" + - "label.discart = Discart\r\n" + - "label.loggedin = Logged in:\r\n" + - "label.logout = Logout\r\n" + - "label.ok = OK\r\n" + - "label.store = Store\r\n" + - "label.preview = Preview\r\n" + - "label.open = Open\r\n" + - "label.user.register = Register\r\n" + - "\r\n" + - "message.article.priceerror = Please set the price.\r\n" + - "message.delete.text = Delete {0}?\r\n" + - "message.delete.title = Really delete?\r\n" + - "message.invoiceitem.allfieldsmustbeset = Start, end and article must not be \\r\\n" + - " empty!\r\n" + - "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" + - ""); - } + assertEquals(countCloseBaces, countOpenBaces, + "Count of Braces doesn't match. Open = " + countOpenBaces + ", Close = " + countCloseBaces); + + assertNotNull(linePackage); + assertNotNull(lineClass); + + assertThat(linePackage, + Matchers.stringContainsInOrder(Arrays.asList("package", "de.kreth.property2java", ";"))); + + assertThat(lineClass, + Matchers.stringContainsInOrder(Arrays.asList("public", "enum", "Application_Properties"))); + + } + + @Test + void testOneInputGeneratesOneOutput() throws IOException, GeneratorException { + + Writer out = mock(Writer.class); + Writer nonOut = mock(Writer.class); + when(config.outWriter(anyString())).thenReturn(out, nonOut); + generator.start(); + verify(out).close(); + verify(nonOut, never()).close(); + verify(nonOut, never()).flush(); + } + + @Test + void testKeys() throws IOException, GeneratorException { + + StringWriter out = new StringWriter(); + when(config.outWriter(anyString())).thenReturn(out); + generator.start(); + + List lines = out.toString().lines().filter(line -> line.contains(" (\"")) + .collect(Collectors.toList()); + + assertEquals(21, lines.size()); + assertLineMatch(lines, "label", "label"); + assertLineMatch(lines, "label_addarticle", "label.addarticle"); + assertLineMatch(lines, "label_user_register", "label.user.register"); + assertLineMatch(lines, "message_article_priceerror", "message.article.priceerror"); + assertLineMatch(lines, "message_invoiceitem_startbeforeend", + "message.invoiceitem.startbeforeend"); + assertLineMatch(lines, "message_invoiceitem_allfieldsmustbeset", + "message.invoiceitem.allfieldsmustbeset"); + } + + private void assertLineMatch(List lines, String key, String expected) { + Optional found = lines.stream().filter(line -> keyMatches(line, key)) + .findFirst(); + + assertTrue(found.isPresent(), "No line found with key = " + key); + final String line = found.get().trim(); + int indexEquals = line.indexOf('('); + String value = line.substring(indexEquals + 1).trim().substring(1); + value = value.substring(0, value.length() - 3); + assertEquals(expected, value, "Line \"" + line + "\" don't match expected Value \"" + expected + "\""); + + } + + private boolean keyMatches(String line, String key) { + line = line.toLowerCase(); + key = key.toLowerCase(); + return line.contains("\t" + key + " "); + } + + private StringReader testProperties() { + return new StringReader("\r\n" + + "label = \r\n" + + "\r\n" + + "label.addarticle = Add Article\r\n" + + "label.cancel = Cancel\r\n" + + "label.close = Close\r\n" + + "label.delete = Delete\r\n" + + "label.discart = Discart\r\n" + + "label.loggedin = Logged in:\r\n" + + "label.logout = Logout\r\n" + + "label.ok = OK\r\n" + + "label.store = Store\r\n" + + "label.preview = Preview\r\n" + + "label.open = Open\r\n" + + "label.user.register = Register\r\n" + + "\r\n" + + "message.article.priceerror = Please set the price.\r\n" + + "message.delete.text = Delete {0}?\r\n" + + "message.delete.title = Really delete?\r\n" + + "message.invoiceitem.allfieldsmustbeset = Start, end and article must not be \\r\\n" + + " empty!\r\n" + + "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" + + ""); + } } diff --git a/src/test/java/de/kreth/property2java/processor/Property2JavaGeneratorTest.java b/src/test/java/de/kreth/property2java/processor/Property2JavaGeneratorTest.java new file mode 100644 index 0000000..d974371 --- /dev/null +++ b/src/test/java/de/kreth/property2java/processor/Property2JavaGeneratorTest.java @@ -0,0 +1,46 @@ +package de.kreth.property2java.processor; + +import static org.mockito.Mockito.when; + +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.TypeElement; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class Property2JavaGeneratorTest { + + private Property2JavaGenerator processor; + @Mock + private ProcessingEnvironment processingEnv; + @Mock + private RoundEnvironment roundEnv; + private Set annotations; + @Mock + private Messager messanger; + + @BeforeEach + void initProcesor() { + MockitoAnnotations.initMocks(this); + annotations = new HashSet<>(); + + processor = new Property2JavaGenerator(); + processor.init(processingEnv); + when(processingEnv.getMessager()).thenReturn(messanger); + } + + @Test + void testGeneratorInitializedCorrectly() { + when(roundEnv.getElementsAnnotatedWith(ArgumentMatchers.any(Class.class))) + .thenReturn(annotations); + processor.process(annotations, roundEnv); + } +}