odrl-ruby 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fb3d332368286411a6dc8570e113453f818e1ce56c2cb736556d0c86a7e2db3
4
- data.tar.gz: 8990fa784f9460a581a659c62cd66cb10ecb0c441b5b47cc9cafa30f3a200720
3
+ metadata.gz: fe2979f7b53376990eda47051aa5eff33f6d67952742b35abb9e650ce5434a09
4
+ data.tar.gz: 0e9f46bd539435cfe5d601b0d16648850811139fa967f0b948f1984117e6fb6d
5
5
  SHA512:
6
- metadata.gz: 359241dc53fe82dce671a867333b192caa91b047c1d92ae4f2e25480335b75f145c6b7b61c76b2d1b980db9c3db80863f20d6ee4311e588cef9239450a8c1811
7
- data.tar.gz: dad4de8bfed921097a08aeaa0e0417b24fb86a004d088691dbad0a4c63a9755316de95cd37596c27589607c37c54f813a755834912ad85ae027809b3b50e3b7f
6
+ metadata.gz: 1d209dd7d1ae1e37aa3a655fd9a76c2be59e8dea5439b05ff0f12fe9ded99aabace239b64e56795a619294b531edfc21191531a514892322699e2b607380f2c6
7
+ data.tar.gz: 8ebd782fb9662a236befa968a2fccd8e8b36dcf789092d1f22398cac2bda6aafc0b375bc0bc9314ecd0826ce6882e26af92527900f7777be026425aac31c5600
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- odrl-ruby (0.1.6)
4
+ odrl-ruby (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
 
@@ -0,0 +1,47 @@
1
+ require '../lib/odrl/profile/builder.rb'
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 'odrl/ruby'
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
- title: "Offer for the use of BGV Germplasm",
9
- creator: "https://orcid.org/0000-0001-6960-357X",
10
- description: "An offer any non-Commercial entity to use Germplasm from the BGV - UPM",
11
- subject: "nagoya-constraint", # this is a tag
12
- issued: "2022-06-29"
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", title: "César Gómez Campo Banco de Germoplasma Vegetal de la UPM")
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
- 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",)
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
- title: "Use by non-profit organization",
33
- leftOperand: "industry",
34
- operator: "neq",
35
- rightOperand: "https://w3id.org/dingo#ForProfitOrganisation"
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
- title: "Use for non-commercial purposes",
39
- leftOperand: "purpose",
40
- operator: "neq",
41
- rightOperand: "http://purl.obolibrary.org/obo/ExO_0000085"
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: 'turtle')
53
+ result = policy.serialize(format: "turtle")
53
54
  puts result
54
-
@@ -1,47 +1,47 @@
1
1
  @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
2
2
 
3
- <http://example.org#constraint_68801640962093>
4
- <http://purl.org/dc/terms/identifier> <http://example.org#constraint_68801640962093> ;
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#constraint_68801640962093> .
11
+ <http://www.w3.org/ns/odrl/2/uid> <http://example.org#constraint_68801650224698> .
12
12
 
13
- <http://example.org#constraint_68801640962112>
14
- <http://purl.org/dc/terms/identifier> <http://example.org#constraint_68801640962112> ;
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#constraint_68801640962112> .
21
+ <http://www.w3.org/ns/odrl/2/uid> <http://example.org#constraint_68801650224712> .
22
22
 
23
- <http://example.org#policy_68801640962017>
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#policy_68801640962017> ;
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#rule_68801640962070> ;
33
- <http://www.w3.org/ns/odrl/2/uid> <http://example.org#policy_68801640962017> .
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#rule_68801640962070>
36
- <http://purl.org/dc/terms/identifier> <http://example.org#rule_68801640962070> ;
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#constraint_68801640962093>, <http://example.org#constraint_68801640962112> ;
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#rule_68801640962070> .
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
- CPOLICY= ODRLV.Policy.to_s
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 # this is goofy ODRL stuff...
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 = ODRLV.assignee.to_s
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
- 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,
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
- module ODRL
66
- class Base
67
-
68
- @@repository = RDF::Repository.new()
69
-
70
- # If you add an attribute, you mustr also add it to the constructor,
71
- # and to the @attribute list
72
- # andn to the .load_graph
73
- attr_accessor :title, :creator, :description, :subject, :baseURI, :uid, :id, :type, :label, :issued
74
-
75
- def self.baseURI
76
- return ENV['ODRL_BASEURI'] || "http://example.org"
77
- end
78
-
79
- def self.repository
80
- return @@repository
81
- end
82
- def repository
83
- return @@repository
84
- end
85
-
86
- def self.clear_repository
87
- @@repository.clear!
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
- end
127
-
128
- def get_writer(type:)
129
- w = RDF::Writer.for(type)
130
- # w.prefix(:foaf, RDF::URI.new("http://xmlns.com/foaf/0.1/"))
131
- # w.prefix(:dc, RDF::URI.new("http://purl.org/dc/terms/"))
132
- # w.prefix(:rdf, RDF::URI.new("http://www.w3.org/1999/02/22-rdf-syntax-ns#"))
133
- # w.prefix(:rdfs, RDF::URI.new("http://www.w3.org/2000/01/rdf-schema#"))
134
- # w.prefix(:vcard, RDF::URI.new("http://www.w3.org/2006/vcard/ns#"))
135
- # w.prefix(:odrl, RDF::URI.new("http://www.w3.org/ns/odrl/2/"))
136
- # w.prefix(:this, RDF::URI.new("http://w3id.org/FAIR_Training_LDP/DAV/home/LDP/DUC-CCE/IPGB#"))
137
- # w.prefix(:obo, RDF::URI.new("http://purl.obolibrary.org/obo/"))
138
- # w.prefix(:xsd, RDF::URI.new("http://www.w3.org/2001/XMLSchema#"))
139
- # w.prefix(:orcid, RDF::URI.new("https://orcid.org/"))
140
- # warn "W"
141
- # warn w.prefixes.inspect
142
-
143
- return w
144
- end
145
-
146
- def triplify(s, p, o, repo)
147
-
148
- if s.class == String
149
- s = s.strip
150
- end
151
- if p.class == String
152
- p = p.strip
153
- end
154
- if o.class == String
155
- o = o.strip
156
- end
157
-
158
- unless s.respond_to?('uri')
159
-
160
- if s.to_s =~ /^\w+:\/?\/?[^\s]+/
161
- s = RDF::URI.new(s.to_s)
162
- else
163
- raise "Subject #{s.to_s} must be a URI-compatible thingy #{s}, #{p}, #{o}"
164
- end
165
- end
166
-
167
- unless p.respond_to?('uri')
168
-
169
- if p.to_s =~ /^\w+:\/?\/?[^\s]+/
170
- p = RDF::URI.new(p.to_s)
171
- else
172
- raise "Predicate #{p.to_s} must be a URI-compatible thingy #{s}, #{p}, #{o}"
173
- end
174
- end
175
- unless o.respond_to?('uri')
176
- if o.to_s =~ /^\w+:\/?\/?[^\s]+/
177
- o = RDF::URI.new(o.to_s)
178
- elsif o.to_s =~ /^\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d/
179
- o = RDF::Literal.new(o.to_s, :datatype => RDF::XSD.date)
180
- elsif o.to_s =~ /^\d\.\d/
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
- o = RDF::Literal.new(o.to_s, :language => :en)
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
- end
212
-
213
- def serialize(format: $format)
214
- format = format.to_sym
215
- w = get_writer(type: format)
216
- return w.dump(self.repository)
217
- end
218
-
219
- private
220
-
221
-
222
- end
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
@@ -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
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ODRL
4
4
  module ODRL
5
- VERSION = "0.1.6"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
data/lib/odrl/party.rb CHANGED
@@ -21,14 +21,18 @@ module ODRL
21
21
  @partOf = partOf
22
22
  @predicate = predicate
23
23
 
24
- if @predicate
25
- unless [PASSIGNER, PASSIGNEE].include? @predicate
26
- raise "You didn't indicate a valid predicate (assigner/assignee) so we will default to assigner. This may not be what you want!"
27
- @predicate = PASSIGNER
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
- else
30
- raise "If you don't indicate a predicate (assigner/assignee) we will default to assigner. This may not be what you want!"
31
- @predicate = "http://www.w3.org/ns/odrl/2/assigner"
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
@@ -40,8 +44,8 @@ module ODRL
40
44
 
41
45
  return unless @partOf and !(@partOf.is_a? PartyCollection) # if it exists and is the wrong type
42
46
 
43
- raise "The parent collection of a Party must be of type ODRL::PaertyCollection. The provided value will be discarded"
44
- @partOf = nil
47
+ raise "The parent collection of a Party must be of type ODRL::PaertyCollection."
48
+ # @partOf = nil
45
49
  end
46
50
 
47
51
  def addRefinement(refinement: args)
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.6
4
+ version: 0.2.0
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-29 00:00:00.000000000 Z
11
+ date: 2023-06-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: builds ODRL files nicely.
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