package com.firefly.core.support.annotation; import com.firefly.annotation.Component; import com.firefly.core.support.AbstractBeanReader; import com.firefly.core.support.BeanDefinition; import com.firefly.utils.ReflectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.jar.JarEntry; import static com.firefly.core.support.annotation.AnnotationBeanUtils.*; /** * Annotation Bean processor * * @author AlvinQiu */ public class AnnotationBeanReader extends AbstractBeanReader { private static Logger log = LoggerFactory.getLogger("firefly-system"); public AnnotationBeanReader() { this(null); } public AnnotationBeanReader(String file) { beanDefinitions = new ArrayList<>(); Config config = ConfigReader.getInstance().load(file); for (String pack : config.getPaths()) { log.info("componentPath [{}]", pack); scan(pack.trim()); } } private void scan(String packageName) { String packageDirName = packageName.replace('.', '/'); log.debug("package directory name -> {} ", packageDirName); URL url = AnnotationBeanReader.class.getClassLoader().getResource(packageDirName); if (url == null) { error(packageName + " can not be found"); } else { log.debug("URL -> {}", url.toString()); String protocol = url.getProtocol(); if ("file".equals(protocol)) { parseFile(url, packageDirName); } else if ("jar".equals(protocol)) { parseJar(url, packageDirName); } } } private void parseFile(URL url, final String packageDirName) { try { File path = new File(url.toURI()); path.listFiles(file -> { String name = file.getName(); if (name.endsWith(".class") && !name.contains("$")) { parseClass(packageDirName.replace('/', '.') + "." + name.substring(0, file.getName().length() - 6)); } else if (file.isDirectory()) { try { parseFile(file.toURI().toURL(), packageDirName + "/" + name); } catch (Throwable t) { log.error("parse file error", t); } } return false; }); } catch (Throwable t) { log.error("parse file error", t); } } private void parseJar(URL url, String packageDirName) { try { Enumeration<JarEntry> entries = ((JarURLConnection) url.openConnection()).getJarFile().entries(); while (entries.hasMoreElements()) { String name = entries.nextElement().getName(); if (!name.endsWith(".class") || name.contains("$") || !name.startsWith(packageDirName + "/")) { continue; } parseClass(name.substring(0, name.length() - 6).replace('/', '.')); } } catch (IOException t) { log.error("parse jar error", t); } } private void parseClass(String className) { try { Class<?> c = AnnotationBeanReader.class.getClassLoader().loadClass(className); BeanDefinition beanDefinition = getBeanDefinition(c); if (beanDefinition != null) { beanDefinitions.add(beanDefinition); } } catch (Throwable t) { log.error("parse class error", t); } } protected BeanDefinition getBeanDefinition(Class<?> c) { if (c.isAnnotationPresent(Component.class)) { log.info("classes [{}]", c.getName()); return componentParser(c); } else { return null; } } protected BeanDefinition componentParser(Class<?> c) { AnnotationBeanDefinition annotationBeanDefinition = new AnnotatedBeanDefinition(); annotationBeanDefinition.setClassName(c.getName()); annotationBeanDefinition.setId(c.getAnnotation(Component.class).value()); annotationBeanDefinition.setInterfaceNames(ReflectUtils.getInterfaceNames(c)); annotationBeanDefinition.setInjectFields(getInjectFields(c)); annotationBeanDefinition.setInjectMethods(getInjectMethods(c)); annotationBeanDefinition.setConstructor(getInjectConstructor(c)); annotationBeanDefinition.setInitMethod(getInitMethod(c)); annotationBeanDefinition.setDestroyedMethod(getDestroyedMethod(c)); return annotationBeanDefinition; } }