package org.atomnuke.container.packaging.bindings.lang.java; import java.lang.annotation.Annotation; import java.util.LinkedList; import java.util.List; import org.atomnuke.plugin.env.ClassLoaderEnvironment; import org.atomnuke.container.packaging.bindings.lang.java.scanner.ClassLoaderScanner; import org.atomnuke.container.packaging.bindings.lang.java.scanner.ClassVisitor; import org.atomnuke.container.packaging.classloader.IdentityClassLoader; import org.atomnuke.container.packaging.resource.ResourceManager; import org.atomnuke.container.service.annotation.NukeService; import org.atomnuke.service.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author zinic */ public class JavaEnvironment extends ClassLoaderEnvironment { private static final Logger LOG = LoggerFactory.getLogger(JavaEnvironment.class); private final ResourceManager resourceManager; private final ClassLoader envClassloader; public JavaEnvironment(ClassLoader parent, ResourceManager resourceManager) { this(resourceManager, new IdentityClassLoader(parent, resourceManager)); } private JavaEnvironment(ResourceManager resourceManager, ClassLoader envClassloader) { super(envClassloader); this.envClassloader = envClassloader; this.resourceManager = resourceManager; } @Override public List<Service> services() { final List<Service> builtServices = new LinkedList<Service>(); try { stepInto(); for (String serviceClassName : allServiceClassNames()) { try { final Class serviceClazz = envClassloader.loadClass(serviceClassName); builtServices.add((Service) serviceClazz.newInstance()); } catch (Exception ex) { LOG.error("Service init failed for service class: " + serviceClassName + " - Reason: " + ex.getMessage(), ex); } } } finally { stepOut(); } return builtServices; } private List<String> allServiceClassNames() { final List<String> discoveredServiceClasses = new LinkedList<String>(); final ClassLoader scannerClassLoader = new IdentityClassLoader(resourceManager); final ClassLoaderScanner classLoaderScanner = new ClassLoaderScanner(resourceManager, scannerClassLoader); classLoaderScanner.scan(new ClassVisitor() { @Override public void visit(Class<?> clazz) { final Annotation nukeSvcAnnotation = clazz.getAnnotation(NukeService.class); if (nukeSvcAnnotation != null) { discoveredServiceClasses.add(String.valueOf(clazz.getName())); } } }); return discoveredServiceClasses; } }