package org.apache.openwebbeans.environment.osgi.integration; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.webbeans.exception.WebBeansDeploymentException; import org.apache.webbeans.spi.BDABeansXmlScanner; import org.apache.webbeans.spi.ScannerService; import org.osgi.framework.Bundle; /** * * @author Mathieu ANCELIN - SERLI (mathieu.ancelin@serli.com) */ public class OSGiScanner implements ScannerService { /** All classes which have to be scanned for Bean information */ private Set<Class<?>> beanClasses = new HashSet<Class<?>>(); /** the paths of all META-INF/beans.xml files */ private Set<String> beanXMLs = new HashSet<String>(); /**contains all the JARs we found with valid beans.xml in it */ private Set<String> beanArchiveJarNames = new HashSet<String>(); private Map<String, Set<String>> classAnnotations = new HashMap<String, Set<String>>(); private Bundle bundle; public void setBundle(Bundle bundle) { this.bundle = bundle; } @Override public void init(Object object) { // if (object instanceof ServletContext) { // servletContext = (ServletContext) object; // } } @Override public void release() { // beanClasses = new HashSet<Class<?>>(); // beanXMLs = new HashSet<String>(); // beanArchiveJarNames = new HashSet<String>(); // classAnnotations.clear(); } public void release2() { beanClasses = new HashSet<Class<?>>(); beanXMLs = new HashSet<String>(); beanArchiveJarNames = new HashSet<String>(); classAnnotations.clear(); } @Override public void scan() throws WebBeansDeploymentException { if (bundle == null) { throw new RuntimeException("Bundle can't be null"); } // TODO : use BundleScanner API Enumeration beansXml = bundle.findEntries("META-INF", "beans.xml", true); if (beansXml != null) { while (beansXml.hasMoreElements()) { URL url = ((URL) beansXml.nextElement()); beanXMLs.add(url.toString()); } Enumeration foundBeanClasses = bundle.findEntries("", "*.class", true); if (foundBeanClasses != null) { while (foundBeanClasses.hasMoreElements()) { URL url = (URL) foundBeanClasses.nextElement(); String clazz = url.getFile().substring(1).replace("/", ".").replace(".class", ""); try { beanClasses.add(bundle.loadClass(clazz)); } catch (Throwable ex) { ex.printStackTrace(); } } } for (Class<?> clazz : beanClasses) { Set<String> set = collectAnnotations(clazz); if (!classAnnotations.containsKey(clazz.getName())) { classAnnotations.put(clazz.getName(), new HashSet<String>()); } classAnnotations.get(clazz.getName()).addAll(set); } } } private Set<String> collectAnnotations(Class<?> cls) { Set<String> annotations = new HashSet<String>(); addAnnotations(annotations, cls.getAnnotations()); Constructor[] constructors = cls.getDeclaredConstructors(); for (Constructor c : constructors) { addAnnotations(annotations, c.getAnnotations()); } Field[] fields = cls.getDeclaredFields(); for (Field f : fields) { addAnnotations(annotations, f.getAnnotations()); } Method[] methods = cls.getDeclaredMethods(); for (Method m : methods) { addAnnotations(annotations, m.getAnnotations()); Annotation[][] paramsAnns = m.getParameterAnnotations(); for (Annotation[] pAnns : paramsAnns) { addAnnotations(annotations, pAnns); } } return annotations; } private void addAnnotations(Set<String> annStrings, Annotation[] annotations) { for (Annotation ann : annotations) { annStrings.add(ann.getClass().getSimpleName()); } } @Override public Set<String> getBeanXmls() { return beanXMLs; } @Override public Set<Class<?>> getBeanClasses() { return beanClasses; } @Override public Set<String> getAllAnnotations(String className) { return classAnnotations.get(className); } @Override public BDABeansXmlScanner getBDABeansXmlScanner() { return null; } @Override public boolean isBDABeansXmlScanningEnabled() { return false; } }