information-system-model/src/main/java/org/gcube/informationsystem/model/knowledge/ModelKnowledge.java

272 lines
8.7 KiB
Java
Raw Normal View History

2023-10-26 17:19:01 +02:00
package org.gcube.informationsystem.model.knowledge;
2023-10-24 15:18:48 +02:00
2023-10-25 18:01:11 +02:00
import java.util.AbstractMap.SimpleEntry;
2023-10-26 15:25:07 +02:00
import java.util.Arrays;
2023-10-24 15:18:48 +02:00
import java.util.Collection;
import java.util.HashMap;
2023-10-25 18:01:11 +02:00
import java.util.HashSet;
2023-10-26 15:25:07 +02:00
import java.util.List;
2023-10-24 15:18:48 +02:00
import java.util.Map;
2023-10-25 18:01:11 +02:00
import java.util.Map.Entry;
2023-10-24 15:18:48 +02:00
import java.util.Set;
import org.gcube.informationsystem.base.reference.AccessType;
2023-10-25 18:01:11 +02:00
import org.gcube.informationsystem.base.reference.entities.EntityElement;
2023-10-26 15:31:08 +02:00
import org.gcube.informationsystem.base.reference.relations.RelationElement;
2023-10-25 18:01:11 +02:00
import org.gcube.informationsystem.model.reference.entities.Facet;
import org.gcube.informationsystem.model.reference.entities.Resource;
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
import org.gcube.informationsystem.model.reference.relations.IsRelatedTo;
import org.gcube.informationsystem.model.reference.relations.Relation;
2023-10-24 15:18:48 +02:00
import org.gcube.informationsystem.tree.Tree;
2023-10-25 18:01:11 +02:00
import org.gcube.informationsystem.types.PropertyTypeName;
import org.gcube.informationsystem.types.TypeMapper;
import org.gcube.informationsystem.types.impl.properties.PropertyDefinitionImpl;
import org.gcube.informationsystem.types.reference.Type;
2023-10-24 15:18:48 +02:00
import org.gcube.informationsystem.types.reference.entities.FacetType;
import org.gcube.informationsystem.types.reference.entities.ResourceType;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
import org.gcube.informationsystem.types.reference.relations.ConsistsOfType;
import org.gcube.informationsystem.types.reference.relations.IsRelatedToType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
2023-10-26 16:35:03 +02:00
public class ModelKnowledge<T, TI extends TypeInformation<T>> {
2023-10-24 15:18:48 +02:00
private static final Logger logger = LoggerFactory.getLogger(ModelKnowledge.class);
2023-10-26 16:35:03 +02:00
protected TI typeInformation;
2023-10-24 15:18:48 +02:00
protected Map<AccessType, Tree<T>> trees;
2023-10-26 15:25:07 +02:00
protected UsageKnowledge<Entry<String,PropertyDefinition>> propertyUsage;
protected Map<AccessType, UsageKnowledge<LinkedEntity>> erTypesUsage;
2023-10-24 15:18:48 +02:00
2023-10-26 16:35:03 +02:00
public ModelKnowledge(TI typeInformation) {
this.typeInformation = typeInformation;
2023-10-24 15:18:48 +02:00
reset();
}
2023-10-26 15:41:01 +02:00
protected void reset() {
2023-10-24 15:18:48 +02:00
this.trees = new HashMap<>();
2023-10-26 15:25:07 +02:00
this.erTypesUsage = new HashMap<>();
2023-10-24 15:18:48 +02:00
AccessType[] modelTypes = AccessType.getModelTypes();
for(AccessType accessType : modelTypes) {
2023-10-26 16:35:03 +02:00
T t = typeInformation.getRoot(accessType);
2023-10-24 15:18:48 +02:00
2023-10-26 16:35:03 +02:00
Tree<T> tree = new Tree<>(t, typeInformation);
2023-10-24 15:18:48 +02:00
trees.put(accessType, tree);
if(accessType == AccessType.PROPERTY) {
/*
* In this case we get the type which uses such a property
* and the property definition.
2023-10-26 15:25:07 +02:00
* In this way we have a complete overview of the usage of the
2023-10-24 15:18:48 +02:00
* property type
*/
2023-10-26 15:25:07 +02:00
propertyUsage = new UsageKnowledge<>(accessType);
2023-10-24 15:18:48 +02:00
}else {
2023-10-26 15:25:07 +02:00
UsageKnowledge<LinkedEntity> usageKnowledge = new UsageKnowledge<LinkedEntity>(accessType);
erTypesUsage.put(accessType, usageKnowledge);
2023-10-24 15:18:48 +02:00
}
2023-10-26 15:25:07 +02:00
2023-10-24 15:18:48 +02:00
}
}
2023-10-25 18:01:11 +02:00
protected void addUsage(LinkedEntity linkedEntity, UsageKnowledge<LinkedEntity> relationUsage, UsageKnowledge<LinkedEntity> targetEntityUsage) {
2023-10-24 15:18:48 +02:00
if (linkedEntity != null) {
2023-10-26 15:25:07 +02:00
UsageKnowledge<LinkedEntity> resourceUsage = erTypesUsage.get(AccessType.RESOURCE);
2023-10-24 15:18:48 +02:00
String source = linkedEntity.getSource();
resourceUsage.add(source, linkedEntity);
String relation = linkedEntity.getRelation();
relationUsage.add(relation, linkedEntity);
String target = linkedEntity.getTarget();
targetEntityUsage.add(target, linkedEntity);
}
}
2023-10-25 18:01:11 +02:00
protected void addAllUsage(Collection<LinkedEntity> linkedEntities, UsageKnowledge<LinkedEntity> relationUsage, UsageKnowledge<LinkedEntity> targetEntityUsage) {
2023-10-24 15:18:48 +02:00
if(linkedEntities!=null) {
for(LinkedEntity le : linkedEntities) {
2023-10-25 18:01:11 +02:00
addUsage(le, relationUsage, targetEntityUsage);
2023-10-24 15:18:48 +02:00
}
}
}
2023-10-26 15:25:07 +02:00
protected void addPropertyUsage(T t, Set<PropertyDefinition> properties) {
2023-10-25 18:01:11 +02:00
if(properties==null || properties.size()==0) {
return;
}
2023-10-26 16:35:03 +02:00
String typeName = typeInformation.getIdentifier(t);
2023-10-25 18:01:11 +02:00
for(PropertyDefinition propertyDefinition : properties) {
PropertyTypeName propertyTypeName = ((PropertyDefinitionImpl) propertyDefinition).getPropertyTypeName();
if(propertyTypeName.isGenericType()) {
2023-10-26 15:25:07 +02:00
SimpleEntry<String,PropertyDefinition> entry = new SimpleEntry<>(typeName, propertyDefinition);
2023-10-25 18:01:11 +02:00
propertyUsage.add(propertyTypeName.getGenericClassName(), entry);
}
}
}
2023-10-26 15:31:08 +02:00
protected void addEntityMetadataUsage(T t) {
2023-10-25 18:01:11 +02:00
Type type = TypeMapper.createTypeDefinition(EntityElement.class);
2023-10-26 15:25:07 +02:00
addPropertyUsage(t, type.getProperties());
2023-10-25 18:01:11 +02:00
}
2023-10-26 15:31:08 +02:00
protected void addRelationMetadataUsage(T t) {
Type type = TypeMapper.createTypeDefinition(RelationElement.class);
addPropertyUsage(t, type.getProperties());
}
2023-10-26 15:25:07 +02:00
protected void addPropagationConstraintUsage(T t) {
2023-10-25 18:01:11 +02:00
Type type = TypeMapper.createTypeDefinition(Relation.class);
2023-10-26 15:25:07 +02:00
addPropertyUsage(t, type.getProperties());
2023-10-25 18:01:11 +02:00
}
public void addAllType(Collection<T> types) {
Set<T> toRetry = new HashSet<>();
for(T t : types) {
2023-10-26 16:35:03 +02:00
logger.trace("Going to add {}", typeInformation.getIdentifier(t));
2023-10-25 18:01:11 +02:00
try {
addType(t);
}catch (RuntimeException e) {
toRetry.add(t);
}
}
if(toRetry.size()>0) {
addAllType(toRetry);
}
2023-10-24 15:18:48 +02:00
}
public void addType(T t) {
2023-10-26 16:35:03 +02:00
AccessType accessType = typeInformation.getAccessType(t);
String typeName = typeInformation.getIdentifier(t);
2023-10-25 18:01:11 +02:00
Tree<T> tree = trees.get(accessType);
tree.addNode(t);
2023-10-24 15:18:48 +02:00
2023-10-26 15:25:07 +02:00
UsageKnowledge<LinkedEntity> resourceUsage = erTypesUsage.get(AccessType.RESOURCE);
UsageKnowledge<LinkedEntity> facetUsage = erTypesUsage.get(AccessType.FACET);
UsageKnowledge<LinkedEntity> isRelatedToUsage = erTypesUsage.get(AccessType.IS_RELATED_TO);
UsageKnowledge<LinkedEntity> consistsOfUsage = erTypesUsage.get(AccessType.CONSISTS_OF);
2023-10-24 15:18:48 +02:00
switch (accessType) {
case PROPERTY:
// Nothing to do
break;
case RESOURCE:
ResourceType resourceType = (ResourceType) t;
2023-10-25 18:01:11 +02:00
addAllUsage(resourceType.getFacets(), consistsOfUsage, facetUsage);
addAllUsage(resourceType.getResources(), isRelatedToUsage, resourceUsage);
/*
* Metadata is defined in parent type i.e. EntityElement.
* We want to have a reference to all Base type
*/
if(typeName.compareTo(Resource.NAME)==0) {
2023-10-26 15:31:08 +02:00
addEntityMetadataUsage(t);
2023-10-25 18:01:11 +02:00
}
2023-10-24 15:18:48 +02:00
break;
case FACET:
FacetType facetType = (FacetType) t;
2023-10-26 15:31:08 +02:00
/*
* Metadata is defined in parent type i.e. EntityElement.
* We want to have a reference to all Base type
*/
2023-10-25 18:01:11 +02:00
if(typeName.compareTo(Facet.NAME)==0) {
2023-10-26 15:31:08 +02:00
addEntityMetadataUsage(t);
2023-10-25 18:01:11 +02:00
}
2023-10-26 15:25:07 +02:00
addPropertyUsage(t, facetType.getProperties());
2023-10-25 18:01:11 +02:00
2023-10-24 15:18:48 +02:00
break;
case IS_RELATED_TO:
IsRelatedToType isRelatedToType = (IsRelatedToType) t;
2023-10-26 15:31:08 +02:00
/*
* Metadata is defined in parent type i.e. RelationElement.
* We want to have a reference to all Base type
*/
2023-10-25 18:01:11 +02:00
if(typeName.compareTo(IsRelatedTo.NAME)==0) {
2023-10-26 15:31:08 +02:00
addRelationMetadataUsage(t);
2023-10-26 15:25:07 +02:00
addPropagationConstraintUsage(t);
2023-10-25 18:01:11 +02:00
}
2023-10-26 15:25:07 +02:00
addPropertyUsage(t, isRelatedToType.getProperties());
2023-10-24 15:18:48 +02:00
break;
case CONSISTS_OF:
ConsistsOfType consistsOfType = (ConsistsOfType) t;
2023-10-26 15:31:08 +02:00
/*
* Metadata is defined in parent type i.e. RelationElement.
* We want to have a reference to all Base type
*/
2023-10-25 18:01:11 +02:00
if(typeName.compareTo(ConsistsOf.NAME)==0) {
2023-10-26 15:31:08 +02:00
addRelationMetadataUsage(t);
2023-10-26 15:25:07 +02:00
addPropagationConstraintUsage(t);
2023-10-25 18:01:11 +02:00
}
2023-10-26 15:25:07 +02:00
addPropertyUsage(t, consistsOfType.getProperties());
2023-10-24 15:18:48 +02:00
break;
default:
break;
}
}
public Tree<T> getTree(AccessType accessType) {
return trees.get(accessType);
}
2023-10-26 15:25:07 +02:00
public UsageKnowledge<?> getModelTypesUsage(AccessType accessType) {
List<AccessType> modelTypes = Arrays.asList(AccessType.getModelTypes());
if(!modelTypes.contains(accessType)) {
throw new RuntimeException("Only ModelTypes are allowed, i.e. " + modelTypes.toString());
}
if(accessType == AccessType.PROPERTY) {
return propertyUsage;
}else {
return erTypesUsage.get(accessType);
}
}
public UsageKnowledge<LinkedEntity> getERTypesUsage(AccessType accessType) {
List<AccessType> erTypes = Arrays.asList(AccessType.getERTypes());
if(!erTypes.contains(accessType)) {
throw new RuntimeException("Only ERTypes are allowed, i.e. " + erTypes.toString());
}
return erTypesUsage.get(accessType);
}
public UsageKnowledge<Entry<String,PropertyDefinition>> getPropertyUsage(){
return propertyUsage;
2023-10-24 15:18:48 +02:00
}
2023-10-26 15:25:07 +02:00
public UsageKnowledge<LinkedEntity> getResourceUsage() {
return erTypesUsage.get(AccessType.RESOURCE);
}
public UsageKnowledge<LinkedEntity> getFacetUsage() {
return erTypesUsage.get(AccessType.FACET);
}
public UsageKnowledge<LinkedEntity> getIsRelatedToUsage() {
return erTypesUsage.get(AccessType.IS_RELATED_TO);
}
public UsageKnowledge<LinkedEntity> getConsistsOfUsage() {
return erTypesUsage.get(AccessType.CONSISTS_OF);
}
2023-10-24 15:18:48 +02:00
}