Skip to main content

swls_core/systems/properties/
query.rs

1use std::collections::HashMap;
2
3use bevy_ecs::prelude::*;
4
5use super::types::{DefinedClass, DefinedProperty};
6use crate::{prelude::*, store::Store, util::triple::MyTerm};
7
8pub fn find_classes(
9    store: &oxigraph::store::Store,
10) -> Option<HashMap<oxigraph::model::NamedNode, DefinedClass>> {
11    use oxigraph::{
12        model::{Literal, NamedNode},
13        sparql::{QueryResults, SparqlEvaluator},
14    };
15
16    let mut definitions = HashMap::new();
17    if let QueryResults::Solutions(solutions) = SparqlEvaluator::new()
18        .parse_query(include_str!("../../queries/class_definitions.sparql"))
19        .ok()?
20        .on_store(&store)
21        .execute()
22        .ok()?
23    {
24        for solution in solutions {
25            if let Ok(solution) = solution {
26                let class = solution.get("class").unwrap();
27                let title = solution.get("title");
28                let description = solution.get("description");
29
30                match (NamedNode::try_from(class.clone()),) {
31                    (Ok(class),) => {
32                        let v = definitions
33                            .entry(class.clone())
34                            .or_insert_with(|| DefinedClass {
35                                term: MyTerm::named_node(class.as_str(), 0..0).to_owned(),
36                                locations: std::collections::HashSet::new(),
37                                titles: std::collections::HashSet::new(),
38                                descriptions: std::collections::HashSet::new(),
39                            });
40
41                        if let Some(title) = title.and_then(|x| Literal::try_from(x.clone()).ok()) {
42                            v.titles.insert(title.value().to_string());
43                        }
44
45                        if let Some(description) =
46                            description.and_then(|x| Literal::try_from(x.clone()).ok())
47                        {
48                            v.descriptions.insert(description.value().to_string());
49                        }
50                    }
51                    _ => {}
52                }
53            }
54        }
55    }
56
57    Some(definitions)
58}
59
60pub fn find_properties(store: &oxigraph::store::Store) -> Option<HashMap<String, DefinedProperty>> {
61    use oxigraph::{
62        model::{Literal, NamedNode},
63        sparql::{QueryResults, SparqlEvaluator},
64    };
65
66    let mut definitions = HashMap::new();
67    if let QueryResults::Solutions(solutions) = SparqlEvaluator::new()
68        .parse_query(include_str!("../../queries/property_definitions.sparql"))
69        .ok()?
70        .on_store(&store)
71        .execute()
72        .ok()?
73    {
74        for solution in solutions {
75            if let Ok(solution) = solution {
76                let class = solution.get("property").unwrap();
77                let title = solution.get("title");
78                let description = solution.get("description");
79
80                let range = solution
81                    .get("range")
82                    .and_then(|r| NamedNode::try_from(r.clone()).ok())
83                    .map(|r| MyTerm::named_node(r.as_str(), 0..0).to_owned());
84                let domain = solution
85                    .get("domain")
86                    .and_then(|r| NamedNode::try_from(r.clone()).ok())
87                    .map(|r| MyTerm::named_node(r.as_str(), 0..0).to_owned());
88
89                match (NamedNode::try_from(class.clone()),) {
90                    (Ok(class),) => {
91                        let v = definitions
92                            .entry(class.as_str().to_string())
93                            .or_insert_with(|| DefinedProperty {
94                                term: MyTerm::named_node(class.as_str(), 0..0).to_owned(),
95                                locations: std::collections::HashSet::new(),
96                                titles: std::collections::HashSet::new(),
97                                descriptions: std::collections::HashSet::new(),
98                                ranges: std::collections::HashSet::new(),
99                                domains: std::collections::HashSet::new(),
100                            });
101
102                        if let Some(title) = title.and_then(|x| Literal::try_from(x.clone()).ok()) {
103                            v.titles.insert(title.value().to_string());
104                        }
105
106                        if let Some(description) =
107                            description.and_then(|x| Literal::try_from(x.clone()).ok())
108                        {
109                            v.descriptions.insert(description.value().to_string());
110                        }
111                        if let Some(domain) = domain {
112                            v.domains.insert(domain);
113                        }
114
115                        if let Some(range) = range {
116                            v.ranges.insert(range);
117                        }
118                    }
119                    _ => {}
120                }
121            }
122        }
123    }
124
125    Some(definitions)
126}
127
128pub fn derive_ontologies(
129    query: Query<(), Added<Triples>>,
130    store: Res<Store>,
131    mut resource: ResMut<Ontologies>,
132    mut hierarchy: ResMut<TypeHierarchy>,
133) {
134    if !query.is_empty() {
135        if let Some(classes) = find_classes(&store.0) {
136            tracing::debug!("Derive {} classes", classes.len());
137            resource.classes = classes;
138        }
139
140        if let Some(properties) = find_properties(&store.0) {
141            tracing::debug!("Derive {} properties", properties.len());
142            for p in properties.values() {
143                for domain in &p.domains {
144                    let _ = hierarchy.get_id(domain.as_str());
145                }
146
147                for range in &p.ranges {
148                    let _ = hierarchy.get_id(range.as_str());
149                }
150            }
151
152            resource.properties = properties;
153        }
154    }
155}