package io.github.infolis.algorithm; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import io.github.infolis.datastore.LocalClient; import io.github.infolis.datastore.DataStoreClient; import io.github.infolis.datastore.FileResolver; import io.github.infolis.model.entity.Entity; import io.github.infolis.model.entity.EntityLink; import io.github.infolis.model.entity.EntityLink.EntityRelation; import io.github.infolis.InfolisConfig; /** * * @author kata * * Create links to entities in ontology, if study is included there. * */ public class OntologyLinker extends MultiMatchesLinker { private static final Logger log = LoggerFactory.getLogger(OntologyLinker.class); public OntologyLinker(DataStoreClient inputDataStoreClient, DataStoreClient outputDataStoreClient, FileResolver inputFileResolver, FileResolver outputFileResolver) { super(inputDataStoreClient, outputDataStoreClient, inputFileResolver, outputFileResolver); } private String searchOntologyEntity(Entity entity, boolean onlyOntologyEntities) { Multimap<String, String> query = HashMultimap.create(); // entities in ontology and used repositories have exactly one identifier query.put("identifier", entity.getIdentifiers().get(0)); query.put("tags", "infolis-ontology"); List<Entity> entitiesInDatabase = getOutputDataStoreClient().search(Entity.class, query); for (Entity entityInDatabase : entitiesInDatabase) { debug(log, "Found entity in ontology: " + entityInDatabase.getUri()); return entityInDatabase.getUri(); } debug(log, "Did not find entity in ontology"); if (onlyOntologyEntities) return null; else return entity.getUri(); } /** * Return ontology entry for entity if existing. * If not, * <ul> * <li>return null if onlyOntologyEntities is set</li> * <li>return URI of entity if onlyOntologyEntities is not set</li> * </ul> * @param entity * @param onlyOntologyEntities * @return */ private String getOntologyEntity(Entity entity, boolean onlyOntologyEntities) { String baseUri = ""; // TODO add "getUriPrefix"-method to AbstractClient and implementing classes; use this here if (!getOutputDataStoreClient().getClass().isAssignableFrom(LocalClient.class)) { baseUri = InfolisConfig.getFrontendURI() + "/entity/"; } String ontologyUri = baseUri + "dataset_" + entity.getIdentifiers().get(0) .replace("/", "") .replace(".", ""); try { Entity ontologyEntity = getOutputDataStoreClient().get(Entity.class, ontologyUri); if (null != ontologyEntity) { return ontologyUri; } else { if (onlyOntologyEntities) return null; else return entity.getUri(); } } catch (RuntimeException e) { if (onlyOntologyEntities) return null; else return entity.getUri(); } } protected List<String> enhanceLinksUsingOntology(List<String> links) { List<String> newLinks = new ArrayList<>(); for (EntityLink link : getOutputDataStoreClient().get(EntityLink.class, links)) { Entity toEntity = getOutputDataStoreClient().get(Entity.class, link.getToEntity()); String entityUri = getOntologyEntity(toEntity, true); if (null != entityUri) { EntityLink newLink = new EntityLink(toEntity.getUri(), entityUri, 1.0, "", new HashSet<>(Arrays.asList(EntityRelation.same_as))); getOutputDataStoreClient().post(EntityLink.class, newLink); newLinks.add(newLink.getUri()); } } return newLinks; } @Override public void execute() { super.execute(); List<String> links = getExecution().getLinks(); getExecution().getLinks().addAll(enhanceLinksUsingOntology(links)); } }