2019-03-22 15:18:23 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
package org.gcube.informationsystem.utils.discovery;
|
|
|
|
|
|
|
|
import java.lang.reflect.Method;
|
2019-10-30 09:57:14 +01:00
|
|
|
import java.lang.reflect.ParameterizedType;
|
|
|
|
import java.lang.reflect.Type;
|
2019-03-22 15:18:23 +01:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.List;
|
2019-10-30 09:57:14 +01:00
|
|
|
import java.util.Map;
|
2019-03-22 15:18:23 +01:00
|
|
|
import java.util.Objects;
|
2019-10-30 09:57:14 +01:00
|
|
|
import java.util.Set;
|
2019-03-22 15:18:23 +01:00
|
|
|
|
2020-01-30 10:26:43 +01:00
|
|
|
import org.gcube.informationsystem.base.reference.Element;
|
|
|
|
import org.gcube.informationsystem.base.reference.entities.EntityElement;
|
|
|
|
import org.gcube.informationsystem.base.reference.properties.PropertyElement;
|
|
|
|
import org.gcube.informationsystem.base.reference.relations.RelationElement;
|
2019-03-22 15:18:23 +01:00
|
|
|
import org.gcube.informationsystem.types.annotations.ISProperty;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
|
|
*/
|
2020-01-30 10:26:43 +01:00
|
|
|
public class ISMDiscovery<ISM extends Element> {
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
private static Logger logger = LoggerFactory.getLogger(ISMDiscovery.class);
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
protected final Class<ISM> root;
|
|
|
|
protected final List<Package> packages;
|
2019-10-30 09:57:14 +01:00
|
|
|
protected final List<Class<? extends ISM>> discovered;
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-10-30 09:57:14 +01:00
|
|
|
public List<Class<? extends ISM>> getDiscovered() {
|
2019-03-22 15:18:23 +01:00
|
|
|
return discovered;
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
public ISMDiscovery(Class<ISM> root) {
|
|
|
|
this.root = root;
|
|
|
|
this.packages = new ArrayList<>();
|
|
|
|
addPackage(root.getPackage());
|
|
|
|
this.discovered = new ArrayList<>();
|
|
|
|
add(root);
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
public void addPackage(Package p) {
|
|
|
|
packages.add(p);
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-10-30 09:57:14 +01:00
|
|
|
protected void add(Class<? extends ISM> clz) {
|
2019-11-08 12:29:05 +01:00
|
|
|
if(!discovered.contains(clz)) {
|
|
|
|
discovered.add(clz);
|
|
|
|
logger.info("+ Added {}.", clz);
|
|
|
|
}
|
2019-03-22 15:18:23 +01:00
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-10-30 09:57:14 +01:00
|
|
|
protected void analizeISM(Class<? extends ISM> clz) {
|
2019-03-22 15:18:23 +01:00
|
|
|
logger.trace("Analizyng {}", clz);
|
2019-10-24 19:50:43 +02:00
|
|
|
|
|
|
|
if(!clz.isInterface()) {
|
2019-03-22 15:18:23 +01:00
|
|
|
logger.trace("- Discarding {} that is not an interface", clz);
|
|
|
|
return;
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
|
|
|
if(!root.isAssignableFrom(clz)) {
|
2019-03-22 15:18:23 +01:00
|
|
|
logger.trace("- Discarding {} because is not a {}", clz, root.getSimpleName());
|
|
|
|
return;
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
|
|
|
if(discovered.contains(clz)) {
|
2019-03-22 15:18:23 +01:00
|
|
|
logger.trace("- Discarding {} because was already managed", clz);
|
|
|
|
return;
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
Class<?>[] interfaces = clz.getInterfaces();
|
2019-10-24 19:50:43 +02:00
|
|
|
|
|
|
|
for(Class<?> interfaceClass : interfaces) {
|
2019-03-22 15:18:23 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
Class<ISM> parent = (Class<ISM>) interfaceClass;
|
|
|
|
analizeISM(parent);
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2020-01-30 10:26:43 +01:00
|
|
|
if(root == PropertyElement.class) {
|
2019-10-24 19:50:43 +02:00
|
|
|
|
|
|
|
for(Method m : clz.getDeclaredMethods()) {
|
2019-03-22 15:18:23 +01:00
|
|
|
m.setAccessible(true);
|
2019-10-24 19:50:43 +02:00
|
|
|
if(m.isAnnotationPresent(ISProperty.class)) {
|
2019-10-30 09:57:14 +01:00
|
|
|
if(Map.class.isAssignableFrom(m.getReturnType()) || Set.class.isAssignableFrom(m.getReturnType())
|
|
|
|
|| List.class.isAssignableFrom(m.getReturnType())) {
|
|
|
|
|
|
|
|
Type[] typeArguments = ((ParameterizedType) m.getGenericReturnType()).getActualTypeArguments();
|
|
|
|
for(Type t : typeArguments) {
|
|
|
|
@SuppressWarnings("unchecked")
|
2020-01-30 10:26:43 +01:00
|
|
|
Class<? extends PropertyElement> tClass = (Class<? extends PropertyElement>) t;
|
2019-10-30 09:57:14 +01:00
|
|
|
if(root.isAssignableFrom(tClass)) {
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
Class<ISM> type = (Class<ISM>) tClass;
|
|
|
|
analizeISM(type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if(root.isAssignableFrom(m.getReturnType())) {
|
2019-03-22 15:18:23 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
Class<ISM> type = (Class<ISM>) m.getReturnType();
|
|
|
|
analizeISM(type);
|
|
|
|
}
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
add(clz);
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
public void discover() throws Exception {
|
2019-10-24 19:50:43 +02:00
|
|
|
for(Package p : packages) {
|
2019-03-22 15:18:23 +01:00
|
|
|
List<Class<?>> classes = ReflectionUtility.getClassesForPackage(p);
|
2019-10-24 19:50:43 +02:00
|
|
|
for(Class<?> clz : classes) {
|
2019-03-22 15:18:23 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
Class<ISM> ism = (Class<ISM>) clz;
|
|
|
|
analizeISM(ism);
|
|
|
|
}
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
public static void manageISM(SchemaAction schemaAction, List<Package> packages) throws Exception {
|
2019-10-24 19:50:43 +02:00
|
|
|
if(Objects.nonNull(packages) && packages.size() > 0) {
|
2019-03-22 15:18:23 +01:00
|
|
|
manageISM(schemaAction, packages.stream().toArray(Package[]::new));
|
|
|
|
} else {
|
|
|
|
manageISM(schemaAction);
|
|
|
|
}
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
public static void manageISM(SchemaAction schemaAction, Package... packages) throws Exception {
|
2020-01-30 10:26:43 +01:00
|
|
|
ISMDiscovery<PropertyElement> propertyDiscovery = new ISMDiscovery<>(PropertyElement.class);
|
2019-10-28 17:36:09 +01:00
|
|
|
if(Objects.nonNull(packages)) {
|
2019-03-22 15:18:23 +01:00
|
|
|
Arrays.stream(packages).forEach(p -> propertyDiscovery.addPackage(p));
|
2019-10-28 17:36:09 +01:00
|
|
|
}
|
2019-03-22 15:18:23 +01:00
|
|
|
propertyDiscovery.discover();
|
2020-01-30 10:26:43 +01:00
|
|
|
for(Class<? extends PropertyElement> property : propertyDiscovery.getDiscovered()) {
|
2019-03-22 15:18:23 +01:00
|
|
|
logger.trace("Going to manage : {}", property);
|
|
|
|
schemaAction.managePropertyClass(property);
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2020-01-30 10:26:43 +01:00
|
|
|
ISMDiscovery<EntityElement> entityDiscovery = new ISMDiscovery<>(EntityElement.class);
|
2019-10-28 17:36:09 +01:00
|
|
|
if(Objects.nonNull(packages)) {
|
2019-03-22 15:18:23 +01:00
|
|
|
Arrays.stream(packages).forEach(p -> entityDiscovery.addPackage(p));
|
2019-10-28 17:36:09 +01:00
|
|
|
}
|
2019-03-22 15:18:23 +01:00
|
|
|
entityDiscovery.discover();
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2020-01-30 10:26:43 +01:00
|
|
|
for(Class<? extends EntityElement> entity : entityDiscovery.getDiscovered()) {
|
2019-03-22 15:18:23 +01:00
|
|
|
logger.trace("Going to manage : {}", entity);
|
|
|
|
schemaAction.manageEntityClass(entity);
|
2020-01-23 17:14:44 +01:00
|
|
|
/*
|
2019-11-08 12:29:05 +01:00
|
|
|
if(entity.getName().compareTo(BaseEntity.class.getName())==0 ) {
|
|
|
|
schemaAction.manageEntityClass(EntityTypeDefinition.class);
|
|
|
|
}
|
2020-01-23 17:14:44 +01:00
|
|
|
*/
|
2019-03-22 15:18:23 +01:00
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
@SuppressWarnings("rawtypes")
|
2020-01-30 10:26:43 +01:00
|
|
|
ISMDiscovery<RelationElement> relationDiscovery = new ISMDiscovery<RelationElement>(RelationElement.class);
|
2019-10-24 19:50:43 +02:00
|
|
|
if(Objects.nonNull(packages))
|
2019-03-22 15:18:23 +01:00
|
|
|
Arrays.stream(packages).forEach(p -> relationDiscovery.addPackage(p));
|
|
|
|
relationDiscovery.discover();
|
2019-10-24 19:50:43 +02:00
|
|
|
|
|
|
|
for(@SuppressWarnings("rawtypes")
|
2020-01-30 10:26:43 +01:00
|
|
|
Class<? extends RelationElement> relation : relationDiscovery.getDiscovered()) {
|
2019-03-22 15:18:23 +01:00
|
|
|
logger.trace("Going to manage : {}", relation);
|
|
|
|
schemaAction.manageRelationClass(relation);
|
2020-01-23 17:14:44 +01:00
|
|
|
/*
|
2019-11-08 12:29:05 +01:00
|
|
|
if(relation.getName().compareTo(BaseRelation.class.getName())==0 ) {
|
|
|
|
schemaAction.manageRelationClass(RelationTypeDefinition.class);
|
|
|
|
}
|
2020-01-23 17:14:44 +01:00
|
|
|
*/
|
2019-03-22 15:18:23 +01:00
|
|
|
}
|
|
|
|
}
|
2019-10-24 19:50:43 +02:00
|
|
|
|
2019-03-22 15:18:23 +01:00
|
|
|
}
|