jcrvalidator 0.8.0 → 0.8.1
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 +4 -4
- data/lib/jcr/check_groups.rb +4 -14
- data/lib/jcr/evaluate_array_rules.rb +41 -26
- data/lib/jcr/evaluate_group_rules.rb +6 -6
- data/lib/jcr/evaluate_member_rules.rb +7 -6
- data/lib/jcr/evaluate_object_rules.rb +37 -25
- data/lib/jcr/evaluate_rules.rb +83 -32
- data/lib/jcr/evaluate_value_rules.rb +4 -3
- data/lib/jcr/jcr.rb +58 -21
- data/lib/jcr/jcr_validator_error.rb +21 -0
- data/lib/jcr/map_rule_names.rb +6 -4
- data/lib/jcr/parts.rb +16 -2
- data/lib/jcr/process_directives.rb +1 -1
- data/lib/jcr/version.rb +2 -2
- metadata +3 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e15f3d872870b687c53a8cf98ab6668afec8c3c5
         | 
| 4 | 
            +
              data.tar.gz: 01250f5fe01fe29a8025f6aac9da8c83766df494
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 6218f0d7f612b32759383f0869e39bbaf04850cdaf12cd4400796b164e745da40ffc371d9f564abd4e0135417805b5794c0c94af68f7282cb5c8284d3910e3fb
         | 
| 7 | 
            +
              data.tar.gz: 4c1aebcccc76bd2806ca98d9d7e582e3353eda4c07a2fc1fb915a5ffcf192172b2ce04015046bfca5f566e0fa67a789164aa68421b90b3f3aee8df28e41fcc8d
         | 
    
        data/lib/jcr/check_groups.rb
    CHANGED
    
    | @@ -78,8 +78,6 @@ module JCR | |
| 78 78 | 
             
                  disallowed_group_in_member?( trule, mapping )
         | 
| 79 79 | 
             
                elsif node[:group_rule]
         | 
| 80 80 | 
             
                  disallowed_group_in_member?( node[:group_rule], mapping )
         | 
| 81 | 
            -
                else
         | 
| 82 | 
            -
                  check_groups( node, mapping )
         | 
| 83 81 | 
             
                end
         | 
| 84 82 | 
             
              end
         | 
| 85 83 |  | 
| @@ -117,8 +115,6 @@ module JCR | |
| 117 115 | 
             
                    disallowed_group_in_array?(trule, mapping)
         | 
| 118 116 | 
             
                  elsif node[:group_rule]
         | 
| 119 117 | 
             
                    disallowed_group_in_array?(node[:group_rule], mapping)
         | 
| 120 | 
            -
                  else
         | 
| 121 | 
            -
                    check_groups(node, mapping)
         | 
| 122 118 | 
             
                  end
         | 
| 123 119 | 
             
                end
         | 
| 124 120 | 
             
              end
         | 
| @@ -132,9 +128,7 @@ module JCR | |
| 132 128 | 
             
                    disallowed_group_in_array?( groupee[:group_rule], mapping )
         | 
| 133 129 | 
             
                  elsif groupee[:target_rule_name]
         | 
| 134 130 | 
             
                    trule = get_name_mapping( groupee[:target_rule_name][:rule_name], mapping )
         | 
| 135 | 
            -
                     | 
| 136 | 
            -
                      disallowed_group_in_array?( trule[:group_rule], mapping )
         | 
| 137 | 
            -
                    end
         | 
| 131 | 
            +
                    disallowed_group_in_array?( trule, mapping )
         | 
| 138 132 | 
             
                  elsif groupee[:member_rule]
         | 
| 139 133 | 
             
                    raise_group_error( "groups in array rules cannot have member rules", groupee[:member_rule] )
         | 
| 140 134 | 
             
                  else
         | 
| @@ -154,8 +148,6 @@ module JCR | |
| 154 148 | 
             
                    disallowed_group_in_object?(trule, mapping)
         | 
| 155 149 | 
             
                  elsif node[:group_rule]
         | 
| 156 150 | 
             
                    disallowed_group_in_object?(node[:group_rule], mapping)
         | 
| 157 | 
            -
                  else
         | 
| 158 | 
            -
                    check_groups(node, mapping)
         | 
| 159 151 | 
             
                  end
         | 
| 160 152 | 
             
                end
         | 
| 161 153 | 
             
              end
         | 
| @@ -169,9 +161,7 @@ module JCR | |
| 169 161 | 
             
                    disallowed_group_in_object?( groupee[:group_rule], mapping )
         | 
| 170 162 | 
             
                  elsif groupee[:target_rule_name]
         | 
| 171 163 | 
             
                    trule = get_name_mapping( groupee[:target_rule_name][:rule_name], mapping )
         | 
| 172 | 
            -
                     | 
| 173 | 
            -
                      disallowed_group_in_object?( trule[:group_rule], mapping )
         | 
| 174 | 
            -
                    end
         | 
| 164 | 
            +
                    disallowed_group_in_object?( trule, mapping )
         | 
| 175 165 | 
             
                  elsif groupee[:array_rule]
         | 
| 176 166 | 
             
                    raise_group_error( "groups in object rules cannot have array rules", groupee[:member_rule] )
         | 
| 177 167 | 
             
                  elsif groupee[:object_rule]
         | 
| @@ -188,9 +178,9 @@ module JCR | |
| 188 178 | 
             
                if node.is_a?( Parslet::Slice )
         | 
| 189 179 | 
             
                  pos = node.line_and_column
         | 
| 190 180 | 
             
                  name = node.to_str
         | 
| 191 | 
            -
                  raise "group rule error at line " + pos[0].to_s + " column " + pos[1].to_s + " name '" + name + "' :" + str
         | 
| 181 | 
            +
                  raise JCR::JcrValidatorError, "group rule error at line " + pos[0].to_s + " column " + pos[1].to_s + " name '" + name + "' :" + str
         | 
| 192 182 | 
             
                else
         | 
| 193 | 
            -
                  raise "group rule error with '" + node.to_s + "' :" + str
         | 
| 183 | 
            +
                  raise JCR::JcrValidatorError, "group rule error with '" + node.to_s + "' :" + str
         | 
| 194 184 | 
             
                end
         | 
| 195 185 | 
             
              end
         | 
| 196 186 |  | 
| @@ -45,19 +45,28 @@ module JCR | |
| 45 45 | 
             
                end
         | 
| 46 46 | 
             
              end
         | 
| 47 47 |  | 
| 48 | 
            -
              def self.evaluate_array_rule jcr, rule_atom, data, econs, behavior = nil
         | 
| 48 | 
            +
              def self.evaluate_array_rule jcr, rule_atom, data, econs, behavior = nil, target_annotations = nil
         | 
| 49 49 |  | 
| 50 50 | 
             
                push_trace_stack( econs, jcr )
         | 
| 51 | 
            -
                 | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
                 | 
| 51 | 
            +
                if behavior
         | 
| 52 | 
            +
                  trace( econs, "Evaluating group in array rule starting at #{slice_to_s(jcr)} against", data )
         | 
| 53 | 
            +
                  trace_def( econs, "array group", jcr, data )
         | 
| 54 | 
            +
                else
         | 
| 55 | 
            +
                  trace( econs, "Evaluating array rule starting at #{slice_to_s(jcr)} against", data )
         | 
| 56 | 
            +
                  trace_def( econs, "array", jcr, data )
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
                retval = evaluate_array( jcr, rule_atom, data, econs, behavior, target_annotations )
         | 
| 59 | 
            +
                if behavior
         | 
| 60 | 
            +
                  trace_eval( econs, "Array group", retval, jcr, data, "array" )
         | 
| 61 | 
            +
                else
         | 
| 62 | 
            +
                  trace_eval( econs, "Array", retval, jcr, data, "array" )
         | 
| 63 | 
            +
                end
         | 
| 55 64 | 
             
                pop_trace_stack( econs )
         | 
| 56 65 | 
             
                return retval
         | 
| 57 66 |  | 
| 58 67 | 
             
              end
         | 
| 59 68 |  | 
| 60 | 
            -
              def self.evaluate_array jcr, rule_atom, data, econs, behavior = nil
         | 
| 69 | 
            +
              def self.evaluate_array jcr, rule_atom, data, econs, behavior = nil, target_annotations = nil
         | 
| 61 70 |  | 
| 62 71 | 
             
                rules, annotations = get_rules_and_annotations( jcr )
         | 
| 63 72 |  | 
| @@ -76,20 +85,24 @@ module JCR | |
| 76 85 |  | 
| 77 86 | 
             
                # if the data is not an array
         | 
| 78 87 | 
             
                return evaluate_not( annotations,
         | 
| 79 | 
            -
                  Evaluation.new( false, "#{data} is not an array #{raised_rule(jcr,rule_atom)}"), | 
| 88 | 
            +
                  Evaluation.new( false, "#{data} is not an array #{raised_rule(jcr,rule_atom)}"),
         | 
| 89 | 
            +
                                     econs, target_annotations ) unless data.is_a? Array
         | 
| 80 90 |  | 
| 81 91 | 
             
                # if the array is zero length and there are zero sub-rules (it is suppose to be empty)
         | 
| 82 92 | 
             
                return evaluate_not( annotations,
         | 
| 83 | 
            -
                  Evaluation.new( true, nil ), econs ) if rules.empty? && data.empty?
         | 
| 93 | 
            +
                  Evaluation.new( true, nil ), econs, target_annotations ) if rules.empty? && data.empty?
         | 
| 84 94 |  | 
| 85 95 | 
             
                # if the array is not empty and there are zero sub-rules (it is suppose to be empty)
         | 
| 86 96 | 
             
                return evaluate_not( annotations,
         | 
| 87 | 
            -
                  Evaluation.new( false, "Non-empty array for #{raised_rule(jcr,rule_atom)}" ), | 
| 97 | 
            +
                  Evaluation.new( false, "Non-empty array for #{raised_rule(jcr,rule_atom)}" ),
         | 
| 98 | 
            +
                                     econs, target_annotations ) if rules.empty? && data.length != 0
         | 
| 88 99 |  | 
| 89 100 | 
             
                if ordered
         | 
| 90 | 
            -
                  return evaluate_not( annotations, evaluate_array_rule_ordered( rules, rule_atom, data, econs, behavior ), | 
| 101 | 
            +
                  return evaluate_not( annotations, evaluate_array_rule_ordered( rules, rule_atom, data, econs, behavior ),
         | 
| 102 | 
            +
                                       econs, target_annotations )
         | 
| 91 103 | 
             
                else
         | 
| 92 | 
            -
                  return evaluate_not( annotations, evaluate_array_rule_unordered( rules, rule_atom, data, econs, behavior ), | 
| 104 | 
            +
                  return evaluate_not( annotations, evaluate_array_rule_unordered( rules, rule_atom, data, econs, behavior ),
         | 
| 105 | 
            +
                                       econs, target_annotations )
         | 
| 93 106 | 
             
                end
         | 
| 94 107 | 
             
              end
         | 
| 95 108 |  | 
| @@ -115,7 +128,8 @@ module JCR | |
| 115 128 | 
             
                  # groups require the effects of the evaluation to be discarded if they are false
         | 
| 116 129 | 
             
                  # groups must also be given the entire array
         | 
| 117 130 |  | 
| 118 | 
            -
                   | 
| 131 | 
            +
                  grule, target_annotations = get_group( rule, econs )
         | 
| 132 | 
            +
                  if grule
         | 
| 119 133 |  | 
| 120 134 | 
             
                    if repeat_min == 0
         | 
| 121 135 | 
             
                      retval = Evaluation.new( true, nil )
         | 
| @@ -126,7 +140,7 @@ module JCR | |
| 126 140 | 
             
                        else
         | 
| 127 141 | 
             
                          group_behavior = ArrayBehavior.new( behavior )
         | 
| 128 142 | 
             
                          group_behavior.last_index = array_index
         | 
| 129 | 
            -
                          retval = evaluate_rule( grule, rule_atom, data, econs, group_behavior )
         | 
| 143 | 
            +
                          retval = evaluate_rule( grule, rule_atom, data, econs, group_behavior, target_annotations )
         | 
| 130 144 | 
             
                          if retval.success
         | 
| 131 145 | 
             
                            behavior.checked_hash.merge!( group_behavior.checked_hash )
         | 
| 132 146 | 
             
                            array_index = group_behavior.last_index
         | 
| @@ -141,7 +155,7 @@ module JCR | |
| 141 155 | 
             
                        break if array_index == data.length
         | 
| 142 156 | 
             
                        group_behavior = ArrayBehavior.new( behavior )
         | 
| 143 157 | 
             
                        group_behavior.last_index = array_index
         | 
| 144 | 
            -
                        e = evaluate_rule( grule, rule_atom, data, econs, group_behavior )
         | 
| 158 | 
            +
                        e = evaluate_rule( grule, rule_atom, data, econs, group_behavior, target_annotations )
         | 
| 145 159 | 
             
                        if e.success
         | 
| 146 160 | 
             
                          behavior.checked_hash.merge!( group_behavior.checked_hash )
         | 
| 147 161 | 
             
                          array_index = group_behavior.last_index
         | 
| @@ -187,7 +201,7 @@ module JCR | |
| 187 201 | 
             
                behavior.last_index = array_index
         | 
| 188 202 |  | 
| 189 203 | 
             
                if data.length > array_index && behavior.extra_prohibited
         | 
| 190 | 
            -
                  retval = Evaluation.new( false, "More  | 
| 204 | 
            +
                  retval = Evaluation.new( false, "More items in array (#{data.length}) than specified (#{array_index}) for #{raised_rule(jcr,rule_atom)}" )
         | 
| 191 205 | 
             
                end
         | 
| 192 206 |  | 
| 193 207 | 
             
                return retval
         | 
| @@ -218,14 +232,15 @@ module JCR | |
| 218 232 | 
             
                  # groups require the effects of the evaluation to be discarded if they are false
         | 
| 219 233 | 
             
                  # groups must also be given the entire array
         | 
| 220 234 |  | 
| 221 | 
            -
                   | 
| 235 | 
            +
                  grule,target_annotations = get_group(rule, econs)
         | 
| 236 | 
            +
                  if grule
         | 
| 222 237 |  | 
| 223 238 | 
             
                    successes = 0
         | 
| 224 239 | 
             
                    for i in 0..repeat_max-1
         | 
| 225 240 | 
             
                      group_behavior = ArrayBehavior.new( behavior )
         | 
| 226 241 | 
             
                      group_behavior.last_index = highest_index
         | 
| 227 242 | 
             
                      group_behavior.ordered = false
         | 
| 228 | 
            -
                      e = evaluate_rule( grule, rule_atom, data, econs, group_behavior )
         | 
| 243 | 
            +
                      e = evaluate_rule( grule, rule_atom, data, econs, group_behavior, target_annotations )
         | 
| 229 244 | 
             
                      if e.success
         | 
| 230 245 | 
             
                        highest_index = group_behavior.last_index
         | 
| 231 246 | 
             
                        behavior.checked_hash.merge!( group_behavior.checked_hash )
         | 
| @@ -236,13 +251,13 @@ module JCR | |
| 236 251 | 
             
                    end
         | 
| 237 252 |  | 
| 238 253 | 
             
                    if successes == 0 && repeat_min > 0
         | 
| 239 | 
            -
                      retval = Evaluation.new( false, "array does not contain #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 254 | 
            +
                      retval = Evaluation.new( false, "array does not contain #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 240 255 | 
             
                    elsif successes < repeat_min
         | 
| 241 | 
            -
                      retval = Evaluation.new( false, "array does not have enough #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 256 | 
            +
                      retval = Evaluation.new( false, "array does not have enough #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 242 257 | 
             
                    elsif successes > repeat_max
         | 
| 243 | 
            -
                      retval = Evaluation.new( false, "array has too many #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 258 | 
            +
                      retval = Evaluation.new( false, "array has too many #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 244 259 | 
             
                    elsif repeat_step && ( successes - repeat_min ) % repeat_step != 0
         | 
| 245 | 
            -
                      retval = Evaluation.new( false, "array matches (#{successes}) do not meet repetition step of #{repeat_max} % #{repeat_step} with #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 260 | 
            +
                      retval = Evaluation.new( false, "array matches (#{successes}) do not meet repetition step of #{repeat_max} % #{repeat_step} with #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 246 261 | 
             
                    else
         | 
| 247 262 | 
             
                      retval = Evaluation.new( true, nil )
         | 
| 248 263 | 
             
                    end
         | 
| @@ -263,13 +278,13 @@ module JCR | |
| 263 278 | 
             
                    end
         | 
| 264 279 |  | 
| 265 280 | 
             
                    if successes == 0 && repeat_min > 0
         | 
| 266 | 
            -
                      retval = Evaluation.new( false, "array does not contain #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 281 | 
            +
                      retval = Evaluation.new( false, "array does not contain #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 267 282 | 
             
                    elsif successes < repeat_min
         | 
| 268 | 
            -
                      retval = Evaluation.new( false, "array does not have enough #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 283 | 
            +
                      retval = Evaluation.new( false, "array does not have enough #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 269 284 | 
             
                    elsif successes > repeat_max
         | 
| 270 | 
            -
                      retval = Evaluation.new( false, "array has too many #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 285 | 
            +
                      retval = Evaluation.new( false, "array has too many #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 271 286 | 
             
                    elsif repeat_step && ( successes - repeat_min ) % repeat_step != 0
         | 
| 272 | 
            -
                      retval = Evaluation.new( false, "array matches (#{successes}) do not meet repetition step of #{repeat_max} % #{repeat_step} with #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 287 | 
            +
                      retval = Evaluation.new( false, "array matches (#{successes}) do not meet repetition step of #{repeat_max} % #{repeat_step} with #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 273 288 | 
             
                    else
         | 
| 274 289 | 
             
                      retval = Evaluation.new( true, nil)
         | 
| 275 290 | 
             
                    end
         | 
| @@ -281,7 +296,7 @@ module JCR | |
| 281 296 | 
             
                behavior.last_index = highest_index
         | 
| 282 297 |  | 
| 283 298 | 
             
                if data.length > behavior.checked_hash.length && behavior.extra_prohibited
         | 
| 284 | 
            -
                  retval = Evaluation.new( false, "More  | 
| 299 | 
            +
                  retval = Evaluation.new( false, "More items in array than specified for #{raised_rule(jcr,rule_atom)}" )
         | 
| 285 300 | 
             
                end
         | 
| 286 301 |  | 
| 287 302 | 
             
                return retval
         | 
| @@ -26,19 +26,19 @@ require 'jcr/evaluate_rules' | |
| 26 26 |  | 
| 27 27 | 
             
            module JCR
         | 
| 28 28 |  | 
| 29 | 
            -
              def self.evaluate_group_rule jcr, rule_atom, data, econs, behavior = nil
         | 
| 29 | 
            +
              def self.evaluate_group_rule jcr, rule_atom, data, econs, behavior = nil, target_annotations = nil
         | 
| 30 30 |  | 
| 31 31 | 
             
                push_trace_stack( econs, jcr )
         | 
| 32 32 | 
             
                trace( econs, "Evaluating group rule against ", data )
         | 
| 33 33 | 
             
                trace_def( econs, "group", jcr, data )
         | 
| 34 | 
            -
                retval = evaluate_group( jcr, rule_atom, data, econs, behavior )
         | 
| 34 | 
            +
                retval = evaluate_group( jcr, rule_atom, data, econs, behavior, target_annotations )
         | 
| 35 35 | 
             
                trace_eval( econs, "Group", retval, jcr, data, "group" )
         | 
| 36 36 | 
             
                pop_trace_stack( econs )
         | 
| 37 37 | 
             
                return retval
         | 
| 38 38 |  | 
| 39 39 | 
             
              end
         | 
| 40 40 |  | 
| 41 | 
            -
              def self.evaluate_group jcr, rule_atom, data, econs, behavior = nil
         | 
| 41 | 
            +
              def self.evaluate_group jcr, rule_atom, data, econs, behavior = nil, target_annotations = nil
         | 
| 42 42 |  | 
| 43 43 | 
             
                rules, annotations = get_rules_and_annotations( jcr )
         | 
| 44 44 |  | 
| @@ -46,14 +46,14 @@ module JCR | |
| 46 46 |  | 
| 47 47 | 
             
                rules.each do |rule|
         | 
| 48 48 | 
             
                  if rule[:choice_combiner] && retval && retval.success
         | 
| 49 | 
            -
                    return evaluate_not( annotations, retval, econs ) # short circuit
         | 
| 49 | 
            +
                    return evaluate_not( annotations, retval, econs, target_annotations ) # short circuit
         | 
| 50 50 | 
             
                  elsif rule[:sequence_combiner] && retval && !retval.success
         | 
| 51 | 
            -
                    return evaluate_not( annotations, retval, econs ) # short circuit
         | 
| 51 | 
            +
                    return evaluate_not( annotations, retval, econs, target_annotations ) # short circuit
         | 
| 52 52 | 
             
                  end
         | 
| 53 53 | 
             
                  retval = evaluate_rule( rule, rule_atom, data, econs, behavior )
         | 
| 54 54 | 
             
                end
         | 
| 55 55 |  | 
| 56 | 
            -
                return evaluate_not( annotations, retval, econs )
         | 
| 56 | 
            +
                return evaluate_not( annotations, retval, econs, target_annotations )
         | 
| 57 57 | 
             
              end
         | 
| 58 58 |  | 
| 59 59 | 
             
              def self.group_to_s( jcr, shallow=true)
         | 
| @@ -25,19 +25,19 @@ require 'jcr/check_groups' | |
| 25 25 |  | 
| 26 26 | 
             
            module JCR
         | 
| 27 27 |  | 
| 28 | 
            -
              def self.evaluate_member_rule jcr, rule_atom, data, econs
         | 
| 28 | 
            +
              def self.evaluate_member_rule jcr, rule_atom, data, econs, behavior, target_annotations
         | 
| 29 29 |  | 
| 30 30 | 
             
                push_trace_stack( econs, jcr )
         | 
| 31 31 | 
             
                trace( econs, "Evaluating member rule for key '#{data[0]}' starting at #{slice_to_s(jcr)} against ", data[1])
         | 
| 32 32 | 
             
                trace_def( econs, "member", jcr, data )
         | 
| 33 | 
            -
                retval = evaluate_member( jcr, rule_atom, data, econs )
         | 
| 33 | 
            +
                retval = evaluate_member( jcr, rule_atom, data, econs, behavior, target_annotations )
         | 
| 34 34 | 
             
                trace_eval( econs, "Member", retval, jcr, data, "member" )
         | 
| 35 35 | 
             
                pop_trace_stack( econs )
         | 
| 36 36 | 
             
                return retval
         | 
| 37 37 |  | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| 40 | 
            -
              def self.evaluate_member jcr, rule_atom, data, econs
         | 
| 40 | 
            +
              def self.evaluate_member jcr, rule_atom, data, econs, behavior, target_annotations
         | 
| 41 41 |  | 
| 42 42 | 
             
                # unlike the other evaluate functions, here data is not just the json data.
         | 
| 43 43 | 
             
                # it is an array, the first element being the member name or regex and the
         | 
| @@ -68,13 +68,14 @@ module JCR | |
| 68 68 | 
             
                end
         | 
| 69 69 |  | 
| 70 70 | 
             
                if member_match
         | 
| 71 | 
            -
                  e = evaluate_rule( rule, rule_atom, data[ 1 ], econs )
         | 
| 71 | 
            +
                  e = evaluate_rule( rule, rule_atom, data[ 1 ], econs, nil, target_annotations )
         | 
| 72 72 | 
             
                  e.member_found = true
         | 
| 73 | 
            -
                  return evaluate_not( annotations, e, econs )
         | 
| 73 | 
            +
                  return evaluate_not( annotations, e, econs, target_annotations )
         | 
| 74 74 | 
             
                end
         | 
| 75 75 |  | 
| 76 76 | 
             
                return evaluate_not( annotations,
         | 
| 77 | 
            -
                   Evaluation.new( false, "#{match_spec} does not match #{data[0]} for #{raised_rule( jcr, rule_atom)}" ), | 
| 77 | 
            +
                   Evaluation.new( false, "#{match_spec} does not match #{data[0]} for #{raised_rule( jcr, rule_atom)}" ),
         | 
| 78 | 
            +
                                     econs, target_annotations )
         | 
| 78 79 |  | 
| 79 80 | 
             
              end
         | 
| 80 81 |  | 
| @@ -27,33 +27,44 @@ module JCR | |
| 27 27 | 
             
                end
         | 
| 28 28 | 
             
              end
         | 
| 29 29 |  | 
| 30 | 
            -
              def self.evaluate_object_rule jcr, rule_atom, data, econs, behavior = nil
         | 
| 30 | 
            +
              def self.evaluate_object_rule jcr, rule_atom, data, econs, behavior = nil, target_annotations = nil
         | 
| 31 31 |  | 
| 32 32 | 
             
                push_trace_stack( econs, jcr )
         | 
| 33 | 
            -
                 | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
                 | 
| 33 | 
            +
                if behavior
         | 
| 34 | 
            +
                  trace( econs, "Evaluating group in object rule starting at #{slice_to_s(jcr)} against", data )
         | 
| 35 | 
            +
                  trace_def( econs, "object group", jcr, data )
         | 
| 36 | 
            +
                else
         | 
| 37 | 
            +
                  trace( econs, "Evaluating object rule starting at #{slice_to_s(jcr)} against", data )
         | 
| 38 | 
            +
                  trace_def( econs, "object", jcr, data )
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
                retval = evaluate_object( jcr, rule_atom, data, econs, behavior, target_annotations )
         | 
| 41 | 
            +
                if behavior
         | 
| 42 | 
            +
                  trace_eval( econs, "Object group", retval, jcr, data, "object" )
         | 
| 43 | 
            +
                else
         | 
| 44 | 
            +
                  trace_eval( econs, "Object", retval, jcr, data, "object" )
         | 
| 45 | 
            +
                end
         | 
| 37 46 | 
             
                pop_trace_stack( econs )
         | 
| 38 47 | 
             
                return retval
         | 
| 39 48 |  | 
| 40 49 | 
             
              end
         | 
| 41 50 |  | 
| 42 | 
            -
              def self.evaluate_object jcr, rule_atom, data, econs, behavior = nil
         | 
| 51 | 
            +
              def self.evaluate_object jcr, rule_atom, data, econs, behavior = nil, target_annotations = nil
         | 
| 43 52 |  | 
| 44 53 | 
             
                rules, annotations = get_rules_and_annotations( jcr )
         | 
| 45 54 |  | 
| 46 55 | 
             
                # if the data is not an object (Hash)
         | 
| 47 56 | 
             
                return evaluate_not( annotations,
         | 
| 48 | 
            -
                  Evaluation.new( false, "#{data} is not an object for #{raised_rule(jcr,rule_atom)}"), | 
| 57 | 
            +
                  Evaluation.new( false, "#{data} is not an object for #{raised_rule(jcr,rule_atom)}"),
         | 
| 58 | 
            +
                                  econs, target_annotations ) unless data.is_a? Hash
         | 
| 49 59 |  | 
| 50 60 | 
             
                # if the object has no members and there are zero sub-rules (it is suppose to be empty)
         | 
| 51 61 | 
             
                return evaluate_not( annotations,
         | 
| 52 | 
            -
                  Evaluation.new( true, nil ), econs ) if rules.empty? && data.length == 0
         | 
| 62 | 
            +
                  Evaluation.new( true, nil ), econs, target_annotations ) if rules.empty? && data.length == 0
         | 
| 53 63 |  | 
| 54 64 | 
             
                # if the object has members and there are zero sub-rules (it is suppose to be empty)
         | 
| 55 65 | 
             
                return evaluate_not( annotations,
         | 
| 56 | 
            -
                  Evaluation.new( false, "Non-empty object for #{raised_rule(jcr,rule_atom)}" ), | 
| 66 | 
            +
                  Evaluation.new( false, "Non-empty object for #{raised_rule(jcr,rule_atom)}" ),
         | 
| 67 | 
            +
                                     econs, target_annotations ) if rules.empty? && data.length != 0
         | 
| 57 68 |  | 
| 58 69 | 
             
                retval = nil
         | 
| 59 70 | 
             
                behavior = ObjectBehavior.new unless behavior
         | 
| @@ -64,7 +75,7 @@ module JCR | |
| 64 75 | 
             
                  if rule[:choice_combiner] && retval && retval.success
         | 
| 65 76 | 
             
                    next
         | 
| 66 77 | 
             
                  elsif rule[:sequence_combiner] && retval && !retval.success
         | 
| 67 | 
            -
                    return evaluate_not( annotations, retval, econs ) # short circuit
         | 
| 78 | 
            +
                    return evaluate_not( annotations, retval, econs, target_annotations ) # short circuit
         | 
| 68 79 | 
             
                  end
         | 
| 69 80 |  | 
| 70 81 | 
             
                  repeat_min, repeat_max, repeat_step = get_repetitions( rule, econs )
         | 
| @@ -76,13 +87,14 @@ module JCR | |
| 76 87 | 
             
                  # Also, groups must be handed the entire object, not key/values
         | 
| 77 88 | 
             
                  # as member rules use.
         | 
| 78 89 |  | 
| 79 | 
            -
                   | 
| 90 | 
            +
                  grule,gtarget_annotations = get_group(rule, econs)
         | 
| 91 | 
            +
                  if grule
         | 
| 80 92 |  | 
| 81 93 | 
             
                    successes = 0
         | 
| 82 94 | 
             
                    for i in 0..repeat_max-1
         | 
| 83 95 | 
             
                      group_behavior = ObjectBehavior.new
         | 
| 84 96 | 
             
                      group_behavior.checked_hash.merge!( behavior.checked_hash )
         | 
| 85 | 
            -
                      e = evaluate_rule( grule, rule_atom, data, econs, group_behavior )
         | 
| 97 | 
            +
                      e = evaluate_rule( grule, rule_atom, data, econs, group_behavior, gtarget_annotations )
         | 
| 86 98 | 
             
                      if e.success
         | 
| 87 99 | 
             
                        behavior.checked_hash.merge!( group_behavior.checked_hash )
         | 
| 88 100 | 
             
                        successes = successes + 1
         | 
| @@ -92,11 +104,11 @@ module JCR | |
| 92 104 | 
             
                    end
         | 
| 93 105 |  | 
| 94 106 | 
             
                    if successes == 0 && repeat_min > 0
         | 
| 95 | 
            -
                      retval = Evaluation.new( false, "object does not contain group #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 107 | 
            +
                      retval = Evaluation.new( false, "object does not contain group #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 96 108 | 
             
                    elsif successes < repeat_min
         | 
| 97 | 
            -
                      retval = Evaluation.new( false, "object does not have contain necessary number of group #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 109 | 
            +
                      retval = Evaluation.new( false, "object does not have contain necessary number of group #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 98 110 | 
             
                    elsif repeat_step && ( successes - repeat_min ) % repeat_step != 0
         | 
| 99 | 
            -
                      retval = Evaluation.new( false, "object matches (#{successes}) do not have contain repetition #{repeat_max} % #{repeat_step} of group #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 111 | 
            +
                      retval = Evaluation.new( false, "object matches (#{successes}) do not have contain repetition #{repeat_max} % #{repeat_step} of group #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 100 112 | 
             
                    else
         | 
| 101 113 | 
             
                      retval = Evaluation.new( true, nil )
         | 
| 102 114 | 
             
                    end
         | 
| @@ -109,7 +121,7 @@ module JCR | |
| 109 121 | 
             
                    # if defined by a name, and not a regex, just pluck it from the object
         | 
| 110 122 | 
             
                    # and short-circuit the enumeration
         | 
| 111 123 |  | 
| 112 | 
            -
                    lookahead = get_leaf_rule( rule, econs )
         | 
| 124 | 
            +
                    lookahead, ltarget_annotations = get_leaf_rule( rule, econs )
         | 
| 113 125 | 
             
                    lrules, lannotations = get_rules_and_annotations( lookahead[:member_rule] )
         | 
| 114 126 | 
             
                    if lrules[0][:member_name]
         | 
| 115 127 |  | 
| @@ -118,13 +130,13 @@ module JCR | |
| 118 130 | 
             
                      v = data[k]
         | 
| 119 131 | 
             
                      if v
         | 
| 120 132 | 
             
                        unless behavior.checked_hash[k]
         | 
| 121 | 
            -
                          e = evaluate_rule(rule, rule_atom, [k, v], econs, nil)
         | 
| 133 | 
            +
                          e = evaluate_rule(rule, rule_atom, [k, v], econs, nil, nil)
         | 
| 122 134 | 
             
                          behavior.checked_hash[k] = e.success
         | 
| 123 135 | 
             
                          repeat_results[ k ] = v if e.success
         | 
| 124 136 | 
             
                        end
         | 
| 125 137 | 
             
                      else
         | 
| 126 138 | 
             
                        trace( econs, "No member '#{k}' found in object.")
         | 
| 127 | 
            -
                        e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil)
         | 
| 139 | 
            +
                        e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil, nil)
         | 
| 128 140 | 
             
                        repeat_results[ nil ] = nil if e.success
         | 
| 129 141 | 
             
                      end
         | 
| 130 142 |  | 
| @@ -137,7 +149,7 @@ module JCR | |
| 137 149 | 
             
                      repeat_results = data.select do |k,v|
         | 
| 138 150 | 
             
                        unless behavior.checked_hash[k]
         | 
| 139 151 | 
             
                          if i < repeat_max
         | 
| 140 | 
            -
                            e = evaluate_rule(rule, rule_atom, [k, v], econs, nil)
         | 
| 152 | 
            +
                            e = evaluate_rule(rule, rule_atom, [k, v], econs, nil, nil)
         | 
| 141 153 | 
             
                            behavior.checked_hash[k] = e.success
         | 
| 142 154 | 
             
                            i = i + 1 if e.success
         | 
| 143 155 | 
             
                            found = true if e.member_found
         | 
| @@ -147,7 +159,7 @@ module JCR | |
| 147 159 | 
             
                      end
         | 
| 148 160 | 
             
                      unless found
         | 
| 149 161 | 
             
                        trace( econs, "No member matching #{regex} found in object.")
         | 
| 150 | 
            -
                        e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil)
         | 
| 162 | 
            +
                        e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil, nil)
         | 
| 151 163 | 
             
                        repeat_results[ nil ] = nil if e.success
         | 
| 152 164 | 
             
                      end
         | 
| 153 165 |  | 
| @@ -155,13 +167,13 @@ module JCR | |
| 155 167 |  | 
| 156 168 | 
             
                    trace( econs, "Found #{repeat_results.length} matching members repetitions in object with min #{repeat_min} and max #{repeat_max}" )
         | 
| 157 169 | 
             
                    if repeat_results.length == 0 && repeat_min > 0
         | 
| 158 | 
            -
                      retval = Evaluation.new( false, "object does not contain #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 170 | 
            +
                      retval = Evaluation.new( false, "object does not contain #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 159 171 | 
             
                    elsif repeat_results.length < repeat_min
         | 
| 160 | 
            -
                      retval = Evaluation.new( false, "object does not have enough #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 172 | 
            +
                      retval = Evaluation.new( false, "object does not have enough #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 161 173 | 
             
                    elsif repeat_results.length > repeat_max
         | 
| 162 | 
            -
                      retval = Evaluation.new( false, "object has too many #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 174 | 
            +
                      retval = Evaluation.new( false, "object has too many #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 163 175 | 
             
                    elsif repeat_step && ( repeat_results.length - repeat_min ) % repeat_step != 0
         | 
| 164 | 
            -
                      retval = Evaluation.new( false, "object matches (#{repeat_results.length}) does not match repetition step of #{repeat_max} & #{repeat_step} for #{rule} for #{raised_rule(jcr,rule_atom)}")
         | 
| 176 | 
            +
                      retval = Evaluation.new( false, "object matches (#{repeat_results.length}) does not match repetition step of #{repeat_max} & #{repeat_step} for #{jcr_to_s(rule)} for #{raised_rule(jcr,rule_atom)}")
         | 
| 165 177 | 
             
                    else
         | 
| 166 178 | 
             
                      retval = Evaluation.new( true, nil)
         | 
| 167 179 | 
             
                    end
         | 
| @@ -169,7 +181,7 @@ module JCR | |
| 169 181 |  | 
| 170 182 | 
             
                end # end if grule else
         | 
| 171 183 |  | 
| 172 | 
            -
                return evaluate_not( annotations, retval, econs )
         | 
| 184 | 
            +
                return evaluate_not( annotations, retval, econs, target_annotations )
         | 
| 173 185 | 
             
              end
         | 
| 174 186 |  | 
| 175 187 | 
             
              def self.object_to_s( jcr, shallow=true )
         | 
    
        data/lib/jcr/evaluate_rules.rb
    CHANGED
    
    | @@ -68,8 +68,14 @@ module JCR | |
| 68 68 | 
             
                end
         | 
| 69 69 |  | 
| 70 70 | 
             
                def report_failure failure
         | 
| 71 | 
            -
                   | 
| 72 | 
            -
                  @failures[  | 
| 71 | 
            +
                  coord = JCR::trace_coord( self )
         | 
| 72 | 
            +
                  @failures[ coord ] = Array.new unless @failures[ coord ]
         | 
| 73 | 
            +
                  @failures[ coord ] << failure
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                def report_success
         | 
| 77 | 
            +
                  coord = JCR::trace_coord( self )
         | 
| 78 | 
            +
                  @failures.delete( coord )
         | 
| 73 79 | 
             
                end
         | 
| 74 80 | 
             
              end
         | 
| 75 81 |  | 
| @@ -91,7 +97,7 @@ module JCR | |
| 91 97 | 
             
                end
         | 
| 92 98 | 
             
              end
         | 
| 93 99 |  | 
| 94 | 
            -
              def self.evaluate_rule jcr, rule_atom, data, econs, behavior = nil
         | 
| 100 | 
            +
              def self.evaluate_rule jcr, rule_atom, data, econs, behavior = nil, target_annotations = nil
         | 
| 95 101 | 
             
                if jcr.is_a?( Hash )
         | 
| 96 102 | 
             
                  if jcr[:rule_name]
         | 
| 97 103 | 
             
                    rn = slice_to_s( jcr[:rule_name] )
         | 
| @@ -102,26 +108,24 @@ module JCR | |
| 102 108 | 
             
                retval = Evaluation.new( false, "failed to evaluate rule properly" )
         | 
| 103 109 | 
             
                case
         | 
| 104 110 | 
             
                  when behavior.is_a?( ArrayBehavior )
         | 
| 105 | 
            -
                    retval = evaluate_array_rule( jcr, rule_atom, data, econs, behavior)
         | 
| 111 | 
            +
                    retval = evaluate_array_rule( jcr, rule_atom, data, econs, behavior, target_annotations )
         | 
| 106 112 | 
             
                  when behavior.is_a?( ObjectBehavior )
         | 
| 107 | 
            -
                    retval = evaluate_object_rule( jcr, rule_atom, data, econs, behavior)
         | 
| 113 | 
            +
                    retval = evaluate_object_rule( jcr, rule_atom, data, econs, behavior, target_annotations )
         | 
| 108 114 | 
             
                  when jcr[:rule]
         | 
| 109 | 
            -
                    retval = evaluate_rule( jcr[:rule], rule_atom, data, econs, behavior)
         | 
| 115 | 
            +
                    retval = evaluate_rule( jcr[:rule], rule_atom, data, econs, behavior, target_annotations)
         | 
| 110 116 | 
             
                  when jcr[:target_rule_name]
         | 
| 111 | 
            -
                    target =  | 
| 112 | 
            -
                     | 
| 113 | 
            -
                    trace( econs, "Referencing target rule #{slice_to_s(target)} from #{slice_to_s( jcr[:target_rule_name][:rule_name] )}" )
         | 
| 114 | 
            -
                    retval = evaluate_rule( target, target, data, econs, behavior )
         | 
| 117 | 
            +
                    target, target_annotations = get_target_rule( jcr, econs )
         | 
| 118 | 
            +
                    retval = evaluate_rule( target, target, data, econs, behavior, target_annotations )
         | 
| 115 119 | 
             
                  when jcr[:primitive_rule]
         | 
| 116 | 
            -
                    retval = evaluate_value_rule( jcr[:primitive_rule], rule_atom, data, econs)
         | 
| 120 | 
            +
                    retval = evaluate_value_rule( jcr[:primitive_rule], rule_atom, data, econs, nil, target_annotations )
         | 
| 117 121 | 
             
                  when jcr[:group_rule]
         | 
| 118 | 
            -
                    retval = evaluate_group_rule( jcr[:group_rule], rule_atom, data, econs, behavior)
         | 
| 122 | 
            +
                    retval = evaluate_group_rule( jcr[:group_rule], rule_atom, data, econs, behavior, target_annotations)
         | 
| 119 123 | 
             
                  when jcr[:array_rule]
         | 
| 120 | 
            -
                    retval = evaluate_array_rule( jcr[:array_rule], rule_atom, data, econs, behavior)
         | 
| 124 | 
            +
                    retval = evaluate_array_rule( jcr[:array_rule], rule_atom, data, econs, behavior, target_annotations )
         | 
| 121 125 | 
             
                  when jcr[:object_rule]
         | 
| 122 | 
            -
                    retval = evaluate_object_rule( jcr[:object_rule], rule_atom, data, econs, behavior)
         | 
| 126 | 
            +
                    retval = evaluate_object_rule( jcr[:object_rule], rule_atom, data, econs, behavior, target_annotations)
         | 
| 123 127 | 
             
                  when jcr[:member_rule]
         | 
| 124 | 
            -
                    retval = evaluate_member_rule( jcr[:member_rule], rule_atom, data, econs)
         | 
| 128 | 
            +
                    retval = evaluate_member_rule( jcr[:member_rule], rule_atom, data, econs, nil, target_annotations)
         | 
| 125 129 | 
             
                  else
         | 
| 126 130 | 
             
                    retval = Evaluation.new( true, nil )
         | 
| 127 131 | 
             
                end
         | 
| @@ -153,6 +157,13 @@ module JCR | |
| 153 157 | 
             
                return retval
         | 
| 154 158 | 
             
              end
         | 
| 155 159 |  | 
| 160 | 
            +
              def self.get_target_rule jcr, econs
         | 
| 161 | 
            +
                target = econs.mapping[ jcr[:target_rule_name][:rule_name].to_s ]
         | 
| 162 | 
            +
                raise "Target rule not in mapping. This should have been checked earlier." unless target
         | 
| 163 | 
            +
                trace( econs, "Referencing target rule #{slice_to_s(target)} from #{slice_to_s( jcr[:target_rule_name][:rule_name] )}" )
         | 
| 164 | 
            +
                return target,jcr[:target_rule_name][:annotations]
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
             | 
| 156 167 | 
             
              def self.get_repetitions rule, econs
         | 
| 157 168 |  | 
| 158 169 | 
             
                repeat_min = 1
         | 
| @@ -245,11 +256,20 @@ module JCR | |
| 245 256 | 
             
                return new_rule
         | 
| 246 257 | 
             
              end
         | 
| 247 258 |  | 
| 248 | 
            -
              def self.evaluate_not annotations, evaluation, econs
         | 
| 259 | 
            +
              def self.evaluate_not annotations, evaluation, econs, target_annotations = nil
         | 
| 249 260 | 
             
                is_not = false
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                target_annotations.each do |a|
         | 
| 263 | 
            +
                  if a[:not_annotation]
         | 
| 264 | 
            +
                    trace( econs, "Not annotation found on reference to rule.")
         | 
| 265 | 
            +
                    is_not = !is_not
         | 
| 266 | 
            +
                    break
         | 
| 267 | 
            +
                  end
         | 
| 268 | 
            +
                end if target_annotations
         | 
| 269 | 
            +
             | 
| 250 270 | 
             
                annotations.each do |a|
         | 
| 251 271 | 
             
                  if a[:not_annotation]
         | 
| 252 | 
            -
                    is_not =  | 
| 272 | 
            +
                    is_not = !is_not
         | 
| 253 273 | 
             
                    break
         | 
| 254 274 | 
             
                  end
         | 
| 255 275 | 
             
                end
         | 
| @@ -262,27 +282,23 @@ module JCR | |
| 262 282 | 
             
              end
         | 
| 263 283 |  | 
| 264 284 | 
             
              def self.get_group rule, econs
         | 
| 265 | 
            -
                return rule[:group_rule] if rule[:group_rule]
         | 
| 285 | 
            +
                return rule[:group_rule], nil if rule[:group_rule]
         | 
| 266 286 | 
             
                #else
         | 
| 267 287 | 
             
                if rule[:target_rule_name]
         | 
| 268 | 
            -
                  target =  | 
| 269 | 
            -
                   | 
| 270 | 
            -
                  trace( econs, "Referencing target rule #{slice_to_s(target)} from #{slice_to_s( rule[:target_rule_name][:rule_name] )}" )
         | 
| 271 | 
            -
                  return get_group( target, econs )
         | 
| 288 | 
            +
                  target, target_annotations = get_target_rule( rule, econs )
         | 
| 289 | 
            +
                  return get_group( target, econs )[0], target_annotations
         | 
| 272 290 | 
             
                end
         | 
| 273 291 | 
             
                #else
         | 
| 274 | 
            -
                return false
         | 
| 292 | 
            +
                return false, nil
         | 
| 275 293 | 
             
              end
         | 
| 276 294 |  | 
| 277 295 | 
             
              def self.get_leaf_rule rule, econs
         | 
| 278 296 | 
             
                if rule[:target_rule_name ]
         | 
| 279 | 
            -
                  target =  | 
| 280 | 
            -
                   | 
| 281 | 
            -
                  trace( econs, "Referencing target rule #{slice_to_s(target)} from #{slice_to_s( rule[:target_rule_name][:rule_name] )}" )
         | 
| 282 | 
            -
                  return target
         | 
| 297 | 
            +
                  target, target_annotations = get_target_rule( rule, econs )
         | 
| 298 | 
            +
                  return target, target_annotations
         | 
| 283 299 | 
             
                end
         | 
| 284 300 | 
             
                #else
         | 
| 285 | 
            -
                return rule
         | 
| 301 | 
            +
                return rule, nil
         | 
| 286 302 | 
             
              end
         | 
| 287 303 |  | 
| 288 304 | 
             
              def self.push_trace_stack econs, jcr
         | 
| @@ -320,11 +336,16 @@ module JCR | |
| 320 336 | 
             
                    message = "#{message} data: #{rule_data( data )}"
         | 
| 321 337 | 
             
                  end
         | 
| 322 338 | 
             
                  last = econs.trace_stack.last
         | 
| 323 | 
            -
                   | 
| 324 | 
            -
                  puts "[ #{econs.trace_stack.length}:#{pos} ] #{message}"
         | 
| 339 | 
            +
                  puts "[ depth=#{econs.trace_stack.length}:#{trace_coord(econs)} ] #{message}"
         | 
| 325 340 | 
             
                end
         | 
| 326 341 | 
             
              end
         | 
| 327 342 |  | 
| 343 | 
            +
              def self.trace_coord econs
         | 
| 344 | 
            +
                last = econs.trace_stack.last
         | 
| 345 | 
            +
                pos = "#{last.line_and_column}" if last
         | 
| 346 | 
            +
                return "pos=#{pos}"
         | 
| 347 | 
            +
              end
         | 
| 348 | 
            +
             | 
| 328 349 | 
             
              def self.rule_def type, jcr
         | 
| 329 350 | 
             
                s = ""
         | 
| 330 351 | 
             
                case type
         | 
| @@ -334,14 +355,18 @@ module JCR | |
| 334 355 | 
             
                    s = elide(member_to_s(jcr))
         | 
| 335 356 | 
             
                  when "object"
         | 
| 336 357 | 
             
                    s = elide(object_to_s(jcr))
         | 
| 358 | 
            +
                  when "object group"
         | 
| 359 | 
            +
                    s = elide(group_to_s(jcr))
         | 
| 337 360 | 
             
                  when "array"
         | 
| 338 361 | 
             
                    s = elide(array_to_s(jcr))
         | 
| 362 | 
            +
                  when "array group"
         | 
| 363 | 
            +
                    s = elide(array_to_s(jcr))
         | 
| 339 364 | 
             
                  when "group"
         | 
| 340 365 | 
             
                    s = elide(group_to_s(jcr))
         | 
| 341 366 | 
             
                  else
         | 
| 342 367 | 
             
                    s = "** unknown rule **"
         | 
| 343 368 | 
             
                end
         | 
| 344 | 
            -
                return "#{type} definition | 
| 369 | 
            +
                return "#{type} definition << #{s} >>"
         | 
| 345 370 | 
             
              end
         | 
| 346 371 |  | 
| 347 372 | 
             
              def self.trace_def econs, type, jcr, data
         | 
| @@ -354,8 +379,12 @@ module JCR | |
| 354 379 | 
             
                      s = elide( member_to_s( jcr  ) )
         | 
| 355 380 | 
             
                    when "object"
         | 
| 356 381 | 
             
                      s = elide( object_to_s( jcr ) )
         | 
| 382 | 
            +
                    when "object group"
         | 
| 383 | 
            +
                      s = elide( group_to_s( jcr ) )
         | 
| 357 384 | 
             
                    when "array"
         | 
| 358 385 | 
             
                      s = elide( array_to_s( jcr ) )
         | 
| 386 | 
            +
                    when "array group"
         | 
| 387 | 
            +
                      s = elide( array_to_s( jcr ) )
         | 
| 359 388 | 
             
                    when "group"
         | 
| 360 389 | 
             
                      s = elide( group_to_s( jcr ) )
         | 
| 361 390 | 
             
                    else
         | 
| @@ -367,6 +396,7 @@ module JCR | |
| 367 396 |  | 
| 368 397 | 
             
              def self.trace_eval econs, message, evaluation, jcr, data, type
         | 
| 369 398 | 
             
                if evaluation.success
         | 
| 399 | 
            +
                  econs.report_success
         | 
| 370 400 | 
             
                  trace( econs, "#{message} evaluation is true" )
         | 
| 371 401 | 
             
                else
         | 
| 372 402 | 
             
                  failure = Failure.new( data, jcr, type, evaluation, econs.trace_stack.length )
         | 
| @@ -409,7 +439,28 @@ module JCR | |
| 409 439 | 
             
              end
         | 
| 410 440 |  | 
| 411 441 | 
             
              def self.raised_rule jcr, rule_atom
         | 
| 412 | 
            -
                " rule at #{slice_to_s(jcr)}  | 
| 442 | 
            +
                " rule at #{slice_to_s(jcr)} #{jcr_to_s(jcr)} from rule at #{slice_to_s(rule_atom)}"
         | 
| 443 | 
            +
              end
         | 
| 444 | 
            +
             | 
| 445 | 
            +
              def self.jcr_to_s( jcr, shallow=true )
         | 
| 446 | 
            +
                if jcr.is_a? Array
         | 
| 447 | 
            +
                  retval = ""
         | 
| 448 | 
            +
                  jcr.each_with_index do |item,idx|
         | 
| 449 | 
            +
                    if idx > 1
         | 
| 450 | 
            +
                      retval = retval + " , "
         | 
| 451 | 
            +
                    end
         | 
| 452 | 
            +
                    retval = retval + jcr_to_s( item, shallow )
         | 
| 453 | 
            +
                  end
         | 
| 454 | 
            +
                elsif jcr.is_a? Parslet::Slice
         | 
| 455 | 
            +
                  retval = slice_to_s( jcr )
         | 
| 456 | 
            +
                else
         | 
| 457 | 
            +
                  if jcr[:q_string]
         | 
| 458 | 
            +
                    retval = value_to_s( jcr )
         | 
| 459 | 
            +
                  else
         | 
| 460 | 
            +
                    retval = rule_to_s( jcr, shallow )
         | 
| 461 | 
            +
                  end
         | 
| 462 | 
            +
                end
         | 
| 463 | 
            +
                return "<< " + retval + " >>"
         | 
| 413 464 | 
             
              end
         | 
| 414 465 |  | 
| 415 466 | 
             
              def self.rule_to_s( rule, shallow=true)
         | 
| @@ -25,14 +25,15 @@ require 'jcr/check_groups' | |
| 25 25 |  | 
| 26 26 | 
             
            module JCR
         | 
| 27 27 |  | 
| 28 | 
            -
              def self.evaluate_value_rule jcr, rule_atom, data, econs
         | 
| 28 | 
            +
              def self.evaluate_value_rule jcr, rule_atom, data, econs, behavior, target_annotations
         | 
| 29 29 |  | 
| 30 30 | 
             
                push_trace_stack( econs, jcr )
         | 
| 31 31 | 
             
                trace( econs, "Evaluating value rule starting at #{slice_to_s(jcr)}" )
         | 
| 32 32 | 
             
                trace_def( econs, "value", jcr, data )
         | 
| 33 33 | 
             
                rules, annotations = get_rules_and_annotations( jcr )
         | 
| 34 34 |  | 
| 35 | 
            -
                retval = evaluate_not( annotations, evaluate_values( rules[0], rule_atom, data, econs ), | 
| 35 | 
            +
                retval = evaluate_not( annotations, evaluate_values( rules[0], rule_atom, data, econs ),
         | 
| 36 | 
            +
                                       econs, target_annotations )
         | 
| 36 37 | 
             
                trace_eval( econs, "Value", retval, jcr, data, "value")
         | 
| 37 38 | 
             
                pop_trace_stack( econs )
         | 
| 38 39 | 
             
                return retval
         | 
| @@ -401,7 +402,7 @@ module JCR | |
| 401 402 | 
             
              end
         | 
| 402 403 |  | 
| 403 404 | 
             
              def self.bad_value jcr, rule_atom, expected, actual
         | 
| 404 | 
            -
                Evaluation.new( false, "expected #{expected} but got #{actual} for #{raised_rule(jcr,rule_atom)}" )
         | 
| 405 | 
            +
                Evaluation.new( false, "expected << #{expected} >> but got << #{actual} >> for #{raised_rule(jcr,rule_atom)}" )
         | 
| 405 406 | 
             
              end
         | 
| 406 407 |  | 
| 407 408 | 
             
              def self.value_to_s( jcr, shallow=true )
         | 
    
        data/lib/jcr/jcr.rb
    CHANGED
    
    | @@ -17,6 +17,7 @@ require 'rubygems' | |
| 17 17 | 
             
            require 'json'
         | 
| 18 18 | 
             
            require 'pp'
         | 
| 19 19 |  | 
| 20 | 
            +
            require 'jcr/jcr_validator_error'
         | 
| 20 21 | 
             
            require 'jcr/parser'
         | 
| 21 22 | 
             
            require 'jcr/evaluate_rules'
         | 
| 22 23 | 
             
            require 'jcr/check_groups'
         | 
| @@ -63,7 +64,7 @@ module JCR | |
| 63 64 | 
             
                  @trace = trace
         | 
| 64 65 | 
             
                  @failed_roots = []
         | 
| 65 66 | 
             
                  if ruleset
         | 
| 66 | 
            -
                    ingested = JCR.ingest_ruleset( ruleset,  | 
| 67 | 
            +
                    ingested = JCR.ingest_ruleset( ruleset, nil, nil )
         | 
| 67 68 | 
             
                    @mapping = ingested.mapping
         | 
| 68 69 | 
             
                    @callbacks = ingested.callbacks
         | 
| 69 70 | 
             
                    @id = ingested.id
         | 
| @@ -73,7 +74,7 @@ module JCR | |
| 73 74 | 
             
                end
         | 
| 74 75 |  | 
| 75 76 | 
             
                def override( ruleset )
         | 
| 76 | 
            -
                  overridden = JCR.ingest_ruleset( ruleset,  | 
| 77 | 
            +
                  overridden = JCR.ingest_ruleset( ruleset, @mapping, nil )
         | 
| 77 78 | 
             
                  mapping = {}
         | 
| 78 79 | 
             
                  mapping.merge!( @mapping )
         | 
| 79 80 | 
             
                  mapping.merge!( overridden.mapping )
         | 
| @@ -87,7 +88,7 @@ module JCR | |
| 87 88 | 
             
                end
         | 
| 88 89 |  | 
| 89 90 | 
             
                def override!( ruleset )
         | 
| 90 | 
            -
                  overridden = JCR.ingest_ruleset( ruleset,  | 
| 91 | 
            +
                  overridden = JCR.ingest_ruleset( ruleset, @mapping, nil )
         | 
| 91 92 | 
             
                  @mapping.merge!( overridden.mapping )
         | 
| 92 93 | 
             
                  @callbacks.merge!( overridden.callbacks )
         | 
| 93 94 | 
             
                  @roots.concat( overridden.roots )
         | 
| @@ -95,11 +96,14 @@ module JCR | |
| 95 96 |  | 
| 96 97 | 
             
              end
         | 
| 97 98 |  | 
| 98 | 
            -
              def self.ingest_ruleset( ruleset,  | 
| 99 | 
            +
              def self.ingest_ruleset( ruleset, existing_mapping = nil, ruleset_alias=nil )
         | 
| 99 100 | 
             
                tree = JCR.parse( ruleset )
         | 
| 100 | 
            -
                mapping = JCR.map_rule_names( tree,  | 
| 101 | 
            -
                 | 
| 102 | 
            -
                 | 
| 101 | 
            +
                mapping = JCR.map_rule_names( tree, ruleset_alias )
         | 
| 102 | 
            +
                combined_mapping = {}
         | 
| 103 | 
            +
                combined_mapping.merge!( existing_mapping ) if existing_mapping
         | 
| 104 | 
            +
                combined_mapping.merge!( mapping )
         | 
| 105 | 
            +
                JCR.check_rule_target_names( tree, combined_mapping )
         | 
| 106 | 
            +
                JCR.check_groups( tree, combined_mapping )
         | 
| 103 107 | 
             
                roots = JCR.find_roots( tree )
         | 
| 104 108 | 
             
                ctx = Context.new
         | 
| 105 109 | 
             
                ctx.tree = tree
         | 
| @@ -114,19 +118,19 @@ module JCR | |
| 114 118 | 
             
                roots = []
         | 
| 115 119 | 
             
                if root_name
         | 
| 116 120 | 
             
                  root_rule = ctx.mapping[root_name]
         | 
| 117 | 
            -
                  raise "No rule by the name of #{root_name} for a root rule has been found" unless root_rule
         | 
| 121 | 
            +
                  raise JcrValidatorError, "No rule by the name of #{root_name} for a root rule has been found" unless root_rule
         | 
| 118 122 | 
             
                  root = JCR::Root.new( root_rule, root_name )
         | 
| 119 123 | 
             
                  roots << root
         | 
| 120 124 | 
             
                else
         | 
| 121 125 | 
             
                  roots = ctx.roots
         | 
| 122 126 | 
             
                end
         | 
| 123 127 |  | 
| 124 | 
            -
                raise "No root rule defined. Specify a root rule name" if roots.empty?
         | 
| 128 | 
            +
                raise JcrValidatorError, "No root rule defined. Specify a root rule name" if roots.empty?
         | 
| 125 129 |  | 
| 126 130 | 
             
                retval = nil
         | 
| 127 131 | 
             
                roots.each do |r|
         | 
| 128 132 | 
             
                  pp "Evaluating Root:", rule_to_s( r.rule, false ) if ctx.trace
         | 
| 129 | 
            -
                  raise "Root rules cannot be member rules" if r.rule[:member_rule]
         | 
| 133 | 
            +
                  raise JcrValidatorError, "Root rules cannot be member rules" if r.rule[:member_rule]
         | 
| 130 134 | 
             
                  econs = EvalConditions.new( ctx.mapping, ctx.callbacks, ctx.trace )
         | 
| 131 135 | 
             
                  retval = JCR.evaluate_rule( r.rule, r.rule, data, econs )
         | 
| 132 136 | 
             
                  break if retval.success
         | 
| @@ -143,24 +147,40 @@ module JCR | |
| 143 147 | 
             
                report = []
         | 
| 144 148 | 
             
                ctx.failed_roots.each do |failed_root|
         | 
| 145 149 | 
             
                  if failed_root.name
         | 
| 146 | 
            -
                    report << "-  | 
| 150 | 
            +
                    report << "- Failures for root rule named '#{failed_root.name}'"
         | 
| 147 151 | 
             
                  else
         | 
| 148 | 
            -
                    report << "-  | 
| 152 | 
            +
                    report << "- Failures for root rule at line #{failed_root.pos[0]}"
         | 
| 149 153 | 
             
                  end
         | 
| 150 154 | 
             
                  failed_root.failures.sort.map do |stack_level, failures|
         | 
| 151 155 | 
             
                    if failures.length > 1
         | 
| 152 | 
            -
                      report << "  - failure at rule  | 
| 156 | 
            +
                      report << "  - failure at rule #{stack_level} caused by one of the following #{failures.length} reasons"
         | 
| 153 157 | 
             
                    else
         | 
| 154 | 
            -
                      report << "  - failure at rule  | 
| 158 | 
            +
                      report << "  - failure at rule #{stack_level} caused by"
         | 
| 155 159 | 
             
                    end
         | 
| 156 160 | 
             
                    failures.each_with_index do |failure, index|
         | 
| 157 | 
            -
                       | 
| 161 | 
            +
                      lines = breakup_message( "<< #{failure.json_elided} >> failed rule #{failure.definition} at #{failure.pos} because #{failure.evaluation.reason}", 75 )
         | 
| 162 | 
            +
                      lines.each_with_index do |l,i|
         | 
| 163 | 
            +
                        if i == 0
         | 
| 164 | 
            +
                          report << "    - #{l}"
         | 
| 165 | 
            +
                        else
         | 
| 166 | 
            +
                          report << "      #{l}"
         | 
| 167 | 
            +
                        end
         | 
| 168 | 
            +
                      end
         | 
| 158 169 | 
             
                    end
         | 
| 159 170 | 
             
                  end
         | 
| 160 171 | 
             
                end
         | 
| 161 172 | 
             
                return report
         | 
| 162 173 | 
             
              end
         | 
| 163 174 |  | 
| 175 | 
            +
              def self.breakup_message( message, line_length )
         | 
| 176 | 
            +
                line = message.gsub(/(.{1,#{line_length}})(\s+|\Z)/, "\\1\n")
         | 
| 177 | 
            +
                lines = []
         | 
| 178 | 
            +
                line.each_line do |l|
         | 
| 179 | 
            +
                  lines << l.strip
         | 
| 180 | 
            +
                end
         | 
| 181 | 
            +
                return lines
         | 
| 182 | 
            +
              end
         | 
| 183 | 
            +
             | 
| 164 184 | 
             
              def self.main my_argv=nil
         | 
| 165 185 |  | 
| 166 186 | 
             
                my_argv = ARGV unless my_argv
         | 
| @@ -199,8 +219,9 @@ module JCR | |
| 199 219 | 
             
                    options[:testjcr] = true
         | 
| 200 220 | 
             
                  end
         | 
| 201 221 |  | 
| 202 | 
            -
                  opt.on("--process-parts", "creates smaller files for specification writing" ) do | | 
| 222 | 
            +
                  opt.on("--process-parts [DIRECTORY]", "creates smaller files for specification writing" ) do |directory|
         | 
| 203 223 | 
             
                    options[:process_parts] = true
         | 
| 224 | 
            +
                    options[:process_parts_directory] = directory
         | 
| 204 225 | 
             
                  end
         | 
| 205 226 |  | 
| 206 227 | 
             
                  opt.on("-S STRING","name of root rule. All roots will be tried if none is specified") do |root_name|
         | 
| @@ -248,15 +269,22 @@ module JCR | |
| 248 269 | 
             
                  opt.separator  ""
         | 
| 249 270 | 
             
                  opt.separator  "Return codes:"
         | 
| 250 271 | 
             
                  opt.separator  " 0 = success"
         | 
| 251 | 
            -
                  opt.separator  " 1 = parsing or other bad condition"
         | 
| 252 | 
            -
                  opt.separator  " 2 =  | 
| 272 | 
            +
                  opt.separator  " 1 = bad JCR parsing or other bad condition"
         | 
| 273 | 
            +
                  opt.separator  " 2 = invalid option or bad use of command"
         | 
| 253 274 | 
             
                  opt.separator  " 3 = unsuccessful evaluation of JSON"
         | 
| 254 275 |  | 
| 255 276 | 
             
                  opt.separator  ""
         | 
| 256 277 | 
             
                  opt.separator  "JCR Version " + JCR::VERSION
         | 
| 257 278 | 
             
                end
         | 
| 258 279 |  | 
| 259 | 
            -
                 | 
| 280 | 
            +
                begin
         | 
| 281 | 
            +
                  opt_parser.parse! my_argv
         | 
| 282 | 
            +
                rescue OptionParser::InvalidOption => e
         | 
| 283 | 
            +
                  puts "Unable to interpret command or options"
         | 
| 284 | 
            +
                  puts e.message
         | 
| 285 | 
            +
                  puts "", "Use -h for help"
         | 
| 286 | 
            +
                  return 2
         | 
| 287 | 
            +
                end
         | 
| 260 288 |  | 
| 261 289 | 
             
                if options[:help]
         | 
| 262 290 | 
             
                  puts "HELP","----",""
         | 
| @@ -264,7 +292,7 @@ module JCR | |
| 264 292 | 
             
                  return 2
         | 
| 265 293 | 
             
                elsif !options[:ruleset]
         | 
| 266 294 | 
             
                  puts "No ruleset passed! Use -R or -r options.", ""
         | 
| 267 | 
            -
                  puts  | 
| 295 | 
            +
                  puts "Use -h for help"
         | 
| 268 296 | 
             
                  return 2
         | 
| 269 297 | 
             
                else
         | 
| 270 298 |  | 
| @@ -290,7 +318,13 @@ module JCR | |
| 290 318 |  | 
| 291 319 | 
             
                    if options[:process_parts]
         | 
| 292 320 | 
             
                      parts = JCR::JcrParts.new
         | 
| 293 | 
            -
                      parts.process_ruleset( options[:ruleset] )
         | 
| 321 | 
            +
                      parts.process_ruleset( options[:ruleset], options[:process_parts_directory] )
         | 
| 322 | 
            +
                      if options[:overrides ]
         | 
| 323 | 
            +
                        options[:overrides].each do |ov|
         | 
| 324 | 
            +
                          parts = JCR::JcrParts.new
         | 
| 325 | 
            +
                          parts.process_ruleset( ov, options[:process_parts_directory] )
         | 
| 326 | 
            +
                        end
         | 
| 327 | 
            +
                      end
         | 
| 294 328 | 
             
                    end
         | 
| 295 329 |  | 
| 296 330 | 
             
                    if options[:testjcr]
         | 
| @@ -328,6 +362,9 @@ module JCR | |
| 328 362 | 
             
                      return ec
         | 
| 329 363 | 
             
                    end
         | 
| 330 364 |  | 
| 365 | 
            +
                  rescue JCR::JcrValidatorError => jcr_error
         | 
| 366 | 
            +
                    puts jcr_error.message
         | 
| 367 | 
            +
                    return 1
         | 
| 331 368 | 
             
                  rescue Parslet::ParseFailed => failure
         | 
| 332 369 | 
             
                    puts failure.parse_failure_cause.ascii_tree unless options[:quiet]
         | 
| 333 370 | 
             
                    return 1
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # Copyright (c) 2017 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 | 
            +
            module JCR
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              class JcrValidatorError < StandardError
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            end
         | 
    
        data/lib/jcr/map_rule_names.rb
    CHANGED
    
    | @@ -12,11 +12,12 @@ | |
| 12 12 | 
             
            # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
         | 
| 13 13 | 
             
            # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
         | 
| 14 14 |  | 
| 15 | 
            +
            require 'jcr/jcr_validator_error'
         | 
| 15 16 | 
             
            require 'jcr/parser'
         | 
| 16 17 |  | 
| 17 18 | 
             
            module JCR
         | 
| 18 19 |  | 
| 19 | 
            -
              def self.map_rule_names( tree,  | 
| 20 | 
            +
              def self.map_rule_names( tree, ruleset_alias = nil )
         | 
| 20 21 | 
             
                prefix = ""
         | 
| 21 22 | 
             
                if ruleset_alias
         | 
| 22 23 | 
             
                  prefix = ruleset_alias
         | 
| @@ -31,8 +32,8 @@ module JCR | |
| 31 32 | 
             
                tree.each do |node|
         | 
| 32 33 | 
             
                  if node[:rule]
         | 
| 33 34 | 
             
                    rn = prefix + node[:rule][:rule_name].to_str
         | 
| 34 | 
            -
                    if rule_name_maping[ rn ] | 
| 35 | 
            -
                      raise "Rule #{rn} already exists and is defined more than once"
         | 
| 35 | 
            +
                    if rule_name_maping[ rn ]
         | 
| 36 | 
            +
                      raise JCR::JcrValidatorError, "Rule #{rn} already exists and is defined more than once"
         | 
| 36 37 | 
             
                    else
         | 
| 37 38 | 
             
                      rule_name_maping[ rn ] = node[:rule]
         | 
| 38 39 | 
             
                    end
         | 
| @@ -76,7 +77,8 @@ module JCR | |
| 76 77 | 
             
              def self.raise_rule_name_missing rule_name
         | 
| 77 78 | 
             
                pos = rule_name.line_and_column
         | 
| 78 79 | 
             
                name = rule_name.to_str
         | 
| 79 | 
            -
                raise  | 
| 80 | 
            +
                raise JCR::JcrValidatorError,
         | 
| 81 | 
            +
                      "rule '" + name + "' at line " + pos[0].to_s + " column " + pos[1].to_s + " does not exist"
         | 
| 80 82 | 
             
              end
         | 
| 81 83 |  | 
| 82 84 | 
             
            end
         | 
    
        data/lib/jcr/parts.rb
    CHANGED
    
    | @@ -68,19 +68,23 @@ module JCR | |
| 68 68 |  | 
| 69 69 | 
             
                # processes the lines
         | 
| 70 70 | 
             
                # ruleset is to be a string read in using File.read
         | 
| 71 | 
            -
                def process_ruleset( ruleset )
         | 
| 71 | 
            +
                def process_ruleset( ruleset, dirname = nil )
         | 
| 72 | 
            +
                  all_file_names = []
         | 
| 72 73 | 
             
                  all_parts = []
         | 
| 73 74 | 
             
                  all_parts_name = nil
         | 
| 74 75 | 
             
                  current_part = nil
         | 
| 75 76 | 
             
                  current_part_name = nil
         | 
| 76 77 | 
             
                  ruleset.lines do |line|
         | 
| 77 78 | 
             
                    if !all_parts_name && ( all_parts_name = get_all( line ) )
         | 
| 78 | 
            -
                       | 
| 79 | 
            +
                      all_parts_name = File.join( dirname, all_parts_name ) if dirname
         | 
| 80 | 
            +
                      all_file_names << all_parts_name
         | 
| 79 81 | 
             
                    elsif ( current_part_name = get_start( line ) )
         | 
| 82 | 
            +
                      current_part_name = File.join( dirname, current_part_name ) if dirname
         | 
| 80 83 | 
             
                      if current_part
         | 
| 81 84 | 
             
                        current_part.close
         | 
| 82 85 | 
             
                      end
         | 
| 83 86 | 
             
                      current_part = File.open( current_part_name, "w" )
         | 
| 87 | 
            +
                      all_file_names << current_part_name
         | 
| 84 88 | 
             
                    elsif get_end( line ) && current_part
         | 
| 85 89 | 
             
                      current_part.close
         | 
| 86 90 | 
             
                      current_part = nil
         | 
| @@ -101,6 +105,16 @@ module JCR | |
| 101 105 | 
             
                    end
         | 
| 102 106 | 
             
                    f.close
         | 
| 103 107 | 
             
                  end
         | 
| 108 | 
            +
                  if all_file_names.length
         | 
| 109 | 
            +
                    xml_fn = File.basename( all_file_names[0],".*" ) + "_xml_entity_refs"
         | 
| 110 | 
            +
                    xml_fn = File.join( File.dirname( all_file_names[0] ), xml_fn )
         | 
| 111 | 
            +
                    xml = File.open( xml_fn, "w" )
         | 
| 112 | 
            +
                    all_file_names.each do |fn|
         | 
| 113 | 
            +
                      bn = File.basename( fn, ".*" )
         | 
| 114 | 
            +
                      xml.puts( "<!ENTITY #{bn} PUBLIC '' '#{fn}'>")
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
                    xml.close
         | 
| 117 | 
            +
                  end
         | 
| 104 118 | 
             
                end
         | 
| 105 119 |  | 
| 106 120 | 
             
              end
         | 
| @@ -74,7 +74,7 @@ module JCR | |
| 74 74 | 
             
                    ruleset = File.open( uri.path )
         | 
| 75 75 | 
             
                end
         | 
| 76 76 |  | 
| 77 | 
            -
                import_ctx = JCR.ingest_ruleset( ruleset,  | 
| 77 | 
            +
                import_ctx = JCR.ingest_ruleset( ruleset, nil, ruleset_alias )
         | 
| 78 78 | 
             
                ctx.mapping.merge!( import_ctx.mapping )
         | 
| 79 79 | 
             
                ctx.roots.concat( import_ctx.roots )
         | 
| 80 80 |  | 
    
        data/lib/jcr/version.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # Copyright (c) 2016 American Registry for Internet Numbers
         | 
| 1 | 
            +
            # Copyright (c) 2016-2017 American Registry for Internet Numbers
         | 
| 2 2 | 
             
            #
         | 
| 3 3 | 
             
            # Permission to use, copy, modify, and/or distribute this software for any
         | 
| 4 4 | 
             
            # purpose with or without fee is hereby granted, provided that the above
         | 
| @@ -15,6 +15,6 @@ | |
| 15 15 |  | 
| 16 16 | 
             
            module JCR
         | 
| 17 17 |  | 
| 18 | 
            -
              VERSION = "0.8. | 
| 18 | 
            +
              VERSION = "0.8.1"
         | 
| 19 19 |  | 
| 20 20 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: jcrvalidator
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.8. | 
| 4 | 
            +
              version: 0.8.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Andrew Newton
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2017-12- | 
| 12 | 
            +
            date: 2017-12-17 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: parslet
         | 
| @@ -85,6 +85,7 @@ files: | |
| 85 85 | 
             
            - lib/jcr/evaluate_value_rules.rb
         | 
| 86 86 | 
             
            - lib/jcr/find_roots.rb
         | 
| 87 87 | 
             
            - lib/jcr/jcr.rb
         | 
| 88 | 
            +
            - lib/jcr/jcr_validator_error.rb
         | 
| 88 89 | 
             
            - lib/jcr/map_rule_names.rb
         | 
| 89 90 | 
             
            - lib/jcr/parser.rb
         | 
| 90 91 | 
             
            - lib/jcr/parts.rb
         |