parent
11f18a9abf
commit
1d447b2045
@ -0,0 +1 @@ |
|||||||
|
de.kreth.property2java.processor.Property2JavaGenerator |
||||||
@ -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: |
||||||
|
* |
||||||
|
* <pre> |
||||||
|
<build> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||||
|
<artifactId>maven-compiler-plugin</artifactId> |
||||||
|
<version>3.8.0</version> |
||||||
|
<configuration> |
||||||
|
<release>${java.version}</release> |
||||||
|
<b><showWarnings>true</showWarnings></b> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
* </pre> |
||||||
|
* |
||||||
|
* @author Markus |
||||||
|
* |
||||||
|
*/ |
||||||
|
public @interface GenerateProperty2Java { |
||||||
|
String[] resources(); |
||||||
|
} |
||||||
@ -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<String, Reader> 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<String, Reader> 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<String> 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<String> resourceNames) { |
||||||
|
this.resourcenames.addAll(resourceNames); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public void startGeneration() throws IOException, GeneratorException { |
||||||
|
Generator g = new Generator(new ProcessorConfiguration(this)); |
||||||
|
g.start(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -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<? extends TypeElement> annotations, RoundEnvironment roundEnv) { |
||||||
|
|
||||||
|
if (!roundEnv.processingOver()) { |
||||||
|
processingEnv.getMessager().printMessage(Kind.NOTE, |
||||||
|
"Processing annotation " + GenerateProperty2Java.class); |
||||||
|
|
||||||
|
Set<? extends Element> 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<? extends Element> 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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1 @@ |
|||||||
|
de.kreth.property2java.processor.Property2JavaGenerator |
||||||
@ -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<TypeElement> 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); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue