1use crate::individual::*;
2use std::collections::{HashMap, HashSet};
3use std::fmt;
4
5#[derive(PartialEq, Debug)]
8pub enum RelType {
9 Sub,
10 Super,
11}
12
13#[derive(Debug)]
14pub struct Onto {
15 pub relations: HashMap<String, HashMap<String, RelType>>,
16 pub prefixes: HashMap<String, String>,
17}
18
19impl fmt::Display for Onto {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 write!(f, "{:#?}", self.relations)
22 }
23}
24
25impl Default for Onto {
26 fn default() -> Self {
27 Onto {
28 relations: HashMap::new(),
29 prefixes: HashMap::new(),
30 }
31 }
32}
33
34impl Onto {
35 pub fn update(&mut self, indv: &mut Individual) -> bool {
36 if let Some(vtype) = indv.get_first_literal("rdf:type") {
37 if vtype == "owl:Class"
38 || vtype == "rdfs:Class"
39 || vtype == "rdf:Property"
40 || vtype == "rdfs:Datatype"
41 || vtype == "owl:ObjectProperty"
42 || vtype == "owl:DatatypeProperty"
43 {
44 let subs = if vtype == "owl:Class" || vtype == "rdfs:Class" {
45 if let Some(_subclasses) = indv.get_literals("rdfs:subClassOf") {
46 _subclasses
47 } else {
48 Vec::new()
49 }
50 } else if vtype == "rdf:Property" || vtype == "owl:ObjectProperty" || vtype == "owl:DatatypeProperty" {
51 if let Some(_subproperties) = indv.get_literals("rdfs:subPropertyOf") {
52 _subproperties
53 } else {
54 Vec::new()
55 }
56 } else {
57 Vec::new()
58 };
59
60 let onto_el = self.relations.entry(indv.obj.uri.clone()).or_default();
62
63 for sub in subs.clone() {
64 let rel_type = onto_el.entry(sub).or_insert(RelType::Super);
65 *rel_type = RelType::Super;
66 }
67
68 for sub in subs {
69 let onto_el = self.relations.entry(sub).or_default();
70 let rel_type = onto_el.entry(indv.obj.uri.clone()).or_insert(RelType::Sub);
71 *rel_type = RelType::Sub;
72 }
73 } else if vtype == "owl:Ontology" {
75 if let Some(full_url) = indv.get_first_literal("v-s:fullUrl") {
76 debug!("prefix : {} -> {}", indv.get_id(), full_url);
77 self.prefixes.insert(indv.get_id().to_owned(), full_url);
78 }
79 } else {
80 debug!("is not onto element: {}", indv.obj.uri)
81 }
82 }
83 true
84 }
85
86 pub fn is_some_entered(&mut self, el: &str, subs: &[&str]) -> bool {
87 for sub in subs {
88 if self.relations.contains_key(*sub) {
89 let onto_el = self.relations.entry((*sub).to_string()).or_default();
90 if let Some(rtype) = onto_el.get(el) {
91 if *rtype == RelType::Sub {
92 return true;
93 }
94 }
95 }
96 }
97
98 false
99 }
100
101 pub fn is_some_entered_it<'a, I>(&mut self, el: &str, subs: I) -> bool
102 where
103 I: Iterator<Item = &'a String>,
104 {
105 for sub in subs {
106 if self.relations.contains_key(sub) {
107 let onto_el = self.relations.entry((*sub).to_string()).or_default();
108 if let Some(rtype) = onto_el.get(el) {
109 if *rtype == RelType::Sub {
110 return true;
111 }
112 }
113 }
114 }
115
116 false
117 }
118
119 pub fn get_subs(&self, el: &str, collector: &mut HashSet<String>) {
120 if self.relations.contains_key(el) {
121 let mut buf = Vec::new();
122 if let Some(qqq) = self.relations.get(el) {
123 for (x, t) in qqq {
124 if *t == RelType::Sub && !collector.contains(x) {
125 collector.insert(x.to_string());
126 buf.push(x.to_string());
127 }
128 }
129 }
130
131 for x in buf {
132 self.get_subs(&x, collector);
133 }
134 }
135 }
136
137 pub fn get_supers(&self, el: &str, collector: &mut HashSet<String>) {
138 if self.relations.contains_key(el) {
139 let mut buf = Vec::new();
140 if let Some(qqq) = self.relations.get(el) {
141 for (x, t) in qqq {
142 if *t == RelType::Super && !collector.contains(x) {
143 collector.insert(x.to_string());
144 buf.push(x.to_string());
145 }
146 }
147 }
148
149 for x in buf {
150 self.get_supers(&x, collector);
151 }
152 }
153 }
154
155 pub fn update_subs(&mut self, el: &str, subs: &mut HashSet<String>) {
156 if self.relations.contains_key(el) {
157 let onto_el = self.relations.entry(el.to_string()).or_default();
158
159 for sub in subs.iter() {
160 let rel_type = onto_el.entry(sub.to_string()).or_insert(RelType::Sub);
161 *rel_type = RelType::Sub;
162 }
163 }
164 }
165
166 pub fn get_full_prefix(&self, short_prefix: &str) -> Option<&String> {
167 self.prefixes.get(short_prefix)
168 }
169}