odrl-ruby 0.1.6 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +57 -3
- data/examples/biohackathon-output.ttl +34 -18
- data/examples/build_profile.rb +47 -0
- data/examples/create-nagoya-es-offer.rb +22 -22
- data/examples/nagoya-output.ttl +14 -14
- data/lib/odrl/base.rb +192 -185
- data/lib/odrl/constraint.rb +6 -1
- data/lib/odrl/odrl/version.rb +1 -1
- data/lib/odrl/party.rb +27 -17
- data/lib/odrl/policy.rb +17 -1
- data/lib/odrl/profile/builder.rb +185 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63cb1e71b635624b49a5ed95f438db8c1dbd93210f454be4d88f1227b487874f
|
4
|
+
data.tar.gz: 40fa678545058fca0b73de3a89d4c379ae6487c0f7a8a4e778f4642b7250723e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: adc87311982d35fafffc09e54afcadf88ec41e89f5acf6c2925cf346f3f871293b5fcff62c8928a64fdbaec240ee5279336eaacafedfc50c52cea965f65ff0c1
|
7
|
+
data.tar.gz: 4438e55d750c5792de355aedd3c991506b6446419c031c492dd2eec7c819af81dce00075524b7400af504469248e095e6b2378d44380f4e92f76786ee046407f
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
# THIS IS BARELY READY FOR USE! DON'T EXPECT MIRACLES
|
2
|
-
|
3
1
|
# ODRL::Ruby
|
4
2
|
|
5
|
-
This is a gem to build ODRL records, and serialize them
|
3
|
+
This is a gem to build ODRL records, and serialize them. Does not cover the full ODRL model (yet!)
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -22,6 +20,10 @@ Or install it yourself as:
|
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
23
|
+
# Two functionalities: Build ODRL Policies; Build ODRL Profiles to extend the core ODRL vocabulary
|
24
|
+
|
25
|
+
# Build Policy:
|
26
|
+
|
25
27
|
```
|
26
28
|
require 'odrl/ruby'
|
27
29
|
|
@@ -67,6 +69,58 @@ result = policy.serialize(format: 'turtle') # get the RDF string
|
|
67
69
|
puts result
|
68
70
|
```
|
69
71
|
|
72
|
+
# Build Profile:
|
73
|
+
|
74
|
+
```
|
75
|
+
require 'odrl/profile/builder'
|
76
|
+
|
77
|
+
p = ODRL::Profile::Builder.new(
|
78
|
+
uri: 'https://example.org/myprofiles/germplasm_odrl_profile.ttl',
|
79
|
+
title: "ODRL Profile for Germplasm resources",
|
80
|
+
description: "There are some properties and comparisons that only make sense in the Germplasm expert domain",
|
81
|
+
author: "Mark D Wilkinson",
|
82
|
+
profile_class: "https://example.org/myprofiles/ontology#SeedOffer"
|
83
|
+
)
|
84
|
+
|
85
|
+
p.asset_relations << ODRL::Profile::AssetRelation.new(
|
86
|
+
uri: "https://example.org/myprofiles/ontology#nagoya_permission",
|
87
|
+
label: "Permission under Nagoya protocol",
|
88
|
+
definition: "Permission is a special thing in the Nagoya protocol")
|
89
|
+
|
90
|
+
|
91
|
+
p.party_functional_roles << ODRL::Profile::AssetRelation.new(
|
92
|
+
uri: "https://example.org/myprofiles/ontology#nagoya_assigner",
|
93
|
+
label: "Assigner with Nagoya authority to assign",
|
94
|
+
definition: "Assigners have special responsibilities in the Nagoya protocol")
|
95
|
+
|
96
|
+
p.actions << ODRL::Profile::Rule.new(
|
97
|
+
uri: "https://example.org/myprofiles/ontology#nagoya_propogate",
|
98
|
+
label: "Plant and Harvest",
|
99
|
+
definition: "the action of planting and harvesting the seed",
|
100
|
+
included_in: ODRLV.use,
|
101
|
+
implies: ODRLV.distribute)
|
102
|
+
|
103
|
+
|
104
|
+
p.leftOperands << ODRL::Profile::LeftOperand.new(
|
105
|
+
uri: "https://example.org/myprofiles/ontology#at_risk_species",
|
106
|
+
label: "At Risk Species",
|
107
|
+
definition: "A species that has been flagged as at-risk of extinction")
|
108
|
+
|
109
|
+
p.rightOperands << ODRL::Profile::RightOperand.new(
|
110
|
+
uri: "https://example.org/myprofiles/ontology#on_watchlist",
|
111
|
+
label: "On Watchlist",
|
112
|
+
definition: "A species whose risk of extinction is on a watchlist")
|
113
|
+
|
114
|
+
p.rightOperands << ODRL::Profile::Relation.new(
|
115
|
+
uri: "https://example.org/myprofiles/ontology#within_risk_boundary",
|
116
|
+
label: "Within Bounds",
|
117
|
+
definition: "comparison of risk boundaries")
|
118
|
+
|
119
|
+
|
120
|
+
p.build()
|
121
|
+
puts p.serialize
|
122
|
+
```
|
123
|
+
|
70
124
|
|
71
125
|
## License
|
72
126
|
|
@@ -1,47 +1,63 @@
|
|
1
1
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
2
2
|
|
3
|
-
<http://example.org#
|
4
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#
|
5
|
-
a <http://www.w3.org/ns/odrl/2/Action> .
|
6
|
-
|
7
|
-
<http://example.org#constraint_68785487525880>
|
8
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#constraint_68785487525880> ;
|
3
|
+
<http://example.org#constraint_68811358965684>
|
4
|
+
<http://purl.org/dc/terms/identifier> <http://example.org#constraint_68811358965684> ;
|
9
5
|
<http://purl.org/dc/terms/title> "Only during the hackathon"@en ;
|
10
6
|
a <http://www.w3.org/ns/odrl/2/Constraint> ;
|
7
|
+
<http://www.w3.org/2000/01/rdf-schema#label> "Only during the hackathon"@en ;
|
11
8
|
<http://www.w3.org/ns/odrl/2/leftOperand> <http://www.w3.org/ns/odrl/2/event> ;
|
12
9
|
<http://www.w3.org/ns/odrl/2/operator> <http://www.w3.org/ns/odrl/2/eq> ;
|
13
|
-
<http://www.w3.org/ns/odrl/2/rightOperand> <https://2023.biohackathon.org>
|
10
|
+
<http://www.w3.org/ns/odrl/2/rightOperand> <https://2023.biohackathon.org> ;
|
11
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#constraint_68811358965684> .
|
14
12
|
|
15
|
-
<http://example.org#
|
13
|
+
<http://example.org#policy_68811358965627>
|
16
14
|
<http://purl.org/dc/terms/creator> <https://orcid.org/0000-0001-6960-357X> ;
|
17
15
|
<http://purl.org/dc/terms/description> "An offer for Toshiaki-san to use the polyA data during the hackathon"@en ;
|
18
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#
|
16
|
+
<http://purl.org/dc/terms/identifier> <http://example.org#policy_68811358965627> ;
|
19
17
|
<http://purl.org/dc/terms/subject> "collaboration"@en ;
|
20
18
|
<http://purl.org/dc/terms/title> "Offer to Toshiaki-san"@en ;
|
21
19
|
a <http://www.w3.org/ns/odrl/2/Offer> ;
|
22
|
-
<http://www.w3.org/
|
20
|
+
<http://www.w3.org/2000/01/rdf-schema#label> "Offer to Toshiaki-san"@en ;
|
21
|
+
<http://www.w3.org/ns/odrl/2/permission> <http://example.org#rule_68811358965667> ;
|
22
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#policy_68811358965627> .
|
23
23
|
|
24
|
-
<http://example.org#
|
25
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#
|
24
|
+
<http://example.org#rule_68811358965667>
|
25
|
+
<http://purl.org/dc/terms/identifier> <http://example.org#rule_68811358965667> ;
|
26
26
|
<http://purl.org/dc/terms/title> "Permission to use"@en ;
|
27
27
|
a <http://www.w3.org/ns/odrl/2/Permission> ;
|
28
|
-
<http://www.w3.org/
|
28
|
+
<http://www.w3.org/2000/01/rdf-schema#label> "Permission to use"@en ;
|
29
|
+
<http://www.w3.org/ns/odrl/2/action> <http://www.w3.org/ns/odrl/2/use> ;
|
29
30
|
<http://www.w3.org/ns/odrl/2/assignee> <https://orcid.org/0000-0001-6960-357X> ;
|
30
31
|
<http://www.w3.org/ns/odrl/2/assigner> <https://orcid.org/0000-0003-2391-0384> ;
|
31
|
-
<http://www.w3.org/ns/odrl/2/constraint> <http://example.org#
|
32
|
-
<http://www.w3.org/ns/odrl/2/target> <http://mark.wilkinson.org/data/polyA>
|
32
|
+
<http://www.w3.org/ns/odrl/2/constraint> <http://example.org#constraint_68811358965684> ;
|
33
|
+
<http://www.w3.org/ns/odrl/2/target> <http://mark.wilkinson.org/data/polyA> ;
|
34
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#rule_68811358965667> .
|
33
35
|
|
34
36
|
<http://mark.wilkinson.org/data/polyA>
|
35
37
|
<http://purl.org/dc/terms/identifier> <http://mark.wilkinson.org/data/polyA> ;
|
36
38
|
<http://purl.org/dc/terms/title> "Mark's PolyA Database"@en ;
|
37
|
-
a <http://www.w3.org/ns/odrl/2/Asset>
|
39
|
+
a <http://www.w3.org/ns/odrl/2/Asset> ;
|
40
|
+
<http://www.w3.org/2000/01/rdf-schema#label> "Mark's PolyA Database"@en ;
|
41
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://mark.wilkinson.org/data/polyA> .
|
42
|
+
|
43
|
+
<http://www.w3.org/ns/odrl/2/use>
|
44
|
+
<http://purl.org/dc/terms/identifier> <http://www.w3.org/ns/odrl/2/use> ;
|
45
|
+
a "type"@en ;
|
46
|
+
<http://www.w3.org/2000/01/rdf-schema#label> ""@en ;
|
47
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://www.w3.org/ns/odrl/2/use> ;
|
48
|
+
<https://schema.org/name> ""@en .
|
38
49
|
|
39
50
|
<https://orcid.org/0000-0001-6960-357X>
|
40
51
|
<http://purl.org/dc/terms/identifier> <https://orcid.org/0000-0001-6960-357X> ;
|
41
52
|
<http://purl.org/dc/terms/title> "Mark D Wilkinson"@en ;
|
42
|
-
a <http://www.w3.org/ns/odrl/2/Party>
|
53
|
+
a <http://www.w3.org/ns/odrl/2/Party> ;
|
54
|
+
<http://www.w3.org/2000/01/rdf-schema#label> "Mark D Wilkinson"@en ;
|
55
|
+
<http://www.w3.org/ns/odrl/2/uid> <https://orcid.org/0000-0001-6960-357X> .
|
43
56
|
|
44
57
|
<https://orcid.org/0000-0003-2391-0384>
|
45
58
|
<http://purl.org/dc/terms/identifier> <https://orcid.org/0000-0003-2391-0384> ;
|
46
59
|
<http://purl.org/dc/terms/title> "Toshiaki Katayama"@en ;
|
47
|
-
a <http://www.w3.org/ns/odrl/2/Party>
|
60
|
+
a <http://www.w3.org/ns/odrl/2/Party> ;
|
61
|
+
<http://www.w3.org/2000/01/rdf-schema#label> "Toshiaki Katayama"@en ;
|
62
|
+
<http://www.w3.org/ns/odrl/2/uid> <https://orcid.org/0000-0003-2391-0384> .
|
63
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'odrl/profile/builder'
|
2
|
+
|
3
|
+
p = ODRL::Profile::Builder.new(
|
4
|
+
uri: 'https://example.org/myprofiles/germplasm_odrl_profile.ttl',
|
5
|
+
title: "ODRL Profile for Germplasm resources",
|
6
|
+
description: "There are some properties and comparisons that only make sense in the Germplasm expert domain",
|
7
|
+
author: "Mark D Wilkinson",
|
8
|
+
profile_class: "https://example.org/myprofiles/ontology#SeedOffer"
|
9
|
+
)
|
10
|
+
|
11
|
+
p.asset_relations << ODRL::Profile::AssetRelation.new(
|
12
|
+
uri: "https://example.org/myprofiles/ontology#nagoya_permission",
|
13
|
+
label: "Permission under Nagoya protocol",
|
14
|
+
definition: "Permission is a special thing in the Nagoya protocol")
|
15
|
+
|
16
|
+
|
17
|
+
p.party_functional_roles << ODRL::Profile::AssetRelation.new(
|
18
|
+
uri: "https://example.org/myprofiles/ontology#nagoya_assigner",
|
19
|
+
label: "Assigner with Nagoya authority to assign",
|
20
|
+
definition: "Assigners have special responsibilities in the Nagoya protocol")
|
21
|
+
|
22
|
+
p.actions << ODRL::Profile::Rule.new(
|
23
|
+
uri: "https://example.org/myprofiles/ontology#nagoya_propogate",
|
24
|
+
label: "Plant and Harvest",
|
25
|
+
definition: "the action of planting and harvesting the seed",
|
26
|
+
included_in: ODRLV.use,
|
27
|
+
implies: ODRLV.distribute)
|
28
|
+
|
29
|
+
|
30
|
+
p.leftOperands << ODRL::Profile::LeftOperand.new(
|
31
|
+
uri: "https://example.org/myprofiles/ontology#at_risk_species",
|
32
|
+
label: "At Risk Species",
|
33
|
+
definition: "A species that has been flagged as at-risk of extinction")
|
34
|
+
|
35
|
+
p.rightOperands << ODRL::Profile::RightOperand.new(
|
36
|
+
uri: "https://example.org/myprofiles/ontology#on_watchlist",
|
37
|
+
label: "On Watchlist",
|
38
|
+
definition: "A species whose risk of extinction is on a watchlist")
|
39
|
+
|
40
|
+
p.rightOperands << ODRL::Profile::Relation.new(
|
41
|
+
uri: "https://example.org/myprofiles/ontology#within_risk_boundary",
|
42
|
+
label: "Within Bounds",
|
43
|
+
definition: "comparison of risk boundaries")
|
44
|
+
|
45
|
+
|
46
|
+
p.build()
|
47
|
+
puts p.serialize
|
@@ -1,26 +1,27 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require "odrl/ruby"
|
3
2
|
|
4
3
|
# an offer to toshiaki from mark to use the polyA resource during the biohackathon
|
5
4
|
|
6
5
|
# core annotatons are: :title, :creator, :description, :subject :baseURI, :uid, :type
|
7
6
|
policy = ODRL::Offer.new(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
title: "Offer for the use of BGV Germplasm",
|
8
|
+
creator: "https://orcid.org/0000-0001-6960-357X",
|
9
|
+
description: "An offer any non-Commercial entity to use Germplasm from the BGV - UPM",
|
10
|
+
subject: "nagoya-constraint", # this is a tag
|
11
|
+
issued: "2022-06-29"
|
13
12
|
)
|
14
13
|
|
15
|
-
asset = ODRL::Asset.new(uid: "https://fdp.bgv.cbgp.upm.es/dataset/65ffbf3d-bed1-4a9a-abf9-0116cc35b40a",
|
14
|
+
asset = ODRL::Asset.new(uid: "https://fdp.bgv.cbgp.upm.es/dataset/65ffbf3d-bed1-4a9a-abf9-0116cc35b40a",
|
15
|
+
title: "César Gómez Campo Banco de Germoplasma Vegetal de la UPM")
|
16
16
|
|
17
17
|
# you indicate the type of party by assigning the predicate (either assigner or assignee)
|
18
18
|
# ODRLV is the RDF::Vocabulary for ODRL, exported to this namespace
|
19
19
|
ministerio = ODRL::Party.new(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
uid: "https://absch.cbd.int/en/database/CON/ABSCH-CON-ES-241810/2",
|
21
|
+
predicate: ODRLV.assigner,
|
22
|
+
title: " Ministerio para la Transición Ecológica y el Reto Demográfico",
|
23
|
+
label: " Ministerio para la Transición Ecológica y el Reto Demográfico"
|
24
|
+
)
|
24
25
|
|
25
26
|
# Rules
|
26
27
|
permission = ODRL::Permission.new(title: "Permission to use")
|
@@ -29,16 +30,16 @@ use = ODRL::Use.new(value: "use") # subclass of action
|
|
29
30
|
|
30
31
|
# Constraints: :uid, :rightOperand, :leftOperand, :operator, :rightOperandReference, :dataType, :unit, :status
|
31
32
|
constraint_nonprofit = ODRL::Constraint.new(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
title: "Use by non-profit organization",
|
34
|
+
leftOperand: "industry",
|
35
|
+
operator: "neq",
|
36
|
+
rightOperand: "https://w3id.org/dingo#ForProfitOrganisation"
|
36
37
|
)
|
37
38
|
constraint_noncommercial = ODRL::Constraint.new(
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
title: "Use for non-commercial purposes",
|
40
|
+
leftOperand: "purpose",
|
41
|
+
operator: "neq",
|
42
|
+
rightOperand: "http://purl.obolibrary.org/obo/ExO_0000085"
|
42
43
|
)
|
43
44
|
permission.addConstraint(constraint: constraint_nonprofit)
|
44
45
|
permission.addConstraint(constraint: constraint_noncommercial)
|
@@ -49,6 +50,5 @@ permission.addAction(action: use)
|
|
49
50
|
policy.addPermission(rule: permission)
|
50
51
|
|
51
52
|
policy.load_graph
|
52
|
-
result = policy.serialize(format:
|
53
|
+
result = policy.serialize(format: "turtle")
|
53
54
|
puts result
|
54
|
-
|
data/examples/nagoya-output.ttl
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
2
2
|
|
3
|
-
<http://example.org#
|
4
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#
|
3
|
+
<http://example.org#constraint_68801650224698>
|
4
|
+
<http://purl.org/dc/terms/identifier> <http://example.org#constraint_68801650224698> ;
|
5
5
|
<http://purl.org/dc/terms/title> "Use by non-profit organization"@en ;
|
6
6
|
a <http://www.w3.org/ns/odrl/2/Constraint> ;
|
7
7
|
<http://www.w3.org/2000/01/rdf-schema#label> "Use by non-profit organization"@en ;
|
8
8
|
<http://www.w3.org/ns/odrl/2/leftOperand> <http://www.w3.org/ns/odrl/2/industry> ;
|
9
9
|
<http://www.w3.org/ns/odrl/2/operator> <http://www.w3.org/ns/odrl/2/neq> ;
|
10
10
|
<http://www.w3.org/ns/odrl/2/rightOperand> <https://w3id.org/dingo#ForProfitOrganisation> ;
|
11
|
-
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#
|
11
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#constraint_68801650224698> .
|
12
12
|
|
13
|
-
<http://example.org#
|
14
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#
|
13
|
+
<http://example.org#constraint_68801650224712>
|
14
|
+
<http://purl.org/dc/terms/identifier> <http://example.org#constraint_68801650224712> ;
|
15
15
|
<http://purl.org/dc/terms/title> "Use for non-commercial purposes"@en ;
|
16
16
|
a <http://www.w3.org/ns/odrl/2/Constraint> ;
|
17
17
|
<http://www.w3.org/2000/01/rdf-schema#label> "Use for non-commercial purposes"@en ;
|
18
18
|
<http://www.w3.org/ns/odrl/2/leftOperand> <http://www.w3.org/ns/odrl/2/purpose> ;
|
19
19
|
<http://www.w3.org/ns/odrl/2/operator> <http://www.w3.org/ns/odrl/2/neq> ;
|
20
20
|
<http://www.w3.org/ns/odrl/2/rightOperand> <http://purl.obolibrary.org/obo/ExO_0000085> ;
|
21
|
-
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#
|
21
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#constraint_68801650224712> .
|
22
22
|
|
23
|
-
<http://example.org#
|
23
|
+
<http://example.org#policy_68801650224632>
|
24
24
|
<http://purl.org/dc/terms/creator> <https://orcid.org/0000-0001-6960-357X> ;
|
25
25
|
<http://purl.org/dc/terms/description> "An offer any non-Commercial entity to use Germplasm from the BGV - UPM"@en ;
|
26
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#
|
26
|
+
<http://purl.org/dc/terms/identifier> <http://example.org#policy_68801650224632> ;
|
27
27
|
<http://purl.org/dc/terms/issued> "2022-06-29"@en ;
|
28
28
|
<http://purl.org/dc/terms/subject> "nagoya-constraint"@en ;
|
29
29
|
<http://purl.org/dc/terms/title> "Offer for the use of BGV Germplasm"@en ;
|
30
30
|
a <http://www.w3.org/ns/odrl/2/Offer> ;
|
31
31
|
<http://www.w3.org/2000/01/rdf-schema#label> "Offer for the use of BGV Germplasm"@en ;
|
32
|
-
<http://www.w3.org/ns/odrl/2/permission> <http://example.org#
|
33
|
-
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#
|
32
|
+
<http://www.w3.org/ns/odrl/2/permission> <http://example.org#rule_68801650224680> ;
|
33
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#policy_68801650224632> .
|
34
34
|
|
35
|
-
<http://example.org#
|
36
|
-
<http://purl.org/dc/terms/identifier> <http://example.org#
|
35
|
+
<http://example.org#rule_68801650224680>
|
36
|
+
<http://purl.org/dc/terms/identifier> <http://example.org#rule_68801650224680> ;
|
37
37
|
<http://purl.org/dc/terms/title> "Permission to use"@en ;
|
38
38
|
a <http://www.w3.org/ns/odrl/2/Permission> ;
|
39
39
|
<http://www.w3.org/2000/01/rdf-schema#label> "Permission to use"@en ;
|
40
40
|
<http://www.w3.org/ns/odrl/2/action> <http://www.w3.org/ns/odrl/2/use> ;
|
41
41
|
<http://www.w3.org/ns/odrl/2/assigner> <https://absch.cbd.int/en/database/CON/ABSCH-CON-ES-241810/2> ;
|
42
|
-
<http://www.w3.org/ns/odrl/2/constraint> <http://example.org#
|
42
|
+
<http://www.w3.org/ns/odrl/2/constraint> <http://example.org#constraint_68801650224698>, <http://example.org#constraint_68801650224712> ;
|
43
43
|
<http://www.w3.org/ns/odrl/2/target> <https://fdp.bgv.cbgp.upm.es/dataset/65ffbf3d-bed1-4a9a-abf9-0116cc35b40a> ;
|
44
|
-
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#
|
44
|
+
<http://www.w3.org/ns/odrl/2/uid> <http://example.org#rule_68801650224680> .
|
45
45
|
|
46
46
|
<http://www.w3.org/ns/odrl/2/use>
|
47
47
|
<http://purl.org/dc/terms/identifier> <http://www.w3.org/ns/odrl/2/use> ;
|
data/lib/odrl/base.rb
CHANGED
@@ -1,41 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "odrl/version"
|
4
|
+
require "linkeddata"
|
4
5
|
|
6
|
+
CPOLICY = ODRLV.Policy.to_s
|
5
7
|
|
6
|
-
|
8
|
+
PPROFILE = ODRLV.profile.to_s
|
7
9
|
|
8
|
-
CSET= ODRLV.Set.to_s
|
9
|
-
COFFER= ODRLV.Offer.to_s
|
10
|
-
CREQUEST= ODRLV.Request.to_s
|
11
|
-
CAGREEMENT= ODRLV.Agreement.to_s
|
12
|
-
CPRIVACY= ODRLV.Privacy.to_s
|
10
|
+
CSET = ODRLV.Set.to_s
|
11
|
+
COFFER = ODRLV.Offer.to_s
|
12
|
+
CREQUEST = ODRLV.Request.to_s
|
13
|
+
CAGREEMENT = ODRLV.Agreement.to_s
|
14
|
+
CPRIVACY = ODRLV.Privacy.to_s
|
13
15
|
PASSET = ODRLV.target.to_s
|
14
|
-
CASSET= ODRLV.Asset.to_s
|
15
|
-
CASSETCOLLECTION= ODRLV.Asset.to_s
|
16
|
+
CASSET = ODRLV.Asset.to_s
|
17
|
+
CASSETCOLLECTION = ODRLV.Asset.to_s
|
16
18
|
|
17
|
-
CRULE= ODRLV.Rule.to_s
|
18
|
-
CPERMISSION= ODRLV.Permission.to_s
|
19
|
+
CRULE = ODRLV.Rule.to_s
|
20
|
+
CPERMISSION = ODRLV.Permission.to_s
|
19
21
|
PPERMISSION = ODRLV.permission.to_s
|
20
|
-
CPROHIBITION= ODRLV.Prohibition.to_s
|
22
|
+
CPROHIBITION = ODRLV.Prohibition.to_s
|
21
23
|
PPROHIBITION = ODRLV.prohibition.to_s
|
22
|
-
PDUTY= ODRLV.obligation.to_s
|
24
|
+
PDUTY = ODRLV.obligation.to_s
|
23
25
|
CDUTY = ODRLV.Duty.to_s
|
24
26
|
|
25
27
|
PRULE = ODRLV.Rule.to_s
|
26
28
|
|
27
|
-
|
28
29
|
PACTION = ODRLV.action.to_s
|
29
|
-
VUSE = ODRLV.use.to_s
|
30
|
-
VTRANSFER = ODRLV.transfer.to_s # this is goofy ODRL stuff...
|
31
|
-
CACTION= ODRLV.Action.to_s
|
30
|
+
VUSE = ODRLV.use.to_s # this is goofy ODRL stuff...
|
31
|
+
VTRANSFER = ODRLV.transfer.to_s # this is goofy ODRL stuff...
|
32
|
+
CACTION = ODRLV.Action.to_s
|
32
33
|
|
33
34
|
PREFINEMENT = ODRLV.refinement.to_s
|
34
35
|
|
35
|
-
PASSIGNER = ODRLV.assigner.to_s
|
36
|
-
PASSIGNEE =
|
37
|
-
CPARTY= ODRLV.Party.to_s
|
38
|
-
CPARTYCOLLECTION= ODRLV.Party.to_s
|
36
|
+
PASSIGNER = ODRLV.assigner.to_s # now in PARTYFUNCTIONS
|
37
|
+
PASSIGNEE = ODRLV.assignee.to_s
|
38
|
+
CPARTY = ODRLV.Party.to_s
|
39
|
+
CPARTYCOLLECTION = ODRLV.Party.to_s
|
39
40
|
|
40
41
|
PCONSTRAINT = ODRLV.constraint.to_s
|
41
42
|
CCONSTRAINT = ODRLV.Constraint.to_s
|
@@ -49,175 +50,181 @@ PSTATUS = ODRLV.status.to_s
|
|
49
50
|
|
50
51
|
PPARTOF = ODRLV.partOf.to_s
|
51
52
|
|
52
|
-
|
53
53
|
PROPERTIES = {
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
54
|
+
title: DCT.title,
|
55
|
+
creator: DCT.creator,
|
56
|
+
description: DCT.description,
|
57
|
+
id: DCT.identifier,
|
58
|
+
type: RDF.type,
|
59
|
+
subject: DCT.subject,
|
60
|
+
uid: ODRLV.uid,
|
61
|
+
label: RDFS.label,
|
62
|
+
issued: DCT.issued
|
63
63
|
}
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
return true
|
89
|
-
end
|
90
|
-
|
91
|
-
def initialize(
|
92
|
-
title: nil,
|
93
|
-
creator: nil,
|
94
|
-
description: nil,
|
95
|
-
issued: nil,
|
96
|
-
subject: nil,
|
97
|
-
baseURI: "http://example.org",
|
98
|
-
uid:,
|
99
|
-
id: nil,
|
100
|
-
type:,
|
101
|
-
label: nil,
|
102
|
-
**_)
|
103
|
-
|
104
|
-
@title = title
|
105
|
-
@creator = creator
|
106
|
-
@issued = issued
|
107
|
-
@description = description
|
108
|
-
@subject = subject
|
109
|
-
@baseURI = baseURI || ODRL::Base.baseURI
|
110
|
-
@uid = uid
|
111
|
-
@type = type
|
112
|
-
@label = label || @title
|
113
|
-
@id = @uid
|
114
|
-
|
115
|
-
raise "Every object must have a uid - attempt to create #{@type}" unless @uid
|
116
|
-
raise "Every object must have a type - " unless @type
|
117
|
-
|
118
|
-
|
119
|
-
$g = RDF::Graph.new()
|
120
|
-
if ENV["TRIPLES_FORMAT"]
|
121
|
-
$format = ENV["TRIPLES_FORMAT"].to_sym
|
122
|
-
else
|
123
|
-
$format = :jsonld
|
124
|
-
end
|
65
|
+
OPERATORS = %w[eq gt gteq hasPart isA isAllOf isAnyOf isNoneOf isPartOf lt lteq neq]
|
66
|
+
LEFTOPERANDS = %w[absolutePosition absoluteSize absoluteSpatialPosition absoluteTemporalPosition
|
67
|
+
count dateTime delayPeriod deliveryChannel device elapsedTime event
|
68
|
+
fileFormat industry language media meteredTime payAmount percentage
|
69
|
+
product purpose recipient relativePosition relativeSize relativeSpatialPosition
|
70
|
+
relativeTemporalPosition resolution spatial spatialCoordinates system
|
71
|
+
systemDevice timeInterval unitOfCount version virtualLocation]
|
72
|
+
|
73
|
+
PARTYFUNCTIONS = %w[assignee assigner attributedParty attributingParty compensatedParty
|
74
|
+
compensatingParty consentedParty consentingParty contractedParty contractingParty informedParty
|
75
|
+
informingParty trackedParty trackingParty]
|
76
|
+
|
77
|
+
# INTERESTING>>>> THIS COULD BE USED IF THERE IS A PROFILE...
|
78
|
+
# module RemovableConstants
|
79
|
+
# def def_if_not_defined(const, value)
|
80
|
+
# self.class.const_set(const, value) unless self.class.const_defined?(const)
|
81
|
+
# end
|
82
|
+
|
83
|
+
# def redef_without_warning(const, value)
|
84
|
+
# self.class.send(:remove_const, const) if self.class.const_defined?(const)
|
85
|
+
# self.class.const_set(const, value)
|
86
|
+
# end
|
87
|
+
# end
|
125
88
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
o = RDF::Literal.new(o.to_s, :datatype => RDF::XSD.float)
|
182
|
-
elsif o.to_s =~ /^[0-9]+$/
|
183
|
-
o = RDF::Literal.new(o.to_s, :datatype => RDF::XSD.int)
|
89
|
+
module ODRL
|
90
|
+
class Base
|
91
|
+
@@repository = RDF::Repository.new
|
92
|
+
|
93
|
+
# If you add an attribute, you mustr also add it to the constructor,
|
94
|
+
# and to the @attribute list
|
95
|
+
# andn to the .load_graph
|
96
|
+
attr_accessor :title, :creator, :description, :subject, :baseURI, :uid, :id, :type, :label, :issued
|
97
|
+
|
98
|
+
def self.baseURI
|
99
|
+
ENV["ODRL_BASEURI"] || "http://example.org"
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.repository
|
103
|
+
@@repository
|
104
|
+
end
|
105
|
+
|
106
|
+
def repository
|
107
|
+
@@repository
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.clear_repository
|
111
|
+
@@repository.clear!
|
112
|
+
true
|
113
|
+
end
|
114
|
+
|
115
|
+
def initialize(
|
116
|
+
uid:, type:, title: nil,
|
117
|
+
creator: nil,
|
118
|
+
description: nil,
|
119
|
+
issued: nil,
|
120
|
+
subject: nil,
|
121
|
+
baseURI: "http://example.org",
|
122
|
+
id: nil,
|
123
|
+
label: nil,
|
124
|
+
**_
|
125
|
+
)
|
126
|
+
|
127
|
+
@title = title
|
128
|
+
@creator = creator
|
129
|
+
@issued = issued
|
130
|
+
@description = description
|
131
|
+
@subject = subject
|
132
|
+
@baseURI = baseURI || ODRL::Base.baseURI
|
133
|
+
@uid = uid
|
134
|
+
@type = type
|
135
|
+
@label = label || @title
|
136
|
+
@id = @uid
|
137
|
+
|
138
|
+
raise "Every object must have a uid - attempt to create #{@type}" unless @uid
|
139
|
+
raise "Every object must have a type - " unless @type
|
140
|
+
|
141
|
+
$g = RDF::Graph.new
|
142
|
+
$format = if ENV["TRIPLES_FORMAT"]
|
143
|
+
ENV["TRIPLES_FORMAT"].to_sym
|
184
144
|
else
|
185
|
-
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
triple = RDF::Statement(s, p, o)
|
190
|
-
repo.insert(triple)
|
191
|
-
|
192
|
-
return true
|
193
|
-
end
|
194
|
-
|
195
|
-
def self.getuuid
|
196
|
-
return Time.now.to_f.to_s.gsub("\.", "")[1..14]
|
197
|
-
end
|
198
|
-
|
199
|
-
def load_graph
|
200
|
-
[:title, :label, :issued, :creator, :description, :subject, :uid, :id, :type].each do |method|
|
201
|
-
next unless self.send(method)
|
202
|
-
next if self.send(method).empty?
|
203
|
-
subject = self.uid # me!
|
204
|
-
predicate = PROPERTIES[method] # look up the predicate for this property
|
205
|
-
# warn "prediate #{predicate} for method #{method}"
|
206
|
-
object = self.send(method) # get the value of this property from self
|
207
|
-
# warn "value #{object.to_s}"
|
208
|
-
repo = self.repository
|
209
|
-
triplify(subject, predicate, object, repo)
|
145
|
+
:jsonld
|
210
146
|
end
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
147
|
+
end
|
148
|
+
|
149
|
+
def get_writer(type:)
|
150
|
+
RDF::Writer.for(type)
|
151
|
+
# w.prefix(:foaf, RDF::URI.new("http://xmlns.com/foaf/0.1/"))
|
152
|
+
# w.prefix(:dc, RDF::URI.new("http://purl.org/dc/terms/"))
|
153
|
+
# w.prefix(:rdf, RDF::URI.new("http://www.w3.org/1999/02/22-rdf-syntax-ns#"))
|
154
|
+
# w.prefix(:rdfs, RDF::URI.new("http://www.w3.org/2000/01/rdf-schema#"))
|
155
|
+
# w.prefix(:vcard, RDF::URI.new("http://www.w3.org/2006/vcard/ns#"))
|
156
|
+
# w.prefix(:odrl, RDF::URI.new("http://www.w3.org/ns/odrl/2/"))
|
157
|
+
# w.prefix(:this, RDF::URI.new("http://w3id.org/FAIR_Training_LDP/DAV/home/LDP/DUC-CCE/IPGB#"))
|
158
|
+
# w.prefix(:obo, RDF::URI.new("http://purl.obolibrary.org/obo/"))
|
159
|
+
# w.prefix(:xsd, RDF::URI.new("http://www.w3.org/2001/XMLSchema#"))
|
160
|
+
# w.prefix(:orcid, RDF::URI.new("https://orcid.org/"))
|
161
|
+
# warn "W"
|
162
|
+
# warn w.prefixes.inspect
|
163
|
+
end
|
164
|
+
|
165
|
+
def triplify(s, p, o, repo)
|
166
|
+
s = s.strip if s.instance_of?(String)
|
167
|
+
p = p.strip if p.instance_of?(String)
|
168
|
+
o = o.strip if o.instance_of?(String)
|
169
|
+
|
170
|
+
unless s.respond_to?("uri")
|
171
|
+
|
172
|
+
raise "Subject #{s} must be a URI-compatible thingy #{s}, #{p}, #{o}" unless s.to_s =~ %r{^\w+:/?/?[^\s]+}
|
173
|
+
|
174
|
+
s = RDF::URI.new(s.to_s)
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
unless p.respond_to?("uri")
|
179
|
+
|
180
|
+
raise "Predicate #{p} must be a URI-compatible thingy #{s}, #{p}, #{o}" unless p.to_s =~ %r{^\w+:/?/?[^\s]+}
|
181
|
+
|
182
|
+
p = RDF::URI.new(p.to_s)
|
183
|
+
|
184
|
+
end
|
185
|
+
unless o.respond_to?("uri")
|
186
|
+
o = if o.to_s =~ %r{^\w+:/?/?[^\s]+}
|
187
|
+
RDF::URI.new(o.to_s)
|
188
|
+
elsif o.to_s =~ /^\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d/
|
189
|
+
RDF::Literal.new(o.to_s, datatype: RDF::XSD.date)
|
190
|
+
elsif o.to_s =~ /^\d\.\d/
|
191
|
+
RDF::Literal.new(o.to_s, datatype: RDF::XSD.float)
|
192
|
+
elsif o.to_s =~ /^[0-9]+$/
|
193
|
+
RDF::Literal.new(o.to_s, datatype: RDF::XSD.int)
|
194
|
+
else
|
195
|
+
RDF::Literal.new(o.to_s, language: :en)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
triple = RDF::Statement(s, p, o)
|
200
|
+
repo.insert(triple)
|
201
|
+
|
202
|
+
true
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.getuuid
|
206
|
+
Time.now.to_f.to_s.gsub(".", "")[1..14]
|
207
|
+
end
|
208
|
+
|
209
|
+
def load_graph
|
210
|
+
%i[title label issued creator description subject uid id type].each do |method|
|
211
|
+
next unless send(method)
|
212
|
+
next if send(method).empty?
|
213
|
+
|
214
|
+
subject = uid # me!
|
215
|
+
predicate = PROPERTIES[method] # look up the predicate for this property
|
216
|
+
# warn "prediate #{predicate} for method #{method}"
|
217
|
+
object = send(method) # get the value of this property from self
|
218
|
+
# warn "value #{object.to_s}"
|
219
|
+
repo = repository
|
220
|
+
triplify(subject, predicate, object, repo)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def serialize(format: $format)
|
225
|
+
format = format.to_sym
|
226
|
+
w = get_writer(type: format)
|
227
|
+
w.dump(repository)
|
228
|
+
end
|
229
|
+
end
|
223
230
|
end
|
data/lib/odrl/constraint.rb
CHANGED
@@ -22,9 +22,12 @@ module ODRL
|
|
22
22
|
raise "Constraints must haves a Right operand such as 'event' - I'm dead!" unless @rightOperand
|
23
23
|
|
24
24
|
# if it is already a URI, then let it go
|
25
|
-
@rightOperand = "http://www.w3.org/ns/odrl/2/#{@rightOperand}" unless @rightOperand =~ %r{https?://}
|
25
|
+
# @rightOperand = "http://www.w3.org/ns/odrl/2/#{@rightOperand}" unless @rightOperand =~ %r{https?://}
|
26
26
|
|
27
27
|
@leftOperand = leftOperand
|
28
|
+
unless LEFTOPERANDS.include?(@leftOperand)
|
29
|
+
warn "The selected leftOperand is not part of the default set... just sayin'"
|
30
|
+
end
|
28
31
|
unless @leftOperand
|
29
32
|
raise "Constraints must haves a Left Operand such as 'http://some.event.org/on-now' - I'm dead!"
|
30
33
|
end
|
@@ -35,6 +38,8 @@ module ODRL
|
|
35
38
|
@operator = operator
|
36
39
|
raise "Constraints must haves an operator such as 'eq' - I'm dead!" unless @operator
|
37
40
|
|
41
|
+
warn "The selected operator is not part of the default set... just sayin'" unless OPERATORS.include?(@operator)
|
42
|
+
|
38
43
|
# if it is already a URI, then let it go
|
39
44
|
@operator = "http://www.w3.org/ns/odrl/2/#{@operator}" unless @operator =~ %r{https?://}
|
40
45
|
|
data/lib/odrl/odrl/version.rb
CHANGED
data/lib/odrl/party.rb
CHANGED
@@ -18,17 +18,21 @@ module ODRL
|
|
18
18
|
super(uid: @uid, type: type, **args)
|
19
19
|
|
20
20
|
@refinements = {}
|
21
|
-
@partOf =
|
22
|
-
@predicate = predicate
|
23
|
-
|
24
|
-
if @predicate
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
@partOf = {}
|
22
|
+
@predicate = predicate.to_s
|
23
|
+
|
24
|
+
if @predicate&.match(/https?:/)
|
25
|
+
# do nothing! It's their choice to send a full predicate!
|
26
|
+
elsif @predicate # we're guessing it will be a string from the valid list?
|
27
|
+
unless PARTYFUNCTIONS.include? @predicate
|
28
|
+
raise "You didn't indicate a valid predicate"
|
29
|
+
# @predicate = ODRLV.assigner
|
30
|
+
else
|
31
|
+
@predicate = "#{ODRLV.to_s}#{predicate}" # make the URI form of the valid predicate
|
28
32
|
end
|
29
|
-
|
30
|
-
raise "If you don't indicate a predicate
|
31
|
-
@predicate =
|
33
|
+
elsif @predicate.nil?
|
34
|
+
raise "If you don't indicate a predicate at all"
|
35
|
+
# @predicate = ODRLV.assigner
|
32
36
|
end
|
33
37
|
|
34
38
|
refinements = [refinements] unless refinements.is_a? Array
|
@@ -38,10 +42,17 @@ module ODRL
|
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
41
|
-
|
45
|
+
partOf = [partOf] unless partOf.is_a? Array
|
46
|
+
unless partOf.first.nil?
|
47
|
+
partOf.each do |p|
|
48
|
+
p.addPart(part: self)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
unless @partOf and !(@partOf.is_a? PartyCollection) # if it exists and is the wrong type
|
53
|
+
raise "The parent collection of a Party must be of type ODRL::PaertyCollection."
|
54
|
+
end
|
42
55
|
|
43
|
-
raise "The parent collection of a Party must be of type ODRL::PaertyCollection. The provided value will be discarded"
|
44
|
-
@partOf = nil
|
45
56
|
end
|
46
57
|
|
47
58
|
def addRefinement(refinement: args)
|
@@ -51,16 +62,15 @@ module ODRL
|
|
51
62
|
end
|
52
63
|
|
53
64
|
def addPart(part: args)
|
54
|
-
raise "Party cannot be added as part of something that is not an PartyCollection" unless is_a?(PartyCollection)
|
55
|
-
raise "Only Parties can be added as part of PartyCollections" unless part.is_a?(Asset)
|
56
|
-
|
65
|
+
raise "Party cannot be added as part of something that is not an PartyCollection" unless self.is_a?(PartyCollection)
|
57
66
|
part.partOf[uid] = [PPARTOF, self]
|
58
67
|
end
|
59
68
|
|
60
69
|
def load_graph
|
61
70
|
super
|
62
71
|
# TODO: This is bad DRY!! Put the bulk of this method into the base object
|
63
|
-
|
72
|
+
# TODO: Currently we don't support partOf
|
73
|
+
%i[refinements].each do |connected_object_type|
|
64
74
|
next unless send(connected_object_type)
|
65
75
|
|
66
76
|
send(connected_object_type).each do |_uid, typedconnection|
|
data/lib/odrl/policy.rb
CHANGED
@@ -6,7 +6,7 @@ module ODRL
|
|
6
6
|
class Error < StandardError; end
|
7
7
|
|
8
8
|
class Policy < Base
|
9
|
-
attr_accessor :rules
|
9
|
+
attr_accessor :rules, :profiles
|
10
10
|
|
11
11
|
def initialize(uid: nil, type: CPOLICY, **args)
|
12
12
|
@uid = uid
|
@@ -14,6 +14,7 @@ module ODRL
|
|
14
14
|
super(uid: @uid, type: type, **args)
|
15
15
|
|
16
16
|
@rules = {}
|
17
|
+
@profiles = {}
|
17
18
|
end
|
18
19
|
|
19
20
|
def addDuty(rule:)
|
@@ -31,6 +32,11 @@ module ODRL
|
|
31
32
|
rules[uid] = [PPROHIBITION, rule]
|
32
33
|
end
|
33
34
|
|
35
|
+
def addProfile(profile:)
|
36
|
+
uid = profile.uid
|
37
|
+
profiles[uid] = [PPROFILE, uid]
|
38
|
+
end
|
39
|
+
|
34
40
|
def load_graph
|
35
41
|
super
|
36
42
|
rules.each do |_uid, rulepair|
|
@@ -41,6 +47,16 @@ module ODRL
|
|
41
47
|
triplify(subject, predicate, object, repo)
|
42
48
|
ruleobject.load_graph # start the cascade
|
43
49
|
end
|
50
|
+
|
51
|
+
# TODO make test for profiles
|
52
|
+
profiles.each do |_uid, profile_pair|
|
53
|
+
predicate, profileuri = profile_pair # e.g. "permission", RuleObject
|
54
|
+
object = profileuri
|
55
|
+
subject = uid
|
56
|
+
repo = repository
|
57
|
+
triplify(subject, predicate, object, repo)
|
58
|
+
end
|
59
|
+
|
44
60
|
end
|
45
61
|
|
46
62
|
def serialize(format:)
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require "linkeddata"
|
2
|
+
|
3
|
+
RDFS = RDF::Vocabulary.new("http://www.w3.org/2000/01/rdf-schema#")
|
4
|
+
DCAT = RDF::Vocabulary.new("http://www.w3.org/ns/dcat#")
|
5
|
+
DC = RDF::Vocabulary.new("http://purl.org/dc/elements/1.1/")
|
6
|
+
DCT = RDF::Vocabulary.new("http://purl.org/dc/terms/")
|
7
|
+
FUND = RDF::Vocabulary.new("http://vocab.ox.ac.uk/projectfunding#")
|
8
|
+
SKOS = RDF::Vocabulary.new("http://www.w3.org/2004/02/skos/core#")
|
9
|
+
ODRLV = RDF::Vocabulary.new("http://www.w3.org/ns/odrl/2/")
|
10
|
+
OBO = RDF::Vocabulary.new("http://purl.obolibrary.org/obo/")
|
11
|
+
XSD = RDF::Vocabulary.new("http://www.w3.org/2001/XMLSchema#")
|
12
|
+
SCHEMA = RDF::Vocabulary.new("https://schema.org/")
|
13
|
+
OWL = RDF::Vocabulary.new("http://www.w3.org/2002/07/owl#")
|
14
|
+
|
15
|
+
module ODRL
|
16
|
+
module Profile
|
17
|
+
class Builder
|
18
|
+
attr_accessor :uri, :profile_class, :repository, :title, :description, :author
|
19
|
+
attr_accessor :asset_relations, :party_functional_roles, :actions, :leftOperands, :rightOperands
|
20
|
+
|
21
|
+
# attr_accessor :logicalConstraints, :conflict_strategies, :rules
|
22
|
+
def initialize(uri:, profile_class:, title:, description:, author:)
|
23
|
+
@uri = uri
|
24
|
+
@profile_class = profile_class
|
25
|
+
@title = title
|
26
|
+
@description = description
|
27
|
+
@author = author
|
28
|
+
@repository = RDF::Repository.new
|
29
|
+
@asset_relations = []
|
30
|
+
@party_functional_roles = []
|
31
|
+
@actions = []
|
32
|
+
@leftOperands = []
|
33
|
+
@rightOperands = []
|
34
|
+
@asset_relations = []
|
35
|
+
|
36
|
+
# Required declarations of disjointedness
|
37
|
+
ODRL::Profile::Builder.triplify(@profile_class, RDFS.subClassOf, ODRLV.Policy, @repository)
|
38
|
+
ODRL::Profile::Builder.triplify(@profile_class, OWL.disjointWith, ODRLV.Agreement, @repository)
|
39
|
+
ODRL::Profile::Builder.triplify(@profile_class, OWL.disjointWith, ODRLV.Offer, @repository)
|
40
|
+
ODRL::Profile::Builder.triplify(@profile_class, OWL.disjointWith, ODRLV.Privacy, @repository)
|
41
|
+
ODRL::Profile::Builder.triplify(@profile_class, OWL.disjointWith, ODRLV.Request, @repository)
|
42
|
+
ODRL::Profile::Builder.triplify(@profile_class, OWL.disjointWith, ODRLV.Ticket, @repository)
|
43
|
+
ODRL::Profile::Builder.triplify(@profile_class, OWL.disjointWith, ODRLV.Assertion, @repository)
|
44
|
+
end
|
45
|
+
|
46
|
+
def build
|
47
|
+
repo = repository # just shorter :-)
|
48
|
+
title and ODRL::Profile::Builder.triplify(uri, DCT.title, title, repo)
|
49
|
+
description and ODRL::Profile::Builder.triplify(uri, DCT.title, description, repo)
|
50
|
+
author and ODRL::Profile::Builder.triplify(uri, DC.creator, author, repo)
|
51
|
+
|
52
|
+
[asset_relations, party_functional_roles, actions, leftOperands, rightOperands, asset_relations].flatten.each do |elem|
|
53
|
+
elem.build(repo: repo)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def serialize(format: :turtle)
|
58
|
+
format = format.to_sym
|
59
|
+
w = get_writer(type: format)
|
60
|
+
w.dump(repository)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_writer(type: :turtle)
|
64
|
+
RDF::Writer.for(type)
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.triplify(s, p, o, repo)
|
68
|
+
s = s.strip if s.instance_of?(String)
|
69
|
+
p = p.strip if p.instance_of?(String)
|
70
|
+
o = o.strip if o.instance_of?(String)
|
71
|
+
|
72
|
+
unless s.respond_to?("uri")
|
73
|
+
|
74
|
+
raise "Subject #{s} must be a URI-compatible thingy #{s}, #{p}, #{o}" unless s.to_s =~ %r{^\w+:/?/?[^\s]+}
|
75
|
+
|
76
|
+
s = RDF::URI.new(s.to_s)
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
unless p.respond_to?("uri")
|
81
|
+
|
82
|
+
raise "Predicate #{p} must be a URI-compatible thingy #{s}, #{p}, #{o}" unless p.to_s =~ %r{^\w+:/?/?[^\s]+}
|
83
|
+
|
84
|
+
p = RDF::URI.new(p.to_s)
|
85
|
+
|
86
|
+
end
|
87
|
+
unless o.respond_to?("uri")
|
88
|
+
o = if o.to_s =~ %r{^\w+:/?/?[^\s]+}
|
89
|
+
RDF::URI.new(o.to_s)
|
90
|
+
elsif o.to_s =~ /^\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d/
|
91
|
+
RDF::Literal.new(o.to_s, datatype: RDF::XSD.date)
|
92
|
+
elsif o.to_s =~ /^\d\.\d/
|
93
|
+
RDF::Literal.new(o.to_s, datatype: RDF::XSD.float)
|
94
|
+
elsif o.to_s =~ /^[0-9]+$/
|
95
|
+
RDF::Literal.new(o.to_s, datatype: RDF::XSD.int)
|
96
|
+
else
|
97
|
+
RDF::Literal.new(o.to_s, language: :en)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
triple = RDF::Statement(s, p, o)
|
102
|
+
repo.insert(triple)
|
103
|
+
|
104
|
+
true
|
105
|
+
end
|
106
|
+
end # end of Class Builder
|
107
|
+
|
108
|
+
class ProfileElement
|
109
|
+
attr_accessor :uri, :label, :definition
|
110
|
+
|
111
|
+
def initialize(uri:, label:, definition:, **_args)
|
112
|
+
@uri = uri
|
113
|
+
@label = label
|
114
|
+
@definition = definition
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class AssetRelation < ProfileElement
|
119
|
+
# ex:myRelation rdfs:subPropertyOf odrl:relation .
|
120
|
+
def build(repo:)
|
121
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.subPropertyOf, ODRLV.relation, repo)
|
122
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.label, label, repo)
|
123
|
+
ODRL::Profile::Builder.triplify(uri, SKOS.defintion, definition, repo)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class PartyFunction < ProfileElement
|
128
|
+
# ex:myFunctionRole rdfs:subPropertyOf odrl:function
|
129
|
+
def build(repo:)
|
130
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.subPropertyOf, ODRLV.function, repo)
|
131
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.label, label, repo)
|
132
|
+
ODRL::Profile::Builder.triplify(uri, SKOS.defintion, definition, repo)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class Rule < ProfileElement
|
137
|
+
# ex:myAction a odrl:Action .
|
138
|
+
# ex:myAction odrl:includedIn odrl:use .
|
139
|
+
# ex:myAction odrl:implies odrl:distribute .
|
140
|
+
attr_accessor :implies, :included_in
|
141
|
+
|
142
|
+
def initialize(implies: nil, included_in: ODRLV.use, **args)
|
143
|
+
@implies = implies
|
144
|
+
@included_in = included_in
|
145
|
+
super(**args)
|
146
|
+
end
|
147
|
+
|
148
|
+
def build(repo:)
|
149
|
+
ODRL::Profile::Builder.triplify(uri, RDF.type, ODRLV.Action, repo)
|
150
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.label, label, repo)
|
151
|
+
ODRL::Profile::Builder.triplify(uri, SKOS.defintion, definition, repo)
|
152
|
+
ODRL::Profile::Builder.triplify(uri, ODRLV.includedIn, included_in, repo)
|
153
|
+
return unless implies
|
154
|
+
ODRL::Profile::Builder.triplify(uri, ODRLV.implies, implies, repo)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class LeftOperand < ProfileElement
|
159
|
+
# ex:myLeftOperand a odrl:LeftOperand .
|
160
|
+
def build(repo:)
|
161
|
+
ODRL::Profile::Builder.triplify(uri, RDF.type, ODRLV.LeftOperand, repo)
|
162
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.label, label, repo)
|
163
|
+
ODRL::Profile::Builder.triplify(uri, SKOS.defintion, definition, repo)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class RightOperand < ProfileElement
|
168
|
+
# ex:myRightOperand a odrl:RightOperand .
|
169
|
+
def build(repo:)
|
170
|
+
ODRL::Profile::Builder.triplify(uri, RDF.type, ODRLV.RightOperand, repo)
|
171
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.label, label, repo)
|
172
|
+
ODRL::Profile::Builder.triplify(uri, SKOS.defintion, definition, repo)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
class Relation < ProfileElement
|
177
|
+
# ex:myOperator a odrl:Operator .
|
178
|
+
def build(repo:)
|
179
|
+
ODRL::Profile::Builder.triplify(uri, RDF.type, ODRLV.Operator, repo)
|
180
|
+
ODRL::Profile::Builder.triplify(uri, RDFS.label, label, repo)
|
181
|
+
ODRL::Profile::Builder.triplify(uri, SKOS.defintion, definition, repo)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
metadata
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: odrl-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Wilkinson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description: A builder for ODRL files. Does basic validation against core ODRL vocabularies.
|
14
|
+
Has a Builder that allows you to create ODRL Profiles to extend the core vocabulary. DOES
|
15
|
+
NOT validate against a profile. DOES NOT cover the full ODRL specificaiton, only
|
16
|
+
the bits that I needed!
|
14
17
|
email:
|
15
18
|
- markw@illuminae.com
|
16
19
|
executables: []
|
@@ -27,6 +30,7 @@ files:
|
|
27
30
|
- bin/console
|
28
31
|
- bin/setup
|
29
32
|
- examples/biohackathon-output.ttl
|
33
|
+
- examples/build_profile.rb
|
30
34
|
- examples/create-biohackathon-offer.rb
|
31
35
|
- examples/create-nagoya-es-offer.rb
|
32
36
|
- examples/nagoya-output.ttl
|
@@ -38,6 +42,7 @@ files:
|
|
38
42
|
- lib/odrl/odrl/version.rb
|
39
43
|
- lib/odrl/party.rb
|
40
44
|
- lib/odrl/policy.rb
|
45
|
+
- lib/odrl/profile/builder.rb
|
41
46
|
- lib/odrl/ruby.rb
|
42
47
|
- lib/odrl/rule.rb
|
43
48
|
homepage: https://example.org
|