View Javadoc
1   /*
2    * Copyright (C) 2016 Uwe Plonus
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16   */
17  package org.sw4j.tool.annotation.jpa.processor;
18  
19  import java.util.Set;
20  import javax.annotation.Nonnull;
21  import javax.annotation.processing.ProcessingEnvironment;
22  import javax.lang.model.element.Element;
23  import javax.lang.model.element.ElementKind;
24  import javax.lang.model.element.TypeElement;
25  import javax.tools.Diagnostic;
26  import org.sw4j.tool.annotation.jpa.generator.model.Entity;
27  import org.sw4j.tool.annotation.jpa.generator.model.Model;
28  import org.sw4j.tool.annotation.jpa.generator.model.Table;
29  
30  /**
31   * This is a processor to handle classes with an @Entity annotation.
32   *
33   * @author Uwe Plonus
34   */
35  public class EntityProcessor {
36  
37      /**
38       * The processor to handle attributes of the processed entity.
39       */
40      private final AttributeProcessor attributeProcessor;
41  
42      /** The processing environment used to access the tool facilities. */
43      private ProcessingEnvironment processingEnv;
44  
45      /**
46       * Default constructor for the entity processor.
47       *
48       */
49      public EntityProcessor() {
50          this.attributeProcessor = new AttributeProcessor();
51      }
52  
53      /**
54       * Initializes the processor with the processing environment.
55       *
56       * @param processingEnv environment to access facilities the tool framework provides to the processor.
57       */
58      @SuppressWarnings("checkstyle:HiddenField")
59      public void init(@Nonnull final ProcessingEnvironment processingEnv) {
60          this.processingEnv = processingEnv;
61          this.attributeProcessor.init(this.processingEnv);
62      }
63  
64      /**
65       * Process all entities annotated with {@code @Entity}.
66       *
67       * @param elements the elements to process (all must be an {@code @Entity}).
68       * @param model the model where the final entity is added to.
69       */
70      public void process(@Nonnull final Set<? extends Element> elements, @Nonnull final Model model) {
71          for (Element element: elements) {
72              this.process(element, model);
73          }
74      }
75  
76      /**
77       * Process a single entity annotated with {@code @Entity}.
78       *
79       * @param element the element to process (must be an {@code @Entity}.
80       * @param model the model where the final entity is added to.
81       */
82      private void process(@Nonnull final Element element, @Nonnull final Model model) {
83          javax.persistence.Entity entityAnnotation = element.getAnnotation(javax.persistence.Entity.class);
84          this.processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
85                  new StringBuilder("Processing class \"").append(element.getSimpleName())
86                          .append("\".").toString(), element);
87          if (entityAnnotation == null) {
88              this.processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
89                      new StringBuilder("The processed class \"").append(element.getSimpleName())
90                              .append("\" is not an entity.").toString(), element);
91          } else if (ElementKind.CLASS.equals(element.getKind()) &&
92                  element.getEnclosingElement() != null &&
93                  ElementKind.PACKAGE.equals(element.getEnclosingElement().getKind())) {
94              // This is a top level class therefore we can continue.
95              TypeElement typeElement = (TypeElement)element;
96              String className = typeElement.getQualifiedName().toString();
97              String entityName;
98              if ("".equals(entityAnnotation.name())) {
99                  entityName = element.getSimpleName().toString();
100             } else {
101                 entityName = entityAnnotation.name();
102             }
103             Entity entity = new Entity(entityName, className);
104 
105             javax.persistence.Table tableAnnotation = element.getAnnotation(javax.persistence.Table.class);
106             String tableName;
107             String catalogName;
108             String schemaName;
109             if (tableAnnotation != null) {
110                 tableName = tableAnnotation.name();
111                 catalogName = tableAnnotation.catalog();
112                 schemaName = tableAnnotation.schema();
113                 if ("".equals(tableName)) {
114                     tableName = entityName;
115                 }
116             } else {
117                 tableName = entityName;
118                 catalogName = "";
119                 schemaName = "";
120             }
121             Table table = new Table(tableName, catalogName, schemaName, entity);
122             entity.addTable(table);
123 
124             model.addEntity(entity);
125 
126             this.attributeProcessor.process(entity, element.getEnclosedElements());
127         } else {
128             this.processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
129                     new StringBuilder("The processed entity \"").append(element.getSimpleName())
130                             .append("\" is no top level class."), element);
131         }
132     }
133 
134 }