jcrvalidator 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|