126 lines
3.0 KiB
Java
126 lines
3.0 KiB
Java
/**
|
|
*
|
|
*/
|
|
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<ISM extends ISManageable> {
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(ISMDiscovery.class);
|
|
|
|
protected final Graph<Class<ISM>, DefaultEdge> graph;
|
|
|
|
public Graph<Class<ISM>, DefaultEdge> getGraph() {
|
|
return graph;
|
|
}
|
|
|
|
protected final Class<ISM> root;
|
|
protected final Set<Class<ISM>> visited;
|
|
|
|
public ISMDiscovery(Class<ISM> 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<ISM> clz, Class<ISM> parent) {
|
|
graph.addEdge(parent, clz);
|
|
visited.add(clz);
|
|
logger.debug("Adding {} as children of {}", clz, parent);
|
|
}
|
|
|
|
protected void analizeISM(Class<ISM> 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<ISM> parent = (Class<ISM>) 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<ISM> type = (Class<ISM>) m.getReturnType();
|
|
analizeISM(type);
|
|
addISM(clz, type);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
logger.trace("{}", (Object[]) interfaces);
|
|
}
|
|
}
|
|
|
|
public void discover() throws Exception {
|
|
|
|
List<Class<?>> 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> ism = (Class<ISM>) clz;
|
|
analizeISM(ism);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|