package org.gcube.informationsystem.knowledge; import java.util.AbstractMap.SimpleEntry; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.base.reference.entities.EntityElement; 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; import org.gcube.informationsystem.tree.NodeInformation; import org.gcube.informationsystem.tree.Tree; 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; 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) */ public class ModelKnowledge> { private static final Logger logger = LoggerFactory.getLogger(ModelKnowledge.class); protected NI nodeInformation; protected Map> trees; protected Map> usageKnowledges; public ModelKnowledge(NI nodeInformation) { this.nodeInformation = nodeInformation; reset(); } private void reset() { this.trees = new HashMap<>(); this.usageKnowledges = new HashMap<>(); AccessType[] modelTypes = AccessType.getModelTypes(); for(AccessType accessType : modelTypes) { T t = nodeInformation.getRoot(accessType); Tree tree = new Tree<>(t, nodeInformation); trees.put(accessType, tree); UsageKnowledge usageKnowledge; if(accessType == AccessType.PROPERTY) { /* * In this case we get the type which uses such a property * and the property definition. * In this way we have a complete overview of the usege of the * property type */ usageKnowledge = new UsageKnowledge>(accessType); }else { usageKnowledge = new UsageKnowledge(accessType); } usageKnowledges.put(accessType, usageKnowledge); } } protected void addUsage(LinkedEntity linkedEntity, UsageKnowledge relationUsage, UsageKnowledge targetEntityUsage) { if (linkedEntity != null) { @SuppressWarnings("unchecked") UsageKnowledge resourceUsage = (UsageKnowledge) usageKnowledges.get(AccessType.RESOURCE); String source = linkedEntity.getSource(); resourceUsage.add(source, linkedEntity); String relation = linkedEntity.getRelation(); relationUsage.add(relation, linkedEntity); String target = linkedEntity.getTarget(); targetEntityUsage.add(target, linkedEntity); } } protected void addAllUsage(Collection linkedEntities, UsageKnowledge relationUsage, UsageKnowledge targetEntityUsage) { if(linkedEntities!=null) { for(LinkedEntity le : linkedEntities) { addUsage(le, relationUsage, targetEntityUsage); } } } protected void addPropertyUsage(T t, Set properties, UsageKnowledge> propertyUsage) { if(properties==null || properties.size()==0) { return; } for(PropertyDefinition propertyDefinition : properties) { PropertyTypeName propertyTypeName = ((PropertyDefinitionImpl) propertyDefinition).getPropertyTypeName(); if(propertyTypeName.isGenericType()) { SimpleEntry entry = new SimpleEntry<>(t, propertyDefinition); propertyUsage.add(propertyTypeName.getGenericClassName(), entry); } } } protected void addMetadataUsage(T t, UsageKnowledge> propertyUsage) { Type type = TypeMapper.createTypeDefinition(EntityElement.class); addPropertyUsage(t, type.getProperties(), propertyUsage); } protected void addPropagationConstraintUsage(T t, UsageKnowledge> propertyUsage) { Type type = TypeMapper.createTypeDefinition(Relation.class); addPropertyUsage(t, type.getProperties(), propertyUsage); } public void addAllType(Collection types) { Set toRetry = new HashSet<>(); for(T t : types) { logger.trace("Going to add {}", nodeInformation.getIdentifier(t)); try { addType(t); }catch (RuntimeException e) { toRetry.add(t); } } if(toRetry.size()>0) { addAllType(toRetry); } } public void addType(T t) { AccessType accessType = nodeInformation.getAccessType(t); String typeName = nodeInformation.getIdentifier(t); Tree tree = trees.get(accessType); tree.addNode(t); @SuppressWarnings("unchecked") UsageKnowledge> propertyUsage = (UsageKnowledge>) usageKnowledges.get(AccessType.PROPERTY); @SuppressWarnings("unchecked") UsageKnowledge resourceUsage = (UsageKnowledge) usageKnowledges.get(AccessType.RESOURCE); @SuppressWarnings("unchecked") UsageKnowledge facetUsage = (UsageKnowledge) usageKnowledges.get(AccessType.FACET); @SuppressWarnings("unchecked") UsageKnowledge isRelatedToUsage = (UsageKnowledge) usageKnowledges.get(AccessType.IS_RELATED_TO); @SuppressWarnings("unchecked") UsageKnowledge consistsOfUsage = (UsageKnowledge) usageKnowledges.get(AccessType.CONSISTS_OF); switch (accessType) { case PROPERTY: // Nothing to do break; case RESOURCE: ResourceType resourceType = (ResourceType) t; 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) { addMetadataUsage(t, propertyUsage); } break; case FACET: FacetType facetType = (FacetType) t; if(typeName.compareTo(Facet.NAME)==0) { addMetadataUsage(t, propertyUsage); } addPropertyUsage(t, facetType.getProperties(), propertyUsage); break; case IS_RELATED_TO: IsRelatedToType isRelatedToType = (IsRelatedToType) t; if(typeName.compareTo(IsRelatedTo.NAME)==0) { addMetadataUsage(t, propertyUsage); addPropagationConstraintUsage(t, propertyUsage); } addPropertyUsage(t, isRelatedToType.getProperties(), propertyUsage); break; case CONSISTS_OF: ConsistsOfType consistsOfType = (ConsistsOfType) t; if(typeName.compareTo(ConsistsOf.NAME)==0) { addMetadataUsage(t, propertyUsage); addPropagationConstraintUsage(t, propertyUsage); } addPropertyUsage(t, consistsOfType.getProperties(), propertyUsage); break; default: break; } } public Tree getTree(AccessType accessType) { return trees.get(accessType); } public UsageKnowledge getUsageKnowledge(AccessType accessType) { return usageKnowledges.get(accessType); } }