Exemple #1
0
        /// <summary>
        /// Obtiene los detalles de un rdf
        /// </summary>
        /// <returns></returns>
        public IActionResult DetailsRdf(Guid itemId)
        {
            //Cargamos la ontología
            RohGraph ontologyGraph = new RohGraph();

            ontologyGraph = _callEDtlPublishService.CallGetOntology();

            SparqlResultSet sparqlResultSetNombresPropiedades = (SparqlResultSet)ontologyGraph.ExecuteQuery("select distinct ?entidad ?nombre where { ?entidad <http://www.w3.org/2000/01/rdf-schema#label> ?nombre. FILTER(lang(?nombre) = 'es')}");

            //Guardamos todos los nombres de las propiedades en un diccionario
            Dictionary <string, string> communNamePropierties = new Dictionary <string, string>();

            foreach (SparqlResult sparqlResult in sparqlResultSetNombresPropiedades.Results)
            {
                communNamePropierties.Add(sparqlResult["entidad"].ToString(), ((LiteralNode)(sparqlResult["nombre"])).Value);
            }

            //Cargamos los datos
            DiscoverItem discoveryGraph = _discoverItemService.GetDiscoverItemById(itemId);
            RohGraph     dataGraph      = new RohGraph();

            dataGraph.LoadFromString(discoveryGraph.DiscoverRdf, new RdfXmlParser());

            //Guardamos todas las entidades que no son blankNodes
            List <String>   entities = new List <string>();
            SparqlResultSet sparqlResultSetListaEntidadesNotBN = (SparqlResultSet)dataGraph.ExecuteQuery("select ?s count(?p) as ?num where { ?s ?p ?o. FILTER (!isBlank(?s)) }group by ?s order by desc(?num) ");

            foreach (SparqlResult sparqlResult in sparqlResultSetListaEntidadesNotBN.Results)
            {
                entities.Add(sparqlResult["s"].ToString());
            }
            List <DiscoverRdfViewModel> model = new List <DiscoverRdfViewModel>();

            //Guardamos todas las entidades
            List <String>   allEntities = new List <string>();
            SparqlResultSet sparqlResultSetEntidades = (SparqlResultSet)dataGraph.ExecuteQuery("select distinct ?s where { ?s ?p ?o }");

            foreach (SparqlResult sparqlResult in sparqlResultSetEntidades.Results)
            {
                allEntities.Add(sparqlResult["s"].ToString());
            }
            SparqlResultSet sparqlResultSet = (SparqlResultSet)dataGraph.ExecuteQuery("select ?s ?p ?o where { ?s ?p ?o }");
            Dictionary <string, List <SparqlResult> > entitySparqlResult = new Dictionary <string, List <SparqlResult> >();

            foreach (SparqlResult sparqlResult in sparqlResultSet.Results)
            {
                if (!entitySparqlResult.ContainsKey(sparqlResult["s"].ToString()))
                {
                    entitySparqlResult.Add(sparqlResult["s"].ToString(), new List <SparqlResult>());
                }
                entitySparqlResult[sparqlResult["s"].ToString()].Add(sparqlResult);
            }

            foreach (var idEntity in entities)
            {
                DiscoverRdfViewModel entidad = createDiscoverRdfViewModel(idEntity, entitySparqlResult, new List <string>(), allEntities, communNamePropierties, discoveryGraph.LoadedEntities);
                model.Add(entidad);
            }
            return(View(model));
        }
        /// <summary>
        /// Obtiene los triples de un RDF
        /// </summary>
        /// <param name="pXMLRDF">XML RDF</param>
        /// <returns>Lista de triples</returns>
        public static List <string> GetTriplesFromRDF(XmlDocument pXMLRDF)
        {
            RohGraph g = new RohGraph();

            g.LoadFromString(pXMLRDF.InnerXml, new RdfXmlParser());
            return(GetTriplesFromGraph(g));
        }
Exemple #3
0
        /// <summary>
        /// Valida un RDF
        /// </summary>
        /// <param name="pRdfFileContent">XML RDF</param>
        /// <param name="pShapesConfig">Lista de Shapes de validación</param>
        /// <returns>Lista de triples</returns>
        public static ShapeReport ValidateRDF(string pRdfFileContent, List <ShapeConfig> pShapesConfig)
        {
            //Cargamos la ontología
            RohGraph ontologyGraph = new RohGraph();

            ontologyGraph.LoadFromFile("Config/Ontology/roh-v2.owl");

            //Cargamos datos a validar
            RohGraph dataGraph = new RohGraph();

            dataGraph.LoadFromString(pRdfFileContent, new RdfXmlParser());

            //Aplicamos inferencias de la ontologia
            RohRdfsReasoner reasoner = new RohRdfsReasoner();

            reasoner.Initialise(ontologyGraph);
            reasoner.Apply(dataGraph);

            ShapeReport response = new ShapeReport();

            response.conforms = true;
            response.results  = new List <ShapeReport.Result>();
            foreach (ShapeConfig shape in pShapesConfig)
            {
                IGraph shapeGraph = new Graph();
                shapeGraph.LoadFromString(shape.Shape);
                ShapesGraph shapesGraph = new ShapesGraph(shapeGraph);

                Report report = shapesGraph.Validate(dataGraph);
                if (!report.Conforms)
                {
                    response.conforms = false;
                    response.results.AddRange(report.Results.ToList().Select(x => new ShapeReport.Result()
                    {
                        severity    = (x.Severity != null) ? x.Severity.ToString() : null,
                        focusNode   = (x.FocusNode != null) ? x.FocusNode.ToString() : null,
                        resultValue = (x.ResultValue != null) ? x.ResultValue.ToString() : null,
                        message     = (x.Message != null) ? x.Message.ToString() : null,
                        resultPath  = (x.ResultPath != null) ? x.ResultPath.ToString() : null,
                        shapeID     = shape.ShapeConfigID,
                        shapeName   = shape.Name,
                        sourceShape = (x.SourceShape != null) ? x.SourceShape.ToString() : null,
                    }).ToList());
                }
            }

            if (response.results.Exists(x => x.severity == "http://www.w3.org/ns/shacl#Violation"))
            {
                response.severity = "http://www.w3.org/ns/shacl#Violation";
            }
            else if (response.results.Exists(x => x.severity == "http://www.w3.org/ns/shacl#Warning"))
            {
                response.severity = "http://www.w3.org/ns/shacl#Warning";
            }
            else if (response.results.Exists(x => x.severity == "http://www.w3.org/ns/shacl#Info"))
            {
                response.severity = "http://www.w3.org/ns/shacl#Info";
            }
            return(response);
        }
Exemple #4
0
        public void TestEquivalenceDiscover()
        {
            //Cargamos el RDF sobre el que aplicar el reconocimiento de enlaces
            RohGraph dataGraph = new RohGraph();

            dataGraph.LoadFromString(System.IO.File.ReadAllText("rdfFiles/rdfFile.rdf"), new RdfXmlParser());

            //TODO cargar ejemplo
            //Cargamos el RDF que simula la BBDD de Unidata
            //Si se quiere ejecutar sobre la BBDD no habría que modificar discoverUtility.mSparqlUtility y sería necesario especificar los datos del SPARQL endpoint
            RohGraph dataGraphBBDD = new RohGraph();

            dataGraphBBDD.LoadFromString(System.IO.File.ReadAllText("rdfFiles/rdfFile.rdf"), new RdfXmlParser());

            //Cargamos el RDF de la ontología
            RohGraph ontologyGraph = new RohGraph();

            ontologyGraph.LoadFromFile("Ontology/roh-v2.owl");

            //Cargamos configuraciones necesarias
            ConfigService ConfigService = new ConfigService();
            float         maxScore      = ConfigService.GetMaxScore();
            float         minScore      = ConfigService.GetMinScore();
            string        unidataDomain = ConfigService.GetUnidataDomain();

            DiscoverUtility discoverUtility = new DiscoverUtility();

            discoverUtility.mSparqlUtility = new SparqlUtilityMock(dataGraphBBDD);
            discoverUtility.test           = true;

            //Aplicamos el descubrimiento de equivalencias
            //Los datos de configuración de SPARQL se mandan vacíos porque utilizamos el MOCK
            discoverUtility.ApplyEquivalenceDiscover(ref dataGraph, ontologyGraph, out Dictionary <string, Dictionary <string, float> > reconciliationEntitiesProbability, unidataDomain, minScore, maxScore, "", "", "", "", "");
        }
Exemple #5
0
        public void TestReconciliation()
        {
            //Cargamos el RDF sobre el que aplicar la reconciliación
            RohGraph dataGraph = new RohGraph();

            dataGraph.LoadFromString(System.IO.File.ReadAllText("rdfFiles/rdfFileRecon.rdf"), new RdfXmlParser());

            //Cargamos el RDF de la ontología
            RohGraph ontologyGraph = new RohGraph();

            ontologyGraph.LoadFromFile("Ontology/roh-v2.owl");

            //Cargamos el RDF que simula la BBDD
            RohGraph dataGraphBBDD = new RohGraph();

            dataGraph.LoadFromString(System.IO.File.ReadAllText("rdfFiles/rdfFile.rdf"), new RdfXmlParser());

            //Cargamos configuraciones necesarias
            ConfigService ConfigService = new ConfigService();
            float         maxScore      = ConfigService.GetMaxScore();
            float         minScore      = ConfigService.GetMinScore();

            //Construimos el objeto DiscoverUtility
            DiscoverUtility discoverUtility = new DiscoverUtility();

            //Sustituimos mSparqlUtility por un MOCK en el que cargamos el grafo en memoria 'dataGraphBBDD'
            //Si se quiere ejecutar sobre la BBDD no habría que modificar discoverUtility.mSparqlUtility y sería necesario especificar los datos del SPARQL endpoint
            discoverUtility.mSparqlUtility = new SparqlUtilityMock(dataGraphBBDD);
            discoverUtility.test           = true;

            //Aplicamos la reconciliación
            //Los datos de configuración de SPARQL se mandan vacíos porque utilizamos el MOCK
            ReconciliationData reconciliationData = discoverUtility.ApplyReconciliation(ref dataGraph, ontologyGraph, "", "", "", "", "", minScore, maxScore, out Dictionary <string, Dictionary <string, float> > reconciliationEntitiesProbability);

            //En 'reconciliationData' estarán los datos que se han modificado fruto de la reconciliación
            //En 'dataGraph' estará el grafo modificado tras la reconciliación
            //En 'reconciliationEntitiesProbability' estarán las entidades para las que ha habido problemas de desambiguación
        }
Exemple #6
0
 public IActionResult dataValidate(IFormFile rdfFile, Guid repositoryIdentifier)
 {
     try
     {
         string   rdfFileContent = SparqlUtility.GetTextFromFile(rdfFile);
         RohGraph ontologyGraph  = new RohGraph();
         ontologyGraph.LoadFromString(OntologyService.GetOntology());
         return(Ok(SparqlUtility.ValidateRDF(rdfFileContent, _shapeConfigService.GetShapesConfigs().FindAll(x => x.RepositoryID == repositoryIdentifier), ontologyGraph)));
     }
     catch (Exception ex)
     {
         return(Problem(ex.ToString()));
     }
 }
Exemple #7
0
        /// <summary>
        /// Obtiene los triples de un RDF
        /// </summary>
        /// <param name="pXMLRDF">XML RDF</param>
        /// <returns>Lista de triples</returns>
        public static List <string> GetTriplesFromRDF(XmlDocument pXMLRDF)
        {
            RohGraph g = new RohGraph();

            g.LoadFromString(pXMLRDF.InnerXml, new RdfXmlParser());
            System.IO.StringWriter sw             = new System.IO.StringWriter();
            NTriplesWriter         nTriplesWriter = new NTriplesWriter();

            nTriplesWriter.Save(g, sw);
            return(sw.ToString().Split("\n").ToList().Select(x => Regex.Replace(
                                                                 x,
                                                                 @"\\u(?<Value>[a-zA-Z0-9]{4})",
                                                                 m => {
                return ((char)int.Parse(m.Groups["Value"].Value, NumberStyles.HexNumber)).ToString();
            })).ToList());
        }
Exemple #8
0
 public IActionResult LoadOntology(IFormFile ontology)
 {
     try
     {
         OntologyService.SetOntology(ontology);
         string ontologyGraph = "";
         ontologyGraph = _configSparql.GetGraphRoh();
         RohGraph graph = new RohGraph();
         graph.LoadFromString(OntologyService.GetOntology());
         SparqlUtility.LoadOntology(graph, _configSparql.GetEndpoint(), _configSparql.GetQueryParam(), ontologyGraph);
         return(Ok());
     }
     catch (Exception ex)
     {
         return(Problem(ex.ToString()));
     }
 }
Exemple #9
0
        /// <summary>
        /// Comprueba si la ontología ha cambiado. Si es así devuelve la nueva.
        /// </summary>
        /// <returns>La ontología actualizada</returns>
        public RohGraph CallGetOntology()
        {
            string response = _serviceApi.CallGetApi(_serviceUrl.GetUrl(), $"etl/getontologyhash", _token);

            if (response == hash)
            {
                return(ontologia);
            }
            else
            {
                string response2 = _serviceApi.CallGetApi(_serviceUrl.GetUrl(), $"etl/getontology", _token);
                ontologia = new RohGraph();
                ontologia.LoadFromString(response2);
                hash = response;
                return(ontologia);
            }
        }
Exemple #10
0
        /// <summary>
        /// Obtiene los detalles de un error de descubrimiento
        /// </summary>
        /// <returns></returns>
        public IActionResult Details(Guid itemId)
        {
            var discovery = _discoverItemService.GetDiscoverItemById(itemId);
            DiscoverItemViewModel model = new DiscoverItemViewModel();

            model.DissambiguationProblems       = new Dictionary <string, List <string> >();
            model.DissambiguationProblemsTitles = new Dictionary <string, string>();
            if (discovery.Status.Equals("Error"))
            {
                model.Error          = discovery.Error;
                model.JobId          = discovery.JobID;
                model.IdDiscoverItem = discovery.ID;
            }
            else
            {
                RohGraph dataGraph = new RohGraph();
                dataGraph.LoadFromString(discovery.DiscoverRdf, new RdfXmlParser());
                model.JobId = discovery.JobID;

                foreach (var item in discovery.DissambiguationProblems)
                {
                    model.IdDiscoverItem = item.DiscoverItemID;
                    if (!model.DissambiguationProblems.ContainsKey(item.IDOrigin))
                    {
                        model.DissambiguationProblems.Add(item.IDOrigin, new List <string>());
                        model.DissambiguationProblemsTitles.Add(item.IDOrigin, "");
                        SparqlResultSet sparqlResultSet = (SparqlResultSet)dataGraph.ExecuteQuery("select ?title where{<" + item.IDOrigin + "> ?prop ?title. FILTER(?prop in (<http://purl.org/roh#title>,<http://purl.org/roh/mirror/foaf#name>))}");
                        foreach (SparqlResult sparqlResult in sparqlResultSet.Results)
                        {
                            model.DissambiguationProblemsTitles[item.IDOrigin] = ((LiteralNode)(sparqlResult["title"])).Value;
                        }
                    }
                    foreach (var problem in item.DissambiguationCandiates)
                    {
                        string opcion = $"{problem.IDCandidate} || {Math.Round(problem.Score, 3)}";
                        model.DissambiguationProblems[item.IDOrigin].Add(opcion);
                    }
                }
            }
            return(View(model));
        }
Exemple #11
0
        public void TestDiscoverLinks()
        {
            //Cargamos el RDF sobre el que aplicar el reconocimiento de enlaces
            RohGraph dataGraph = new RohGraph();

            dataGraph.LoadFromString(System.IO.File.ReadAllText("rdfFiles/rdfFile.rdf"), new RdfXmlParser());

            //Cargamos el RDF de la ontología
            RohGraph ontologyGraph = new RohGraph();

            ontologyGraph.LoadFromFile("Ontology/roh-v2.owl");

            DiscoverUtility discoverUtility = new DiscoverUtility();

            discoverUtility.test = true;

            CallUrisFactoryApiMockService callUrisFactoryApiMockService = new CallUrisFactoryApiMockService();
            //Aplicamos el descubrimiento de enlaces
            Dictionary <string, List <DiscoverLinkData.PropertyData> > discoverLinks = discoverUtility.ApplyDiscoverLinks(ref dataGraph, ontologyGraph, 0.7f, 0.9f, "", "", "HerculesASIO-University-of-Murcia (https://github.com/HerculesCRUE/GnossDeustoBackend; mailto:<mail>) AsioBot", "Basic czAzNjkuZmVjeXQuZXM6VTQ5RDhSWU40d3Mh", callUrisFactoryApiMockService);

            //En 'discoverLinks' estarán los datos que se han recuperado de las integraciones externas junto con su provenance
            //En 'dataGraph' estará el grafo modificado tras el descubrimiento de enlaces
        }
        public IActionResult ResolveDiscover(string idJob, string IdDiscoverItem, Dictionary <string, string> DissambiguationProblemsResolve)
        {
            DiscoverItem item = _discoverItemService.GetDiscoverItemById(new Guid(IdDiscoverItem));

            //Cargamos el RDF
            RohGraph dataGraph = new RohGraph();

            dataGraph.LoadFromString(item.DiscoverRdf, new RdfXmlParser());

            //Modificamos el RDF
            TripleStore store = new TripleStore();

            store.Add(dataGraph);
            //Cambiamos candidato.Key por entityID
            foreach (string uriOriginal in DissambiguationProblemsResolve.Keys)
            {
                if (!string.IsNullOrEmpty(DissambiguationProblemsResolve[uriOriginal]))
                {
                    //En caso de que la resolución sea una URI de Unidata añadimos el SameAs
                    if (!string.IsNullOrEmpty(_unidataPrefix.GetUnidataDomain()) && DissambiguationProblemsResolve[uriOriginal].StartsWith(_unidataPrefix.GetUnidataDomain()))
                    {
                        IUriNode t_subject   = dataGraph.CreateUriNode(UriFactory.Create(uriOriginal));
                        IUriNode t_predicate = dataGraph.CreateUriNode(UriFactory.Create("http://www.w3.org/2002/07/owl#sameAs"));
                        IUriNode t_object    = dataGraph.CreateUriNode(UriFactory.Create(DissambiguationProblemsResolve[uriOriginal]));
                        dataGraph.Assert(new Triple(t_subject, t_predicate, t_object));
                    }
                    else
                    {
                        //En caso de que la resolución NO sea una URI de Unidata modificamos las URLs
                        SparqlUpdateParser parser = new SparqlUpdateParser();
                        //Actualizamos los sujetos
                        SparqlUpdateCommandSet updateSubject = parser.ParseFromString(@"DELETE { ?s ?p ?o. }
                                                                    INSERT{<" + DissambiguationProblemsResolve[uriOriginal] + @"> ?p ?o.}
                                                                    WHERE 
                                                                    {
                                                                        ?s ?p ?o.   FILTER(?s = <" + uriOriginal + @">)
                                                                    }");
                        //Actualizamos los objetos
                        SparqlUpdateCommandSet   updateObject = parser.ParseFromString(@"DELETE { ?s ?p ?o. }
                                                                    INSERT{?s ?p <" + DissambiguationProblemsResolve[uriOriginal] + @">.}
                                                                    WHERE 
                                                                    {
                                                                        ?s ?p ?o.   FILTER(?o = <" + uriOriginal + @">)
                                                                    }");
                        LeviathanUpdateProcessor processor    = new LeviathanUpdateProcessor(store);
                        processor.ProcessCommandSet(updateSubject);
                        processor.ProcessCommandSet(updateObject);
                    }
                }
            }

            System.IO.StringWriter sw           = new System.IO.StringWriter();
            RdfXmlWriter           rdfXmlWriter = new RdfXmlWriter();

            rdfXmlWriter.Save(dataGraph, sw);
            string   rdfXml = sw.ToString();
            Stream   stream = new MemoryStream(Encoding.UTF8.GetBytes(rdfXml));
            FormFile file   = new FormFile(stream, 0, stream.Length, "rdfFile", "rdf.xml");

            //Actualizamos el item
            Dictionary <string, List <string> > discards = new Dictionary <string, List <string> >();

            foreach (DiscoverItem.DiscoverDissambiguation dissambiguation in item.DissambiguationProblems)
            {
                if (DissambiguationProblemsResolve.ContainsKey(dissambiguation.IDOrigin) && DissambiguationProblemsResolve[dissambiguation.IDOrigin] == null)
                {
                    discards.Add(dissambiguation.IDOrigin, dissambiguation.DissambiguationCandiates.Select(x => x.IDCandidate).ToList());
                }
            }

            item.UpdateDissambiguationDiscards(discards, rdfXml);
            item.DiscoverRdf = rdfXml;
            item.Status      = "Pending";

            _discoverItemService.ModifyDiscoverItem(item);

            //Lo reencolamos corregido junto con su identificador
            _callEDtlPublishService.CallDataPublish(file, idJob, false, IdDiscoverItem);

            return(RedirectToAction("DetailsJob", "Job", new { id = idJob }));
        }
        //TODO mover a otro sitio


        /// <summary>
        /// Realiza el proceso completo de desubrimiento sobre un RDF
        /// </summary>
        /// <param name="pDiscoverItem">Item de descubrimiento</param>
        /// <param name="pCallEtlApiService">Servicio para hacer llamadas a los métodos del controlador etl del API_CARGA </param>
        /// <param name="pCallUrisFactoryApiService">Servicio para hacer llamadas a los métodos del Uris Factory</param>
        /// <returns>DiscoverResult con los datos del descubrimiento</returns>
        private DiscoverResult Init(DiscoverItem pDiscoverItem, CallEtlApiService pCallEtlApiService, CallUrisFactoryApiService pCallUrisFactoryApiService)
        {
            #region Cargamos configuraciones
            ConfigSparql   ConfigSparql             = new ConfigSparql();
            string         SGI_SPARQLEndpoint       = ConfigSparql.GetEndpoint();
            string         SGI_SPARQLGraph          = ConfigSparql.GetGraph();
            string         SGI_SPARQLQueryParam     = ConfigSparql.GetQueryParam();
            string         SGI_SPARQLUsername       = ConfigSparql.GetUsername();
            string         SGI_SPARQLPassword       = ConfigSparql.GetPassword();
            string         Unidata_SPARQLEndpoint   = ConfigSparql.GetUnidataEndpoint();
            string         Unidata_SPARQLGraph      = ConfigSparql.GetUnidataGraph();
            string         Unidata_SPARQLQueryParam = ConfigSparql.GetUnidataQueryParam();
            string         Unidata_SPARQLUsername   = ConfigSparql.GetUnidataUsername();
            string         Unidata_SPARQLPassword   = ConfigSparql.GetUnidataPassword();
            ConfigService  ConfigService            = new ConfigService();
            float          MaxScore          = ConfigService.GetMaxScore();
            float          MinScore          = ConfigService.GetMinScore();
            string         UnidataDomain     = ConfigService.GetUnidataDomain();
            ConfigScopus   ConfigScopus      = new ConfigScopus();
            string         ScopusApiKey      = ConfigScopus.GetScopusApiKey();
            string         ScopusUrl         = ConfigScopus.GetScopusUrl();
            ConfigCrossref ConfigCrossref    = new ConfigCrossref();
            string         CrossrefUserAgent = ConfigCrossref.GetCrossrefUserAgent();
            ConfigWOS      ConfigWOS         = new ConfigWOS();
            string         WOSAuthorization  = ConfigWOS.GetWOSAuthorization();
            #endregion

            DiscoverUtility discoverUtility = new DiscoverUtility();

            DateTime discoverInitTime = DateTime.Now;

            //Cargamos la ontología
            if (_ontologyGraph == null)
            {
                _ontologyGraph = pCallEtlApiService.CallGetOntology();
            }

            //Cargamos datos del RDF
            RohGraph dataGraph = new RohGraph();
            Dictionary <string, HashSet <string> > discardDissambiguations = new Dictionary <string, HashSet <string> >();
            if (!string.IsNullOrEmpty(pDiscoverItem.DiscoverRdf))
            {
                //Si tenemos valor en DiscoverRdf, trabajamos con este RDF, ya que estamos reprocesando un rdf validado
                dataGraph.LoadFromString(pDiscoverItem.DiscoverRdf, new RdfXmlParser());
                if (pDiscoverItem.DiscardDissambiguations != null)
                {
                    foreach (DiscoverItem.DiscardDissambiguation discardDissambiguation in pDiscoverItem.DiscardDissambiguations)
                    {
                        if (!discardDissambiguations.ContainsKey(discardDissambiguation.IDOrigin))
                        {
                            discardDissambiguations.Add(discardDissambiguation.IDOrigin, new HashSet <string>());
                        }
                        discardDissambiguations[discardDissambiguation.IDOrigin].UnionWith(discardDissambiguation.DiscardCandidates);
                    }
                }
            }
            else
            {
                dataGraph.LoadFromString(pDiscoverItem.Rdf, new RdfXmlParser());
            }


            //Cargamos el razonador para inferir datos en la ontología
            RohRdfsReasoner reasoner = new RohRdfsReasoner();
            reasoner.Initialise(_ontologyGraph);

            //Cargamos los datos con inferencia
            RohGraph dataInferenceGraph = dataGraph.Clone();
            reasoner.Apply(dataInferenceGraph);

            //Datos para trabajar con la reconciliación
            ReconciliationData reconciliationData = new ReconciliationData();

            //Datos para trabajar con el descubrimiento de enlaces
            DiscoverLinkData discoverLinkData = new DiscoverLinkData();

            //Almacenamos las entidades con dudas acerca de su reonciliación
            Dictionary <string, Dictionary <string, float> > reconciliationEntitiesProbability = new Dictionary <string, Dictionary <string, float> >();

            //Cargamos la caché global
            if (_discoverCacheGlobal == null)
            {
                _discoverCacheGlobal = new DiscoverCacheGlobal();
                discoverUtility.LoadPersonWithName(_discoverCacheGlobal, SGI_SPARQLEndpoint, SGI_SPARQLGraph, SGI_SPARQLQueryParam, SGI_SPARQLUsername, SGI_SPARQLPassword);
                discoverUtility.LoadEntitiesWithTitle(_discoverCacheGlobal, SGI_SPARQLEndpoint, SGI_SPARQLGraph, SGI_SPARQLQueryParam, SGI_SPARQLUsername, SGI_SPARQLPassword);
            }


            if (!pDiscoverItem.DissambiguationProcessed)
            {
                bool hasChanges = true;

                //Cache del proceso de descubrimiento
                DiscoverCache discoverCache = new DiscoverCache();

                //Se realizarán este proceso iterativamente hasta que no haya ningún cambio en lo que a reconciliaciones se refiere
                while (hasChanges)
                {
                    hasChanges = false;

                    //Preparamos los datos para proceder con la reconciliazción
                    discoverUtility.PrepareData(dataGraph, reasoner, out dataInferenceGraph,
                                                out Dictionary <string, HashSet <string> > entitiesRdfTypes,
                                                out Dictionary <string, string> entitiesRdfType,
                                                out Dictionary <string, List <DisambiguationData> > disambiguationDataRdf, false);

                    //Carga los scores de las personas
                    //Aquí se almacenarán los nombres de las personas del RDF, junto con los candidatos de la BBDD y su score
                    Dictionary <string, Dictionary <string, float> > namesScore = new Dictionary <string, Dictionary <string, float> >();
                    discoverUtility.LoadNamesScore(ref namesScore, dataInferenceGraph, discoverCache, _discoverCacheGlobal, MinScore, MaxScore);

                    //0.- Macamos como reconciliadas aquellas que ya estén cargadas en la BBDD con los mismos identificadores
                    List <string> entidadesCargadas = discoverUtility.LoadEntitiesDB(entitiesRdfType.Keys.ToList().Except(reconciliationData.reconciliatedEntityList.Keys.Union(reconciliationData.reconciliatedEntityList.Values)), SGI_SPARQLEndpoint, SGI_SPARQLGraph, SGI_SPARQLQueryParam, SGI_SPARQLUsername, SGI_SPARQLPassword).Keys.ToList();
                    foreach (string entitiID in entidadesCargadas)
                    {
                        reconciliationData.reconciliatedEntityList.Add(entitiID, entitiID);
                        reconciliationData.reconciliatedEntitiesWithSubject.Add(entitiID);
                    }

                    //1.- Realizamos reconciliación con los identificadores configurados (y el roh:identifier) y marcamos como reconciliadas las entidades seleccionadas para no intentar reconciliarlas posteriormente
                    discoverUtility.ReconciliateIDs(ref hasChanges, ref reconciliationData, entitiesRdfType, disambiguationDataRdf, discardDissambiguations, _ontologyGraph, ref dataGraph, discoverCache, SGI_SPARQLEndpoint, SGI_SPARQLQueryParam, SGI_SPARQLGraph, SGI_SPARQLUsername, SGI_SPARQLPassword);

                    //2.- Realizamos la reconciliación con los datos del Propio RDF
                    discoverUtility.ReconciliateRDF(ref hasChanges, ref reconciliationData, _ontologyGraph, ref dataGraph, reasoner, discardDissambiguations, discoverCache, _discoverCacheGlobal, MinScore, MaxScore);

                    //3.- Realizamos la reconciliación con los datos de la BBDD
                    discoverUtility.ReconciliateBBDD(ref hasChanges, ref reconciliationData, out reconciliationEntitiesProbability, _ontologyGraph, ref dataGraph, reasoner, namesScore, discardDissambiguations, discoverCache, _discoverCacheGlobal, MinScore, MaxScore, SGI_SPARQLEndpoint, SGI_SPARQLQueryParam, SGI_SPARQLGraph, SGI_SPARQLUsername, SGI_SPARQLPassword);

                    //4.- Realizamos la reconciliación con los datos de las integraciones externas
                    //TODO descomentar
                    //discoverUtility.ExternalIntegration(ref hasChanges, ref reconciliationData, ref discoverLinkData, ref reconciliationEntitiesProbability, ref dataGraph, reasoner, namesScore,entitiesWithTitle, ontologyGraph, out Dictionary<string, ReconciliationData.ReconciliationScore> entidadesReconciliadasConIntegracionExternaAux, discardDissambiguations, discoverCache,discoverCacheGlobal, ScopusApiKey, ScopusUrl, CrossrefUserAgent, WOSAuthorization, MinScore, MaxScore, SGI_SPARQLEndpoint, SGI_SPARQLQueryParam, SGI_SPARQLGraph, SGI_SPARQLUsername, SGI_SPARQLPassword,pCallUrisFactoryApiService);

                    //Eliminamos de las probabilidades aquellos que ya estén reconciliados
                    foreach (string key in reconciliationData.reconciliatedEntityList.Keys)
                    {
                        reconciliationEntitiesProbability.Remove(key);
                    }
                }

                //5.-Realizamos la detección de equivalencias con Unidata
                //TODO descomentar cuando esté habilitaado Unidata
                //TODO descomentar y revisar en unidata no tienen roh:identifier
                //discoverUtility.EquivalenceDiscover(ontologyGraph, ref dataGraph, reasoner, discoverCache, ref reconciliationEntitiesProbability, discardDissambiguations, UnidataDomain, MinScore, MaxScore, Unidata_SPARQLEndpoint, Unidata_SPARQLQueryParam, Unidata_SPARQLGraph, Unidata_SPARQLUsername, Unidata_SPARQLPassword);
            }
            //TODO comrpobar cuando esté habilitaado Unidata
            DateTime       discoverEndTime = DateTime.Now;
            DiscoverResult resultado       = new DiscoverResult(dataGraph, dataInferenceGraph, _ontologyGraph, reconciliationData, reconciliationEntitiesProbability, discoverInitTime, discoverEndTime, discoverLinkData);

            return(resultado);
        }