diff --git a/src/main/java/ch/powerunit/extensions/matchers/common/AbstractElementMirror.java b/src/main/java/ch/powerunit/extensions/matchers/common/AbstractElementMirror.java index db5fbb21e..9577405f1 100644 --- a/src/main/java/ch/powerunit/extensions/matchers/common/AbstractElementMirror.java +++ b/src/main/java/ch/powerunit/extensions/matchers/common/AbstractElementMirror.java @@ -22,6 +22,7 @@ import java.lang.annotation.Annotation; import java.util.Optional; +import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; /** @@ -29,7 +30,7 @@ * */ public abstract class AbstractElementMirror - implements AbstractRoundMirrorSupport, ElementHelper { + implements AbstractRoundMirrorSupport, ElementHelper, ProcessingEnvironmentHelper { protected final R roundMirror; protected final E element; @@ -39,7 +40,7 @@ public abstract class AbstractElementMirror annotationType, R roundMirror, E element) { this.roundMirror = roundMirror; this.element = element; - this.doc = Optional.ofNullable(roundMirror.getProcessingEnv().getElementUtils().getDocComment(element)); + this.doc = Optional.ofNullable(roundMirror.getElementUtils().getDocComment(element)); this.annotation = Optional.ofNullable(element.getAnnotation(annotationType)); } @@ -64,6 +65,11 @@ public String getParamComment() { return doc.map(AbstractElementMirror::extractParamCommentFromJavadoc).orElse(" * \n"); } + @Override + public ProcessingEnvironment getProcessingEnv() { + return getRoundMirror().getProcessingEnv(); + } + private static String extractParamCommentFromJavadoc(String docComment) { boolean insideParam = false; StringBuilder sb = new StringBuilder(" * \n"); diff --git a/src/main/java/ch/powerunit/extensions/matchers/common/AbstractRoundMirrorReferenceToProcessingEnv.java b/src/main/java/ch/powerunit/extensions/matchers/common/AbstractRoundMirrorReferenceToProcessingEnv.java index 85b27e2ab..ce2461a6b 100644 --- a/src/main/java/ch/powerunit/extensions/matchers/common/AbstractRoundMirrorReferenceToProcessingEnv.java +++ b/src/main/java/ch/powerunit/extensions/matchers/common/AbstractRoundMirrorReferenceToProcessingEnv.java @@ -31,7 +31,8 @@ * @author borettim * */ -public abstract class AbstractRoundMirrorReferenceToProcessingEnv implements ElementHelper { +public abstract class AbstractRoundMirrorReferenceToProcessingEnv + implements ElementHelper, ProcessingEnvironmentHelper { protected final RoundEnvironment roundEnv; protected final ProcessingEnvironment processingEnv; @@ -40,9 +41,10 @@ public abstract class AbstractRoundMirrorReferenceToProcessingEnv implements Ele public AbstractRoundMirrorReferenceToProcessingEnv(RoundEnvironment roundEnv, ProcessingEnvironment processingEnv) { this.roundEnv = roundEnv; this.processingEnv = processingEnv; - this.objectTypeMirror = getProcessingEnv().getElementUtils().getTypeElement("java.lang.Object").asType(); + this.objectTypeMirror = getElementUtils().getTypeElement("java.lang.Object").asType(); } + @Override public ProcessingEnvironment getProcessingEnv() { return processingEnv; } diff --git a/src/main/java/ch/powerunit/extensions/matchers/common/CommonUtils.java b/src/main/java/ch/powerunit/extensions/matchers/common/CommonUtils.java index 977e92bf3..76bcbcfa7 100644 --- a/src/main/java/ch/powerunit/extensions/matchers/common/CommonUtils.java +++ b/src/main/java/ch/powerunit/extensions/matchers/common/CommonUtils.java @@ -19,6 +19,8 @@ */ package ch.powerunit.extensions.matchers.common; +import java.time.Instant; + /** * These are some method to manipulate java. * @@ -59,4 +61,9 @@ public static String addPrefix(String prefix, String input) { .withPrefixAndSuffix("\n", "\n").asString(input.split("\\R")); } + public static String generateGeneratedAnnotation(Class generatedBy, String comments) { + return "@javax.annotation.Generated(value=\"" + generatedBy.getName() + "\",date=\"" + Instant.now().toString() + + "\"" + (comments == null ? "" : (",comments=" + toJavaSyntax(comments))) + ")"; + } + } diff --git a/src/main/java/ch/powerunit/extensions/matchers/common/FactoryHelper.java b/src/main/java/ch/powerunit/extensions/matchers/common/FactoryHelper.java index 1fffb5079..fe969aa8f 100644 --- a/src/main/java/ch/powerunit/extensions/matchers/common/FactoryHelper.java +++ b/src/main/java/ch/powerunit/extensions/matchers/common/FactoryHelper.java @@ -1,7 +1,8 @@ package ch.powerunit.extensions.matchers.common; +import static ch.powerunit.extensions.matchers.common.CommonUtils.generateGeneratedAnnotation; + import java.io.PrintWriter; -import java.time.Instant; import java.util.function.Supplier; import java.util.stream.Stream; @@ -9,6 +10,7 @@ /** * These are some method to generate factory methods. + * * @author borettim * */ @@ -22,8 +24,7 @@ public static void generateFactoryClass(PrintWriter wjfo, Class { + R apply(S input) throws Exception; + } + @FunctionalInterface public static interface ConsumerWithException { void accept(S input) throws Exception; @@ -49,17 +54,26 @@ public static interface FunctionWithException { R apply(T input) throws Exception; } - public static boolean processFileWithIOException( + public static R processFileWithIOExceptionAndResult( SupplierWithException generateFileObject, FunctionWithException openStream, - ConsumerWithException actions, Consumer exceptionHandler) { + FunctionrWithException actions, Consumer exceptionHandler) { try { try (S wjfo = openStream.apply(generateFileObject.get())) { - actions.accept(wjfo); + return actions.apply(wjfo); } } catch (Exception e) { exceptionHandler.accept(e); - return false; + return null; } - return true; + } + + public static boolean processFileWithIOException( + SupplierWithException generateFileObject, FunctionWithException openStream, + ConsumerWithException actions, Consumer exceptionHandler) { + Boolean result = processFileWithIOExceptionAndResult(generateFileObject, openStream, s -> { + actions.accept(s); + return true; + }, exceptionHandler); + return Boolean.TRUE.equals(result); } } diff --git a/src/main/java/ch/powerunit/extensions/matchers/common/ProcessingEnvironmentHelper.java b/src/main/java/ch/powerunit/extensions/matchers/common/ProcessingEnvironmentHelper.java new file mode 100644 index 000000000..735f6075a --- /dev/null +++ b/src/main/java/ch/powerunit/extensions/matchers/common/ProcessingEnvironmentHelper.java @@ -0,0 +1,63 @@ +/** + * Powerunit - A JDK1.8 test framework + * Copyright (C) 2014 Mathieu Boretti. + * + * This file is part of Powerunit + * + * Powerunit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Powerunit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Powerunit. If not, see . + */ +package ch.powerunit.extensions.matchers.common; + +import java.util.Locale; +import java.util.Map; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + +@FunctionalInterface +public interface ProcessingEnvironmentHelper { + ProcessingEnvironment getProcessingEnv(); + + default Map getOptions() { + return getProcessingEnv().getOptions(); + } + + default Messager getMessager() { + return getProcessingEnv().getMessager(); + } + + default Filer getFiler() { + return getProcessingEnv().getFiler(); + } + + default Elements getElementUtils() { + return getProcessingEnv().getElementUtils(); + } + + default Types getTypeUtils() { + return getProcessingEnv().getTypeUtils(); + } + + default SourceVersion getSourceVersion() { + return getProcessingEnv().getSourceVersion(); + } + + default Locale getLocale() { + return getProcessingEnv().getLocale(); + } +} diff --git a/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/ProvidesMatchersAnnotatedElementMirror.java b/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/ProvidesMatchersAnnotatedElementMirror.java index 89a386e7f..17f8e62e6 100644 --- a/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/ProvidesMatchersAnnotatedElementMirror.java +++ b/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/ProvidesMatchersAnnotatedElementMirror.java @@ -20,12 +20,13 @@ package ch.powerunit.extensions.matchers.provideprocessor; import static ch.powerunit.extensions.matchers.common.CommonUtils.addPrefix; +import static ch.powerunit.extensions.matchers.common.CommonUtils.generateGeneratedAnnotation; +import static ch.powerunit.extensions.matchers.common.FileObjectHelper.processFileWithIOExceptionAndResult; import static ch.powerunit.extensions.matchers.provideprocessor.dsl.DSLMethod.of; import static java.util.Collections.unmodifiableList; import static java.util.stream.Collectors.toList; import java.io.PrintWriter; -import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -38,8 +39,6 @@ import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic.Kind; -import ch.powerunit.extensions.matchers.common.CommonUtils; -import ch.powerunit.extensions.matchers.common.FileObjectHelper; import ch.powerunit.extensions.matchers.provideprocessor.dsl.DSLMethod; public class ProvidesMatchersAnnotatedElementMirror extends ProvidesMatchersAnnotatedElementMatcherMirror { @@ -55,8 +54,8 @@ public ProvidesMatchersAnnotatedElementMirror(TypeElement typeElement, RoundMirr tmp.add(this::generateParentDSLStarter); if (hasParentInSameRound) { tmp.add(this::generateParentValueDSLStarter); - if (((TypeElement) roundMirror.getProcessingEnv().getTypeUtils().asElement(element.getSuperclass())) - .getTypeParameters().isEmpty()) { + if (((TypeElement) roundMirror.getTypeUtils().asElement(element.getSuperclass())).getTypeParameters() + .isEmpty()) { tmp.add(this::generateParentInSameRoundWithChaningDSLStarter); } } @@ -70,20 +69,16 @@ public ProvidesMatchersAnnotatedElementMirror(TypeElement typeElement, RoundMirr } public Collection process() { - RoundMirror rm = roundMirror; Element te = element; String simpleName = getSimpleNameOfGeneratedClass(); - Collection results = new ArrayList<>(); - FileObjectHelper.processFileWithIOException( - () -> rm.getProcessingEnv().getFiler().createSourceFile(getFullyQualifiedNameOfGeneratedClass(), te), + return processFileWithIOExceptionAndResult( + () -> getFiler().createSourceFile(getFullyQualifiedNameOfGeneratedClass(), te), jfo -> new PrintWriter(jfo.openWriter()), wjfo -> { wjfo.println("package " + getPackageNameOfGeneratedClass() + ";"); wjfo.println(); wjfo.println(generateMainJavaDoc()); - wjfo.println("@javax.annotation.Generated(value=\"" - + ProvidesMatchersAnnotationsProcessor.class.getName() + "\",date=\"" - + Instant.now().toString() + "\",comments=" - + CommonUtils.toJavaSyntax(annotation.get().comments()) + ")"); + wjfo.println(generateGeneratedAnnotation(ProvidesMatchersAnnotationsProcessor.class, + annotation.get().comments())); wjfo.println("public final class " + simpleName + " {"); wjfo.println(); wjfo.println(" private " + simpleName + "() {}"); @@ -97,10 +92,9 @@ public Collection process() { Collection tmp = generateDSLStarter(); tmp.stream().map(m -> addPrefix(" ", m.asStaticImplementation())).forEach(wjfo::println); wjfo.println("}"); - results.addAll(tmp); - }, e -> rm.getProcessingEnv().getMessager().printMessage(Kind.ERROR, + return tmp; + }, e -> getMessager().printMessage(Kind.ERROR, "Unable to create the file containing the target class because of " + e, te)); - return results; } public Collection generateDSLStarter() { @@ -180,8 +174,7 @@ public DSLMethod generatParentValueDSLStarter(String argumentForParentBuilder) { public ProvidesMatchersAnnotatedElementMirror getParentMirror() { RoundMirror rm = roundMirror; - return rm.getByName(getQualifiedName( - ((TypeElement) rm.getProcessingEnv().getTypeUtils().asElement(element.getSuperclass())))); + return rm.getByName(getQualifiedName(((TypeElement) rm.getTypeUtils().asElement(element.getSuperclass())))); } public DSLMethod generateParentValueDSLStarter() { diff --git a/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/RoundMirror.java b/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/RoundMirror.java index 2ce76cf20..085cb631a 100644 --- a/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/RoundMirror.java +++ b/src/main/java/ch/powerunit/extensions/matchers/provideprocessor/RoundMirror.java @@ -133,8 +133,8 @@ public boolean isInSameRound(Element t) { public AnnotationMirror getProvideMatchersAnnotation(Element e) { TypeMirror pmtm = processingEnv.getElementUtils() .getTypeElement("ch.powerunit.extensions.matchers.ProvideMatchers").asType(); - return getProcessingEnv().getElementUtils().getAllAnnotationMirrors(e).stream() - .filter(a -> a.getAnnotationType().equals(pmtm)).findAny().orElse(null); + return getElementUtils().getAllAnnotationMirrors(e).stream().filter(a -> a.getAnnotationType().equals(pmtm)) + .findAny().orElse(null); } public Collection> getDSLMethodFor(ProvidesMatchersAnnotatedElementData target) { diff --git a/src/test/java/ch/powerunit/extensions/matchers/common/CommonUtilsTest.java b/src/test/java/ch/powerunit/extensions/matchers/common/CommonUtilsTest.java index 0c2c10f61..0b65b351f 100644 --- a/src/test/java/ch/powerunit/extensions/matchers/common/CommonUtilsTest.java +++ b/src/test/java/ch/powerunit/extensions/matchers/common/CommonUtilsTest.java @@ -16,4 +16,14 @@ public void testAddPrefix() { assertThatBiFunction(CommonUtils::addPrefix, " ", "x").is("\n x\n"); assertThatBiFunction(CommonUtils::addPrefix, " ", "x\ny").is("\n x\n y\n"); } + + @Test(fastFail = false) + public void testGenerateGeneratedAnnotation() { + assertThatBiFunction(CommonUtils::generateGeneratedAnnotation, Object.class, null) + .is(both(containsString("@javax.annotation.Generated(value=\"java.lang.Object\",date")) + .and(not(containsString("comments")))); + assertThatBiFunction(CommonUtils::generateGeneratedAnnotation, Object.class, "x") + .is(both(containsString("@javax.annotation.Generated(value=\"java.lang.Object\",date")) + .and(containsString("comments=\"x\""))); + } } diff --git a/src/test/java/ch/powerunit/extensions/matchers/common/ProcessingEnvironmentHelperTest.java b/src/test/java/ch/powerunit/extensions/matchers/common/ProcessingEnvironmentHelperTest.java new file mode 100644 index 000000000..e8d842cb8 --- /dev/null +++ b/src/test/java/ch/powerunit/extensions/matchers/common/ProcessingEnvironmentHelperTest.java @@ -0,0 +1,67 @@ +/** + * Powerunit - A JDK1.8 test framework + * Copyright (C) 2014 Mathieu Boretti. + * + * This file is part of Powerunit + * + * Powerunit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Powerunit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Powerunit. If not, see . + */ +package ch.powerunit.extensions.matchers.common; + +import javax.annotation.processing.ProcessingEnvironment; + +import ch.powerunit.Rule; +import ch.powerunit.Test; +import ch.powerunit.TestRule; +import ch.powerunit.extensions.matchers.TestSuiteSupport; + +/** + * @author borettim + * + */ +public class ProcessingEnvironmentHelperTest implements TestSuiteSupport, ProcessingEnvironmentHelper { + + private ProcessingEnvironment processingEnv; + + @Rule + public final TestRule rules = mockitoRule().around(before(this::prepare)); + + private void prepare() { + processingEnv = generateMockitoProcessingEnvironment(); + } + + @Override + public ProcessingEnvironment getProcessingEnv() { + return processingEnv; + } + + @Test(fastFail = false) + public void testGetter() { + assertThat(getOptions()).is(sameInstance(processingEnv.getOptions())); + + assertThat(getMessager()).is(sameInstance(processingEnv.getMessager())); + + assertThat(getFiler()).is(sameInstance(processingEnv.getFiler())); + + assertThat(getElementUtils()).is(sameInstance(processingEnv.getElementUtils())); + + assertThat(getTypeUtils()).is(sameInstance(processingEnv.getTypeUtils())); + + assertThat(getSourceVersion()).is(sameInstance(processingEnv.getSourceVersion())); + + assertThat(getLocale()).is(sameInstance(processingEnv.getLocale())); + + } + +}