Skip to contentMethod: propertyIsWanted(Element)
1: /**
2: * Copyright (C) 2023 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.jopa.modelgen;
16:
17:
18: import cz.cvut.kbss.jopa.modelgen.classmodel.Field;
19: import cz.cvut.kbss.jopa.modelgen.classmodel.MappingAnnotations;
20: import cz.cvut.kbss.jopa.modelgen.classmodel.MetamodelClass;
21:
22: import javax.annotation.processing.AbstractProcessor;
23: import javax.annotation.processing.Messager;
24: import javax.annotation.processing.ProcessingEnvironment;
25: import javax.annotation.processing.RoundEnvironment;
26: import javax.annotation.processing.SupportedAnnotationTypes;
27: import javax.annotation.processing.SupportedOptions;
28: import javax.lang.model.SourceVersion;
29: import javax.lang.model.element.AnnotationMirror;
30: import javax.lang.model.element.Element;
31: import javax.lang.model.element.TypeElement;
32: import javax.tools.Diagnostic;
33: import java.util.HashMap;
34: import java.util.List;
35: import java.util.Map;
36: import java.util.Set;
37:
38: /**
39: * Annotation processor that finds JOPA entities and mapped superclasses and generates a static metamodel based on
40: * them.
41: */
42: @SupportedAnnotationTypes({"cz.cvut.kbss.jopa.model.annotations.OWLClass",
43: "cz.cvut.kbss.jopa.model.annotations.MappedSuperclass"})
44: @SupportedOptions({
45: ModelGenProcessor.OUTPUT_DIRECTORY_PARAM,
46: ModelGenProcessor.SOURCE_PACKAGE_PARAM,
47: ModelGenProcessor.DEBUG_PARAM
48: })
49: public class ModelGenProcessor extends AbstractProcessor {
50: public static final String OUTPUT_DIRECTORY_PARAM = "outputDirectory";
51: public static final String SOURCE_PACKAGE_PARAM = "sourcePackage";
52: public static final String DEBUG_PARAM = "debugOption";
53: Messager messager;
54:
55: private Map<String, MetamodelClass> classes;
56:
57: private String sourcePackage;
58: private String outputDirectory;
59: private boolean debugOption;
60:
61: @Override
62: public void init(ProcessingEnvironment env) {
63: super.init(env);
64: this.messager = env.getMessager();
65: messager.printMessage(Diagnostic.Kind.NOTE, "Initializing ModelGenProcessor.");
66: this.classes = new HashMap<>();
67: sourcePackage = env.getOptions().get(SOURCE_PACKAGE_PARAM);
68: outputDirectory = env.getOptions().get(OUTPUT_DIRECTORY_PARAM);
69: debugOption = Boolean.parseBoolean(env.getOptions().get(DEBUG_PARAM));
70: }
71:
72: @Override
73: public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
74: for (TypeElement te : annotations) {
75: for (Element elParent : roundEnv.getElementsAnnotatedWith(te)) {
76: if (!isAnnotatedWithNonEntity(elParent)) {
77: if (sourcePackage == null || elParent.asType().toString().contains(sourcePackage)) {
78: MetamodelClass parentClass = new MetamodelClass(elParent);
79:
80: if (debugOption) {
81: messager.printMessage(Diagnostic.Kind.NOTE,
82: "\t - Started processing class '" + parentClass.getName() + "'");
83: }
84: List<? extends Element> properties = elParent.getEnclosedElements();
85: for (Element elProperty : properties) {
86: if (propertyIsWanted(elProperty)) {
87: Field field = new Field(elProperty, elParent);
88: if (debugOption) {
89: messager.printMessage(Diagnostic.Kind.NOTE,
90: "\t\t - Processing field '" + field.getName() + "'");
91: }
92: parentClass.addField(field);
93: }
94: }
95: classes.put(elParent.toString(), parentClass);
96: if (debugOption) {
97: messager.printMessage(Diagnostic.Kind.NOTE,
98: "\t - Finished processing class '" + parentClass.getName() + "'");
99: }
100: }
101: }
102: }
103: }
104: if (debugOption) {
105: messager.printMessage(Diagnostic.Kind.NOTE, "Generating output files.");
106: }
107: final OutputFilesGenerator outputGenerator = new OutputFilesGenerator(outputDirectory, debugOption, messager);
108: outputGenerator.generateOutputFiles(classes.values());
109: return true;
110: }
111:
112: private boolean propertyIsWanted(Element param) {
113: boolean containsWanted = false;
114: List<? extends AnnotationMirror> paramAnnotations = param.getAnnotationMirrors();
115:• if (!paramAnnotations.isEmpty()) {
116:• for (AnnotationMirror paramAnnotation : paramAnnotations) {
117:• if (paramAnnotation.toString().contains("cz.cvut.kbss.jopa.model.annotations.Transient")) {
118: return false;
119: }
120:• for (MappingAnnotations anEnum : MappingAnnotations.values()) {
121:• if (paramAnnotation.toString().contains(anEnum.getAnnotation())) {
122: containsWanted = true;
123: break;
124: }
125: }
126:
127: }
128: }
129: return containsWanted;
130: }
131:
132: @Override
133: public SourceVersion getSupportedSourceVersion() {
134: return SourceVersion.latestSupported();
135: }
136:
137: public boolean isAnnotatedWithNonEntity(Element element) {
138: TypeElement typeElement = (TypeElement) element;
139: List<? extends AnnotationMirror> annotations = typeElement.getAnnotationMirrors();
140: for (AnnotationMirror annotation : annotations) {
141: if (annotation.getAnnotationType().toString()
142: .equals("cz.cvut.kbss.jopa.model.annotations.util.NonEntity")) {
143: return true;
144: }
145: }
146: return false;
147: }
148: }