odrl-ruby 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/odrl/party.rb CHANGED
@@ -1,100 +1,91 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ODRL
4
-
5
- class Party < Base
6
- attr_accessor :uid, :refinements, :partOf, :predicate, :type
7
- def initialize(
8
- uid: nil,
9
- refinements: nil,
10
- partOf: nil,
11
- predicate: nil,
12
- type: CPARTY,
13
- **args
14
- )
15
-
16
- @uid = uid
17
- unless @uid
18
- @uid = Base.baseURI + "#party_" + Base.getuuid
19
- end
20
- super(uid: @uid, type: type, **args)
21
-
22
-
23
- @refinements = Hash.new
24
- @partOf = partOf
25
- @predicate = predicate
26
-
27
- unless @predicate
28
- raise "If you don't indicate a predicate (assigner/assignee) we will default to assigner. This may not be what you want!"
29
- @predicate = "http://www.w3.org/ns/odrl/2/assigner"
30
- else
31
- unless [PASSIGNER, PASSIGNEE].include? @predicate
32
- raise "You didn't indicate a valid predicate (assigner/assignee) so we will default to assigner. This may not be what you want!"
33
- @predicate = PASSIGNER
34
- end
35
- end
36
-
37
-
38
-
39
- refinements = [refinements] unless refinements.is_a? Array
40
- if !(refinements.first.nil?)
41
- refinements.each do |c|
42
- self.addRefinement(refinement: c)
43
- end
44
- end
45
-
46
- if @partOf and !(@partOf.is_a? PartyCollection) # if it exists and is the wrong type
47
- raise "The parent collection of a Party must be of type ODRL::PaertyCollection. The provided value will be discarded"
48
- @partOf = nil
49
- end
50
-
4
+ class Party < Base
5
+ attr_accessor :uid, :refinements, :partOf, :predicate, :type
6
+
7
+ def initialize(
8
+ uid: nil,
9
+ refinements: nil,
10
+ partOf: nil,
11
+ predicate: nil,
12
+ type: CPARTY,
13
+ **args
14
+ )
15
+
16
+ @uid = uid
17
+ @uid ||= Base.baseURI + "#party_" + Base.getuuid
18
+ super(uid: @uid, type: type, **args)
19
+
20
+ @refinements = {}
21
+ @partOf = partOf
22
+ @predicate = predicate
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
51
32
  end
52
-
53
- def addRefinement(refinement: args)
54
- unless refinement.is_a?(Constraint)
55
- raise "Refinement is not an ODRL Constraint"
56
- else
57
- self.refinements[refinement.uid] = [PREFINEMENT, refinement]
58
- end
33
+ elsif @predicate.nil?
34
+ raise "If you don't indicate a predicate at all"
35
+ # @predicate = ODRLV.assigner
36
+ end
37
+
38
+ refinements = [refinements] unless refinements.is_a? Array
39
+ unless refinements.first.nil?
40
+ refinements.each do |c|
41
+ addRefinement(refinement: c)
59
42
  end
43
+ end
60
44
 
61
- def addPart(part: args)
62
- unless self.is_a?(PartyCollection)
63
- raise "Party cannot be added as part of something that is not an PartyCollection"
64
- end
65
- unless part.is_a?(Asset)
66
- raise "Only Parties can be added as part of PartyCollections"
67
- end
68
- part.partOf[self.uid] = [PPARTOF, self]
69
- end
45
+ return unless @partOf and !(@partOf.is_a? PartyCollection) # if it exists and is the wrong type
70
46
 
71
- def load_graph
72
- super
73
- # TODO This is bad DRY!! Put the bulk of this method into the base object
74
- [:refinements, :partOf].each do |connected_object_type|
75
- next unless self.send(connected_object_type)
76
- self.send(connected_object_type).each do |uid, typedconnection|
77
- predicate, odrlobject = typedconnection # e.g. "refinement", RefinementObject
78
- object = odrlobject.uid
79
- subject = self.uid
80
- repo = self.repository
81
- triplify(subject, predicate, object, repo)
82
- odrlobject.load_graph # start the cascade
83
- end
84
- end
85
- end
47
+ raise "The parent collection of a Party must be of type ODRL::PaertyCollection."
48
+ # @partOf = nil
49
+ end
86
50
 
87
- def serialize(format:)
88
- super
89
- end
51
+ def addRefinement(refinement: args)
52
+ raise "Refinement is not an ODRL Constraint" unless refinement.is_a?(Constraint)
53
+
54
+ refinements[refinement.uid] = [PREFINEMENT, refinement]
55
+ end
90
56
 
57
+ def addPart(part: args)
58
+ raise "Party cannot be added as part of something that is not an PartyCollection" unless is_a?(PartyCollection)
59
+ raise "Only Parties can be added as part of PartyCollections" unless part.is_a?(Asset)
60
+
61
+ part.partOf[uid] = [PPARTOF, self]
91
62
  end
92
- class PartyCollection < Party
93
63
 
94
- def initialize(type: CPARTYCOLLECTION, **args)
95
- super(type: type, **args)
64
+ def load_graph
65
+ super
66
+ # TODO: This is bad DRY!! Put the bulk of this method into the base object
67
+ %i[refinements partOf].each do |connected_object_type|
68
+ next unless send(connected_object_type)
69
+
70
+ send(connected_object_type).each do |_uid, typedconnection|
71
+ predicate, odrlobject = typedconnection # e.g. "refinement", RefinementObject
72
+ object = odrlobject.uid
73
+ subject = uid
74
+ repo = repository
75
+ triplify(subject, predicate, object, repo)
76
+ odrlobject.load_graph # start the cascade
96
77
  end
78
+ end
97
79
  end
98
80
 
81
+ def serialize(format:)
82
+ super
83
+ end
84
+ end
99
85
 
86
+ class PartyCollection < Party
87
+ def initialize(type: CPARTYCOLLECTION, **args)
88
+ super(type: type, **args)
89
+ end
90
+ end
100
91
  end
data/lib/odrl/policy.rb CHANGED
@@ -3,83 +3,95 @@
3
3
  require_relative "odrl/version"
4
4
 
5
5
  module ODRL
6
- class Error < StandardError; end
7
-
8
-
9
- class Policy < Base
10
- attr_accessor :rules
11
-
12
- def initialize(uid: nil, type: CPOLICY, **args)
13
- @uid = uid
14
- unless @uid
15
- self.uid = Base.baseURI + "#policy_" + Base.getuuid
16
- end
17
- super(uid: @uid, type: type, **args)
18
-
19
- @rules = Hash.new
20
- end
21
-
22
- def addDuty(rule:)
23
- uid = rule.uid
24
- self.rules[uid] = [POBLIGATION, rule]
25
- end
26
-
27
- def addPermission(rule:)
28
- uid = rule.uid
29
- self.rules[uid] = [PPERMISSION, rule]
30
-
31
- end
32
-
33
- def addProhibition(rule:)
34
- uid = rule.uid
35
- self.rules[uid] = [PPROHIBITION, rule]
36
- end
37
-
38
- def load_graph
39
- super
40
- self.rules.each do |uid, rulepair|
41
- predicate, ruleobject = rulepair # e.g. "permission", RuleObject
42
- object = ruleobject.uid
43
- subject = self.uid
44
- repo = self.repository
45
- triplify(subject, predicate, object, repo)
46
- ruleobject.load_graph # start the cascade
47
- end
48
- end
49
-
50
- def serialize(format:)
51
- super
52
- end
6
+ class Error < StandardError; end
7
+
8
+ class Policy < Base
9
+ attr_accessor :rules, :profiles
10
+
11
+ def initialize(uid: nil, type: CPOLICY, **args)
12
+ @uid = uid
13
+ self.uid = Base.baseURI + "#policy_" + Base.getuuid unless @uid
14
+ super(uid: @uid, type: type, **args)
15
+
16
+ @rules = {}
17
+ @profiles = {}
18
+ end
19
+
20
+ def addDuty(rule:)
21
+ uid = rule.uid
22
+ rules[uid] = [POBLIGATION, rule]
23
+ end
24
+
25
+ def addPermission(rule:)
26
+ uid = rule.uid
27
+ rules[uid] = [PPERMISSION, rule]
28
+ end
29
+
30
+ def addProhibition(rule:)
31
+ uid = rule.uid
32
+ rules[uid] = [PPROHIBITION, rule]
33
+ end
34
+
35
+ def addProfile(profile:)
36
+ uid = profile.uid
37
+ profiles[uid] = [PPROFILE, uid]
53
38
  end
54
39
 
55
- class Set < Policy
56
- def initialize(type: CSET, **args)
57
- super(type: type, **args)
58
- end
40
+ def load_graph
41
+ super
42
+ rules.each do |_uid, rulepair|
43
+ predicate, ruleobject = rulepair # e.g. "permission", RuleObject
44
+ object = ruleobject.uid
45
+ subject = uid
46
+ repo = repository
47
+ triplify(subject, predicate, object, repo)
48
+ ruleobject.load_graph # start the cascade
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
+
59
60
  end
60
61
 
61
- class Offer < Set
62
- def initialize(type: COFFER, **args)
63
- super(type: type, **args)
64
- end
62
+ def serialize(format:)
63
+ super
65
64
  end
66
- class Agreement < Set
67
- def initialize(type: CAGREEMENT, **args)
68
- super(type: type, **args)
69
- end
65
+ end
66
+
67
+ class Set < Policy
68
+ def initialize(type: CSET, **args)
69
+ super(type: type, **args)
70
70
  end
71
- class Request < Set
72
- def initialize(type: CREQUEST, **args)
73
- super(type: type, **args)
74
- end
71
+ end
72
+
73
+ class Offer < Set
74
+ def initialize(type: COFFER, **args)
75
+ super(type: type, **args)
75
76
  end
77
+ end
76
78
 
77
- class Privacy < Set
78
- def initialize(type: CPRIVACY, **args)
79
- super(type: type, **args)
80
- end
79
+ class Agreement < Set
80
+ def initialize(type: CAGREEMENT, **args)
81
+ super(type: type, **args)
81
82
  end
82
- # ====================================================
83
+ end
83
84
 
85
+ class Request < Set
86
+ def initialize(type: CREQUEST, **args)
87
+ super(type: type, **args)
88
+ end
89
+ end
84
90
 
91
+ class Privacy < Set
92
+ def initialize(type: CPRIVACY, **args)
93
+ super(type: type, **args)
94
+ end
95
+ end
96
+ # ====================================================
85
97
  end
@@ -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
data/lib/odrl/ruby.rb CHANGED
@@ -1,27 +1,26 @@
1
- require 'linkeddata'
2
- require 'rdf/raptor'
3
-
4
- #RDF = RDF::Vocabulary.new("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
1
+ require "linkeddata"
2
+ require "rdf/raptor"
5
3
 
4
+ # RDF = RDF::Vocabulary.new("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
6
5
 
7
6
  RDFS = RDF::Vocabulary.new("http://www.w3.org/2000/01/rdf-schema#")
8
7
  DCAT = RDF::Vocabulary.new("http://www.w3.org/ns/dcat#")
9
8
  DC = RDF::Vocabulary.new("http://purl.org/dc/elements/1.1/")
10
9
  DCT = RDF::Vocabulary.new("http://purl.org/dc/terms/")
11
10
  FUND = RDF::Vocabulary.new("http://vocab.ox.ac.uk/projectfunding#")
12
- SKOS = RDF::Vocabulary.new("http://www.w3.org/2004/02/skos/core#")
13
- ODRLV = RDF::Vocabulary.new("http://www.w3.org/ns/odrl/2/")
11
+ SKOS = RDF::Vocabulary.new("http://www.w3.org/2004/02/skos/core#")
12
+ ODRLV = RDF::Vocabulary.new("http://www.w3.org/ns/odrl/2/")
14
13
  OBO = RDF::Vocabulary.new("http://purl.obolibrary.org/obo/")
15
14
  XSD = RDF::Vocabulary.new("http://www.w3.org/2001/XMLSchema#")
16
15
  SCHEMA = RDF::Vocabulary.new("https://schema.org/")
17
16
 
18
- require_relative "./base"
19
- require_relative "./action"
20
- require_relative "./asset"
21
- require_relative "./constraint"
22
- require_relative "./party"
23
- require_relative "./policy"
24
- require_relative "./rule"
17
+ require_relative "base"
18
+ require_relative "action"
19
+ require_relative "asset"
20
+ require_relative "constraint"
21
+ require_relative "party"
22
+ require_relative "policy"
23
+ require_relative "rule"
25
24
 
26
25
  module ODRL
27
26
  end