opentox-ruby 0.0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +41 -0
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/lib/algorithm.rb +15 -2
- data/lib/authorization.rb +381 -0
- data/lib/compound.rb +6 -0
- data/lib/config/config_ru.rb +1 -0
- data/lib/dataset.rb +98 -43
- data/lib/environment.rb +9 -18
- data/lib/error.rb +99 -0
- data/lib/feature.rb +30 -2
- data/lib/helper.rb +90 -17
- data/lib/model.rb +81 -34
- data/lib/ontology_service.rb +43 -0
- data/lib/opentox-ruby.rb +3 -2
- data/lib/opentox.rb +9 -4
- data/lib/overwrite.rb +87 -28
- data/lib/parser.rb +117 -22
- data/lib/policy.rb +261 -0
- data/lib/rest_client_wrapper.rb +110 -99
- data/lib/serializer.rb +130 -1
- data/lib/task.rb +179 -42
- data/lib/templates/config.yaml +45 -0
- data/lib/templates/default_guest_policy.xml +53 -0
- data/lib/templates/default_policy.xml +53 -0
- data/lib/to-html.rb +112 -0
- data/lib/validation.rb +183 -57
- metadata +31 -94
- data/README.rdoc +0 -23
data/lib/parser.rb
CHANGED
@@ -29,22 +29,37 @@ module OpenTox
|
|
29
29
|
|
30
30
|
# Read metadata from opentox service
|
31
31
|
# @return [Hash] Object metadata
|
32
|
-
def load_metadata
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def load_metadata(subjectid=nil)
|
33
|
+
# avoid using rapper directly because of 2 reasons:
|
34
|
+
# * http errors wont be noticed
|
35
|
+
# * subjectid cannot be sent as header
|
36
|
+
##uri += "?subjectid=#{CGI.escape(subjectid)}" if subjectid
|
37
|
+
## `rapper -i rdfxml -o ntriples #{uri} 2>/dev/null`.each_line do |line|
|
38
|
+
if File.exist?(@uri)
|
39
|
+
file = File.new(@uri)
|
36
40
|
else
|
37
|
-
|
41
|
+
file = Tempfile.new("ot-rdfxml")
|
42
|
+
if @dataset
|
43
|
+
# do not concat /metadata to uri string, this would not work for dataset/R401577?max=3
|
44
|
+
uri = URI::parse(@uri)
|
45
|
+
uri.path = File.join(uri.path,"metadata")
|
46
|
+
uri = uri.to_s
|
47
|
+
else
|
48
|
+
uri = @uri
|
49
|
+
end
|
50
|
+
file.puts OpenTox::RestClientWrapper.get uri,{:subjectid => subjectid,:accept => "application/rdf+xml"},nil,false
|
51
|
+
file.close
|
52
|
+
to_delete = file.path
|
38
53
|
end
|
39
|
-
|
40
54
|
statements = []
|
41
55
|
parameter_ids = []
|
42
|
-
`rapper -i rdfxml -o ntriples #{
|
56
|
+
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
|
43
57
|
triple = line.to_triple
|
44
58
|
@metadata[triple[1]] = triple[2].split('^^').first if triple[0] == @uri and triple[1] != RDF['type']
|
45
59
|
statements << triple
|
46
60
|
parameter_ids << triple[2] if triple[1] == OT.parameters
|
47
61
|
end
|
62
|
+
File.delete(to_delete) if to_delete
|
48
63
|
unless parameter_ids.empty?
|
49
64
|
@metadata[OT.parameters] = []
|
50
65
|
parameter_ids.each do |p|
|
@@ -55,10 +70,45 @@ module OpenTox
|
|
55
70
|
end
|
56
71
|
@metadata
|
57
72
|
end
|
58
|
-
|
73
|
+
|
74
|
+
# creates owl object from rdf-data
|
75
|
+
# @param [String] rdf
|
76
|
+
# @param [String] type of the info (e.g. OT.Task, OT.ErrorReport) needed to get the subject-uri
|
77
|
+
# @return [Owl] with uri and metadata set
|
78
|
+
def self.from_rdf( rdf, type )
|
79
|
+
# write to file and read convert with rapper into tripples
|
80
|
+
file = Tempfile.new("ot-rdfxml")
|
81
|
+
file.puts rdf
|
82
|
+
file.close
|
83
|
+
#puts "cmd: rapper -i rdfxml -o ntriples #{file} 2>/dev/null"
|
84
|
+
triples = `rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`
|
85
|
+
|
86
|
+
# load uri via type
|
87
|
+
uri = nil
|
88
|
+
triples.each_line do |line|
|
89
|
+
triple = line.to_triple
|
90
|
+
if triple[1] == RDF['type'] and triple[2]==type
|
91
|
+
raise "uri already set, two uris found with type: "+type.to_s if uri
|
92
|
+
uri = triple[0]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
File.delete(file.path)
|
96
|
+
# load metadata
|
97
|
+
metadata = {}
|
98
|
+
triples.each_line do |line|
|
99
|
+
triple = line.to_triple
|
100
|
+
metadata[triple[1]] = triple[2].split('^^').first if triple[0] == uri and triple[1] != RDF['type']
|
101
|
+
end
|
102
|
+
owl = Owl::Generic.new(uri)
|
103
|
+
owl.metadata = metadata
|
104
|
+
owl
|
105
|
+
end
|
106
|
+
|
59
107
|
# Generic parser for all OpenTox classes
|
60
108
|
class Generic
|
61
109
|
include Owl
|
110
|
+
|
111
|
+
attr_accessor :uri, :metadata
|
62
112
|
end
|
63
113
|
|
64
114
|
# OWL-DL parser for datasets
|
@@ -71,9 +121,9 @@ module OpenTox
|
|
71
121
|
# Create a new OWL-DL dataset parser
|
72
122
|
# @param uri Dataset URI
|
73
123
|
# @return [OpenTox::Parser::Owl::Dataset] OWL-DL parser
|
74
|
-
def initialize(uri)
|
124
|
+
def initialize(uri, subjectid=nil)
|
75
125
|
super uri
|
76
|
-
@dataset = ::OpenTox::Dataset.new(@uri)
|
126
|
+
@dataset = ::OpenTox::Dataset.new(@uri, subjectid)
|
77
127
|
end
|
78
128
|
|
79
129
|
# Read data from dataset service. Files can be parsed by setting #uri to a filename (after initialization with a real URI)
|
@@ -87,12 +137,27 @@ module OpenTox
|
|
87
137
|
# dataset = parser.load_uri
|
88
138
|
# dataset.save
|
89
139
|
# @return [Hash] Internal dataset representation
|
90
|
-
def load_uri
|
140
|
+
def load_uri(subjectid=nil)
|
141
|
+
|
142
|
+
# avoid using rapper directly because of 2 reasons:
|
143
|
+
# * http errors wont be noticed
|
144
|
+
# * subjectid cannot be sent as header
|
145
|
+
##uri += "?subjectid=#{CGI.escape(subjectid)}" if subjectid
|
146
|
+
##`rapper -i rdfxml -o ntriples #{file} 2>/dev/null`.each_line do |line|
|
147
|
+
if File.exist?(@uri)
|
148
|
+
file = File.new(@uri)
|
149
|
+
else
|
150
|
+
file = Tempfile.new("ot-rdfxml")
|
151
|
+
file.puts OpenTox::RestClientWrapper.get @uri,{:subjectid => subjectid,:accept => "application/rdf+xml"},nil,false
|
152
|
+
file.close
|
153
|
+
to_delete = file.path
|
154
|
+
end
|
155
|
+
|
91
156
|
data = {}
|
92
157
|
feature_values = {}
|
93
158
|
feature = {}
|
94
159
|
other_statements = {}
|
95
|
-
`rapper -i rdfxml -o ntriples #{
|
160
|
+
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
|
96
161
|
triple = line.chomp.split(' ',3)
|
97
162
|
triple = triple[0..2].collect{|i| i.sub(/\s+.$/,'').gsub(/[<>"]/,'')}
|
98
163
|
case triple[1]
|
@@ -105,32 +170,62 @@ module OpenTox
|
|
105
170
|
data[triple[0]] = {:compound => "", :values => []} unless data[triple[0]]
|
106
171
|
data[triple[0]][:compound] = triple[2]
|
107
172
|
when /#{OT.feature}/i
|
108
|
-
feature[triple[0]] = triple[2]
|
173
|
+
feature[triple[0]] = triple[2]
|
174
|
+
when /#{RDF.type}/i
|
175
|
+
if triple[2]=~/#{OT.Compound}/i and !data[triple[0]]
|
176
|
+
data[triple[0]] = {:compound => triple[0], :values => []}
|
177
|
+
end
|
109
178
|
else
|
110
179
|
end
|
111
180
|
end
|
181
|
+
File.delete(to_delete) if to_delete
|
112
182
|
data.each do |id,entry|
|
113
|
-
entry[:values].
|
114
|
-
|
115
|
-
@dataset.
|
183
|
+
if entry[:values].size==0
|
184
|
+
# no feature values add plain compounds
|
185
|
+
@dataset.add_compound(entry[:compound])
|
186
|
+
else
|
187
|
+
entry[:values].each do |value_id|
|
188
|
+
split = feature_values[value_id].split(/\^\^/)
|
189
|
+
case split[-1]
|
190
|
+
when XSD.double, XSD.float
|
191
|
+
value = split.first.to_f
|
192
|
+
when XSD.boolean
|
193
|
+
value = split.first=~/(?i)true/ ? true : false
|
194
|
+
else
|
195
|
+
value = split.first
|
196
|
+
end
|
197
|
+
@dataset.add entry[:compound],feature[value_id],value
|
198
|
+
end
|
116
199
|
end
|
117
200
|
end
|
118
|
-
load_features
|
119
|
-
@dataset.metadata = load_metadata
|
201
|
+
load_features subjectid
|
202
|
+
@dataset.metadata = load_metadata(subjectid)
|
120
203
|
@dataset
|
121
204
|
end
|
122
205
|
|
123
206
|
# Read only features from a dataset service.
|
124
207
|
# @return [Hash] Internal features representation
|
125
|
-
def load_features
|
126
|
-
|
208
|
+
def load_features(subjectid=nil)
|
209
|
+
if File.exist?(@uri)
|
210
|
+
file = File.new(@uri)
|
211
|
+
else
|
212
|
+
file = Tempfile.new("ot-rdfxml")
|
213
|
+
# do not concat /features to uri string, this would not work for dataset/R401577?max=3
|
214
|
+
uri = URI::parse(@uri)
|
215
|
+
uri.path = File.join(uri.path,"features")
|
216
|
+
uri = uri.to_s
|
217
|
+
file.puts OpenTox::RestClientWrapper.get uri,{:subjectid => subjectid,:accept => "application/rdf+xml"},nil,false
|
218
|
+
file.close
|
219
|
+
to_delete = file.path
|
220
|
+
end
|
127
221
|
statements = []
|
128
222
|
features = Set.new
|
129
|
-
`rapper -i rdfxml -o ntriples #{
|
223
|
+
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
|
130
224
|
triple = line.chomp.split('> ').collect{|i| i.sub(/\s+.$/,'').gsub(/[<>"]/,'')}[0..2]
|
131
225
|
statements << triple
|
132
|
-
features << triple[0] if triple[1] == RDF['type'] and triple[2] == OT.Feature
|
226
|
+
features << triple[0] if triple[1] == RDF['type'] and (triple[2] == OT.Feature || triple[2] == OT.NumericFeature)
|
133
227
|
end
|
228
|
+
File.delete(to_delete) if to_delete
|
134
229
|
statements.each do |triple|
|
135
230
|
if features.include? triple[0]
|
136
231
|
@dataset.features[triple[0]] = {} unless @dataset.features[triple[0]]
|
data/lib/policy.rb
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
module OpenTox
|
2
|
+
require "rexml/document"
|
3
|
+
|
4
|
+
#Module for policy-processing
|
5
|
+
# @see also http://www.opentox.org/dev/apis/api-1.2/AA for opentox API specs
|
6
|
+
# Class Policies corresponds to <policies> container of an xml-policy-fle
|
7
|
+
class Policies
|
8
|
+
|
9
|
+
attr_accessor :name, :policies
|
10
|
+
|
11
|
+
def initialize()
|
12
|
+
@policies = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
#create new policy instance with name
|
16
|
+
# @param [String]name of the policy
|
17
|
+
def new_policy(name)
|
18
|
+
@policies[name] = Policy.new(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
#drop a specific policy in a policies instance
|
22
|
+
# @param [String]name of the policy
|
23
|
+
# @return [Boolean]
|
24
|
+
def drop_policy(name)
|
25
|
+
return true if @policies.delete(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
#drop all policies in a policies instance
|
29
|
+
def drop_policies
|
30
|
+
@policies.each do |name, policy|
|
31
|
+
drop_policy(name)
|
32
|
+
end
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Array] set of arrays affected by policies
|
37
|
+
def uris
|
38
|
+
@policies.collect{ |k,v| v.uris }.flatten.uniq
|
39
|
+
end
|
40
|
+
|
41
|
+
#drop all policies in a policies instance
|
42
|
+
def names
|
43
|
+
out = []
|
44
|
+
@policies.each do |name, policy|
|
45
|
+
out << name
|
46
|
+
end
|
47
|
+
return out
|
48
|
+
end
|
49
|
+
|
50
|
+
#loads a default policy template in policies instance
|
51
|
+
def load_default_policy(user, uri, group="member")
|
52
|
+
template = case user
|
53
|
+
when "guest", "anonymous" then "default_guest_policy"
|
54
|
+
else "default_policy"
|
55
|
+
end
|
56
|
+
xml = File.read(File.join(File.dirname(__FILE__), "templates/#{template}.xml"))
|
57
|
+
self.load_xml(xml)
|
58
|
+
datestring = Time.now.strftime("%Y-%m-%d-%H-%M-%S-x") + rand(1000).to_s
|
59
|
+
|
60
|
+
@policies["policy_user"].name = "policy_user_#{user}_#{datestring}"
|
61
|
+
@policies["policy_user"].rules["rule_user"].uri = uri
|
62
|
+
@policies["policy_user"].rules["rule_user"].name = "rule_user_#{user}_#{datestring}"
|
63
|
+
@policies["policy_user"].subjects["subject_user"].name = "subject_user_#{user}_#{datestring}"
|
64
|
+
@policies["policy_user"].subjects["subject_user"].value = "uid=#{user},ou=people,dc=opentox,dc=org"
|
65
|
+
@policies["policy_user"].subject_group = "subjects_user_#{user}_#{datestring}"
|
66
|
+
|
67
|
+
@policies["policy_group"].name = "policy_group_#{group}_#{datestring}"
|
68
|
+
@policies["policy_group"].rules["rule_group"].uri = uri
|
69
|
+
@policies["policy_group"].rules["rule_group"].name = "rule_group_#{group}_#{datestring}"
|
70
|
+
@policies["policy_group"].subjects["subject_group"].name = "subject_group_#{group}_#{datestring}"
|
71
|
+
@policies["policy_group"].subjects["subject_group"].value = "cn=#{group},ou=groups,dc=opentox,dc=org"
|
72
|
+
@policies["policy_group"].subject_group = "subjects_#{group}_#{datestring}"
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
|
76
|
+
#loads a xml template
|
77
|
+
def load_xml(xml)
|
78
|
+
rexml = REXML::Document.new(xml)
|
79
|
+
rexml.elements.each("Policies/Policy") do |pol| #Policies
|
80
|
+
policy_name = pol.attributes["name"]
|
81
|
+
new_policy(policy_name)
|
82
|
+
#@policies[policy_name] = Policy.new(policy_name)
|
83
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Rule") do |r| #Rules
|
84
|
+
rule_name = r.attributes["name"]
|
85
|
+
uri = rexml.elements["Policies/Policy[@name='#{policy_name}']/Rule[@name='#{rule_name}']/ResourceName"].attributes["name"]
|
86
|
+
@policies[policy_name].rules[rule_name] = @policies[policy_name].new_rule(rule_name, uri)
|
87
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Rule[@name='#{rule_name}']/AttributeValuePair") do |attribute_pairs|
|
88
|
+
action=nil; value=nil;
|
89
|
+
attribute_pairs.each_element do |elem|
|
90
|
+
action = elem.attributes["name"] if elem.attributes["name"]
|
91
|
+
value = elem.text if elem.text
|
92
|
+
end
|
93
|
+
if action and value
|
94
|
+
case action
|
95
|
+
when "GET"
|
96
|
+
@policies[policy_name].rules[rule_name].get = value
|
97
|
+
when "POST"
|
98
|
+
@policies[policy_name].rules[rule_name].post = value
|
99
|
+
when "PUT"
|
100
|
+
@policies[policy_name].rules[rule_name].put = value
|
101
|
+
when "DELETE"
|
102
|
+
@policies[policy_name].rules[rule_name].delete = value
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Subjects") do |subjects| #Subjects
|
108
|
+
@policies[policy_name].subject_group = subjects.attributes["name"]
|
109
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Subjects[@name='#{@policies[policy_name].subject_group}']/Subject") do |s| #Subject
|
110
|
+
subject_name = s.attributes["name"]
|
111
|
+
subject_type = s.attributes["type"]
|
112
|
+
subject_value = rexml.elements["Policies/Policy[@name='#{policy_name}']/Subjects[@name='#{@policies[policy_name].subject_group}']/Subject[@name='#{subject_name}']/AttributeValuePair/Value"].text
|
113
|
+
@policies[policy_name].new_subject(subject_name, subject_type, subject_value) if subject_name and subject_type and subject_value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#generates xml from policies instance
|
120
|
+
def to_xml
|
121
|
+
doc = REXML::Document.new()
|
122
|
+
doc << REXML::DocType.new("Policies", "PUBLIC \"-//Sun Java System Access Manager7.1 2006Q3\n Admin CLI DTD//EN\" \"jar://com/sun/identity/policy/policyAdmin.dtd\"")
|
123
|
+
doc.add_element(REXML::Element.new("Policies"))
|
124
|
+
|
125
|
+
@policies.each do |name, pol|
|
126
|
+
policy = REXML::Element.new("Policy")
|
127
|
+
policy.attributes["name"] = pol.name
|
128
|
+
policy.attributes["referralPolicy"] = false
|
129
|
+
policy.attributes["active"] = true
|
130
|
+
@policies[name].rules.each do |r,rl|
|
131
|
+
rule = @policies[name].rules[r]
|
132
|
+
out_rule = REXML::Element.new("Rule")
|
133
|
+
out_rule.attributes["name"] = rule.name
|
134
|
+
servicename = REXML::Element.new("ServiceName")
|
135
|
+
servicename.attributes["name"]="iPlanetAMWebAgentService"
|
136
|
+
out_rule.add_element(servicename)
|
137
|
+
rescourcename = REXML::Element.new("ResourceName")
|
138
|
+
rescourcename.attributes["name"] = rule.uri
|
139
|
+
out_rule.add_element(rescourcename)
|
140
|
+
|
141
|
+
["get","post","delete","put"].each do |act|
|
142
|
+
if rule.method(act).call
|
143
|
+
attribute = REXML::Element.new("Attribute")
|
144
|
+
attribute.attributes["name"] = act.upcase
|
145
|
+
attributevaluepair = REXML::Element.new("AttributeValuePair")
|
146
|
+
attributevaluepair.add_element(attribute)
|
147
|
+
attributevalue = REXML::Element.new("Value")
|
148
|
+
attributevaluepair.add_element(attributevalue)
|
149
|
+
attributevalue.add_text REXML::Text.new(rule.method(act).call)
|
150
|
+
out_rule.add_element(attributevaluepair)
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
154
|
+
policy.add_element(out_rule)
|
155
|
+
end
|
156
|
+
|
157
|
+
subjects = REXML::Element.new("Subjects")
|
158
|
+
subjects.attributes["name"] = pol.subject_group
|
159
|
+
subjects.attributes["description"] = ""
|
160
|
+
@policies[name].subjects.each do |subj, subjs|
|
161
|
+
subject = REXML::Element.new("Subject")
|
162
|
+
subject.attributes["name"] = pol.subjects[subj].name
|
163
|
+
subject.attributes["type"] = pol.subjects[subj].type
|
164
|
+
subject.attributes["includeType"] = "inclusive"
|
165
|
+
attributevaluepair = REXML::Element.new("AttributeValuePair")
|
166
|
+
attribute = REXML::Element.new("Attribute")
|
167
|
+
attribute.attributes["name"] = "Values"
|
168
|
+
attributevaluepair.add_element(attribute)
|
169
|
+
attributevalue = REXML::Element.new("Value")
|
170
|
+
attributevalue.add_text REXML::Text.new(pol.subjects[subj].value)
|
171
|
+
attributevaluepair.add_element(attributevalue)
|
172
|
+
subject.add_element(attributevaluepair)
|
173
|
+
subjects.add_element(subject)
|
174
|
+
end
|
175
|
+
policy.add_element(subjects)
|
176
|
+
doc.root.add_element(policy)
|
177
|
+
end
|
178
|
+
out = ""
|
179
|
+
doc.write(out, 2)
|
180
|
+
return out
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
#single policy in a policies instance
|
186
|
+
class Policy
|
187
|
+
|
188
|
+
attr_accessor :name, :rules, :subject_group, :subjects
|
189
|
+
|
190
|
+
def initialize(name)
|
191
|
+
@name = name
|
192
|
+
@rules = {}
|
193
|
+
@subject_group = ""
|
194
|
+
@subjects = {}
|
195
|
+
end
|
196
|
+
|
197
|
+
#create a new rule instance for the policy
|
198
|
+
def new_rule(name, uri)
|
199
|
+
@rules[name] = Rule.new(name, uri)
|
200
|
+
end
|
201
|
+
|
202
|
+
#create a new subject instance for the policy
|
203
|
+
def new_subject(name, type, value)
|
204
|
+
@subjects[name] = Subject.new(name, type, value)
|
205
|
+
end
|
206
|
+
|
207
|
+
# @return [Array] set of uris affected by policy
|
208
|
+
def uris
|
209
|
+
@rules.collect{ |k,v| v.uri }.uniq
|
210
|
+
end
|
211
|
+
|
212
|
+
#rule inside a policy
|
213
|
+
class Rule
|
214
|
+
|
215
|
+
attr_accessor :name, :uri, :get, :post, :put, :delete
|
216
|
+
|
217
|
+
def initialize(name, uri)
|
218
|
+
@name = name
|
219
|
+
@uri = uri
|
220
|
+
end
|
221
|
+
|
222
|
+
def rename(new, old)
|
223
|
+
self[new] = self.delete(old)
|
224
|
+
self[new].name = new
|
225
|
+
end
|
226
|
+
|
227
|
+
def get=(value)
|
228
|
+
@get = check_value(value, @get)
|
229
|
+
end
|
230
|
+
|
231
|
+
def post=(value)
|
232
|
+
@post = check_value(value, @post)
|
233
|
+
end
|
234
|
+
|
235
|
+
def delete=(value)
|
236
|
+
@delete = check_value(value, @delete)
|
237
|
+
end
|
238
|
+
|
239
|
+
def put=(value)
|
240
|
+
@put = check_value(value, @put)
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
#checks if value is allow or deny. returns old value if not valid.
|
245
|
+
def check_value(new_value, old_value)
|
246
|
+
return (new_value=="allow" || new_value=="deny" || new_value==nil) ? new_value : old_value
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
class Subject
|
251
|
+
|
252
|
+
attr_accessor :name, :type, :value
|
253
|
+
|
254
|
+
def initialize(name, type, value)
|
255
|
+
@name = name
|
256
|
+
@type = type
|
257
|
+
@value = value
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|