143 * Source level of the compile. |
143 * Source level of the compile. |
144 */ |
144 */ |
145 Source source; |
145 Source source; |
146 |
146 |
147 private ClassLoader processorClassLoader; |
147 private ClassLoader processorClassLoader; |
|
148 private SecurityException processorClassLoaderException; |
148 |
149 |
149 /** |
150 /** |
150 * JavacMessages object used for localization |
151 * JavacMessages object used for localization |
151 */ |
152 */ |
152 private JavacMessages messages; |
153 private JavacMessages messages; |
153 |
154 |
154 private MultiTaskListener taskListener; |
155 private MultiTaskListener taskListener; |
155 |
156 |
156 private Context context; |
157 private Context context; |
157 |
158 |
158 public JavacProcessingEnvironment(Context context, Iterable<? extends Processor> processors) { |
159 /** Get the JavacProcessingEnvironment instance for this context. */ |
|
160 public static JavacProcessingEnvironment instance(Context context) { |
|
161 JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class); |
|
162 if (instance == null) |
|
163 instance = new JavacProcessingEnvironment(context); |
|
164 return instance; |
|
165 } |
|
166 |
|
167 protected JavacProcessingEnvironment(Context context) { |
159 this.context = context; |
168 this.context = context; |
160 log = Log.instance(context); |
169 log = Log.instance(context); |
161 source = Source.instance(context); |
170 source = Source.instance(context); |
162 diags = JCDiagnostic.Factory.instance(context); |
171 diags = JCDiagnostic.Factory.instance(context); |
163 options = Options.instance(context); |
172 options = Options.instance(context); |
182 typeUtils = JavacTypes.instance(context); |
191 typeUtils = JavacTypes.instance(context); |
183 processorOptions = initProcessorOptions(context); |
192 processorOptions = initProcessorOptions(context); |
184 unmatchedProcessorOptions = initUnmatchedProcessorOptions(); |
193 unmatchedProcessorOptions = initUnmatchedProcessorOptions(); |
185 messages = JavacMessages.instance(context); |
194 messages = JavacMessages.instance(context); |
186 taskListener = MultiTaskListener.instance(context); |
195 taskListener = MultiTaskListener.instance(context); |
|
196 initProcessorClassLoader(); |
|
197 } |
|
198 |
|
199 public void setProcessors(Iterable<? extends Processor> processors) { |
|
200 Assert.checkNull(discoveredProcs); |
187 initProcessorIterator(context, processors); |
201 initProcessorIterator(context, processors); |
188 } |
202 } |
189 |
203 |
190 private Set<String> initPlatformAnnotations() { |
204 private Set<String> initPlatformAnnotations() { |
191 Set<String> platformAnnotations = new HashSet<String>(); |
205 Set<String> platformAnnotations = new HashSet<String>(); |
197 platformAnnotations.add("java.lang.annotation.Retention"); |
211 platformAnnotations.add("java.lang.annotation.Retention"); |
198 platformAnnotations.add("java.lang.annotation.Target"); |
212 platformAnnotations.add("java.lang.annotation.Target"); |
199 return Collections.unmodifiableSet(platformAnnotations); |
213 return Collections.unmodifiableSet(platformAnnotations); |
200 } |
214 } |
201 |
215 |
|
216 private void initProcessorClassLoader() { |
|
217 JavaFileManager fileManager = context.get(JavaFileManager.class); |
|
218 try { |
|
219 // If processorpath is not explicitly set, use the classpath. |
|
220 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
|
221 ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) |
|
222 : fileManager.getClassLoader(CLASS_PATH); |
|
223 |
|
224 if (processorClassLoader != null && processorClassLoader instanceof Closeable) { |
|
225 JavaCompiler compiler = JavaCompiler.instance(context); |
|
226 compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader); |
|
227 } |
|
228 } catch (SecurityException e) { |
|
229 processorClassLoaderException = e; |
|
230 } |
|
231 } |
|
232 |
202 private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) { |
233 private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) { |
203 Log log = Log.instance(context); |
234 Log log = Log.instance(context); |
204 Iterator<? extends Processor> processorIterator; |
235 Iterator<? extends Processor> processorIterator; |
205 |
236 |
206 if (options.isSet(XPRINT)) { |
237 if (options.isSet(XPRINT)) { |
215 } |
246 } |
216 } else if (processors != null) { |
247 } else if (processors != null) { |
217 processorIterator = processors.iterator(); |
248 processorIterator = processors.iterator(); |
218 } else { |
249 } else { |
219 String processorNames = options.get(PROCESSOR); |
250 String processorNames = options.get(PROCESSOR); |
220 JavaFileManager fileManager = context.get(JavaFileManager.class); |
251 if (processorClassLoaderException == null) { |
221 try { |
|
222 // If processorpath is not explicitly set, use the classpath. |
|
223 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
|
224 ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) |
|
225 : fileManager.getClassLoader(CLASS_PATH); |
|
226 |
|
227 if (processorClassLoader != null && processorClassLoader instanceof Closeable) { |
|
228 JavaCompiler compiler = JavaCompiler.instance(context); |
|
229 compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader); |
|
230 } |
|
231 |
|
232 /* |
252 /* |
233 * If the "-processor" option is used, search the appropriate |
253 * If the "-processor" option is used, search the appropriate |
234 * path for the named class. Otherwise, use a service |
254 * path for the named class. Otherwise, use a service |
235 * provider mechanism to create the processor iterator. |
255 * provider mechanism to create the processor iterator. |
236 */ |
256 */ |
237 if (processorNames != null) { |
257 if (processorNames != null) { |
238 processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log); |
258 processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log); |
239 } else { |
259 } else { |
240 processorIterator = new ServiceIterator(processorClassLoader, log); |
260 processorIterator = new ServiceIterator(processorClassLoader, log); |
241 } |
261 } |
242 } catch (SecurityException e) { |
262 } else { |
243 /* |
263 /* |
244 * A security exception will occur if we can't create a classloader. |
264 * A security exception will occur if we can't create a classloader. |
245 * Ignore the exception if, with hindsight, we didn't need it anyway |
265 * Ignore the exception if, with hindsight, we didn't need it anyway |
246 * (i.e. no processor was specified either explicitly, or implicitly, |
266 * (i.e. no processor was specified either explicitly, or implicitly, |
247 * in service configuration file.) Otherwise, we cannot continue. |
267 * in service configuration file.) Otherwise, we cannot continue. |
248 */ |
268 */ |
249 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", e); |
269 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", |
|
270 processorClassLoaderException); |
250 } |
271 } |
251 } |
272 } |
252 discoveredProcs = new DiscoveredProcessors(processorIterator); |
273 discoveredProcs = new DiscoveredProcessors(processorIterator); |
253 } |
274 } |
254 |
275 |
1471 return Pattern.compile(s_prime); |
1492 return Pattern.compile(s_prime); |
1472 } |
1493 } |
1473 } |
1494 } |
1474 |
1495 |
1475 /** |
1496 /** |
1476 * For internal use only. This method will be |
1497 * For internal use only. This method may be removed without warning. |
1477 * removed without warning. |
|
1478 */ |
1498 */ |
1479 public Context getContext() { |
1499 public Context getContext() { |
1480 return context; |
1500 return context; |
|
1501 } |
|
1502 |
|
1503 /** |
|
1504 * For internal use only. This method may be removed without warning. |
|
1505 */ |
|
1506 public ClassLoader getProcessorClassLoader() { |
|
1507 return processorClassLoader; |
1481 } |
1508 } |
1482 |
1509 |
1483 public String toString() { |
1510 public String toString() { |
1484 return "javac ProcessingEnvironment"; |
1511 return "javac ProcessingEnvironment"; |
1485 } |
1512 } |