Advertisement
Guest User

Eelco

a guest
Oct 13th, 2009
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.40 KB | None | 0 0
  1. /**
  2.  * Scans the class path for jars that contain the provided package
  3.  */
  4. class EagerBinder {
  5.  
  6.     private static final Logger log = Logger.getLogger(EagerBinder.class
  7.             .getName());
  8.  
  9.     private final AbstractBindings bindings;
  10.  
  11.     /**
  12.      * Create eager binder.
  13.      *
  14.      * @param bindings
  15.      *            bindings to bind to
  16.      */
  17.     public EagerBinder(AbstractBindings bindings) {
  18.         this.bindings = bindings;
  19.     }
  20.  
  21.     /**
  22.      * Perform classpath scanning and binding.
  23.      *
  24.      * @param scanPackage
  25.      *            root package to scan classes in, for instance com.edgenuity
  26.      */
  27.     public void scanAndBind(String scanPackage) {
  28.         ClassLoader classLoader = getClassLoader();
  29.         try {
  30.             for (Enumeration<URL> resources = classLoader
  31.                     .getResources((scanPackage != null) ? scanPackage.replace(
  32.                             '.', '/') : "/"); resources.hasMoreElements();) {
  33.                 URL url = resources.nextElement();
  34.                 String s = url.toString();
  35.                 log.config("scanning " + s);
  36.                 if (s.startsWith("jar:")) {
  37.                     s = s.substring(4, s.indexOf(".jar") + 4);
  38.                     File f = new File(s);
  39.                     assert (f.exists());
  40.                     ZipFile zip = new ZipFile(new File(new URL(s).toURI()));
  41.                     try {
  42.                         for (Enumeration<? extends ZipEntry> entries = zip
  43.                                 .entries(); entries.hasMoreElements();) {
  44.                             ZipEntry entry = (ZipEntry) entries.nextElement();
  45.                             if (entry.getName().endsWith(".class")) {
  46.                                 InputStream is = zip.getInputStream(entry);
  47.                                 processClass(is);
  48.                             }
  49.                         }
  50.                     } finally {
  51.                         zip.close();
  52.                     }
  53.                 } else if (s.startsWith("file:")) {
  54.                     traverse(new File(url.toURI()));
  55.                 } // else ignore
  56.             }
  57.         } catch (IOException e) {
  58.             throw new RuntimeException(e);
  59.         } catch (URISyntaxException e) {
  60.             throw new RuntimeException(e);
  61.         }
  62.     }
  63.  
  64.     private void processClass(InputStream is) throws IOException {
  65.         ClassReader reader = new ClassReader(is);
  66.         reader.accept(new EmptyVisitor() {
  67.  
  68.             private String owner;
  69.  
  70.             private Class<?> ownerType;
  71.  
  72.             private Class<?> annotationType;
  73.  
  74.             @Override
  75.             public void visit(final int version, final int access,
  76.                     final String name, final String signature,
  77.                     final String superName, final String[] interfaces) {
  78.                 owner = name;
  79.             }
  80.  
  81.             private void setOwnerType() {
  82.                 try {
  83.                     ownerType = getClassLoader().loadClass(
  84.                             owner.replace('/', '.'));
  85.                 } catch (ClassNotFoundException e) {
  86.                     throw new RuntimeException(e);
  87.                 }
  88.             }
  89.  
  90.             @Override
  91.             public AnnotationVisitor visitAnnotation(String desc,
  92.                     boolean visible) {
  93.                 if ("Lcom/google/inject/Singleton;".equals(desc)) {
  94.                     annotationType = Singleton.class;
  95.                     setOwnerType();
  96.                     if (!bindings.isBound(ownerType)
  97.                             && !bindings.isOnEagerBindingBlackList(ownerType)) {
  98.                         bindings.bind(ownerType).asEagerSingleton();
  99.                         log.config("bound " + ownerType + " as a singleton");
  100.                     }
  101.                 } else if ("Lcom/google/inject/ImplementedBy;".equals(desc)) {
  102.                     annotationType = ImplementedBy.class;
  103.                     setOwnerType();
  104.                 } else if ("Lcom/google/inject/ProvidedBy;".equals(desc)) {
  105.                     annotationType = ProvidedBy.class;
  106.                     setOwnerType();
  107.                 } else {
  108.                     annotationType = null;
  109.                 }
  110.                 return this;
  111.             }
  112.  
  113.             @SuppressWarnings("unchecked")
  114.             @Override
  115.             public void visit(String name, Object value) {
  116.                 if (annotationType != null) {
  117.                     log.config(owner + ", " + annotationType + ", " + name
  118.                             + "=" + value);
  119.                     if (annotationType == ProvidedBy.class) {
  120.                         if (!bindings.isBound(ownerType)
  121.                                 && !bindings
  122.                                         .isOnEagerBindingBlackList(ownerType)) {
  123.                             Class provider = loadClass((com.teachscape.esb.asm.Type) value);
  124.                             ScopedBindingBuilder b = bindings.bind(ownerType)
  125.                                     .toProvider(provider);
  126.                             if (provider.getAnnotation(Singleton.class) != null) {
  127.                                 b.asEagerSingleton();
  128.                                 log.config("bound " + ownerType.getName()
  129.                                         + " to provider " + provider);
  130.                             } else {
  131.                                 log.config("bound " + ownerType.getName()
  132.                                         + " to provider " + provider
  133.                                         + " as a singleton");
  134.                             }
  135.                         }
  136.                     } else if (annotationType == ImplementedBy.class) {
  137.                         if (ownerType.isInterface()
  138.                                 && !bindings.isBound(ownerType)
  139.                                 && !bindings
  140.                                         .isOnEagerBindingBlackList(ownerType)) {
  141.                             Class implementation = loadClass((com.teachscape.esb.asm.Type) value);
  142.                             ScopedBindingBuilder b = bindings.bind(ownerType)
  143.                                     .to(implementation);
  144.                             if (implementation.getAnnotation(Singleton.class) != null) {
  145.                                 b.asEagerSingleton();
  146.                                 log.config("bound " + ownerType.getName()
  147.                                         + " to impl " + implementation);
  148.                             } else {
  149.                                 log.config("bound " + ownerType.getName()
  150.                                         + " to impl " + implementation
  151.                                         + " as a singleton");
  152.                             }
  153.                         }
  154.                     }
  155.                 }
  156.             }
  157.         }, 0);
  158.     }
  159.  
  160.     private void traverse(File file) {
  161.         if (file.isDirectory()) {
  162.             for (File child : file.listFiles()) {
  163.                 traverse(child);
  164.             }
  165.         }
  166.         if (file.getName().endsWith(".class")) {
  167.             try {
  168.                 InputStream is = new FileInputStream(file);
  169.                 try {
  170.                     processClass(is);
  171.                 } finally {
  172.                     is.close();
  173.                 }
  174.             } catch (IOException e) {
  175.                 throw new RuntimeException(e);
  176.             }
  177.         }
  178.     }
  179.  
  180.     private ClassLoader getClassLoader() {
  181.         ClassLoader classLoader = Thread.currentThread()
  182.                 .getContextClassLoader();
  183.         if (classLoader == null) {
  184.             classLoader = EagerBinder.class.getClassLoader();
  185.         }
  186.         return classLoader;
  187.     }
  188.  
  189.     private Class<?> loadClass(com.teachscape.esb.asm.Type type) {
  190.         try {
  191.             return getClassLoader().loadClass(type.getClassName());
  192.         } catch (ClassNotFoundException e) {
  193.             throw new RuntimeException(e);
  194.         }
  195.     }
  196. }
  197.  
  198.  
  199. /**
  200.  * Configuration for dependency injection through {@link Dependencies}.
  201.  */
  202. abstract class AbstractBindings extends AbstractModule {
  203.  
  204.     /**
  205.      * Whether the provided type is already bound (managed) by Guice.
  206.      *
  207.      * @param type
  208.      *            the type to check
  209.      * @return true if bound, false otherwise
  210.      */
  211.     public abstract boolean isBound(Class<?> type);
  212.  
  213.     /**
  214.      * Whether the provided type should be ignored for eager loading if that is
  215.      * turned on.
  216.      *
  217.      * @param type
  218.      * @return true if the type should be ignore, false otherwise
  219.      * @see EagerBinder
  220.      */
  221.     public abstract boolean isOnEagerBindingBlackList(Class<?> type);
  222.  
  223.     @Override
  224.     public <T> AnnotatedBindingBuilder<T> bind(Class<T> clazz) {
  225.         return super.bind(clazz);
  226.     }
  227. }
  228.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement