1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.testdoc.collect.processor;
17
18 import java.io.File;
19 import java.util.Collections;
20 import java.util.HashSet;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.logging.Level;
24 import java.util.logging.Logger;
25
26 import javax.annotation.processing.AbstractProcessor;
27 import javax.annotation.processing.Filer;
28 import javax.annotation.processing.ProcessingEnvironment;
29 import javax.annotation.processing.RoundEnvironment;
30 import javax.annotation.processing.SupportedAnnotationTypes;
31 import javax.annotation.processing.SupportedSourceVersion;
32 import javax.lang.model.element.TypeElement;
33 import javax.lang.model.util.Elements;
34
35 import org.apache.commons.lang.StringUtils;
36
37 import de.smartics.testdoc.collect.extractor.ExtractorConfig;
38 import de.smartics.testdoc.core.TestDocProperty;
39 import de.smartics.testdoc.core.adapter.BasedFilerSingletonInMemoryExportAdapter;
40 import de.smartics.testdoc.core.adapter.DirectoryExportAdapter;
41 import de.smartics.testdoc.core.adapter.FilerExportAdapter;
42 import de.smartics.testdoc.core.doc.names.EnglishTestNameUtils;
43 import de.smartics.testdoc.core.doc.names.TestNameUtils;
44 import de.smartics.testdoc.core.export.ExportAdapter;
45 import de.smartics.testdoc.core.source.SourceCodeHelper;
46 import de.smartics.testdoc.core.source.SourceCodeHelperFactory;
47
48
49
50
51
52
53
54 @SupportedAnnotationTypes("de.smartics.testdoc.annotations.Uut")
55 @SupportedSourceVersion(javax.lang.model.SourceVersion.RELEASE_6)
56 public class TestDocProcessor extends AbstractProcessor
57 {
58
59
60
61
62
63
64
65 private static final Logger LOG = Logger.getLogger(TestDocProcessor.class
66 .getName());
67
68
69
70
71
72
73 private boolean quiet;
74
75
76
77
78 private ProcessorLogHelper log;
79
80
81
82
83 private ExportAdapter exporter;
84
85
86
87
88 private TestNameUtils testNameUtils;
89
90
91
92
93 private Filer filer;
94
95
96
97
98 private ExtractorConfig extractorConfig;
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 @Override
118 public synchronized void init(final ProcessingEnvironment processingEnv)
119 {
120 super.init(processingEnv);
121
122 log = new ProcessorLogHelper(quiet, processingEnv);
123
124 filer = processingEnv.getFiler();
125 final Map<String, String> options = processingEnv.getOptions();
126 initProcessor(options);
127 initTestNameUtils(options);
128 initExporter(options);
129
130 final Elements elementUtils = processingEnv.getElementUtils();
131
132 final SourceCodeHelperFactory factory =
133 new SourceCodeHelperFactory(processingEnv);
134
135 final SourceCodeHelper sourceCodeHelper = factory.create();
136 extractorConfig =
137 new ExtractorConfig(elementUtils, sourceCodeHelper, testNameUtils);
138 }
139
140 private void initProcessor(final Map<String, String> options)
141 {
142 final String key = TestDocProperty.PROC_CONF_QUIET.getName();
143 final String quietValue = options.get(key);
144 if (quietValue != null)
145 {
146 quiet = Boolean.valueOf(quietValue);
147 }
148 else
149 {
150 quiet = (Boolean) TestDocProperty.PROC_CONF_QUIET.getDefaultValue();
151 }
152 }
153
154 private void initTestNameUtils(final Map<String, String> options)
155 {
156 final String key = TestDocProperty.TEST_NAME_UTILS_CLASS_NAME.getName();
157 final String className = options.get(key);
158 if (StringUtils.isNotBlank(className))
159 {
160 testNameUtils = (TestNameUtils) createInstance(className);
161 }
162 else
163 {
164 testNameUtils = new EnglishTestNameUtils();
165 }
166 }
167
168 private void initExporter(final Map<String, String> options)
169 {
170 final String baseDirKey = TestDocProperty.EXPORT_ADAPTER_BASE_DIR.getName();
171 final String baseDirName = options.get(baseDirKey);
172 if (StringUtils.isNotBlank(baseDirName))
173 {
174 final File baseDir = new File(baseDirName);
175 exporter = new DirectoryExportAdapter(baseDir);
176 }
177 else
178 {
179 final String key = TestDocProperty.EXPORT_ADAPTER_CLASS_NAME.getName();
180 final String className = options.get(key);
181 if (StringUtils.isNotBlank(className) && isNoFilerBasedType(className))
182 {
183 exporter = (ExportAdapter) createInstance(className);
184 }
185 else
186 {
187 if (FilerExportAdapter.class.getName().equals(className))
188 {
189 exporter = new FilerExportAdapter(filer);
190 }
191 else
192 {
193 exporter = new BasedFilerSingletonInMemoryExportAdapter(filer);
194 }
195 }
196 }
197 }
198
199 private static boolean isNoFilerBasedType(final String className)
200 {
201 return !FilerExportAdapter.class.getName().equals(className)
202 && !BasedFilerSingletonInMemoryExportAdapter.class.getName().equals(
203 className);
204 }
205
206 private Object createInstance(final String className)
207 {
208 try
209 {
210 return Class.forName(className).newInstance();
211 }
212 catch (final InstantiationException e)
213 {
214 throw handleCreationProblem(className, ExportAdapter.class, e);
215 }
216 catch (final IllegalAccessException e)
217 {
218 throw handleCreationProblem(className, ExportAdapter.class, e);
219 }
220 catch (final ClassNotFoundException e)
221 {
222 throw handleCreationProblem(className, ExportAdapter.class, e);
223 }
224 }
225
226 @Override
227 public Set<String> getSupportedOptions()
228 {
229 final Set<String> options = new HashSet<String>();
230 options.addAll(super.getSupportedOptions());
231 for (final TestDocProperty property : TestDocProperty.values())
232 {
233 final String name = property.getName();
234 options.add(name);
235 }
236 return Collections.unmodifiableSet(options);
237 }
238
239 private RuntimeException handleCreationProblem(final String className,
240 final Class<?> type, final Exception e)
241 {
242 final String message =
243 "Cannot instantiate '" + className + "' as implementation of the '"
244 + type.getName() + "' interface.";
245 log.error(message);
246 return new IllegalArgumentException(message, e);
247 }
248
249
250
251
252
253
254 @Override
255 public boolean process(final Set<? extends TypeElement> annotations,
256 final RoundEnvironment roundEnv)
257 {
258 for (final TypeElement annotation : annotations)
259 {
260 LOG.log(Level.FINER, "Processing annotation {0}.",
261 annotation.getQualifiedName());
262
263 final UutProcess process = new UutProcess(log, exporter, extractorConfig);
264 process.processElements(roundEnv, annotation);
265 }
266
267 return false;
268 }
269
270
271
272 }