293 } |
293 } |
294 } |
294 } |
295 |
295 |
296 /** |
296 /** |
297 * Use a service loader appropriate for the platform to provide an |
297 * Use a service loader appropriate for the platform to provide an |
298 * iterator over annotations processors. If |
298 * iterator over annotations processors; fails if a loader is |
299 * java.util.ServiceLoader is present use it, otherwise, use |
299 * needed but unavailable. |
300 * sun.misc.Service, otherwise fail if a loader is needed. |
|
301 */ |
300 */ |
302 private class ServiceIterator implements Iterator<Processor> { |
301 private class ServiceIterator implements Iterator<Processor> { |
303 // The to-be-wrapped iterator. |
302 private Iterator<Processor> iterator; |
304 private Iterator<?> iterator; |
|
305 private Log log; |
303 private Log log; |
306 private Class<?> loaderClass; |
304 private ServiceLoader<Processor> loader; |
307 private boolean jusl; |
|
308 private Object loader; |
|
309 |
305 |
310 ServiceIterator(ClassLoader classLoader, Log log) { |
306 ServiceIterator(ClassLoader classLoader, Log log) { |
311 String loadMethodName; |
|
312 |
|
313 this.log = log; |
307 this.log = log; |
314 try { |
308 try { |
315 try { |
309 try { |
316 loaderClass = Class.forName("java.util.ServiceLoader"); |
310 loader = ServiceLoader.load(Processor.class, classLoader); |
317 loadMethodName = "load"; |
311 this.iterator = loader.iterator(); |
318 jusl = true; |
312 } catch (Exception e) { |
319 } catch (ClassNotFoundException cnfe) { |
313 // Fail softly if a loader is not actually needed. |
320 try { |
314 this.iterator = handleServiceLoaderUnavailability("proc.no.service", null); |
321 loaderClass = Class.forName("sun.misc.Service"); |
315 } |
322 loadMethodName = "providers"; |
|
323 jusl = false; |
|
324 } catch (ClassNotFoundException cnfe2) { |
|
325 // Fail softly if a loader is not actually needed. |
|
326 this.iterator = handleServiceLoaderUnavailability("proc.no.service", |
|
327 null); |
|
328 return; |
|
329 } |
|
330 } |
|
331 |
|
332 // java.util.ServiceLoader.load or sun.misc.Service.providers |
|
333 Method loadMethod = loaderClass.getMethod(loadMethodName, |
|
334 Class.class, |
|
335 ClassLoader.class); |
|
336 |
|
337 Object result = loadMethod.invoke(null, |
|
338 Processor.class, |
|
339 classLoader); |
|
340 |
|
341 // For java.util.ServiceLoader, we have to call another |
|
342 // method to get the iterator. |
|
343 if (jusl) { |
|
344 loader = result; // Store ServiceLoader to call reload later |
|
345 Method m = loaderClass.getMethod("iterator"); |
|
346 result = m.invoke(result); // serviceLoader.iterator(); |
|
347 } |
|
348 |
|
349 // The result should now be an iterator. |
|
350 this.iterator = (Iterator<?>) result; |
|
351 } catch (Throwable t) { |
316 } catch (Throwable t) { |
352 log.error("proc.service.problem"); |
317 log.error("proc.service.problem"); |
353 throw new Abort(t); |
318 throw new Abort(t); |
354 } |
319 } |
355 } |
320 } |
356 |
321 |
357 public boolean hasNext() { |
322 public boolean hasNext() { |
358 try { |
323 try { |
359 return iterator.hasNext(); |
324 return iterator.hasNext(); |
|
325 } catch(ServiceConfigurationError sce) { |
|
326 log.error("proc.bad.config.file", sce.getLocalizedMessage()); |
|
327 throw new Abort(sce); |
360 } catch (Throwable t) { |
328 } catch (Throwable t) { |
361 if ("ServiceConfigurationError". |
|
362 equals(t.getClass().getSimpleName())) { |
|
363 log.error("proc.bad.config.file", t.getLocalizedMessage()); |
|
364 } |
|
365 throw new Abort(t); |
329 throw new Abort(t); |
366 } |
330 } |
367 } |
331 } |
368 |
332 |
369 public Processor next() { |
333 public Processor next() { |
370 try { |
334 try { |
371 return (Processor)(iterator.next()); |
335 return iterator.next(); |
|
336 } catch (ServiceConfigurationError sce) { |
|
337 log.error("proc.bad.config.file", sce.getLocalizedMessage()); |
|
338 throw new Abort(sce); |
372 } catch (Throwable t) { |
339 } catch (Throwable t) { |
373 if ("ServiceConfigurationError". |
|
374 equals(t.getClass().getSimpleName())) { |
|
375 log.error("proc.bad.config.file", t.getLocalizedMessage()); |
|
376 } else { |
|
377 log.error("proc.processor.constructor.error", t.getLocalizedMessage()); |
|
378 } |
|
379 throw new Abort(t); |
340 throw new Abort(t); |
380 } |
341 } |
381 } |
342 } |
382 |
343 |
383 public void remove() { |
344 public void remove() { |
384 throw new UnsupportedOperationException(); |
345 throw new UnsupportedOperationException(); |
385 } |
346 } |
386 |
347 |
387 public void close() { |
348 public void close() { |
388 if (jusl) { |
349 if (loader != null) { |
389 try { |
350 try { |
390 // Call java.util.ServiceLoader.reload |
351 loader.reload(); |
391 Method reloadMethod = loaderClass.getMethod("reload"); |
|
392 reloadMethod.invoke(loader); |
|
393 } catch(Exception e) { |
352 } catch(Exception e) { |
394 ; // Ignore problems during a call to reload. |
353 ; // Ignore problems during a call to reload. |
395 } |
354 } |
396 } |
355 } |
397 } |
356 } |