/** * */ package org.gcube.informationsystem.model.discovery; import java.lang.reflect.Method; import java.util.HashSet; import java.util.List; import java.util.Set; import org.gcube.informationsystem.impl.utils.discovery.ReflectionUtility; import org.gcube.informationsystem.model.ISManageable; import org.gcube.informationsystem.model.annotations.ISProperty; import org.gcube.informationsystem.model.embedded.Embedded; import org.jgrapht.Graph; import org.jgrapht.graph.DefaultDirectedGraph; import org.jgrapht.graph.DefaultEdge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) */ public class ISMDiscovery { private static Logger logger = LoggerFactory.getLogger(ISMDiscovery.class); protected final Graph, DefaultEdge> graph; public Graph, DefaultEdge> getGraph() { return graph; } protected final Class root; protected final Set> visited; public ISMDiscovery(Class root) { this.root = root; this.graph = new DefaultDirectedGraph<>(DefaultEdge.class); this.visited = new HashSet<>(); this.graph.addVertex(root); this.visited.add(root); } protected void addISM(Class clz, Class parent) { graph.addEdge(parent, clz); visited.add(clz); logger.debug("Adding {} as children of {}", clz, parent); } protected void analizeISM(Class clz) { logger.trace(" --- Analizyng {}", clz.getCanonicalName()); if (visited.contains(clz)) { logger.trace(" --------- discarding {} because was already managed", clz); return; } else { graph.addVertex(clz); Class[] interfaces = clz.getInterfaces(); for (Class interfaceClass : interfaces) { if (!root.isAssignableFrom(interfaceClass)) { logger.trace(" --------- discarding {} because is not a {}", interfaceClass, root.getClass().getSimpleName()); continue; } @SuppressWarnings("unchecked") Class parent = (Class) interfaceClass; if (!visited.contains(parent)) { analizeISM(parent); } addISM(clz, parent); } if(root==Embedded.class){ for (Method m : clz.getDeclaredMethods()){ m.setAccessible(true); if(m.isAnnotationPresent(ISProperty.class)){ if(root.isAssignableFrom(m.getReturnType())){ @SuppressWarnings("unchecked") Class type = (Class) m.getReturnType(); analizeISM(type); addISM(clz, type); } } } } logger.trace("{}", (Object[]) interfaces); } } public void discover() throws Exception { List> classes = ReflectionUtility.getClassesForPackage(root.getPackage()); for (Class clz : classes) { logger.trace("Analyzing {}", clz); if (!clz.isInterface()) { logger.trace("Discarding {} that is not an interface", clz); continue; } if (root.isAssignableFrom(clz)) { @SuppressWarnings("unchecked") Class ism = (Class) clz; analizeISM(ism); } } } }