swls_core/systems/properties/
query.rs1use 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}