jcrvalidator 0.5.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.
- checksums.yaml +7 -0
- data/bin/jcr +26 -0
- data/lib/jcr/check_groups.rb +195 -0
- data/lib/jcr/evaluate_array_rules.rb +270 -0
- data/lib/jcr/evaluate_group_rules.rb +46 -0
- data/lib/jcr/evaluate_member_rules.rb +61 -0
- data/lib/jcr/evaluate_object_rules.rb +115 -0
- data/lib/jcr/evaluate_rules.rb +211 -0
- data/lib/jcr/evaluate_value_rules.rb +279 -0
- data/lib/jcr/find_roots.rb +106 -0
- data/lib/jcr/jcr.rb +228 -0
- data/lib/jcr/map_rule_names.rb +82 -0
- data/lib/jcr/parser.rb +398 -0
- data/lib/jcr/process_directives.rb +83 -0
- data/lib/jcr.rb +1 -0
- metadata +60 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 42b7b9f30fbdce18d3eb52e3fbea46a1a8a1350e
|
4
|
+
data.tar.gz: 80f3a34f4134303c2bc2c2e153330e316b4c0bef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 660737cced532d5aefa2de290c374eb3a69184d7628215ebfed9feac7d99f92ee7307fb470af295982641bb4dfb688497bfe15f45dc4bb6b53d134f5ad31488c
|
7
|
+
data.tar.gz: 6fd4e1d6b0cde8f89794d7529d5f19af9a13d6c51a8c1ab31c8350d1bd8dc58122c8e888304e496374899c4df20bcf92eca0ffd7a558a2637de059ce23250e00
|
data/bin/jcr
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (c) 2014-2015 American Registry for Internet Numbers
|
3
|
+
#
|
4
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
5
|
+
# purpose with or without fee is hereby granted, provided that the above
|
6
|
+
# copyright notice and this permission notice appear in all copies.
|
7
|
+
#
|
8
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
9
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
10
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
11
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
12
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
13
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
14
|
+
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
15
|
+
|
16
|
+
require 'rubygems'
|
17
|
+
begin
|
18
|
+
require 'jcr'
|
19
|
+
rescue LoadError
|
20
|
+
lib = File.expand_path("../lib",File.dirname(__FILE__))
|
21
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
22
|
+
require 'jcr'
|
23
|
+
end
|
24
|
+
|
25
|
+
JCR.main
|
26
|
+
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# Copyright (c) 2015 American Registry for Internet Numbers
|
2
|
+
#
|
3
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
# purpose with or without fee is hereby granted, provided that the above
|
5
|
+
# copyright notice and this permission notice appear in all copies.
|
6
|
+
#
|
7
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
13
|
+
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
|
+
|
15
|
+
require 'jcr/parser'
|
16
|
+
require 'jcr/map_rule_names'
|
17
|
+
|
18
|
+
module JCR
|
19
|
+
|
20
|
+
def self.check_groups( tree, mapping )
|
21
|
+
if tree.is_a? Array
|
22
|
+
tree.each do |node|
|
23
|
+
check_groups( node, mapping )
|
24
|
+
end
|
25
|
+
else # is a hash
|
26
|
+
if tree[:rule]
|
27
|
+
check_groups( tree[:rule], mapping )
|
28
|
+
elsif tree[:primitive_rule]
|
29
|
+
check_value_for_group( tree[:primitive_rule], mapping )
|
30
|
+
elsif tree[:type_choice_signifier]
|
31
|
+
check_value_for_group( tree, mapping )
|
32
|
+
elsif tree[:member_rule]
|
33
|
+
check_member_for_group( tree[:member_rule], mapping )
|
34
|
+
elsif tree[:array_rule]
|
35
|
+
check_array_for_group( tree[:array_rule], mapping )
|
36
|
+
elsif tree[:object_rule]
|
37
|
+
check_object_for_group( tree[:object_rule], mapping )
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.check_value_for_group node, mapping
|
43
|
+
if node[:group_rule]
|
44
|
+
disallowed_group_in_value?( node[:group_rule], mapping )
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.disallowed_group_in_value? node, mapping
|
49
|
+
if node.is_a? Hash
|
50
|
+
node = [ node ]
|
51
|
+
end
|
52
|
+
node.each do |groupee|
|
53
|
+
if groupee[:sequence_combiner]
|
54
|
+
raise_group_error( 'AND (comma) operation in group rule of value rule', groupee[:sequence_combiner] )
|
55
|
+
end
|
56
|
+
if groupee[:group_rule]
|
57
|
+
disallowed_group_in_value?( groupee[:group_rule], mapping )
|
58
|
+
elsif groupee[:target_rule_name]
|
59
|
+
trule = get_name_mapping( groupee[:target_rule_name][:rule_name], mapping )
|
60
|
+
disallowed_group_in_value?( trule[:rule], mapping )
|
61
|
+
elsif groupee[:member_rule]
|
62
|
+
raise_group_error( "groups in value rules cannot have member rules", groupee[:member_rule] )
|
63
|
+
elsif groupee[:object_rule]
|
64
|
+
raise_group_error( "groups in value rules cannot have object rules", groupee[:member_rule] )
|
65
|
+
elsif groupee[:array_rule]
|
66
|
+
raise_group_error( "groups in value rules cannot have array rules", groupee[:member_rule] )
|
67
|
+
elsif groupee[:primitive_rule]
|
68
|
+
disallowed_group_in_value?( groupee[:primitive_rule], mapping )
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.check_member_for_group node, mapping
|
74
|
+
if node[:target_rule_name]
|
75
|
+
trule = get_name_mapping( node[:target_rule_name][:rule_name], mapping )
|
76
|
+
disallowed_group_in_member?( trule, mapping )
|
77
|
+
elsif node[:group_rule]
|
78
|
+
disallowed_group_in_member?( node[:group_rule], mapping )
|
79
|
+
else
|
80
|
+
check_groups( node, mapping )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.disallowed_group_in_member? node, mapping
|
85
|
+
if node.is_a? Hash
|
86
|
+
node = [ node ]
|
87
|
+
end
|
88
|
+
node.each do |groupee|
|
89
|
+
if groupee[:sequence_combiner]
|
90
|
+
raise_group_error( 'AND (comma) operation in group rule of member rule', groupee[:sequence_combiner] )
|
91
|
+
end
|
92
|
+
if groupee[:group_rule]
|
93
|
+
disallowed_group_in_member?( groupee[:group_rule], mapping )
|
94
|
+
elsif groupee[:target_rule_name]
|
95
|
+
trule = get_name_mapping( groupee[:target_rule_name][:rule_name], mapping )
|
96
|
+
if trule[:group_rule]
|
97
|
+
disallowed_group_in_member?( trule[:group_rule], mapping )
|
98
|
+
end
|
99
|
+
elsif groupee[:member_rule]
|
100
|
+
raise_group_error( "groups in member rules cannot have member rules", groupee[:member_rule] )
|
101
|
+
else
|
102
|
+
check_groups( groupee, mapping )
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.check_array_for_group node, mapping
|
108
|
+
if node.is_a?( Array )
|
109
|
+
node.each do |child_node|
|
110
|
+
check_array_for_group( child_node, mapping )
|
111
|
+
end
|
112
|
+
elsif node.is_a? Hash
|
113
|
+
if node[:target_rule_name]
|
114
|
+
trule = get_name_mapping(node[:target_rule_name][:rule_name], mapping)
|
115
|
+
disallowed_group_in_array?(trule, mapping)
|
116
|
+
elsif node[:group_rule]
|
117
|
+
disallowed_group_in_array?(node[:group_rule], mapping)
|
118
|
+
else
|
119
|
+
check_groups(node, mapping)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.disallowed_group_in_array? node, mapping
|
125
|
+
if node.is_a? Hash
|
126
|
+
node = [ node ]
|
127
|
+
end
|
128
|
+
node.each do |groupee|
|
129
|
+
if groupee[:group_rule]
|
130
|
+
disallowed_group_in_array?( groupee[:group_rule], mapping )
|
131
|
+
elsif groupee[:target_rule_name]
|
132
|
+
trule = get_name_mapping( groupee[:target_rule_name][:rule_name], mapping )
|
133
|
+
if trule[:group_rule]
|
134
|
+
disallowed_group_in_array?( trule[:group_rule], mapping )
|
135
|
+
end
|
136
|
+
elsif groupee[:member_rule]
|
137
|
+
raise_group_error( "groups in array rules cannot have member rules", groupee[:member_rule] )
|
138
|
+
else
|
139
|
+
check_groups( groupee, mapping )
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.check_object_for_group node, mapping
|
145
|
+
if node.is_a?( Array )
|
146
|
+
node.each do |child_node|
|
147
|
+
check_object_for_group( child_node, mapping )
|
148
|
+
end
|
149
|
+
elsif node.is_a? Hash
|
150
|
+
if node[:target_rule_name]
|
151
|
+
trule = get_name_mapping(node[:target_rule_name][:rule_name], mapping)
|
152
|
+
disallowed_group_in_object?(trule, mapping)
|
153
|
+
elsif node[:group_rule]
|
154
|
+
disallowed_group_in_object?(node[:group_rule], mapping)
|
155
|
+
else
|
156
|
+
check_groups(node, mapping)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.disallowed_group_in_object? node, mapping
|
162
|
+
if node.is_a? Hash
|
163
|
+
node = [ node ]
|
164
|
+
end
|
165
|
+
node.each do |groupee|
|
166
|
+
if groupee[:group_rule]
|
167
|
+
disallowed_group_in_object?( groupee[:group_rule], mapping )
|
168
|
+
elsif groupee[:target_rule_name]
|
169
|
+
trule = get_name_mapping( groupee[:target_rule_name][:rule_name], mapping )
|
170
|
+
if trule[:group_rule]
|
171
|
+
disallowed_group_in_object?( trule[:group_rule], mapping )
|
172
|
+
end
|
173
|
+
elsif groupee[:array_rule]
|
174
|
+
raise_group_error( "groups in object rules cannot have array rules", groupee[:member_rule] )
|
175
|
+
elsif groupee[:object_rule]
|
176
|
+
raise_group_error( "groups in object rules cannot have other object rules", groupee[:member_rule] )
|
177
|
+
elsif groupee[:primitive_rule]
|
178
|
+
raise_group_error( "groups in object rules cannot have value rules", groupee[:member_rule] )
|
179
|
+
else
|
180
|
+
check_groups( groupee, mapping )
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.raise_group_error str, node
|
186
|
+
if node.is_a?( Parslet::Slice )
|
187
|
+
pos = node.line_and_column
|
188
|
+
name = node.to_str
|
189
|
+
raise "group rule error at line " + pos[0].to_s + " column " + pos[1].to_s + " name '" + name + "' :" + str
|
190
|
+
else
|
191
|
+
raise "group rule error with '" + node.to_s + "' :" + str
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
# Copyright (c) 2015 American Registry for Internet Numbers
|
2
|
+
#
|
3
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
# purpose with or without fee is hereby granted, provided that the above
|
5
|
+
# copyright notice and this permission notice appear in all copies.
|
6
|
+
#
|
7
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
13
|
+
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
|
+
|
15
|
+
require 'ipaddr'
|
16
|
+
require 'time'
|
17
|
+
require 'addressable/uri'
|
18
|
+
require 'addressable/template'
|
19
|
+
require 'email_address_validator'
|
20
|
+
require 'big-phoney'
|
21
|
+
|
22
|
+
require 'jcr/parser'
|
23
|
+
require 'jcr/map_rule_names'
|
24
|
+
require 'jcr/check_groups'
|
25
|
+
require 'jcr/evaluate_rules'
|
26
|
+
|
27
|
+
module JCR
|
28
|
+
|
29
|
+
class ArrayBehavior
|
30
|
+
attr_accessor :checked_hash, :last_index, :ordered, :extra_prohibited
|
31
|
+
|
32
|
+
def initialize( current_behavior = nil )
|
33
|
+
if current_behavior
|
34
|
+
@checked_hash = {}
|
35
|
+
@checked_hash.merge!( current_behavior.checked_hash )
|
36
|
+
@last_index = current_behavior.last_index
|
37
|
+
@ordered = current_behavior.ordered
|
38
|
+
@extra_prohibited = false
|
39
|
+
else
|
40
|
+
@checked_hash = {}
|
41
|
+
@last_index = 0
|
42
|
+
@ordered = true
|
43
|
+
@extra_prohibited = true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.evaluate_array_rule jcr, rule_atom, data, econs, behavior = nil
|
49
|
+
|
50
|
+
rules, annotations = get_rules_and_annotations( jcr )
|
51
|
+
|
52
|
+
ordered = true
|
53
|
+
|
54
|
+
if behavior && behavior.is_a?( ArrayBehavior )
|
55
|
+
ordered = behavior.ordered
|
56
|
+
end
|
57
|
+
|
58
|
+
annotations.each do |a|
|
59
|
+
if a[:unordered_annotation]
|
60
|
+
ordered = false
|
61
|
+
break
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# if the data is not an array
|
66
|
+
return evaluate_reject( annotations,
|
67
|
+
Evaluation.new( false, "#{data} is not an array at #{jcr} from #{rule_atom}") ) unless data.is_a? Array
|
68
|
+
|
69
|
+
# if the array is zero length and there are zero sub-rules (it is suppose to be empty)
|
70
|
+
return evaluate_reject( annotations,
|
71
|
+
Evaluation.new( true, nil ) ) if rules.empty? && data.empty?
|
72
|
+
|
73
|
+
# if the array is not empty and there are zero sub-rules (it is suppose to be empty)
|
74
|
+
return evaluate_reject( annotations,
|
75
|
+
Evaluation.new( false, "Non-empty array at #{jcr} from #{rule_atom}" ) ) if rules.empty? && data.length != 0
|
76
|
+
|
77
|
+
if ordered
|
78
|
+
return evaluate_reject( annotations, evaluate_array_rule_ordered( rules, rule_atom, data, econs, behavior ) )
|
79
|
+
else
|
80
|
+
return evaluate_reject( annotations, evaluate_array_rule_unordered( rules, rule_atom, data, econs, behavior ) )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.evaluate_array_rule_ordered jcr, rule_atom, data, econs, behavior = nil
|
85
|
+
retval = nil
|
86
|
+
|
87
|
+
behavior = ArrayBehavior.new unless behavior
|
88
|
+
array_index = behavior.last_index
|
89
|
+
|
90
|
+
|
91
|
+
jcr.each do |rule|
|
92
|
+
|
93
|
+
# short circuit logic
|
94
|
+
if rule[:choice_combiner] && retval && retval.success
|
95
|
+
next
|
96
|
+
elsif rule[:sequence_combiner] && retval && !retval.success
|
97
|
+
break
|
98
|
+
end
|
99
|
+
|
100
|
+
repeat_min, repeat_max = get_repetitions( rule )
|
101
|
+
|
102
|
+
# group rules must be evaluated differently
|
103
|
+
# groups require the effects of the evaluation to be discarded if they are false
|
104
|
+
# groups must also be given the entire array
|
105
|
+
|
106
|
+
if (grule = get_group(rule, econs))
|
107
|
+
|
108
|
+
if repeat_min == 0
|
109
|
+
retval = Evaluation.new( true, nil )
|
110
|
+
else
|
111
|
+
for i in 1..repeat_min do
|
112
|
+
if array_index == data.length
|
113
|
+
return Evaluation.new( false, "array is not large enough for #{jcr} from #{rule_atom}" )
|
114
|
+
else
|
115
|
+
group_behavior = ArrayBehavior.new( behavior )
|
116
|
+
group_behavior.last_index = array_index
|
117
|
+
retval = evaluate_rule( grule, rule_atom, data, econs, group_behavior )
|
118
|
+
if retval.success
|
119
|
+
behavior.checked_hash.merge!( group_behavior.checked_hash )
|
120
|
+
array_index = group_behavior.last_index
|
121
|
+
else
|
122
|
+
break;
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
if !retval || retval.success
|
128
|
+
for i in behavior.checked_hash.length..repeat_max-1 do
|
129
|
+
break if array_index == data.length
|
130
|
+
group_behavior = ArrayBehavior.new( behavior )
|
131
|
+
group_behavior.last_index = array_index
|
132
|
+
e = evaluate_rule( grule, rule_atom, data, econs, group_behavior )
|
133
|
+
if e.success
|
134
|
+
behavior.checked_hash.merge!( group_behavior.checked_hash )
|
135
|
+
array_index = group_behavior.last_index
|
136
|
+
else
|
137
|
+
break;
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
else # else not grule (group)
|
143
|
+
|
144
|
+
if repeat_min == 0
|
145
|
+
retval = Evaluation.new( true, nil )
|
146
|
+
else
|
147
|
+
for i in 1..repeat_min do
|
148
|
+
if array_index == data.length
|
149
|
+
return Evaluation.new( false, "array is not large enough for #{jcr} from #{rule_atom}" )
|
150
|
+
else
|
151
|
+
retval = evaluate_rule( rule, rule_atom, data[ array_index ], econs, nil )
|
152
|
+
break unless retval.success
|
153
|
+
array_index = array_index + 1
|
154
|
+
behavior.checked_hash[ i + behavior.last_index ] = retval.success
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
if !retval || retval.success
|
159
|
+
for i in behavior.checked_hash.length..repeat_max-1 do
|
160
|
+
break if array_index == data.length
|
161
|
+
e = evaluate_rule( rule, rule_atom, data[ array_index ], econs, nil )
|
162
|
+
break unless e.success
|
163
|
+
array_index = array_index + 1
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end # end if grule else
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
behavior.last_index = array_index
|
172
|
+
|
173
|
+
if data.length > array_index && behavior.extra_prohibited
|
174
|
+
retval = Evaluation.new( false, "More itmes in array than specified for #{jcr} from #{rule_atom}" )
|
175
|
+
end
|
176
|
+
|
177
|
+
return retval
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.evaluate_array_rule_unordered jcr, rule_atom, data, econs, behavior = nil
|
182
|
+
|
183
|
+
retval = nil
|
184
|
+
unless behavior
|
185
|
+
behavior = ArrayBehavior.new
|
186
|
+
behavior.ordered = false
|
187
|
+
end
|
188
|
+
highest_index = 0
|
189
|
+
|
190
|
+
jcr.each do |rule|
|
191
|
+
|
192
|
+
# short circuit logic
|
193
|
+
if rule[:choice_combiner] && retval && retval.success
|
194
|
+
next
|
195
|
+
elsif rule[:sequence_combiner] && retval && !retval.success
|
196
|
+
break
|
197
|
+
end
|
198
|
+
|
199
|
+
repeat_min, repeat_max = get_repetitions( rule )
|
200
|
+
|
201
|
+
# group rules must be evaluated differently
|
202
|
+
# groups require the effects of the evaluation to be discarded if they are false
|
203
|
+
# groups must also be given the entire array
|
204
|
+
|
205
|
+
if (grule = get_group(rule, econs))
|
206
|
+
|
207
|
+
successes = 0
|
208
|
+
for i in 0..repeat_max-1
|
209
|
+
group_behavior = ArrayBehavior.new( behavior )
|
210
|
+
group_behavior.last_index = highest_index
|
211
|
+
group_behavior.ordered = false
|
212
|
+
e = evaluate_rule( grule, rule_atom, data, econs, group_behavior )
|
213
|
+
if e.success
|
214
|
+
highest_index = group_behavior.last_index
|
215
|
+
behavior.checked_hash.merge!( group_behavior.checked_hash )
|
216
|
+
successes = successes + 1
|
217
|
+
else
|
218
|
+
break;
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
if successes == 0 && repeat_min > 0
|
223
|
+
retval = Evaluation.new( false, "array does not contain #{rule} for #{jcr} from #{rule_atom}")
|
224
|
+
elsif successes < repeat_min
|
225
|
+
retval = Evaluation.new( false, "array does not have enough #{rule} for #{jcr} from #{rule_atom}")
|
226
|
+
elsif successes > repeat_max
|
227
|
+
retval = Evaluation.new( false, "array has too many #{rule} for #{jcr} from #{rule_atom}")
|
228
|
+
else
|
229
|
+
retval = Evaluation.new( true, nil )
|
230
|
+
end
|
231
|
+
|
232
|
+
else # else not group rule
|
233
|
+
|
234
|
+
successes = 0
|
235
|
+
for i in behavior.last_index..data.length
|
236
|
+
break if successes == repeat_max
|
237
|
+
unless behavior.checked_hash[ i ]
|
238
|
+
e = evaluate_rule( rule, rule_atom, data[ i ], econs, nil )
|
239
|
+
if e.success
|
240
|
+
behavior.checked_hash[ i ] = e.success
|
241
|
+
highest_index = i if i > highest_index
|
242
|
+
successes = successes + 1
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
if successes == 0 && repeat_min > 0
|
248
|
+
retval = Evaluation.new( false, "array does not contain #{rule} for #{jcr} from #{rule_atom}")
|
249
|
+
elsif successes < repeat_min
|
250
|
+
retval = Evaluation.new( false, "array does not have enough #{rule} for #{jcr} from #{rule_atom}")
|
251
|
+
elsif successes > repeat_max
|
252
|
+
retval = Evaluation.new( false, "array has too many #{rule} for #{jcr} from #{rule_atom}")
|
253
|
+
else
|
254
|
+
retval = Evaluation.new( true, nil)
|
255
|
+
end
|
256
|
+
|
257
|
+
end # if grule else
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
behavior.last_index = highest_index
|
262
|
+
|
263
|
+
if data.length > behavior.checked_hash.length && behavior.extra_prohibited
|
264
|
+
retval = Evaluation.new( false, "More itmes in array than specified for #{jcr} from #{rule_atom}" )
|
265
|
+
end
|
266
|
+
|
267
|
+
return retval
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Copyright (c) 2015 American Registry for Internet Numbers
|
2
|
+
#
|
3
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
# purpose with or without fee is hereby granted, provided that the above
|
5
|
+
# copyright notice and this permission notice appear in all copies.
|
6
|
+
#
|
7
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
13
|
+
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
|
+
|
15
|
+
require 'ipaddr'
|
16
|
+
require 'time'
|
17
|
+
require 'addressable/uri'
|
18
|
+
require 'addressable/template'
|
19
|
+
require 'email_address_validator'
|
20
|
+
require 'big-phoney'
|
21
|
+
|
22
|
+
require 'jcr/parser'
|
23
|
+
require 'jcr/map_rule_names'
|
24
|
+
require 'jcr/check_groups'
|
25
|
+
|
26
|
+
module JCR
|
27
|
+
|
28
|
+
def self.evaluate_group_rule jcr, rule_atom, data, econs, behavior = nil
|
29
|
+
|
30
|
+
rules, annotations = get_rules_and_annotations( jcr )
|
31
|
+
|
32
|
+
retval = nil
|
33
|
+
|
34
|
+
rules.each do |rule|
|
35
|
+
if rule[:choice_combiner] && retval && retval.success
|
36
|
+
return evaluate_reject( annotations, retval ) # short circuit
|
37
|
+
elsif rule[:sequence_combiner] && retval && !retval.success
|
38
|
+
return evaluate_reject( annotations, retval ) # short circuit
|
39
|
+
end
|
40
|
+
retval = evaluate_rule( rule, rule_atom, data, econs, behavior )
|
41
|
+
end
|
42
|
+
|
43
|
+
return evaluate_reject( annotations, retval )
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Copyright (c) 2015 American Registry for Internet Numbers
|
2
|
+
#
|
3
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
# purpose with or without fee is hereby granted, provided that the above
|
5
|
+
# copyright notice and this permission notice appear in all copies.
|
6
|
+
#
|
7
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
13
|
+
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
|
+
|
15
|
+
require 'ipaddr'
|
16
|
+
require 'time'
|
17
|
+
require 'addressable/uri'
|
18
|
+
require 'addressable/template'
|
19
|
+
require 'email_address_validator'
|
20
|
+
require 'big-phoney'
|
21
|
+
|
22
|
+
require 'jcr/parser'
|
23
|
+
require 'jcr/map_rule_names'
|
24
|
+
require 'jcr/check_groups'
|
25
|
+
|
26
|
+
module JCR
|
27
|
+
|
28
|
+
def self.evaluate_member_rule jcr, rule_atom, data, econs
|
29
|
+
|
30
|
+
# unlike the other evaluate functions, here data is not just the json data.
|
31
|
+
# it is an array, the first element being the member name or regex and the
|
32
|
+
# second being the json data to be furthered on to other evaluation functions
|
33
|
+
|
34
|
+
rules, annotations = get_rules_and_annotations( jcr )
|
35
|
+
rule = rules[0]
|
36
|
+
|
37
|
+
member_match = false
|
38
|
+
|
39
|
+
if rule[:member_name]
|
40
|
+
match_spec = rule[:member_name][:q_string].to_s
|
41
|
+
if match_spec == data[ 0 ]
|
42
|
+
member_match = true
|
43
|
+
end
|
44
|
+
else # must be regex
|
45
|
+
match_spec = Regexp.new( rule[:member_regex][:regex].to_s )
|
46
|
+
if match_spec =~ data[ 0 ]
|
47
|
+
member_match = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if member_match
|
52
|
+
e = evaluate_rule( rule, rule_atom, data[ 1 ], econs )
|
53
|
+
return evaluate_reject( annotations, e )
|
54
|
+
end
|
55
|
+
|
56
|
+
return evaluate_reject( annotations,
|
57
|
+
Evaluation.new( false, "#{match_spec} does not match #{data[0]} for #{jcr} from #{rule_atom}" ) )
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|