View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.apt.processor;
21  
22  import javax.annotation.processing.AbstractProcessor;
23  import javax.annotation.processing.RoundEnvironment;
24  import javax.lang.model.element.Element;
25  import javax.lang.model.element.PackageElement;
26  import javax.lang.model.element.TypeElement;
27  import javax.tools.Diagnostic;
28  import java.io.PrintWriter;
29  import java.io.StringWriter;
30  import java.util.ArrayList;
31  import java.util.Collection;
32  import java.util.Comparator;
33  import java.util.List;
34  import java.util.Set;
35  
36  public abstract class AbstractGenerator extends AbstractProcessor {
37  
38    private List<TypeElement> types;
39    private List<PackageElement> packages;
40  
41    @Override
42    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
43  
44      info("**********************************************************************************");
45      info("* Starting generator: " + getClass().getName());
46      info("* Number of annotations:   " + annotations.size());
47      for (final TypeElement typeElement : annotations) {
48        info("* Type element: " + typeElement.getQualifiedName());
49      }
50  
51      if (annotations.size() == 0) {
52        // TDB Why this case happen?
53        return false;
54      }
55  
56      types = new ArrayList<>();
57      packages = new ArrayList<>();
58      for (final TypeElement element : annotations) {
59        final Collection<? extends Element> elementsAnnotatedWith = roundEnv
60            .getElementsAnnotatedWith(element);
61        for (final Element e : elementsAnnotatedWith) {
62          if (e instanceof TypeElement) {
63            if (!types.contains(e)) { // todo: optimize, O(n^2)?
64              types.add((TypeElement) e);
65            }
66          }
67          if (e instanceof PackageElement) {
68            if (!packages.contains(e)) {
69              packages.add((PackageElement) e);
70            }
71          }
72        }
73      }
74  
75      types.sort(Comparator.comparing(d -> d.getSimpleName().toString()));
76  
77      configure();
78  
79      try {
80        generate();
81      } catch (final Exception e) {
82        error(e);
83      }
84  
85      return false;
86    }
87  
88    protected abstract void configure();
89  
90    protected abstract void generate()
91        throws Exception;
92  
93    protected void info(final String message) {
94      processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
95          "<" + getClass().getSimpleName() + "> " + message);
96    }
97  
98    protected void warn(final String message) {
99      processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
100         "<" + getClass().getSimpleName() + "> " + message);
101   }
102 
103   protected void error(final Exception e) {
104     final StringWriter out = new StringWriter();
105     e.printStackTrace(new PrintWriter(out));
106     processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
107         "<" + getClass().getSimpleName() + "> " + e.getMessage() + "\n"
108             + (e.getCause() != null ? e.getCause().getMessage() + "\n" : "")
109             + out.toString());
110   }
111 
112   public List<TypeElement> getTypes() {
113     return types;
114   }
115 
116   public List<PackageElement> getPackages() {
117     return packages;
118   }
119 }