diff options
-rw-r--r-- | src/lombok/core/SpiLoadUtil.java | 63 | ||||
-rw-r--r-- | src/lombok/eclipse/HandlerLibrary.java | 27 |
2 files changed, 81 insertions, 9 deletions
diff --git a/src/lombok/core/SpiLoadUtil.java b/src/lombok/core/SpiLoadUtil.java index bf4bddf4..b26dd747 100644 --- a/src/lombok/core/SpiLoadUtil.java +++ b/src/lombok/core/SpiLoadUtil.java @@ -1,12 +1,75 @@ package lombok.core; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.net.URL; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; + +import lombok.Lombok; public class SpiLoadUtil { private SpiLoadUtil() {} + public static <C> Iterator<C> findServices(Class<C> target) throws IOException { + return findServices(target, Thread.currentThread().getContextClassLoader()); + } + + public static <C> Iterator<C> findServices(final Class<C> target, final ClassLoader loader) throws IOException { + Enumeration<URL> resources = loader.getResources("META-INF/services/" + target.getName()); + final Set<String> entries = new LinkedHashSet<String>(); + while ( resources.hasMoreElements() ) { + URL url = resources.nextElement(); + readServicesFromUrl(entries, url); + } + + final Iterator<String> names = entries.iterator(); + return new Iterator<C>() { + public boolean hasNext() { + return names.hasNext(); + } + + public C next() { + try { + return target.cast(Class.forName(names.next(), true, loader).newInstance()); + } catch ( Throwable t ) { + throw Lombok.sneakyThrow(t); + } + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + private static void readServicesFromUrl(Collection<String> list, URL url) throws IOException { + InputStream in = url.openStream(); + try { + if ( in == null ) return; + BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF-8")); + while ( true ) { + String line = r.readLine(); + if ( line == null ) break; + int idx = line.indexOf('#'); + if ( idx != -1 ) line = line.substring(0, idx); + line = line.trim(); + if ( line.length() == 0 ) continue; + list.add(line); + } + } finally { + try { in.close(); } catch ( Throwable ignore ) {} + } + } + @SuppressWarnings("unchecked") public static Class<? extends Annotation> findAnnotationClass(Class<?> c, Class<?> base) { if ( c == Object.class || c == null ) return null; diff --git a/src/lombok/eclipse/HandlerLibrary.java b/src/lombok/eclipse/HandlerLibrary.java index 37610a33..6ee2baaa 100644 --- a/src/lombok/eclipse/HandlerLibrary.java +++ b/src/lombok/eclipse/HandlerLibrary.java @@ -8,9 +8,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; +import lombok.Lombok; import lombok.core.AnnotationValues; import lombok.core.PrintAST; import lombok.core.SpiLoadUtil; @@ -58,7 +57,13 @@ public class HandlerLibrary { } @SuppressWarnings("unchecked") private static void loadAnnotationHandlers(HandlerLibrary lib) { - Iterator<EclipseAnnotationHandler> it = ServiceLoader.load(EclipseAnnotationHandler.class).iterator(); + Iterator<EclipseAnnotationHandler> it; + try { + it = SpiLoadUtil.findServices(EclipseAnnotationHandler.class); + } catch ( Throwable t ) { + throw Lombok.sneakyThrow(t); + } + while ( it.hasNext() ) { try { EclipseAnnotationHandler<?> handler = it.next(); @@ -69,19 +74,24 @@ public class HandlerLibrary { Eclipse.error(null, "Duplicate handlers for annotation type: " + container.annotationClass.getName()); } lib.typeLibrary.addType(container.annotationClass.getName()); - } catch ( ServiceConfigurationError e ) { - Eclipse.error(null, "Can't load Lombok annotation handler for eclipse: ", e); + } catch ( Throwable t ) { + Eclipse.error(null, "Can't load Lombok annotation handler for eclipse: ", t); } } } private static void loadVisitorHandlers(HandlerLibrary lib) { - Iterator<EclipseASTVisitor> it = ServiceLoader.load(EclipseASTVisitor.class).iterator(); + Iterator<EclipseASTVisitor> it; + try { + it = SpiLoadUtil.findServices(EclipseASTVisitor.class); + } catch ( Throwable t ) { + throw Lombok.sneakyThrow(t); + } while ( it.hasNext() ) { try { lib.visitorHandlers.add(it.next()); - } catch ( ServiceConfigurationError e ) { - Eclipse.error(null, "Can't load Lombok visitor handler for eclipse: ", e); + } catch ( Throwable t ) { + Eclipse.error(null, "Can't load Lombok visitor handler for eclipse: ", t); } } } @@ -105,7 +115,6 @@ public class HandlerLibrary { try { handled |= container.handle(annotation, annotationNode); } catch ( AnnotationValueDecodeFail fail ) { - fail.printStackTrace(); //TODO debug! fail.owner.setError(fail.getMessage(), fail.idx); } catch ( Throwable t ) { Eclipse.error(ast, String.format("Lombok annotation handler %s failed", container.handler.getClass()), t); |