Maria Hansen 1年前
当前提交
a82e9dfe70
找不到此签名对应的密钥

+ 1
- 0
.gitignore 查看文件

@@ -0,0 +1 @@
1
+/target

+ 1229
- 0
Cargo.lock
文件差异内容过多而无法显示
查看文件


+ 16
- 0
Cargo.toml 查看文件

@@ -0,0 +1,16 @@
1
+[package]
2
+name = "odrlpublic"
3
+version = "0.1.0"
4
+edition = "2021"
5
+
6
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
+
8
+[dependencies]
9
+serde_json = "1.0.111"
10
+serde = { version = "1.0.195", features = ["derive"] }
11
+uuid = { version = "1.7.0", features = ["v4"] }
12
+url = "2.5.0"
13
+lazy_static = "1.4.0"
14
+sophia = "0.8.0"
15
+sophia_jsonld = "0.8.0"
16
+sophia_term = "0.8.0"

+ 12
- 0
src/NameSpaces.rs 查看文件

@@ -0,0 +1,12 @@
1
+pub const RDF_NS: &'static str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
2
+pub const RDFS_NS: &'static str = "http://www.w3.org/2000/01/rdf-schema#";
3
+pub const OWL_NS: &'static str = "http://www.w3.org/2002/07/owl#";
4
+pub const XSD_NS: &'static str = "http://www.w3.org/2001/XMLSchema#";
5
+pub const SKOS_NS: &'static str = "http://www.w3.org/2004/02/skos/core#";
6
+pub const DCTERMS_NS: &'static str = "http://purl.org/dc/terms/";
7
+pub const VCARD_NS: &'static str = "http://www.w3.org/2006/vcard/ns#";
8
+pub const FOAF_NS: &'static str = "http://xmlns.com/foaf/0.1/";
9
+pub const SCHEMA_NS: &'static str = "http://schema.org/";
10
+pub const CC_NS: &'static str = "https://creativecommons.org/ns#";
11
+pub const LD_NS: &'static str = "http://www.w3.org/ns/odrl.jsonld#";
12
+pub const ODRL_NS: &'static str = "http://www.w3.org/ns/odrl/2/";

+ 0
- 0
src/ODRL/Evaluator.rs 查看文件


+ 0
- 0
src/ODRL/JsonParser.rs 查看文件


+ 0
- 0
src/ODRL/Profile.rs 查看文件


+ 338
- 0
src/ODRL/Serializer.rs 查看文件

@@ -0,0 +1,338 @@
1
+use sophia::api::prelude::*;
2
+use sophia::api::ns::Namespace;
3
+use sophia::api::ns::rdf;
4
+use sophia::api::term::SimpleTerm;
5
+use sophia::iri::IriRef;
6
+use sophia::iri::Iri;
7
+use sophia::inmem::graph::LightGraph;
8
+use sophia::turtle::serializer::nt::NtSerializer;
9
+use sophia_jsonld::*;
10
+use sophia_term::RcTerm;
11
+
12
+
13
+use crate::{model, NameSpaces};
14
+use model::Action::*;
15
+use model::Asset::*;
16
+use model::ConflictTerm::*;
17
+use model::Constraint::*;
18
+use model::Party::*;
19
+use model::Policy::*;
20
+use model::Rule::*;
21
+
22
+use serde_json::Value;
23
+
24
+
25
+fn create_policy() -> Policy {
26
+
27
+    let (use_action, _) = Action::init_top_level();
28
+
29
+    let simple_asset = Asset::new(
30
+        Some("http://example.com/asset:9898.movie".to_string()),
31
+        vec![],
32
+        Relation::new(None),
33
+        None
34
+    );
35
+
36
+    let example_permission = Rule::Permission(Permission::new(
37
+        None,
38
+        use_action,
39
+        None,
40
+        vec![],
41
+        vec![],
42
+        vec![],
43
+        simple_asset,
44
+        None,
45
+        None,
46
+        vec![],
47
+    ));
48
+
49
+    let set_policy = Policy::SetPolicy(
50
+        SetPolicy::new(
51
+            "http://example.com/policy:1010".to_string(),
52
+            vec![example_permission],
53
+            vec![],
54
+            vec![],
55
+            None,
56
+            None
57
+        )
58
+    );
59
+
60
+    set_policy
61
+}
62
+
63
+trait Serializable {
64
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>>;
65
+}
66
+
67
+// TODO: Implement Serializable for all ODRL-Model-Types
68
+impl Serializable for Action {
69
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
70
+        // TODO
71
+        Ok(())
72
+    }
73
+}
74
+
75
+impl Serializable for Asset {
76
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
77
+        // TODO
78
+        Ok(())
79
+    }
80
+}
81
+
82
+impl Serializable for ConflictTerm {
83
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
84
+        // TODO
85
+        Ok(())
86
+    }
87
+}
88
+
89
+impl Serializable for Constraint {
90
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
91
+        // TODO
92
+        Ok(())
93
+    }
94
+}
95
+
96
+impl Serializable for Party {
97
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
98
+        // TODO
99
+        Ok(())
100
+    }
101
+}
102
+
103
+impl Serializable for Obligation {
104
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
105
+        // TODO
106
+        Ok(())
107
+    }
108
+}
109
+
110
+impl Serializable for Policy {
111
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
112
+        match self {
113
+            Policy::SetPolicy(set_policy) => set_policy.add_to_graph(graph),
114
+            Policy::OfferPolicy(offer_policy) => offer_policy.add_to_graph(graph),
115
+            Policy::AgreementPolicy(agreement_policy) => agreement_policy.add_to_graph(graph),
116
+        }.expect("Error adding policy to graph since its type is not supported");
117
+
118
+        Ok(())
119
+    }
120
+}
121
+
122
+impl Serializable for SetPolicy {
123
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
124
+        let set_policy_type = IriRef::new(format!("{}type", NameSpaces::RDF_NS))?;
125
+        let set_policy_uid = self.uid.clone();
126
+        let set_policy_term = IriRef::new(set_policy_uid).unwrap();
127
+
128
+        // Insert triples for SetPolicy
129
+        graph.insert(&set_policy_term, &set_policy_type, &IriRef::new(format!("{}Set", NameSpaces::LD_NS)).unwrap())?; // Type
130
+        graph.insert(&set_policy_term, &IriRef::new(format!("{}uid", NameSpaces::LD_NS)).unwrap(), &set_policy_term)?; // UID
131
+
132
+
133
+        // Insert other triples for fields:
134
+        //      rules: Vec<Rule>,
135
+        //      profiles: Vec<IRI>,
136
+        //      inherit_from: Vec<IRI>,
137
+        //      conflict: Option<ConflictTerm>,
138
+        //      obligation: Option<Vec<Obligation>>,
139
+        for rule in &self.rules {
140
+            rule.add_to_graph(graph)?;
141
+            // Rules can be of type Permission, Prohibition, or Duty, therefore their insertion will be handled by the add_to_graph() method.
142
+        }
143
+        /* Profiles and inherit_from are represented as IRIs, therefore can be directly added to the graph as object values in triples. */
144
+        for profile in &self.profiles {
145
+            graph.insert(&set_policy_term, &IriRef::new(NameSpaces::ODRL_NS).unwrap(), &IriRef::new(profile.to_string()).unwrap())?;
146
+        }
147
+        for inherit in &self.inherit_from {
148
+            graph.insert(&set_policy_term, &IriRef::new(NameSpaces::ODRL_NS).unwrap(), &IriRef::new(inherit.to_string()).unwrap())?;
149
+        }
150
+        /* Since ConcflictTerms and Obligations are more complex structures, they may require more than just the IRI to be represented in the graph.
151
+         Therefore, their insertion will be handled by the add_to_graph() method. */
152
+        if let Some(conflict) = &self.conflict {
153
+            conflict.add_to_graph(graph)?;
154
+        }
155
+        if let Some(obligations) = &self.obligation {
156
+            for obligation in obligations {
157
+                obligation.add_to_graph(graph)?;
158
+            }
159
+        }
160
+        Ok(())
161
+    }
162
+}
163
+
164
+impl Serializable for OfferPolicy {
165
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
166
+        // TODO
167
+        Ok(())
168
+    }
169
+}
170
+
171
+impl Serializable for AgreementPolicy {
172
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
173
+        // TODO
174
+        Ok(())
175
+    }
176
+}
177
+
178
+impl Serializable for Rule {
179
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
180
+        match self {
181
+            Rule::Permission(permission) => permission.add_to_graph(graph),
182
+            Rule::Prohibition(prohibition) => prohibition.add_to_graph(graph),
183
+            Rule::Duty(duty) => duty.add_to_graph(graph),
184
+        }.expect("Error adding rule to graph since its type is not supported");
185
+        Ok(())
186
+    }
187
+}
188
+
189
+impl Serializable for Permission {
190
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
191
+        // Define terms
192
+        let set_policy_type = IriRef::new(format!("{}Set", NameSpaces::LD_NS))?;
193
+        let permission_term = IriRef::new(format!("{}_permission", NameSpaces::LD_NS))?;
194
+        let target_term = IriRef::new(&self.target)?;
195
+        let action_term = IriRef::new(format!("{}{}", NameSpaces::LD_NS, self.action))?;
196
+
197
+        // Insert triples for permission
198
+        graph.insert(&permission_term, &set_policy_type, &action_term)?;
199
+        graph.insert(&permission_term, &set_policy_type, &target_term)?;
200
+
201
+        Ok(())
202
+    }
203
+}
204
+
205
+impl Serializable for Prohibition {
206
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
207
+        // TODO
208
+        Ok(())
209
+    }
210
+}
211
+
212
+impl Serializable for Duty {
213
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
214
+        // TODO
215
+        Ok(())
216
+    }
217
+}
218
+
219
+impl Serializable for Agreement {
220
+    fn add_to_graph(&self, graph: &mut LightGraph) -> Result<(), Box<dyn std::error::Error>> {
221
+        // TODO
222
+        Ok(())
223
+    }
224
+}
225
+
226
+pub fn build_graph<T: Serializable>(odrl_object: &T) -> Result<(), Box<dyn std::error::Error>> {
227
+
228
+    // TODO
229
+    Ok::<(), Box<dyn std::error::Error>>(())
230
+
231
+}
232
+
233
+pub fn json_ld_from_graph() {
234
+
235
+    // TODO
236
+
237
+}
238
+
239
+pub fn main() -> Result<(), Box<dyn std::error::Error>> {
240
+
241
+    let policy = create_policy();
242
+
243
+    let mut policy_uid = String::new();
244
+    let mut policy_type = "";
245
+    let mut rule_type = "";
246
+    let mut action_type = String::new();
247
+    let mut target_uid = String::new();
248
+
249
+    if let Policy::SetPolicy(ref policy) = policy {
250
+        policy_uid = policy.uid.clone();
251
+        policy_type = "Set";
252
+        for rule in policy.rules.clone() {
253
+            match rule {
254
+                Rule::Permission(Permission {
255
+                                     uid, action, relation, function, failures,
256
+                                     constraints, target, assigner, assignee, duties }) => {
257
+                    rule_type = "permission";
258
+                    action_type = action.name;
259
+                    target_uid = target.uid.unwrap_or_else(|| "unknown".to_string());
260
+                },
261
+                _ => {
262
+                    rule_type = "unknown"; // match mit anderen Rule-Typen erstellen
263
+                }
264
+            }
265
+        }
266
+    }
267
+
268
+
269
+    // Erstellen des RDF-Graphen
270
+    let mut graph = LightGraph::new();
271
+
272
+    // Beispiel-Tripel hinzufügen
273
+    let policy_uri = IriRef::new("policy").unwrap();
274
+    let asset_uri = IriRef::new("asset").unwrap();
275
+    let set_uri = IriRef::new("Set").unwrap();
276
+    let use_uri = IriRef::new("use").unwrap();
277
+
278
+    let policy_id = IriRef::new(policy_uid.clone()).unwrap();
279
+    let asset_id = IriRef::new(target_uid.clone()).unwrap();
280
+
281
+    graph.insert(&policy_id, &rdf::type_, &set_uri).unwrap();
282
+    graph.insert(&policy_id, &IriRef::new("uid").unwrap(), &policy_id).unwrap();
283
+    graph.insert(&policy_id, &IriRef::new(rule_type).unwrap(), &asset_id).unwrap();
284
+    graph.insert(&asset_id, &rdf::type_, &asset_uri).unwrap();
285
+    graph.insert(&policy_id, &use_uri, &asset_id).unwrap();
286
+
287
+    let mut nt_stringifier = NtSerializer::new_stringifier();
288
+    let w3_example = nt_stringifier.serialize_graph(&graph)?.as_str();
289
+
290
+
291
+    let graph_data = graph.into_dataset();
292
+
293
+    let mut ld_jsonifier = JsonLdStringifier::new_stringifier();
294
+    let mut data_string = ld_jsonifier.serialize_dataset(&graph_data)?.to_string();
295
+
296
+    let test_obj: Value = serde_json::from_str(&data_string)?;
297
+
298
+    println!("The resulting JSON-LD from graph (parsed):\n{}\n", serde_json::to_string_pretty(&test_obj)?);
299
+
300
+
301
+
302
+    let mut test_graph = LightGraph::new();
303
+    policy.add_to_graph(&mut test_graph).expect("Wasn't able to add policy to graph.");
304
+
305
+    let mut nt2_stringifier = NtSerializer::new_stringifier();
306
+    let test_graph2 = nt2_stringifier.serialize_graph(&test_graph)?.as_str();
307
+    println!("\n\nThe resulting graph:\n{}", test_graph2);
308
+
309
+    let final_data = test_graph.into_dataset();
310
+
311
+    let mut new_jsonifier = JsonLdStringifier::new_stringifier();
312
+
313
+    let mut final_string = new_jsonifier.serialize_dataset(&final_data)?.to_string();
314
+
315
+    let final_obj: Value = serde_json::from_str(&final_string)?;
316
+
317
+    println!("The resulting JSON-LD from graph (parsed):\n{}\n", serde_json::to_string_pretty(&final_obj)?);
318
+
319
+    Ok::<(), Box<dyn std::error::Error>>(())
320
+}
321
+
322
+pub trait QuadsToString {
323
+    fn to_string(&self) -> String {
324
+        "Default".to_string()
325
+    }
326
+}
327
+
328
+impl<'a> QuadsToString for SimpleTerm<'a> {
329
+    fn to_string(&self) -> String {
330
+        match self {
331
+            SimpleTerm::Iri(iri) => iri.to_string(),
332
+            SimpleTerm::BlankNode(node) => node.to_string(),
333
+            SimpleTerm::LiteralDatatype(value, datatype) => format!("\"{}\"^^{}", value, datatype),
334
+            SimpleTerm::LiteralLanguage(value, language) => format!("\"{}\"@{}", value, language.to_string()),
335
+            _ => "Triple or Variable".to_string(), // TODO: Implement other types
336
+        }
337
+    }
338
+}

+ 0
- 0
src/ODRL/Validator.rs 查看文件


+ 298
- 0
src/ODRL/Vocab/ActionTerm.rs 查看文件

@@ -0,0 +1,298 @@
1
+use crate::ODRL::Vocabulary::Vocabulary;
2
+
3
+use std::collections::HashMap;
4
+use lazy_static::lazy_static;
5
+use std::sync::Mutex;
6
+
7
+
8
+#[derive(Clone)]
9
+struct ActionTerm {
10
+
11
+	value: String,
12
+	parent_term: Option<Box<ActionTerm>>,
13
+	child_terms: Vec<ActionTerm>,
14
+
15
+}
16
+
17
+impl ActionTerm {
18
+
19
+	pub fn new(value: String, parent_term: Option<Box<ActionTerm>>) -> Self {
20
+
21
+		let mut action_term = ActionTerm {
22
+			value,
23
+			parent_term: None,
24
+			child_terms: Vec::new(),
25
+		};
26
+
27
+		if let Some(mut parent) = parent_term {
28
+			parent.child_terms.push(action_term.clone());
29
+			action_term.parent_term = Some(parent);
30
+		}
31
+
32
+		action_term
33
+
34
+	}
35
+
36
+	pub fn get_ancestor_terms(&self) -> Vec<ActionTerm> {
37
+		let mut ancestors = Vec::new();
38
+		self.add_ancestor_term(&mut ancestors);
39
+		ancestors
40
+	}
41
+
42
+	fn add_ancestor_term(&self, ancestors: &mut Vec<ActionTerm>) {
43
+		if let Some(parent) = &self.parent_term {
44
+			ancestors.insert(0, (**parent).clone());
45
+			parent.add_ancestor_term(ancestors);
46
+		}
47
+	}
48
+
49
+	pub fn get_root_term(&self) -> ActionTerm {
50
+		let ancestors = self.get_ancestor_terms();
51
+		if !ancestors.is_empty() {
52
+			ancestors[0].clone()
53
+		} else {
54
+			self.clone()
55
+		}
56
+	}
57
+
58
+	pub fn get_descendant_terms(&self) -> Vec<ActionTerm> {
59
+		let mut descendants = Vec::new();
60
+		self.add_descendant_term(&mut descendants);
61
+		descendants
62
+	}
63
+
64
+	fn add_descendant_term(&self, descendants: &mut Vec<ActionTerm>) {
65
+		for child in &self.child_terms {
66
+			descendants.push(child.clone());
67
+			child.add_descendant_term(descendants);
68
+		}
69
+	}
70
+
71
+}
72
+
73
+lazy_static! {
74
+	static ref ACTIONTERMS: Mutex<HashMap<String, ActionTerm>> = {
75
+		let mut map = HashMap::new();
76
+		init_action_terms();
77
+		Mutex::new(map)
78
+	};
79
+}
80
+
81
+pub fn register_action_term(value: String, action_term: ActionTerm) {
82
+	ACTIONTERMS.lock().unwrap().insert(value, action_term);
83
+}
84
+
85
+fn init_action_terms() {
86
+
87
+	/// Actions for Permission or Prohibition
88
+
89
+	/// "use" and subitems
90
+	/* The Assigner permits/prohibits the Assignee to use the Asset as agreed.
91
+	More details may be defined in the applicable agreements or under applicable commercial laws.
92
+	Refined types of actions can be expressed by the narrower actions. */
93
+	let use_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("use"), None);
94
+	register_action_term("USE".to_string(), use_term.clone());
95
+
96
+	/* The Assigner permits/prohibits the Assignee(s) to use the Asset or parts of it as part of a composite collection. */
97
+	let aggregate_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("aggregate"), Some(Box::new(use_term.clone())));
98
+	register_action_term("AGGREGATE".to_string(), aggregate_term.clone());
99
+
100
+	/* 	The Assigner permits/prohibits the Assignee(s) to add explanatory notations/commentaries to the Asset without
101
+	modifying the Asset in any other way. */
102
+	let annotate_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("annotate"), Some(Box::new(use_term.clone())));
103
+	register_action_term("ANNOTATE".to_string(), annotate_term.clone());
104
+
105
+	/* The Assigner permits/prohibits the Assignee(s) to anonymize all or parts of the Asset.
106
+	For example, to remove identifying particulars for statistical or for other comparable purposes,
107
+	or to use the asset without stating the author / source */
108
+	let anonymize_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("anonymize"), Some(Box::new(use_term.clone())));
109
+	register_action_term("ANONYMIZE".to_string(), anonymize_term.clone());
110
+
111
+	/* The Assigner permits/prohibits the Assignee(s) to store the Asset (in a non-transient form).
112
+	Constraints may be used for temporal conditions. */
113
+	let archive_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("archive"), Some(Box::new(use_term.clone())));
114
+	register_action_term("ARCHIVE".to_string(), archive_term.clone());
115
+
116
+	/* 	The Assigner permits/prohibits the Assignee(s) to create multiple copies of the Asset that are being concurrently used. */
117
+	let concurrent_use_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("concurrent"), Some(Box::new(use_term.clone())));
118
+	register_action_term("CONCURRENT_USE".to_string(), concurrent_use_term.clone());
119
+
120
+	/* The Assigner permits/prohibits the Assignee(s) to create a new derivative Asset from this Asset and to edit or modify the derivative.
121
+	A new asset is created and may have significant overlaps with the original Asset. (Note that the notion of whether or not the change is
122
+	 significant enough to qualify as a new asset is subjective.) To the derived Asset a next policy may be applied. */
123
+	let derive_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("derive"), Some(Box::new(use_term.clone())));
124
+	register_action_term("DERIVE".to_string(), derive_term.clone());
125
+
126
+	/* The Assigner permits/prohibits the Assignee(s) to produce a digital copy of (or otherwise digitize) the Asset from its analogue form. */
127
+	let digitize_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("digitize"), Some(Box::new(use_term.clone())));
128
+	register_action_term("DIGITIZE".to_string(), digitize_term.clone());
129
+
130
+	/* The Assigner permits/prohibits the Assignee(s) to distribute the Asset. */
131
+	let distribute_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("distribute"), Some(Box::new(use_term.clone())));
132
+	register_action_term("DISTRIBUTE".to_string(), distribute_term.clone());
133
+
134
+	/* The Assigner permits/prohibits the Assignee(s) to run the computer program Asset.
135
+	For example, machine executable code or Java such as a game or application. */
136
+	let execute_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("execute"), Some(Box::new(use_term.clone())));
137
+	register_action_term("EXECUTE".to_string(), execute_term.clone());
138
+
139
+	/* The Assigner permits/prohibits the Assignee to grant the use the Asset to third parties.
140
+	This action enables the Assignee to create policies for the use of the Asset for third parties.
141
+	nextPolicy is recommended to be agreed with the third party. Use of temporal constraints is recommended. */
142
+	let grant_use_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("grantUse"), Some(Box::new(use_term.clone()))); // towards third-party only
143
+	register_action_term("GRANT_USE".to_string(), grant_use_term.clone());
144
+
145
+	/* The Assigner permits/prohibits the Assignee(s) to record the Asset in an index.
146
+	For example, to include a link to the Asset in a search engine database. */
147
+	let index_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("index"), Some(Box::new(use_term.clone())));
148
+	register_action_term("INDEX".to_string(), index_term.clone());
149
+
150
+	/* The Assigner permits/prohibits the Assignee(s) to load the computer program Asset onto a storage device
151
+	which allows operating or running the Asset. */
152
+	let install_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("install"), Some(Box::new(use_term.clone())));
153
+	register_action_term("INSTALL".to_string(), install_term.clone());
154
+
155
+	/* The Assigner permits/prohibits the Assignee(s) to update existing content of the Asset. A new asset is not created by this action.
156
+	This action will modify an asset which is typically updated from time to time without creating a new asset like a database.
157
+	If the result from modifying the asset should be a new asset the actions derive or extract should be used.
158
+	(Note that the notion of whether or not the change is significant enough to qualify as a new asset is subjective.) */
159
+	let modify_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("modify"), Some(Box::new(use_term.clone())));
160
+	register_action_term("MODIFY".to_string(), modify_term.clone());
161
+
162
+	/* The Assigner permits/prohibits the Assignee(s) to move the Asset from one digital location to another including deleting the original copy.
163
+	After the Asset has been moved, the original copy must be deleted. */
164
+	let move_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("move"), Some(Box::new(use_term.clone())));
165
+	register_action_term("MOVE".to_string(), move_term.clone());
166
+
167
+	/* The Assigner permits/prohibits the Assignee(s) to obtain data from the Asset.
168
+	For example, the ability to read a record from a database (the Asset). */
169
+	let read_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("read"), Some(Box::new(use_term.clone())));
170
+	register_action_term("READ".to_string(), read_term.clone());
171
+
172
+	/* The Assigner permits/prohibits the Assignee(s) to have a text Asset read out loud to an audience. */
173
+	let text_to_speech_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("textToSpeech"), Some(Box::new(use_term.clone())));
174
+	register_action_term("TEXT_TO_SPEECH".to_string(), text_to_speech_term.clone());
175
+
176
+	/* The Assigner permits/prohibits the Assignee(s) to make a digital copy of the digital Asset in another digital format.
177
+	Typically used to convert the Asset into a different format for consumption on/transfer to a third party system. */
178
+	let transform_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("transform"), Some(Box::new(use_term.clone())));
179
+	register_action_term("TRANSFORM".to_string(), transform_term.clone());
180
+
181
+	/* 	The Assigner permits/prohibits the Assignee(s) to translate the original natural language of an Asset into another natural language.
182
+	A new derivative Asset is created by that action. */
183
+	let translate_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("translate"), Some(Box::new(use_term.clone())));
184
+	register_action_term("TRANSLATE".to_string(), translate_term.clone());
185
+
186
+	/// "present" and subitems
187
+	/* The Assigner permits/prohibits the Assignee(s) to perform or exhibit an Asset to an audience. */
188
+	let present_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("present"), Some(Box::new(use_term.clone())));
189
+	register_action_term("PRESENT".to_string(), present_term.clone());
190
+
191
+	/* The Assigner permits/prohibits the Assignee(s) to display the visual media Asset to an audience or the public.
192
+	For example, displaying an image on a screen. */
193
+	let display_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("display"), Some(Box::new(present_term.clone())));
194
+	register_action_term("DISPLAY".to_string(), display_term.clone());
195
+
196
+	/* The Assigner permits/prohibits the Assignee(s) to perform an audio Asset to an audience. */
197
+	let play_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("play"), Some(Box::new(present_term.clone())));
198
+	register_action_term("PLAY".to_string(), play_term.clone());
199
+
200
+	/* The Assigner permits/prohibits the Assignee(s) to print an Asset onto paper or to create a hard copy.
201
+	For example, creating a permanent, fixed (static), and directly perceivable representation of the Asset. */
202
+	let print_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("print"), Some(Box::new(present_term.clone())));
203
+	register_action_term("PRINT".to_string(), print_term.clone());
204
+
205
+	/// "reproduce" and subitems
206
+	/* The Assigner permits/prohibits the Assignee(s) to make (an) exact reproduction(s) of the Asset. */
207
+	let reproduce_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("reproduce"), Some(Box::new(use_term.clone())));
208
+	register_action_term("REPRODUCE".to_string(), reproduce_term.clone());
209
+
210
+	/* The Assigner permits/prohibits the Assignee(s) to extract parts of the Asset and to use it as a new Asset.
211
+	A new asset is created and may have very little in common with the original Asset. (Note that the notion of
212
+	whether or not the change is significant enough to qualify as a new asset is subjective.) To the extracted
213
+	Asset a next policy may be applied. */
214
+	let extract_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("extract"), Some(Box::new(reproduce_term.clone())));
215
+	register_action_term("EXTRACT".to_string(), extract_term.clone());
216
+
217
+	/// "transfer" and subitems
218
+	/* The Assigner transfers/does not transfer the ownership in perpetuity to the Assignee(s). */
219
+	let transfer_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("transfer"), None);
220
+	register_action_term("TRANSFER".to_string(), transfer_term.clone());
221
+
222
+	/* The Assigner permits/prohibits the Assignee(s) to transfer the ownership of the Asset to a third party without
223
+	compensation and while deleting the original asset. */
224
+	let give_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("give"), Some(Box::new(transfer_term.clone()))); // towards third-party only
225
+	register_action_term("GIVE".to_string(), give_term.clone());
226
+
227
+	/* The Assigner permits/prohibits the Assignee(s) to transfer the ownership of the Asset to a third party with compensation and while deleting the original asset. */
228
+	let sell_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("sell"), Some(Box::new(transfer_term.clone()))); // towards third-party only
229
+	register_action_term("SELL".to_string(), sell_term.clone());
230
+
231
+
232
+	/// Actions for Duty
233
+	/* The Assigner requires that the Assignee(s) accepts that the use of the Asset may be tracked
234
+	The collected information may be tracked by the Assigner, or may link to a Party with the role function “trackingParty”. */
235
+	let accept_tracking_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("acceptTracking"), None);
236
+	register_action_term("ACCEPT_TRACKING".to_string(), accept_tracking_term.clone());
237
+
238
+	/* The Assigner requires that the Assignee(s) attributes the Asset to the Assigner or an attributed Party.
239
+	May link to an Asset with the attribution information. May link to a Party with the role function “attributedParty”. */
240
+	let attribute_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("attribute"), None);
241
+	register_action_term("ATTRIBUTE".to_string(), attribute_term.clone());
242
+
243
+	/* The Assigner requires that the Assignee(s) compensates the Assigner (or other specified compensation Party) by some amount of value,
244
+	if defined, for use of the Asset.
245
+	The compensation may use different types of things with a value:
246
+		– the  thing is expressed by the value (term) of the Constraint name
247
+		– the value is expressed by operator, rightOperand, dataType and unit */
248
+	let compensate_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("compensate"), None);
249
+	register_action_term("COMPENSATE".to_string(), compensate_term.clone());
250
+
251
+	/* The Assigner requires that the Assignee(s) permanently removes all copies of the Asset.
252
+	Use a constraint to define under which conditions the Asset should be deleted. */
253
+	let delete_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("delete"), None);
254
+	register_action_term("DELETE".to_string(), delete_term.clone());
255
+
256
+	/* The Assignee requires that the Assigner(s) ensure(s) that the permission on the Asset is exclusive to the Assignee. */
257
+	let ensure_exclusivity_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("ensureExclusivity"), None);
258
+	register_action_term("ENSURE_EXCLUSIVITY".to_string(), ensure_exclusivity_term.clone());
259
+
260
+	/* The Assigner requires that the Assignee(s) include(s) other related assets in the Asset.
261
+	For example; Bio picture must be included in the attribution. Use of the Asset relation attribute is required */
262
+	let include_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("include"), None);
263
+	register_action_term("INCLUDE".to_string(), include_term.clone());
264
+
265
+	/* The Assigner requires that the Assignee(s) inform(s) the Assigner or an informed Party that an action has been performed
266
+	in relation to the Asset.
267
+	May link to a Party with the role function “informedParty”. */
268
+	let inform_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("inform"), None);
269
+	register_action_term("INFORM".to_string(), inform_term.clone());
270
+
271
+	/* The Assigner requires that the Assignee(s) grants the specified Policy to a third party for their use of the Asset. */
272
+	let next_policy_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("nextPolicy"), None);
273
+	register_action_term("NEXT_POLICY".to_string(), next_policy_term.clone());
274
+
275
+	/* The Assigner requires that the Assignee(s) obtains explicit consent from the Assigner or a consenting Party to perform the requested
276
+	action in relation to the Asset.
277
+	Used as a Duty to ensure that the Assigner or a Party is authorized to approve such actions on a case-by-case basis.
278
+	May link to a Party with the role function “consentingParty”. */
279
+	let obtain_consent_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("obtainConsent"), None);
280
+	register_action_term("OBTAIN_CONSENT".to_string(), obtain_consent_term.clone());
281
+
282
+	/* The Assigner requires that the Assignee(s) has(ve) a person review the Policy applicable to the Asset.
283
+	Used when human intervention is required to review the Policy. May link to an Asset which represents the full Policy information. */
284
+	let review_policy_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("reviewPolicy"), None);
285
+	register_action_term("REVIEW_POLICY".to_string(), review_policy_term.clone());
286
+
287
+	/* The Assigner requires that the Assignee(s) unload(s) and delete(s) the computer program Asset from a storage device and
288
+	disable(s) its readiness for operation.
289
+	The Asset is no longer accessible to the Assignee(s). */
290
+	let uninstall_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("uninstall"), None);
291
+	register_action_term("UNINSTALL".to_string(), uninstall_term.clone());
292
+
293
+	/* The Assigner requires that the Assignee(s) apply(ies) a watermark as provided by the Assigner to the Asset.
294
+	It is recommended to embed a link to the watermark. */
295
+	let watermark_term = ActionTerm::new(Vocabulary::create_odrl_vocab_item("watermark"), None);
296
+	register_action_term("WATERMARK".to_string(), watermark_term.clone());
297
+
298
+}

+ 60
- 0
src/ODRL/Vocab/AssetRelationTerm.rs 查看文件

@@ -0,0 +1,60 @@
1
+use crate::ODRL::Vocabulary::Vocabulary;
2
+use crate::datatypes::URI::URI;
3
+
4
+use std::collections::HashMap;
5
+use lazy_static::lazy_static;
6
+use std::sync::Mutex;
7
+
8
+pub struct AssetRelationTerm {
9
+
10
+	value: String,
11
+
12
+}
13
+
14
+impl AssetRelationTerm {
15
+
16
+	fn new(value: String) -> Self {
17
+		AssetRelationTerm {
18
+			value: value.to_string(),
19
+		}
20
+	}
21
+
22
+	fn new_from_uri(uri: URI) -> Self {
23
+		AssetRelationTerm::new(uri.value)
24
+	}
25
+
26
+}
27
+
28
+lazy_static! {
29
+	static ref ASSETRELATIONTERMS: Mutex<HashMap<String, AssetRelationTerm>> = {
30
+		let mut map = HashMap::new();
31
+		init_asset_relation_terms();
32
+		Mutex::new(map)
33
+	};
34
+}
35
+
36
+pub fn register_asset_relation_term(value: String, assetrelationterm: AssetRelationTerm) {
37
+	ASSETRELATIONTERMS.lock().unwrap().insert(value, assetrelationterm);
38
+}
39
+
40
+/// Terms for the attribute “relation” of the entity Relation
41
+fn init_asset_relation_terms() {
42
+
43
+	/* 	The Asset upon which the Action is performed
44
+	This is the default value and must be supported. Only one target can be specified. */
45
+	register_asset_relation_term("TARGET".to_string(), AssetRelationTerm::new(Vocabulary::create_odrl_vocab_item("target")));
46
+
47
+	/* The Asset which is created from the output of the Action
48
+	For example, can indicate that a Translated Asset uses a specific UID.
49
+	This UID of the newly created Asset can then be used in other Policy expressions. */
50
+	register_asset_relation_term("OUTPUT".to_string(), AssetRelationTerm::new(Vocabulary::create_odrl_vocab_item("output")));
51
+
52
+}
53
+
54
+pub fn is_asset_relation_term(value: String) -> bool {
55
+	ASSETRELATIONTERMS.lock().unwrap().contains_key(&value)
56
+}
57
+
58
+pub fn get_asset_relation_term_values() -> Vec<String> {
59
+	ASSETRELATIONTERMS.lock().unwrap().keys().map(|key| key.to_string()).collect()
60
+}

+ 87
- 0
src/ODRL/Vocab/ConstraintOperator.rs 查看文件

@@ -0,0 +1,87 @@
1
+use crate::ODRL::Vocabulary::Vocabulary;
2
+use crate::datatypes::URI::URI;
3
+
4
+use std::collections::HashMap;
5
+use lazy_static::lazy_static;
6
+use std::sync::Mutex;
7
+
8
+pub struct ConstraintOperator {
9
+
10
+	value: String,
11
+
12
+}
13
+
14
+impl ConstraintOperator {
15
+
16
+	fn new(value: String) -> Self {
17
+		ConstraintOperator {
18
+			value: value.to_string(),
19
+		}
20
+	}
21
+
22
+	fn new_from_uri(uri: URI) -> Self {
23
+		ConstraintOperator::new(uri.value)
24
+	}
25
+
26
+}
27
+
28
+lazy_static! {
29
+	static ref CONSTRAINTOPERATORS: Mutex<HashMap<String, ConstraintOperator>> = {
30
+		let mut map = HashMap::new();
31
+		init_constraint_operators();
32
+		Mutex::new(map)
33
+	};
34
+}
35
+
36
+pub fn register_constraint_operator(value: String, constraintoperator: ConstraintOperator) {
37
+	CONSTRAINTOPERATORS.lock().unwrap().insert(value, constraintoperator);
38
+}
39
+
40
+/// Terms for the attribute “operator” of the entity Constraint
41
+fn init_constraint_operators() {
42
+
43
+	/* 	The “Equals” operator indicating that a given value equals the rightOperand of the Constraint */
44
+	register_constraint_operator("EQUAL".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("eq")));
45
+
46
+	/* The “Greater Than” operator indicating that a given value is greater than the rightOperand of the Constraint */
47
+	register_constraint_operator("GREATER_THAN".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("gt")));
48
+
49
+	/* The “Greater Than or Equal To” operator indicating that a given value is greater than or equal to the rightOperand of the Constraint */
50
+	register_constraint_operator("GREATER_THAN_OR_EQUAL".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("gteq")));
51
+
52
+	/* The “Has Part” operator indicating that a given value contains the rightOperand of the Constraint */
53
+	register_constraint_operator("HAS_PART".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("hasPart")));
54
+
55
+	/* The “Is A” operator indicating that a given value is an instance of the rightOperand of the Constraint */
56
+	register_constraint_operator("IS_A".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("isA")));
57
+
58
+	/* The “Is All Of” operator indicating that a given value is all of the rightOperand of the Constraint */
59
+	register_constraint_operator("IS_ALL_OF".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("isAllOf")));
60
+
61
+	/* The “Is Any Of” operator indicating that a given value is any of the rightOperand of the Constraint */
62
+	register_constraint_operator("IS_ANY_OF".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("isAnyOf")));
63
+
64
+	/* The “Is None Of” operator indicating that a given value is none of the rightOperand of the Constraint */
65
+	register_constraint_operator("IS_NONE_OF".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("isNoneOf")));
66
+
67
+	/* The “Is Part Of” operator indicating that a given value is part of the rightOperand of the Constraint */
68
+	register_constraint_operator("IS_PART_OF".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("isPartOf")));
69
+
70
+	/* The “Less Than” operator indicating that a given value is less than the rightOperand of the Constraint */
71
+	register_constraint_operator("LESS_THAN".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("lt")));
72
+
73
+	/* The “Less Than or Equal To” operator indicating that a given value is less than or equal to the rightOperand of the Constraint */
74
+	register_constraint_operator("LESS_THAN_OR_EQUAL".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("lteq")));
75
+
76
+	/* The “Not Equal To” operator indicating that a given value is not equal to the rightOperand of the Constraint */
77
+	register_constraint_operator("NOT_EQUAL".to_string(), ConstraintOperator::new(Vocabulary::create_odrl_vocab_item("neq")));
78
+
79
+}
80
+
81
+pub fn is_constraint_operator(value: String) -> bool {
82
+	CONSTRAINTOPERATORS.lock().unwrap().contains_key(&value)
83
+}
84
+
85
+pub fn get_constraint_operator_values() -> Vec<String> {
86
+	CONSTRAINTOPERATORS.lock().unwrap().keys().map(|x| x.to_string()).collect()
87
+}

+ 155
- 0
src/ODRL/Vocab/ConstraintTerm.rs 查看文件

@@ -0,0 +1,155 @@
1
+use crate::ODRL::Vocabulary::Vocabulary;
2
+use crate::datatypes::URI::URI;
3
+
4
+use std::collections::HashMap;
5
+use lazy_static::lazy_static;
6
+use std::sync::Mutex;
7
+
8
+pub struct ConstraintTerm {
9
+
10
+	value: String,
11
+
12
+}
13
+
14
+impl ConstraintTerm {
15
+
16
+	fn new(value: String) -> Self {
17
+		ConstraintTerm {
18
+			value: value.to_string(),
19
+		}
20
+	}
21
+
22
+	fn new_from_uri(uri: URI) -> Self {
23
+		ConstraintTerm::new(uri.value)
24
+	}
25
+
26
+}
27
+
28
+lazy_static! {
29
+	static ref CONSTRAINTTERMS: Mutex<HashMap<String, ConstraintTerm>> = {
30
+		let mut map = HashMap::new();
31
+		init_constraint_terms();
32
+		Mutex::new(map)
33
+	};
34
+}
35
+
36
+pub fn register_constraint_term(value: String, constraintterm: ConstraintTerm) {
37
+	CONSTRAINTTERMS.lock().unwrap().insert(value, constraintterm);
38
+}
39
+
40
+/// Terms for the attribute “name” of the entity Constraint
41
+fn init_constraint_terms() {
42
+
43
+	/* A point defined with absolute coordinates
44
+	For example, JPEG image must be positioned at 100×100 pixel location. This may be used to express [PLUS] semantics. */
45
+	register_constraint_term("ABSOLUTE_POSITION".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("absolutePosition")));
46
+
47
+	/* The absolute dimension that the Asset may be resized
48
+	For example, JPEG image must be reproduced onto an area no larger than A0. This may be used to express [PLUS] semantics. */
49
+	register_constraint_term("ABSOLUTE_SIZE".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("absoluteSize")));
50
+
51
+	/* 	The numeric count indicating the number of times the corresponding entity may be exercised
52
+	Should be a positive integer. */
53
+	register_constraint_term("COUNT".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("count")));
54
+
55
+	/* The date (and optional time and timezone) representing a point in time or period
56
+	Date and Time value must conform to [ISO-8601] as represented in [W3CXMLSCHEMA]. The use of Timezone information is strongly recommended. */
57
+	register_constraint_term("DATE_TIME".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("dateTime")));
58
+
59
+	/* The file format applicable to the Asset
60
+	For example, this may be used to express [PLUS] semantics; only JPEG image may be distributed. */
61
+	register_constraint_term("FILE_FORMAT".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("fileFormat")));
62
+
63
+	/* The defined industry sector applicable to the asset usage
64
+	For example, publishing, financial. */
65
+	register_constraint_term("INDUSTRY".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("industry")));
66
+
67
+	/* The natural language applicable to the asset usage
68
+	For example, this may be used to express [PLUS] semantics; JPEG image may only be reproduced with Spanish text. Must use [BCP-47] codes. */
69
+	register_constraint_term("LANGUAGE".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("language")));
70
+
71
+	/* The delivery channel used for storing or communicating the asset
72
+	For example, the asset may be distributed only on mobile networks. */
73
+	register_constraint_term("DELIVERY_CHANNEL".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("deliveryChannel")));
74
+
75
+	/* A period of time in which the policy action can be exercised.
76
+	The start of the period is when the action is first exercised. */
77
+	register_constraint_term("ELAPSED_TIME".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("elapsedTime")));
78
+
79
+	/* 	Specification of a defined event applicable to the asset usage
80
+	For example, asset may be used at the “FIFA World Cup” only. To express events related to undertaking Duties, a specific event value has been defined:
81
+		policyUsage – the time period whilst the policy is being exercised
82
+	This will enable constraints to be expressed such as “event lt o:policyUsage” indicating before the policy is exercised. */
83
+	register_constraint_term("EVENT".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("event")));
84
+
85
+	/* The media type in which the asset may be used
86
+	For example, electronic, print, advertising, marketing. This may be used to express [PLUS] semantics. */
87
+	register_constraint_term("MEDIA".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("media")));
88
+
89
+	/* The maximum period of metered usage time
90
+	Value must conform to [ISO-8601] as represented in [W3CXMLSCHEMA]. For example “P30H” indicates a 30 hour period. */
91
+	register_constraint_term("METERED_TIME".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("meteredTime")));
92
+
93
+	/* The value of the financial payment
94
+	The dataType attribute may be used to indicate the type of the value (eg decimal) and the unit attribute to indicate the currency.
95
+	May be used for compensation duties. */
96
+	register_constraint_term("PAY_AMOUNT".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("payAmount")));
97
+
98
+	/* The amount (as a percentage) of the action applicable to the asset
99
+	A numeric value from 0 to 100. For example, extract a maximum of 50% of the asset */
100
+	register_constraint_term("PERCENTAGE".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("percentage")));
101
+
102
+	/* The specified Product or Service name
103
+	For example, this may be used to express [PLUS] semantics; images may only be reproduced in the XYZ Magazine. */
104
+	register_constraint_term("PRODUCT".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("product")));
105
+
106
+	/* Specification of a defined purpose applicable to the asset usage
107
+	For example, educational use. [P3P] Purpose values may also be used. */
108
+	register_constraint_term("PURPOSE".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("purpose")));
109
+
110
+	/* The party that receives the result of the Action on the Asset
111
+	The right operand must identify one or more specific parties or categories of party */
112
+	register_constraint_term("RECIPIENT".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("recipient")));
113
+
114
+	/* 	A point defined with reference to another position
115
+	For example, this may be used to express [PLUS] semantics; JPEG image must be positioned at the Top of the Page. */
116
+	register_constraint_term("RELATIVE_POSITION".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("relativePosition")));
117
+
118
+	/* The relative dimension that the Asset may be resized
119
+	For example, this may be used to express [PLUS] semantics; JPEG image resized to maximum of 200%. */
120
+	register_constraint_term("RELATIVE_SIZE".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("relativeSize")));
121
+
122
+	/* The resolution at which the asset may be used
123
+	For example, may be printed at 1200dpi. */
124
+	register_constraint_term("RESOLUTION".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("resolution")));
125
+
126
+	/* A code representing a geospatial area
127
+	The code value and code source must be represented.
128
+	For example, the ISO-3166 Country Codes and the Getty Thesaurus of Geographic Names. A URI should be used to represent this value. */
129
+	register_constraint_term("SPATIAL".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("spatial")));
130
+
131
+	/* Recurring period of time in which the usage may be exercised
132
+	Interval value must conform to [ISO-8601] as represented in [W3CXMLSCHEMA]. For example, “P7D” indicates a 7 day period. */
133
+	register_constraint_term("TIME_INTERVAL".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("timeInterval")));
134
+
135
+	/* An identifiable computing system
136
+	For example, identifiable via the CPU or unique hardware address. */
137
+	register_constraint_term("SYSTEM_DEVICE".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("systemDevice")));
138
+
139
+	/* The scope of versions for the asset
140
+	For example, Single Paperback, or Multiple Issues. This may be used to express [PLUS] semantics. */
141
+	register_constraint_term("VERSION".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("version")));
142
+
143
+	/* Specification of a digital locale
144
+	For example, an Internet domain or IP address range */
145
+	register_constraint_term("VIRTUAL_LOCATION".to_string(), ConstraintTerm::new(Vocabulary::create_odrl_vocab_item("virtualLocation")));
146
+
147
+}
148
+
149
+pub fn is_constraint_term(value: String) -> bool {
150
+	CONSTRAINTTERMS.lock().unwrap().contains_key(&value)
151
+}
152
+
153
+pub fn get_constraint_terms_values() -> Vec<String> {
154
+	CONSTRAINTTERMS.lock().unwrap().keys().map(|x| x.to_string()).collect()
155
+}

+ 79
- 0
src/ODRL/Vocab/FunctionTerm.rs 查看文件

@@ -0,0 +1,79 @@
1
+use crate::ODRL::Vocabulary::Vocabulary;
2
+use crate::datatypes::URI::URI;
3
+
4
+use std::collections::HashMap;
5
+use lazy_static::lazy_static;
6
+use std::sync::Mutex;
7
+
8
+pub struct FunctionTerm {
9
+
10
+	value: String,
11
+
12
+}
13
+
14
+impl FunctionTerm {
15
+
16
+	fn new(value: String) -> Self {
17
+		FunctionTerm {
18
+			value: value.to_string(),
19
+		}
20
+	}
21
+
22
+	fn new_from_uri(uri: URI) -> Self {
23
+		FunctionTerm::new(uri.value)
24
+	}
25
+
26
+}
27
+
28
+lazy_static! {
29
+	static ref FUNCTIONTERMS: Mutex<HashMap<String, FunctionTerm>> = {
30
+		let mut map = HashMap::new();
31
+		init_function_terms();
32
+		Mutex::new(map)
33
+	};
34
+}
35
+
36
+pub fn register_function_term(value: String, functionterm: FunctionTerm) {
37
+	FUNCTIONTERMS.lock().unwrap().insert(value, functionterm);
38
+}
39
+
40
+/// Terms for the attribute “function” of the entity Role
41
+fn init_function_terms() {
42
+
43
+	/* The Party is the issuer of the policy statement
44
+	Must be supported. */
45
+	register_function_term("ASSIGNER".to_string(), FunctionTerm::new(Vocabulary::create_odrl_vocab_item("assigner")));
46
+
47
+	/* The Party is the recipient of the policy statement
48
+	Must be supported. */
49
+	register_function_term("ASSIGNEE".to_string(), FunctionTerm::new(Vocabulary::create_odrl_vocab_item("assignee")));
50
+
51
+	/* The Party to be attributed
52
+	May be specified as part of the attribute action. */
53
+	register_function_term("ATTRIBUTED_PARTY".to_string(), FunctionTerm::new(Vocabulary::create_odrl_vocab_item("attributedParty")));
54
+
55
+	/* The Party to obtain consent from
56
+	May be specified as part of the obtainConsent action. */
57
+	register_function_term("CONSENTING_PARTY".to_string(), FunctionTerm::new(Vocabulary::create_odrl_vocab_item("consentingParty")));
58
+
59
+	/* The Party to be informed of all uses
60
+	May be specified as part of the inform action. */
61
+	register_function_term("INFORMED_PARTY".to_string(), FunctionTerm::new(Vocabulary::create_odrl_vocab_item("informedParty")));
62
+
63
+	/* The Party is the recipient of the compensation
64
+	May be specified as part of the compensate duty action. */
65
+	register_function_term("COMPENSATED_PARTY".to_string(), FunctionTerm::new(Vocabulary::create_odrl_vocab_item("compensatedParty")));
66
+
67
+	/* 	The Party is the usage tracker
68
+	May be specified as part of the acceptTracking action. */
69
+	register_function_term("TRACKING_PARTY".to_string(), FunctionTerm::new(Vocabulary::create_odrl_vocab_item("trackingParty")));
70
+
71
+}
72
+
73
+pub fn is_function_term(term: &str) -> bool {
74
+	FUNCTIONTERMS.lock().unwrap().contains_key(term)
75
+}
76
+
77
+pub fn get_function_term_values() -> Vec<String> {
78
+	FUNCTIONTERMS.lock().unwrap().keys().map(|term| term.to_string()).collect()
79
+}

+ 85
- 0
src/ODRL/Vocab/PolicyType.rs 查看文件

@@ -0,0 +1,85 @@
1
+use crate::ODRL::Vocabulary::Vocabulary;
2
+use crate::datatypes::URI::URI;
3
+
4
+use std::collections::HashMap;
5
+use lazy_static::lazy_static;
6
+use std::sync::Mutex;
7
+
8
+pub struct PolicyType {
9
+
10
+	value: String,
11
+
12
+}
13
+
14
+impl PolicyType {
15
+
16
+	pub fn new(value: String) -> Self {
17
+		PolicyType {
18
+			value: value.to_string(),
19
+		}
20
+	}
21
+
22
+	pub fn new_policy_type_from_uri(uri: URI) -> Self {
23
+		PolicyType::new(uri.value)
24
+	}
25
+
26
+}
27
+
28
+lazy_static! {
29
+	static ref POLICIES: Mutex<HashMap<String, PolicyType>> = {
30
+		let mut map = HashMap::new();
31
+		init_policies();
32
+		Mutex::new(map)
33
+	};
34
+}
35
+
36
+pub fn register_policy_type(value: String, policy_type: PolicyType) {
37
+	POLICIES.lock().unwrap().insert(value, policy_type);
38
+}
39
+
40
+fn init_policies() {
41
+
42
+	/// Policy expressions that consists of entities from the complete model
43
+	/// The Set is aimed at scenarios where there is an open criteria for the semantics of the
44
+	/// policy expressions and typically refined by other systems/profiles that process the
45
+	/// information at a later time. No privileges are granted to any Party.
46
+	register_policy_type("SET".to_string(), PolicyType::new(Vocabulary::create_odrl_vocab_item("set")));
47
+
48
+	/// Policy expressions that propose terms of usage from an Asset owner
49
+	/// Must contain a Party entity with Assigner role. The Offer may contain a Party entity
50
+	/// with Assignee role, but does not grant any privileges to that Party.
51
+	register_policy_type("OFFER".to_string(), PolicyType::new(Vocabulary::create_odrl_vocab_item("offer")));
52
+
53
+	/// Policy expressions that are formal contracts (or licenses) stipulating all the terms of usage and all the parties involved.
54
+	/// Must contain at least the Party entity with Assigner role and a Party with Assignee role.
55
+	/// The latter being granted the terms of the Agreement from the former.
56
+	register_policy_type("AGREEMENT".to_string(), PolicyType::new(Vocabulary::create_odrl_vocab_item("agreement")));
57
+
58
+	/// Policy expressions that propose terms of usage to an Asset owner
59
+	/// Must contain a Party entity with Assignee role. The Request may also contain the Party
60
+	/// entity with Assigner role if this is known. No privileges are granted to any Party.
61
+	register_policy_type("REQUEST".to_string(), PolicyType::new(Vocabulary::create_odrl_vocab_item("request")));
62
+
63
+	/// Policy expressions that stipulate the terms of usage over personal information.
64
+	/// Must contain at least the Party entity with Assigner role and a Party with Assignee role.
65
+	/// Must also contain a Duty on the assignee related to obligations towards managing the
66
+	/// assigner’s Asset containing personal information. The Assignee is being granted the terms
67
+	/// of the Privacy policy from the Assigner.
68
+	register_policy_type("PRIVACY".to_string(), PolicyType::new(Vocabulary::create_odrl_vocab_item("privacy")));
69
+
70
+	/// Policy expressions that stipulate the terms of usage and is redeemable by any Party who currently holds the Ticket in their possession
71
+	/// May contain the Party entity with Assigner role and the Party entity with Assignee role.
72
+	/// A Ticket (or Voucher) may be anonymous or personalised, where the holder of that
73
+	/// Ticket may remain unknown or has to be identified. The holder, or if known, the Assignee,
74
+	/// is being granted the terms of the Ticket from the Assigner (in known).
75
+	register_policy_type("TICKET".to_string(), PolicyType::new(Vocabulary::create_odrl_vocab_item("ticket")));
76
+
77
+}
78
+
79
+pub fn is_policy_type(uri: &URI) -> bool {
80
+	POLICIES.lock().unwrap().contains_key(&uri.value)
81
+}
82
+
83
+pub fn get_policies_values() -> Vec<String> {
84
+	POLICIES.lock().unwrap().keys().map(|k| k.to_string()).collect()
85
+}

+ 74
- 0
src/ODRL/Vocab/ScopeTerm.rs 查看文件

@@ -0,0 +1,74 @@
1
+use crate::ODRL::Vocabulary::Vocabulary;
2
+use crate::datatypes::URI::URI;
3
+
4
+use std::collections::HashMap;
5
+use lazy_static::lazy_static;
6
+use std::sync::Mutex;
7
+
8
+pub struct ScopeTerm {
9
+
10
+	value: String,
11
+
12
+}
13
+
14
+impl ScopeTerm {
15
+
16
+	fn new(value: String) -> Self {
17
+		ScopeTerm {
18
+			value: value.to_string(),
19
+		}
20
+	}
21
+
22
+	fn new_from_uri(uri: URI) -> Self {
23
+		ScopeTerm::new(uri.value)
24
+	}
25
+
26
+}
27
+
28
+lazy_static! {
29
+	static ref SCOPETERMS: Mutex<HashMap<String, ScopeTerm>> = {
30
+		let mut map = HashMap::new();
31
+		init_scope_terms();
32
+		Mutex::new(map)
33
+	};
34
+}
35
+
36
+pub fn register_scope_term(value: String, scopeterm: ScopeTerm) {
37
+	SCOPETERMS.lock().unwrap().insert(value, scopeterm);
38
+}
39
+
40
+/// Terms for the attribute “scope” of the entity Role
41
+fn init_scope_terms() {
42
+
43
+	/* The Party is a single individual
44
+	Must be supported. */
45
+	register_scope_term("INDIVIDUAL".to_string(), ScopeTerm::new(Vocabulary::create_odrl_vocab_item("Individual")));
46
+
47
+	/* The Party represents a defined group with multiple individual members
48
+	Must be supported. */
49
+	register_scope_term("GROUP".to_string(), ScopeTerm::new(Vocabulary::create_odrl_vocab_item("Group")));
50
+
51
+	/* All the collective individuals within a context
52
+	For example, may be used to indicate all the users of a specific social network the party is a member of. Note that “group” scope is also assumed. */
53
+	register_scope_term("ALL".to_string(), ScopeTerm::new(Vocabulary::create_odrl_vocab_item("All")));
54
+
55
+	/* All the first-level connections of the Party
56
+	For example, may be used to indicate all “friends” of the Party. Note that “group” scope is also assumed. */
57
+	register_scope_term("ALL_CONNECTIONS".to_string(), ScopeTerm::new(Vocabulary::create_odrl_vocab_item("AllConnections")));
58
+
59
+	/* All the second-level connections of the Party
60
+	For example, may be used to indicate all “friends of friends” of the Party. Note that “group” scope is also assumed. */
61
+	register_scope_term("ALL_2ND_CONNECTIONS".to_string(), ScopeTerm::new(Vocabulary::create_odrl_vocab_item("All2ndConnections")));
62
+
63
+	/* 	All the group connections of the Party
64
+	For example, may be used to indicate all groups that the Party is a member of. Note that “group” scope is also assumed. */
65
+	register_scope_term("ALL_GROUPS".to_string(), ScopeTerm::new(Vocabulary::create_odrl_vocab_item("AllGroups")));
66
+}
67
+
68
+pub fn is_scope_term(value: String) -> bool {
69
+	SCOPETERMS.lock().unwrap().contains_key(&value)
70
+}
71
+
72
+pub fn get_scope_term_values() -> Vec<String> {
73
+	SCOPETERMS.lock().unwrap().keys().map(|key| key.to_string()).collect()
74
+}

+ 7
- 0
src/ODRL/Vocab/mod.rs 查看文件

@@ -0,0 +1,7 @@
1
+pub mod ActionTerm;
2
+pub mod AssetRelationTerm;
3
+pub mod ConstraintOperator;
4
+pub mod ConstraintTerm;
5
+pub mod FunctionTerm;
6
+pub mod PolicyType;
7
+pub mod ScopeTerm;

+ 32
- 0
src/ODRL/Vocabulary.rs 查看文件

@@ -0,0 +1,32 @@
1
+use crate::datatypes::URI::URI;
2
+
3
+pub struct Vocabulary;
4
+
5
+impl Vocabulary {
6
+
7
+	fn new() -> Self {
8
+		Vocabulary
9
+	}
10
+
11
+	const ODRL_NS: &'static str = "http://www.w3.org/ns/odrl/2/";
12
+
13
+	pub fn create_vocab_identifier(namespace_uri: &str, name: &str) -> String {
14
+		format!("{}{}", namespace_uri, name)
15
+	}
16
+
17
+	/// The URI identifying the ODRL Version 2 Common Vocabulary is defined as:
18
+	///
19
+	///    http://www.w3.org/ns/odrl/2/
20
+	///
21
+	/// This URI must be used in all encodings of ODRL policies to refer to the ODRL Common Vocabulary.
22
+	/// A URI identifying an ODRL Common Vocabulary term is created by appending the identifier of that term to the URI of the vocabulary.
23
+	///
24
+	/// For example, below are the target and play terms:
25
+	///
26
+	///    http://www.w3.org/ns/odrl/2/target
27
+	///    http://www.w3.org/ns/odrl/2/play
28
+	pub fn create_odrl_vocab_item(name: &str) -> String {
29
+		Self::create_vocab_identifier(Self::ODRL_NS, name)
30
+	}
31
+
32
+}

+ 4
- 0
src/ODRL/mod.rs 查看文件

@@ -0,0 +1,4 @@
1
+pub mod JsonParser;
2
+pub mod Serializer;
3
+mod Vocabulary;
4
+mod Vocab;

+ 80
- 0
src/datatypes/URI.rs 查看文件

@@ -0,0 +1,80 @@
1
+use uuid::Uuid;
2
+use url::Url;
3
+
4
+use std::cmp::PartialEq;
5
+use std::str::FromStr;
6
+
7
+#[derive(Eq)]
8
+pub struct URI {
9
+	pub value: String,
10
+	pub is_uri: bool,
11
+}
12
+
13
+impl URI {
14
+	fn new(value: Option<String>) -> Self {
15
+
16
+		let mut uri = URI {
17
+			value: String::new(),
18
+			is_uri: false,
19
+		};
20
+
21
+		if let Some(v) = value {
22
+			uri.value = v;
23
+		}
24
+
25
+		uri
26
+	}
27
+
28
+	fn generate_random() -> Self {
29
+		URI::new(Some(Uuid::new_v4().to_string()))
30
+	}
31
+
32
+	fn check_uri(&mut self) {
33
+		if let Ok(_) = Url::parse(&self.value) {
34
+			self.is_uri = true;
35
+		}
36
+	}
37
+
38
+	pub fn to_string(&self) -> &str {
39
+		&self.value
40
+	}
41
+
42
+	pub fn to_uri(&self) -> Result<Url, DataTypeException> {
43
+		Url::parse(&self.value).map_err(|_| DataTypeException::new("Value is not a valid URI"))
44
+	}
45
+
46
+}
47
+
48
+impl PartialEq for URI {
49
+	fn eq(&self, other: &Self) -> bool {
50
+		self.value == other.value
51
+	}
52
+}
53
+
54
+#[derive(Debug)]
55
+pub struct DataTypeException {
56
+	message: String,
57
+}
58
+
59
+impl DataTypeException {
60
+	fn new(message: &str) -> Self {
61
+		DataTypeException {
62
+			message: message.to_string(),
63
+		}
64
+	}
65
+}
66
+
67
+impl FromStr for URI {
68
+	type Err = DataTypeException;
69
+
70
+	fn from_str(s: &str) -> Result<Self, Self::Err> {
71
+		let mut uri = URI::new(None);
72
+		uri.value = s.to_string();
73
+		uri.check_uri();
74
+
75
+		if !uri.is_uri {
76
+			return Err(DataTypeException::new("Invalid value. Value format must conform to a URI"));
77
+		}
78
+		Ok(uri)
79
+	}
80
+}

+ 1
- 0
src/datatypes/mod.rs 查看文件

@@ -0,0 +1 @@
1
+pub mod URI;

+ 46
- 0
src/main.rs 查看文件

@@ -0,0 +1,46 @@
1
+pub mod NameSpaces;
2
+
3
+mod model {
4
+
5
+    pub mod Action;
6
+    pub mod Asset;
7
+    pub mod ConflictTerm;
8
+    pub mod Constraint;
9
+    pub mod Party;
10
+    pub mod Policy;
11
+    pub mod Rule;
12
+    pub mod TypeAlias;
13
+
14
+}
15
+
16
+mod datatypes {
17
+
18
+    pub mod URI;
19
+
20
+}
21
+
22
+mod ODRL {
23
+
24
+    pub mod JsonParser;
25
+    pub mod Serializer;
26
+    pub mod Vocabulary;
27
+    pub mod Vocab {
28
+        pub mod ActionTerm;
29
+        pub mod AssetRelationTerm;
30
+        pub mod ConstraintOperator;
31
+        pub mod ConstraintTerm;
32
+        pub mod FunctionTerm;
33
+        pub mod PolicyType;
34
+        pub mod ScopeTerm;
35
+    }
36
+
37
+}
38
+
39
+use ODRL::Serializer as ODRLSerializer;
40
+
41
+fn main() {
42
+
43
+    ODRLSerializer::main();
44
+
45
+
46
+}

+ 45
- 0
src/model/Action.rs 查看文件

@@ -0,0 +1,45 @@
1
+use crate::model::Constraint::Constraint;
2
+
3
+#[derive(Debug, Clone)]
4
+pub struct Action {
5
+
6
+    pub name: String,
7
+    pub refinements: Vec<Constraint>,
8
+    pub included_in: Option<Box<Action>>, // Use Box to allow recursive type definition
9
+    pub implies: Vec<Box<Action>>,
10
+
11
+}
12
+
13
+impl Action {
14
+
15
+    pub fn new(name: &str, refinements: Vec<Constraint>, included_in: Option<Action>, implies: Vec<Action>) -> Action {
16
+        Action {
17
+            name: name.to_string(),
18
+            refinements,
19
+            included_in: match included_in {
20
+                Some(action) => Some(Box::new(action)),
21
+                None => None,
22
+            },
23
+            implies: implies.into_iter().map(Box::new).collect(),
24
+        }
25
+    }
26
+
27
+    // Function to create the two top level actions "use" and "transfer"
28
+    pub fn init_top_level() -> (Action, Action) {
29
+        let use_action = Action {
30
+            name: "use".to_string(),
31
+            refinements: vec![],
32
+            included_in: None,
33
+            implies: vec![],
34
+        };
35
+        let transfer_action = Action {
36
+            name: "transfer".to_string(),
37
+            refinements: vec![],
38
+            included_in: None,
39
+            implies: vec![],
40
+        };
41
+
42
+        (use_action, transfer_action)
43
+    }
44
+
45
+}

+ 66
- 0
src/model/Asset.rs 查看文件

@@ -0,0 +1,66 @@
1
+use crate::model::Policy::Policy;
2
+use crate::model::Constraint::Constraint;
3
+use crate::model::TypeAlias::IRI;
4
+
5
+
6
+#[derive(Debug, Clone)]
7
+pub struct Relation {
8
+
9
+    pub target: Option<Box<Asset>>,
10
+
11
+}
12
+
13
+impl Relation {
14
+
15
+    pub fn new(target: Option<Asset>) -> Relation {
16
+        Relation {
17
+            target: match target {
18
+                Some(asset) => Some(Box::new(asset)),
19
+                None => None,
20
+            }
21
+        }
22
+    }
23
+
24
+}
25
+
26
+#[derive(Debug, Clone)]
27
+pub struct AssetCollection {
28
+
29
+    pub source: Option<IRI>,
30
+    pub refinement: Vec<Constraint>,
31
+
32
+}
33
+
34
+impl AssetCollection {
35
+
36
+    pub fn new(source: Option<IRI>, refinement: Vec<Constraint>) -> AssetCollection {
37
+        AssetCollection {
38
+            source,
39
+            refinement,
40
+        }
41
+    }
42
+
43
+}
44
+
45
+#[derive(Debug, Clone)]
46
+pub struct Asset {
47
+
48
+    pub uid: Option<IRI>,
49
+    pub part_of: Vec<AssetCollection>,
50
+    pub relation: Relation,
51
+    pub has_policy: Option<Policy>, // Target Policy Property
52
+
53
+}
54
+
55
+impl Asset {
56
+
57
+    pub fn new(uid: Option<IRI>, part_of: Vec<AssetCollection>, relation: Relation, has_policy: Option<Policy>) -> Asset {
58
+        Asset {
59
+            uid,
60
+            part_of,
61
+            relation,
62
+            has_policy
63
+        }
64
+    }
65
+
66
+}

+ 9
- 0
src/model/ConflictTerm.rs 查看文件

@@ -0,0 +1,9 @@
1
+#[derive(Debug, PartialEq, Eq, Clone)]
2
+pub enum ConflictTerm {
3
+
4
+    Perm,
5
+    Prohibit,
6
+    Invalid,
7
+
8
+}
9
+

+ 99
- 0
src/model/Constraint.rs 查看文件

@@ -0,0 +1,99 @@
1
+use crate::model::TypeAlias::IRI;
2
+
3
+#[derive(Debug, Clone)]
4
+pub enum LeftOperand {
5
+
6
+    Literal(String),
7
+    IRI(IRI),
8
+    Reference(IRI),
9
+
10
+}
11
+
12
+#[derive(Debug, Clone)]
13
+pub enum Operator {
14
+
15
+    Equal,
16
+    NotEqual,
17
+    GreaterThan,
18
+    LessThan,
19
+    GreaterThanOrEqual,
20
+    LessThanOrEqual,
21
+
22
+}
23
+
24
+#[derive(Debug, Clone)]
25
+pub enum RightOperand {
26
+
27
+    Literal(String),
28
+    IRI(IRI),
29
+    Reference(IRI),
30
+
31
+}
32
+
33
+#[derive(Debug, Clone)]
34
+pub struct Constraint {
35
+
36
+    pub uid: Option<IRI>,
37
+    pub left_operand: LeftOperand,
38
+    pub operator: Operator,
39
+    pub right_operand: Option<RightOperand>,
40
+    pub data_type: Option<IRI>,
41
+    pub unit: Option<IRI>,
42
+    pub status: Option<IRI>,
43
+
44
+}
45
+
46
+impl Constraint {
47
+
48
+    pub fn new(
49
+        uid: Option<IRI>,
50
+        left_operand: LeftOperand,
51
+        operator: Operator,
52
+        right_operand: Option<RightOperand>,
53
+        data_type: Option<IRI>,
54
+        unit: Option<IRI>,
55
+        status: Option<IRI>,
56
+    ) -> Constraint {
57
+
58
+        Constraint {
59
+            uid,
60
+            left_operand,
61
+            operator,
62
+            right_operand,
63
+            data_type,
64
+            unit,
65
+            status,
66
+        }
67
+    }
68
+
69
+}
70
+
71
+#[derive(Debug, Clone)]
72
+pub enum LogicalOperator {
73
+
74
+    Or, // at least one of the Constraints MUST be satisfied
75
+    Xone, // only one, and not more, of the Constraints MUST be satisfied
76
+    And, // all of the Constraints MUST be satisfied
77
+    AndSequence, // all of the Constraints - in sequence - MUST be satisfied
78
+    // Add other logical operators as needed
79
+}
80
+
81
+#[derive(Debug, Clone)]
82
+pub struct LogicalConstraint {
83
+
84
+    pub uid: Option<IRI>,
85
+    pub operand: Option<(LogicalOperator, Vec<Constraint>)>,
86
+
87
+}
88
+
89
+impl LogicalConstraint {
90
+
91
+
92
+    pub fn new(uid: Option<IRI>, operand: Option<(LogicalOperator, Vec<Constraint>)>) -> LogicalConstraint {
93
+        LogicalConstraint {
94
+            uid,
95
+            operand
96
+        }
97
+    }
98
+
99
+}

+ 52
- 0
src/model/Party.rs 查看文件

@@ -0,0 +1,52 @@
1
+use crate::model::Constraint::Constraint;
2
+use crate::model::TypeAlias::IRI;
3
+
4
+
5
+#[derive(Debug, Clone)]
6
+pub struct Function {
7
+
8
+    pub assigner: Option<Box<Party>>,
9
+    pub assignee: Option<Box<Party>>,
10
+
11
+}
12
+
13
+#[derive(Debug, Clone)]
14
+pub struct Party {
15
+
16
+    pub uid: Option<IRI>,
17
+    pub part_of: Vec<PartyCollection>,
18
+    pub function: Function,
19
+
20
+}
21
+
22
+impl Party {
23
+
24
+    pub fn new(uid: Option<IRI>, part_of: Vec<PartyCollection>, function: Function) -> Party {
25
+        Party {
26
+            uid,
27
+            part_of,
28
+            function
29
+        }
30
+    }
31
+
32
+}
33
+
34
+
35
+#[derive(Debug, Clone)]
36
+pub struct PartyCollection {
37
+
38
+    pub source: Option<IRI>,
39
+    pub refinement: Vec<Constraint>,
40
+
41
+}
42
+
43
+impl PartyCollection {
44
+
45
+    pub fn new(source: Option<IRI>, refinement: Vec<Constraint>) -> PartyCollection {
46
+        PartyCollection {
47
+            source,
48
+            refinement
49
+        }
50
+    }
51
+
52
+}

+ 122
- 0
src/model/Policy.rs 查看文件

@@ -0,0 +1,122 @@
1
+use crate::model::Party::Party;
2
+use crate::model::Rule::*;
3
+use crate::model::ConflictTerm::ConflictTerm;
4
+use crate::model::Action::Action;
5
+use crate::model::TypeAlias::IRI;
6
+
7
+
8
+// A Policy MAY include an obligation to fulfil a Duty. The obligation is fulfilled if all constraints are satisfied and if its action, with all refinements satisfied, has been exercised.
9
+#[derive(Debug, Clone)]
10
+pub struct Obligation {
11
+
12
+    pub assigner: Party,
13
+    pub assignee: Party,
14
+    pub action: Action,
15
+    pub consequence: Vec<Duty>,
16
+
17
+}
18
+
19
+/// Default Policy of type Set
20
+#[derive(Debug, Clone)]
21
+pub struct SetPolicy {
22
+
23
+    pub uid: IRI,
24
+    pub rules: Vec<Rule>,
25
+    pub profiles: Vec<IRI>,
26
+    pub inherit_from: Vec<IRI>,
27
+    pub conflict: Option<ConflictTerm>,
28
+    pub obligation: Option<Vec<Obligation>>,
29
+
30
+}
31
+
32
+impl SetPolicy {
33
+
34
+    pub fn new(uid: IRI, rules: Vec<Rule>, profiles: Vec<IRI>, inherit_from: Vec<IRI>, conflict: Option<ConflictTerm>, obligation: Option<Vec<Obligation>>) -> Self {
35
+        SetPolicy {
36
+            uid,
37
+            rules,
38
+            profiles,
39
+            inherit_from,
40
+            conflict,
41
+            obligation
42
+        }
43
+    }
44
+
45
+}
46
+
47
+#[derive(Debug, Clone)]
48
+pub struct OfferPolicy {
49
+
50
+    pub uid: IRI,
51
+    pub assigner: Party,
52
+    pub rules: Vec<Rule>,
53
+    pub profiles: Vec<IRI>,
54
+    pub inherit_from: Vec<IRI>,
55
+    pub conflict: Option<ConflictTerm>,
56
+    pub obligation: Option<Vec<Obligation>>
57
+
58
+}
59
+
60
+impl OfferPolicy {
61
+
62
+    pub fn new(uid: IRI, assigner: Party, rules: Vec<Rule>, profiles: Vec<IRI>, inherit_from: Vec<IRI>, conflict: Option<ConflictTerm>, obligation: Option<Vec<Obligation>>) -> Self {
63
+        OfferPolicy {
64
+            uid,
65
+            assigner,
66
+            rules,
67
+            profiles,
68
+            inherit_from,
69
+            conflict,
70
+            obligation
71
+        }
72
+    }
73
+
74
+}
75
+
76
+#[derive(Debug, Clone)]
77
+pub struct AgreementPolicy {
78
+
79
+    pub uid: IRI,
80
+    pub assigner: Party,
81
+    pub assignee: Party,
82
+    pub rules: Vec<Rule>,
83
+    pub profiles: Vec<IRI>,
84
+    pub inherit_from: Vec<IRI>,
85
+    pub conflict: Option<ConflictTerm>,
86
+    pub obligation: Option<Vec<Obligation>>
87
+
88
+}
89
+
90
+impl AgreementPolicy {
91
+
92
+    pub fn new(uid: IRI, assigner: Party, assignee: Party, rules: Vec<Rule>, profiles: Vec<IRI>, inherit_from: Vec<IRI>, conflict: Option<ConflictTerm>, obligation: Option<Vec<Obligation>>) -> Self {
93
+        AgreementPolicy {
94
+            uid,
95
+            assigner,
96
+            assignee,
97
+            rules,
98
+            profiles,
99
+            inherit_from,
100
+            conflict,
101
+            obligation
102
+        }
103
+    }
104
+
105
+}
106
+
107
+
108
+#[derive(Debug, Clone)]
109
+pub enum Policy {
110
+
111
+    SetPolicy(SetPolicy),
112
+    OfferPolicy(OfferPolicy),
113
+    AgreementPolicy(AgreementPolicy),
114
+
115
+}
116
+
117
+impl Default for Policy {
118
+    fn default() -> Self {
119
+        // Default to SetPolicy
120
+        Policy::SetPolicy(SetPolicy::new("default_policy".to_string(), vec![], vec![], vec![], None, None))
121
+    }
122
+}

+ 153
- 0
src/model/Rule.rs 查看文件

@@ -0,0 +1,153 @@
1
+use crate::model::Action::Action;
2
+use crate::model::Asset::Asset;
3
+use crate::model::Party::Party;
4
+use crate::model::Constraint::Constraint;
5
+use crate::model::TypeAlias::IRI;
6
+
7
+
8
+#[derive(Debug, Clone)]
9
+pub enum Rule {
10
+
11
+    Permission(Permission),
12
+    Prohibition(Prohibition),
13
+    Duty(Duty),
14
+
15
+}
16
+
17
+
18
+#[derive(Debug, Clone)]
19
+pub struct Permission {
20
+
21
+    pub uid: Option<IRI>,
22
+    pub action: Action,
23
+    pub relation: Option<Asset>,
24
+    pub function: Vec<Party>,
25
+    pub failures: Vec<Rule>,
26
+    pub constraints: Vec<Constraint>,
27
+
28
+    pub target: Asset,
29
+    pub assigner: Option<Party>,
30
+    pub assignee: Option<Party>,
31
+    pub duties: Vec<Duty>,
32
+
33
+}
34
+
35
+impl Permission {
36
+
37
+    pub fn new(uid: Option<IRI>, action: Action, relation: Option<Asset>, function: Vec<Party>, failures: Vec<Rule>, constraints: Vec<Constraint>, target: Asset, assigner: Option<Party>, assignee: Option<Party>, duties: Vec<Duty>) -> Self {
38
+        Permission {
39
+            uid,
40
+            action,
41
+            relation,
42
+            function,
43
+            failures,
44
+            constraints,
45
+            target,
46
+            assigner,
47
+            assignee,
48
+            duties
49
+        }
50
+    }
51
+
52
+}
53
+
54
+
55
+#[derive(Debug, Clone)]
56
+pub struct Prohibition {
57
+
58
+    pub uid: Option<IRI>,
59
+    pub action: Action,
60
+    pub relation: Option<Asset>,
61
+    pub function: Vec<Party>,
62
+    pub failures: Vec<Rule>,
63
+    pub constraints: Vec<Constraint>,
64
+
65
+    pub target: Asset,
66
+    pub assigner: Option<Party>,
67
+    pub assignee: Option<Party>,
68
+    pub remedies: Vec<Duty>,
69
+
70
+}
71
+
72
+impl Prohibition {
73
+
74
+    pub fn new(uid: Option<IRI>, action: Action, relation: Option<Asset>, function: Vec<Party>, failures: Vec<Rule>, constraints: Vec<Constraint>, target: Asset, assigner: Option<Party>, assignee: Option<Party>, remedies: Vec<Duty>) -> Self {
75
+        Prohibition {
76
+            uid,
77
+            action,
78
+            relation,
79
+            function,
80
+            failures,
81
+            constraints,
82
+            target,
83
+            assigner,
84
+            assignee,
85
+            remedies
86
+        }
87
+    }
88
+}
89
+
90
+
91
+#[derive(Debug, Clone)]
92
+pub struct Duty {
93
+
94
+    pub uid: Option<IRI>,
95
+    pub action: Action,
96
+    pub relation: Option<Asset>,
97
+    pub failures: Vec<Rule>,
98
+    pub constraints: Vec<Constraint>,
99
+
100
+    pub target: Option<Asset>,
101
+    pub assigner: Option<Party>,
102
+    pub assignee: Option<Party>,
103
+    pub consequences: Vec<Duty>,
104
+    pub pre_condition: Option<Vec<Duty>>,
105
+    pub function: Option<Vec<Party>>,
106
+
107
+}
108
+
109
+impl Duty {
110
+
111
+    pub fn new(uid: Option<IRI>, action: Action, relation: Option<Asset>, failures: Vec<Rule>, constraints: Vec<Constraint>, target: Option<Asset>, assigner: Option<Party>, assignee: Option<Party>, consequences: Vec<Duty>, pre_condition: Option<Vec<Duty>>, function: Option<Vec<Party>>) -> Self {
112
+        Duty {
113
+            uid,
114
+            action,
115
+            relation,
116
+            failures,
117
+            constraints,
118
+            target,
119
+            assigner,
120
+            assignee,
121
+            consequences,
122
+            pre_condition,
123
+            function
124
+        }
125
+    }
126
+
127
+}
128
+
129
+
130
+#[derive(Debug, Clone)]
131
+pub struct Agreement {
132
+    uid: IRI,
133
+    profile: IRI,
134
+    conflict: Option<String>,
135
+    permission: Option<Vec<Permission>>,
136
+    prohibition: Option<Vec<Prohibition>>,
137
+    // Add other properties specific to Agreement as needed
138
+}
139
+
140
+impl Agreement {
141
+
142
+    pub fn new(uid: IRI, profile: IRI, conflict: Option<String>, permission: Option<Vec<Permission>>, prohibition: Option<Vec<Prohibition>>) -> Self {
143
+        Agreement {
144
+            uid,
145
+            profile,
146
+            conflict,
147
+            permission,
148
+            prohibition,
149
+        }
150
+    }
151
+
152
+}
153
+

+ 1
- 0
src/model/TypeAlias.rs 查看文件

@@ -0,0 +1 @@
1
+pub type IRI = String;

+ 8
- 0
src/model/mod.rs 查看文件

@@ -0,0 +1,8 @@
1
+pub mod Action;
2
+pub mod Asset;
3
+pub mod ConflictTerm;
4
+pub mod Constraint;
5
+pub mod Party;
6
+pub mod Policy;
7
+pub mod Rule;
8
+pub mod TypeAlias;