2019-10-24 11:57:21 +02:00
|
|
|
package org.gcube.informationsystem.types.impl;
|
2019-10-23 18:19:55 +02:00
|
|
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.lang.reflect.TypeVariable;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Set;
|
|
|
|
|
2019-10-24 19:50:43 +02:00
|
|
|
import org.gcube.informationsystem.base.impl.ISManageableImpl;
|
2019-10-23 18:19:55 +02:00
|
|
|
import org.gcube.informationsystem.base.reference.ISManageable;
|
2019-10-24 11:26:49 +02:00
|
|
|
import org.gcube.informationsystem.base.reference.entities.BaseEntity;
|
|
|
|
import org.gcube.informationsystem.base.reference.properties.BaseProperty;
|
|
|
|
import org.gcube.informationsystem.base.reference.relations.BaseRelation;
|
2019-10-23 18:19:55 +02:00
|
|
|
import org.gcube.informationsystem.model.reference.entities.Resource;
|
2019-10-24 11:57:21 +02:00
|
|
|
import org.gcube.informationsystem.types.TypeBinder;
|
2019-10-23 18:19:55 +02:00
|
|
|
import org.gcube.informationsystem.types.annotations.Abstract;
|
|
|
|
import org.gcube.informationsystem.types.annotations.ISProperty;
|
2019-10-24 11:26:49 +02:00
|
|
|
import org.gcube.informationsystem.types.impl.entities.EntityTypeDefinitionImpl;
|
2019-10-23 18:19:55 +02:00
|
|
|
import org.gcube.informationsystem.types.impl.properties.PropertyDefinitionImpl;
|
2019-10-24 11:26:49 +02:00
|
|
|
import org.gcube.informationsystem.types.impl.properties.PropertyTypeDefinitionImpl;
|
|
|
|
import org.gcube.informationsystem.types.impl.relations.RelationTypeDefinitionImpl;
|
2019-10-23 18:19:55 +02:00
|
|
|
import org.gcube.informationsystem.types.reference.TypeDefinition;
|
|
|
|
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
2019-10-24 15:03:14 +02:00
|
|
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
2019-10-23 18:19:55 +02:00
|
|
|
|
2019-10-24 15:03:14 +02:00
|
|
|
// @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
|
|
|
|
@JsonTypeName(value=TypeDefinition.NAME)
|
2019-10-25 17:46:13 +02:00
|
|
|
public class TypeDefinitionImpl<ISM extends ISManageable> extends ISManageableImpl implements TypeDefinition<ISM> {
|
2019-10-24 11:26:49 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Generated Serial Version UID
|
|
|
|
*/
|
|
|
|
private static final long serialVersionUID = 2698204820689338513L;
|
2019-10-23 18:19:55 +02:00
|
|
|
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(TypeDefinitionImpl.class);
|
|
|
|
|
2019-10-24 19:50:43 +02:00
|
|
|
public final static String DESCRIPTION = "DESCRIPTION";
|
2019-10-23 18:19:55 +02:00
|
|
|
|
|
|
|
protected String name;
|
|
|
|
protected String description;
|
|
|
|
@JsonProperty(value="abstract")
|
|
|
|
protected boolean abstractType;
|
|
|
|
protected Set<String> superClasses;
|
|
|
|
protected Set<PropertyDefinition> properties;
|
|
|
|
|
2019-10-24 11:26:49 +02:00
|
|
|
protected static <ISM extends ISManageable> Set<String> retrieveSuperClasses(Class<? extends ISM> type, Class<ISM> baseClass, String topSuperClass){
|
2019-10-23 18:19:55 +02:00
|
|
|
Set<String> interfaceList = new HashSet<>();
|
|
|
|
|
|
|
|
if(type==baseClass){
|
|
|
|
interfaceList.add(topSuperClass);
|
|
|
|
return interfaceList;
|
|
|
|
}
|
|
|
|
|
|
|
|
Class<?>[] interfaces = type.getInterfaces();
|
|
|
|
|
|
|
|
for (Class<?> interfaceClass : interfaces) {
|
|
|
|
|
|
|
|
if(!baseClass.isAssignableFrom(interfaceClass)){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
Class<? extends ISManageable> clz = (Class<? extends ISManageable>) interfaceClass;
|
|
|
|
interfaceList.add(TypeBinder.getType(clz));
|
|
|
|
}
|
|
|
|
|
|
|
|
return interfaceList;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static Set<PropertyDefinition> retrieveListOfProperties(Class<?> type){
|
|
|
|
Set<PropertyDefinition> properties = new HashSet<>();
|
|
|
|
for (Method m : type.getDeclaredMethods()){
|
|
|
|
m.setAccessible(true);
|
|
|
|
if(m.isAnnotationPresent(ISProperty.class)){
|
|
|
|
if(m.isBridge()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ISProperty propAnnotation = m.getAnnotation(ISProperty.class);
|
|
|
|
PropertyDefinition prop = new PropertyDefinitionImpl(propAnnotation, m);
|
|
|
|
properties.add(prop);
|
|
|
|
logger.trace("Property {} retrieved in type {} ", prop, type.getSimpleName());
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
|
2019-10-24 11:26:49 +02:00
|
|
|
protected static Class<?> getGenericClass(java.lang.reflect.Type type){
|
2019-10-23 18:19:55 +02:00
|
|
|
TypeVariable<?> typeVariable = (TypeVariable<?>) type;
|
|
|
|
java.lang.reflect.Type[] bounds = typeVariable.getBounds();
|
|
|
|
java.lang.reflect.Type t = bounds[0];
|
|
|
|
return (Class<?>) t;
|
|
|
|
}
|
|
|
|
|
2019-10-24 11:26:49 +02:00
|
|
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
|
|
public static <ISM extends ISManageable> TypeDefinition<ISM> getInstance(Class<ISM> clz) {
|
|
|
|
if(BaseEntity.class.isAssignableFrom(clz)) {
|
|
|
|
return new EntityTypeDefinitionImpl(clz);
|
|
|
|
} else if(BaseRelation.class.isAssignableFrom(clz)){
|
|
|
|
return new RelationTypeDefinitionImpl(clz);
|
|
|
|
} else if(BaseProperty.class.isAssignableFrom(clz)){
|
|
|
|
return new PropertyTypeDefinitionImpl(clz);
|
2019-10-25 17:46:13 +02:00
|
|
|
} else if(TypeDefinition.class.isAssignableFrom(clz)) {
|
|
|
|
return new TypeDefinitionImpl(clz);
|
2019-10-24 11:26:49 +02:00
|
|
|
} else {
|
|
|
|
throw new RuntimeException("Serialization required");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected TypeDefinitionImpl(Class<ISM> clz) {
|
2019-10-23 18:19:55 +02:00
|
|
|
this.name = TypeBinder.getType(clz);
|
|
|
|
this.description = TypeBinder.getStaticStringFieldByName(clz, DESCRIPTION, "");
|
|
|
|
this.abstractType = false;
|
|
|
|
|
|
|
|
if(clz.isAnnotationPresent(Abstract.class)){
|
|
|
|
this.abstractType = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!Resource.class.isAssignableFrom(clz)){
|
|
|
|
this.properties = retrieveListOfProperties(clz);
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.trace("{} : {} ", clz, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2019-10-24 11:26:49 +02:00
|
|
|
@Override
|
2019-10-23 18:19:55 +02:00
|
|
|
public String getDescription() {
|
|
|
|
return description;
|
|
|
|
}
|
|
|
|
|
2019-10-24 11:26:49 +02:00
|
|
|
@Override
|
2019-10-23 18:19:55 +02:00
|
|
|
public boolean isAbstract() {
|
|
|
|
return abstractType;
|
|
|
|
}
|
|
|
|
|
2019-10-24 11:26:49 +02:00
|
|
|
@Override
|
2019-10-23 18:19:55 +02:00
|
|
|
public Set<String> getSuperClasses() {
|
|
|
|
return superClasses;
|
|
|
|
}
|
|
|
|
|
2019-10-24 11:26:49 +02:00
|
|
|
@Override
|
2019-10-23 18:19:55 +02:00
|
|
|
public Set<PropertyDefinition> getProperties() {
|
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|