kwalify 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +14 -3
- data/README.txt +3 -3
- data/bin/kwalify +4 -15
- data/doc/users-guide.html +237 -61
- data/examples/address-book/address-book.schema.yaml +1 -1
- data/examples/invoice/invoice.schema.yaml +2 -2
- data/examples/tapkit/tapkit.schema.yaml +39 -39
- data/lib/kwalify.rb +4 -4
- data/lib/kwalify/errors.rb +21 -14
- data/lib/kwalify/main.rb +357 -0
- data/lib/kwalify/messages.rb +38 -9
- data/lib/kwalify/meta-validator.rb +96 -64
- data/lib/kwalify/rule.rb +356 -269
- data/lib/kwalify/types.rb +53 -35
- data/lib/kwalify/util/assert-diff.rb +2 -2
- data/lib/kwalify/util/option-parser.rb +2 -2
- data/lib/kwalify/util/yaml-helper.rb +2 -2
- data/lib/kwalify/validator.rb +8 -17
- data/lib/kwalify/{parser.rb → yaml-parser.rb} +70 -41
- data/test/test-main.rb +179 -0
- data/test/test-main.yaml +756 -0
- data/test/test-metavalidator.rb +38 -721
- data/test/test-metavalidator.yaml +1104 -0
- data/test/test-rule.rb +60 -0
- data/test/test-rule.yaml +314 -0
- data/test/test-validator.rb +5 -5
- data/test/test-validator.yaml +816 -0
- data/test/{test-parser.rb → test-yamlparser.rb} +17 -17
- data/test/test-yamlparser.yaml +1080 -0
- data/test/test.rb +5 -3
- data/todo.txt +1 -0
- metadata +16 -11
- data/lib/kwalify/main-program.rb +0 -258
data/ChangeLog
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
.=title: ChangeLog
|
2
|
-
.?release: $Release: 0.
|
3
|
-
.?lastupdate: $Date$
|
4
|
-
.?version: $Rev$
|
2
|
+
.?release: $Release: 0.5.0 $
|
3
|
+
.?lastupdate: $Date: 2005-12-17 13:49:16 +0900 (Sat, 17 Dec 2005) $
|
4
|
+
.?version: $Rev: 42 $
|
5
|
+
|
6
|
+
.: 2005-12-17 (release 0.5.0)
|
7
|
+
.* Enhances:
|
8
|
+
.- Meta-validation check for 'max < min', 'max-ex <= min-ex', and so on.
|
9
|
+
.- Many test-cases are added
|
10
|
+
.* Changes:
|
11
|
+
.- 'Parser' class is renamed to 'YamlParser'
|
12
|
+
.- 'PlainParser' class is renamed to 'PlainYamlParser'
|
13
|
+
.- YamlParser#set_error_linenums() is renamed to set_errors_linenum()
|
14
|
+
.- ValidatorError#<=> added
|
15
|
+
.- ParseError class is renamed to YamlSyntaxError
|
5
16
|
|
6
17
|
.: 2005-10-26 (release 0.4.1)
|
7
18
|
.* Bugfix:
|
data/README.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
.=title: README
|
2
|
-
.?version: $Rev:
|
3
|
-
.?lastupdate: $Date: 2005-
|
4
|
-
.?release: $Release: 0.
|
2
|
+
.?version: $Rev: 41 $
|
3
|
+
.?lastupdate: $Date: 2005-11-22 03:24:54 +0900 (Tue, 22 Nov 2005) $
|
4
|
+
.?release: $Release: 0.5.0 $
|
5
5
|
|
6
6
|
|
7
7
|
.$ About Kwalify
|
data/bin/kwalify
CHANGED
@@ -1,24 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Rev:
|
5
|
-
### $Release: 0.
|
4
|
+
### $Rev: 42 $
|
5
|
+
### $Release: 0.5.0 $
|
6
6
|
### copyright(c) 2005 kuwata-lab all rights reserved.
|
7
7
|
###
|
8
8
|
|
9
9
|
require 'kwalify'
|
10
|
-
require 'kwalify/main
|
11
|
-
|
10
|
+
require 'kwalify/main'
|
12
11
|
|
13
12
|
command = File.basename($0)
|
14
|
-
|
15
|
-
main = Kwalify::MainProgram.new(ARGV, command)
|
16
|
-
s = main.execute()
|
17
|
-
print s if s
|
18
|
-
rescue CommandOptionError => ex
|
19
|
-
$stderr.puts ex.message
|
20
|
-
exit 1
|
21
|
-
rescue Kwalify::KwalifyError => ex
|
22
|
-
$stderr.puts "ERROR: #{ex.message}"
|
23
|
-
exit 1
|
24
|
-
end
|
13
|
+
Kwalify::Main.main(command, ARGV)
|
data/doc/users-guide.html
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="Content-Type" content="text/html">
|
5
|
-
<title>Kwalify Users' Guide</title>
|
5
|
+
<title>Kwalify Users' Guide (for Ruby and Java)</title>
|
6
6
|
<meta name="author" content="makoto kuwata <kwa(at)kuwata-lab.com>">
|
7
7
|
<meta name="generator" content="kwaser">
|
8
8
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
@@ -12,18 +12,18 @@
|
|
12
12
|
|
13
13
|
<div class="mainbody">
|
14
14
|
|
15
|
-
<div align="left"><h1>Kwalify Users' Guide</h1></div>
|
15
|
+
<div align="left"><h1>Kwalify Users' Guide (for Ruby and Java)</h1></div>
|
16
16
|
<div align="left">
|
17
17
|
makoto kuwata <kwa(at)kuwata-lab.com><br>
|
18
|
-
last update: $Date: 2005-
|
18
|
+
last update: $Date: 2005-12-17 13:49:16 +0900 (Sat, 17 Dec 2005) $<br>
|
19
19
|
</div>
|
20
20
|
|
21
21
|
<a name="preface"></a>
|
22
22
|
<h2 class="section1">Preface</h2>
|
23
23
|
<p>Kwalify<sup>(<a href="#fnref:1" name="fnlink:1">*1</a>)</sup> is a tiny schema validator for YAML and JSON document.
|
24
24
|
</p>
|
25
|
-
<p>
|
26
|
-
Kwalify is based on a new "50-5 rule" which suggests that 5% of the population owns 50 of the wealth.
|
25
|
+
<p>You know "80-20 rule" known as Pareto Law, don't you? This rule suggests that 20% of the population owns 80% of the wealth.
|
26
|
+
Kwalify is based on a new "50-5 rule" which suggests that 5% of the population owns 50% of the wealth.
|
27
27
|
This rule is more aggressive and cost-effective than Pareto Law. The rule is named as "Levi's Law".
|
28
28
|
</p>
|
29
29
|
<div align="center">
|
@@ -54,7 +54,7 @@ This rule is more aggressive and cost-effective than Pareto Law. The rule is nam
|
|
54
54
|
</tr>
|
55
55
|
</table>
|
56
56
|
</div>
|
57
|
-
<p>Kwalify is
|
57
|
+
<p>Kwalify is small and in fact poorer than RelaxNG or XML Schema.
|
58
58
|
I hope you extend/customize Kwalify for your own way.
|
59
59
|
</p>
|
60
60
|
Table of Contents:
|
@@ -80,7 +80,7 @@ Table of Contents:
|
|
80
80
|
</li>
|
81
81
|
<li><a href="#schema-map-of-seq">Mapping of Sequence</a>
|
82
82
|
</li>
|
83
|
-
<li><a href="#schema-rules">Rule and
|
83
|
+
<li><a href="#schema-rules">Rule and Entry</a>
|
84
84
|
</li>
|
85
85
|
<li><a href="#schema-unique">Unique constraint</a>
|
86
86
|
</li>
|
@@ -121,11 +121,19 @@ Table of Contents:
|
|
121
121
|
<h3 class="section2">Usage in Command-Line</h3>
|
122
122
|
<div class="terminal_caption">
|
123
123
|
usage1: validate YAML document in command-line</div>
|
124
|
-
<pre class="terminal"
|
124
|
+
<pre class="terminal">### kwalify-ruby
|
125
|
+
$ kwalify -f schema.yaml document.yaml [document2.yaml ...]
|
126
|
+
|
127
|
+
### kwalify-java
|
128
|
+
$ java -classpath kwalify.jar kwalify.Main -f schema.yaml document.yaml [document2.yaml ...]
|
125
129
|
</pre>
|
126
130
|
<div class="terminal_caption">
|
127
131
|
usage2: validate schema definition in command-line</div>
|
128
|
-
<pre class="terminal"
|
132
|
+
<pre class="terminal">### kwalify-ruby
|
133
|
+
$ kwalify -m schema.yaml [schema2.yaml ...]
|
134
|
+
|
135
|
+
### kwalify-java
|
136
|
+
$ java -classpath kwalify.jar kwalify.Main -m schema.yaml [schema2.yaml ...]
|
129
137
|
</pre>
|
130
138
|
<p>Command-line options:
|
131
139
|
</p>
|
@@ -173,6 +181,8 @@ usage2: validate schema definition in command-line</div>
|
|
173
181
|
|
174
182
|
<a name="usage2"></a>
|
175
183
|
<h3 class="section2">Usage in Ruby Script</h3>
|
184
|
+
<p>The followings are example scripts for Ruby.
|
185
|
+
</p>
|
176
186
|
<div class="program_caption">
|
177
187
|
validate YAML document in Ruby script</div>
|
178
188
|
<pre class="program">require 'kwalify'
|
@@ -206,14 +216,51 @@ document = parser.parse()
|
|
206
216
|
## validate document and show errors
|
207
217
|
error_list = validator.validate(document)
|
208
218
|
unless error_list.empty?
|
209
|
-
parser.
|
210
|
-
error_list.sort
|
219
|
+
parser.set_errors_linenum(error_list) # set linenum on error
|
220
|
+
error_list.sort.each do |error|
|
211
221
|
puts "(line %d)[%s] %s" % [error.linenum, error.path, error.message]
|
212
222
|
end
|
213
223
|
end
|
214
224
|
</pre>
|
215
225
|
<p>Kwalify's YAML parser is experimental. You should notice that Kwalify's YAML parser is limited only for basic syntax of YAML.
|
216
226
|
</p>
|
227
|
+
<p>The followings are example programs of Java.
|
228
|
+
</p>
|
229
|
+
<div class="program_caption">
|
230
|
+
validate YAML document and show linenumber on where error is found.</div>
|
231
|
+
<pre class="program">import kwalify.*;
|
232
|
+
|
233
|
+
public class Test {
|
234
|
+
|
235
|
+
public static void main(String[] args) throws Exception {
|
236
|
+
// read schema
|
237
|
+
String schema_str = Util.readFile("schema.yaml");
|
238
|
+
Object schema = new YamlParser(schema_str).parse();
|
239
|
+
|
240
|
+
// read document file
|
241
|
+
String document_str = Util.readFile("document.yaml");
|
242
|
+
YamlParser parser = new YamlParser(document_str);
|
243
|
+
Object document = parser.parse();
|
244
|
+
|
245
|
+
// create validator and validate
|
246
|
+
Validator validator = new Validator(schema);
|
247
|
+
List errors = validator.validate(document);
|
248
|
+
|
249
|
+
// show errors
|
250
|
+
if (errors != null && errors.size() > 0) {
|
251
|
+
parser.setErrorsLineNumber(errors);
|
252
|
+
Collections.sort(errors);
|
253
|
+
for (Iterator it = errors.iterator(); it.hasNext(); ) {
|
254
|
+
ValidationException error = (ValidationException)it.next();
|
255
|
+
int linenum = error.getLineNumber();
|
256
|
+
String path = error.getPath();
|
257
|
+
String mesg = error.getMessage();
|
258
|
+
System.out.println("- " + linenum + ": [" + path + "] " + mesg);
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
263
|
+
</pre>
|
217
264
|
<br>
|
218
265
|
|
219
266
|
|
@@ -430,8 +477,10 @@ document04b.yaml#0: INVALID
|
|
430
477
|
|
431
478
|
|
432
479
|
<a name="schema-rules"></a>
|
433
|
-
<h3 class="section2">Rule and
|
434
|
-
<p>
|
480
|
+
<h3 class="section2">Rule and Entry</h3>
|
481
|
+
<p>Rule is set of entries. Entry usually represents constraint outside of a few exceptions.
|
482
|
+
</p>
|
483
|
+
<p>The followings are constraint entries.
|
435
484
|
</p>
|
436
485
|
<dl class="dl3">
|
437
486
|
<dt class="dt3"><strong>
|
@@ -450,16 +499,6 @@ document04b.yaml#0: INVALID
|
|
450
499
|
Specifies regular expression pattern of value.
|
451
500
|
</dd>
|
452
501
|
<dt class="dt3"><strong>
|
453
|
-
<code>name:</code> </strong></dt>
|
454
|
-
<dd class="dd3">
|
455
|
-
Name of schema.
|
456
|
-
</dd>
|
457
|
-
<dt class="dt3"><strong>
|
458
|
-
<code>desc:</code> </strong></dt>
|
459
|
-
<dd class="dd3">
|
460
|
-
Description. This is not used for validation.
|
461
|
-
</dd>
|
462
|
-
<dt class="dt3"><strong>
|
463
502
|
<code>type:</code> </strong></dt>
|
464
503
|
<dd class="dd3">
|
465
504
|
Type of value. The followings are available:
|
@@ -517,7 +556,7 @@ document04b.yaml#0: INVALID
|
|
517
556
|
<code>assert:</code> </strong></dt>
|
518
557
|
<dd class="dd3">
|
519
558
|
String which represents validation expression. String should contain variable name <code>val</code> which repsents value.
|
520
|
-
(This is an experimental function.
|
559
|
+
(This is an experimental function and supported only Kwartz-ruby).
|
521
560
|
</dd>
|
522
561
|
<dt class="dt3"><strong>
|
523
562
|
<code>unique:</code> </strong></dt>
|
@@ -525,40 +564,55 @@ document04b.yaml#0: INVALID
|
|
525
564
|
Value is unique for mapping or sequence. See the next subsection for detail.
|
526
565
|
</dd>
|
527
566
|
</dl>
|
528
|
-
<p>
|
567
|
+
<p>The followings are non-constraint entries.
|
568
|
+
</p>
|
569
|
+
<dl class="dl3">
|
570
|
+
<dt class="dt3"><strong>
|
571
|
+
<code>name:</code> </strong></dt>
|
572
|
+
<dd class="dd3">
|
573
|
+
Name of schema.
|
574
|
+
</dd>
|
575
|
+
<dt class="dt3"><strong>
|
576
|
+
<code>desc:</code> </strong></dt>
|
577
|
+
<dd class="dd3">
|
578
|
+
Description. This is not used for validation.
|
579
|
+
</dd>
|
580
|
+
</dl>
|
581
|
+
<p>Rule contains 'type:' entry. 'sequence:' entry takes a list of rule. 'mapping:' entry takes a hash which values are rules.
|
529
582
|
</p>
|
530
583
|
<a name="schema05.yaml"></a>
|
531
584
|
<div class="program_caption">
|
532
|
-
<code>schema05.yaml</code> :
|
533
|
-
<pre class="program">type: seq
|
585
|
+
<code>schema05.yaml</code> : rule examples</div>
|
586
|
+
<pre class="program">type: seq # new rule
|
534
587
|
sequence:
|
535
|
-
-
|
588
|
+
-
|
589
|
+
type: map # new rule
|
536
590
|
mapping:
|
537
591
|
name:
|
538
|
-
type: str
|
592
|
+
type: str # new rule
|
539
593
|
required: yes
|
540
594
|
email:
|
541
|
-
type: str
|
595
|
+
type: str # new rule
|
542
596
|
required: yes
|
543
597
|
pattern: /@/
|
544
598
|
password:
|
545
|
-
type:
|
599
|
+
type: text # new rule
|
546
600
|
length: { max: 16, min: 8 }
|
547
601
|
age:
|
548
|
-
type: int
|
602
|
+
type: int # new rule
|
549
603
|
range: { max: 30, min: 18 }
|
550
604
|
# or assert: 18 <= val && val <= 30
|
551
605
|
blood:
|
552
|
-
type: str
|
606
|
+
type: str # new rule
|
553
607
|
enum:
|
554
608
|
- A
|
555
609
|
- B
|
556
610
|
- O
|
557
611
|
- AB
|
558
612
|
birth:
|
559
|
-
type: date
|
613
|
+
type: date # new rule
|
560
614
|
memo:
|
561
|
-
type: any
|
615
|
+
type: any # new rule
|
562
616
|
</pre>
|
563
617
|
<a name="document05a.yaml"></a>
|
564
618
|
<div class="program_caption">
|
@@ -615,15 +669,15 @@ document05b.yaml#0: INVALID
|
|
615
669
|
|
616
670
|
<a name="schema-unique"></a>
|
617
671
|
<h3 class="section2">Unique constraint</h3>
|
618
|
-
<p>'<code>unique:</code>' constraint is available with elements of sequence or mapping.
|
672
|
+
<p>'<code>unique:</code>' constraint entry is available with elements of sequence or mapping.
|
619
673
|
This is equivalent to unique key or primary key of RDBMS.
|
620
674
|
</p>
|
621
|
-
<p>Type of
|
675
|
+
<p>Type of rule which has '<code>unique:</code>' entry must be scalar (str, int, float, ...).
|
622
676
|
Type of parent rule must be sequence or mapping.
|
623
677
|
</p>
|
624
678
|
<a name="schema06.yaml"></a>
|
625
679
|
<div class="program_caption">
|
626
|
-
<code>schema06.yaml</code> : unique constraint with mapping and sequence</div>
|
680
|
+
<code>schema06.yaml</code> : unique constraint entry with mapping and sequence</div>
|
627
681
|
<pre class="program">type: seq
|
628
682
|
sequence:
|
629
683
|
- type: map
|
@@ -697,12 +751,12 @@ document06b.yaml#0: INVALID
|
|
697
751
|
|
698
752
|
<a name="schema-hook"></a>
|
699
753
|
<h3 class="section2">Validator#validator_hook()</h3>
|
700
|
-
<p>You can extend Kwalify::Validator class and override Kwalify::Validator#validator_hook() method.
|
701
|
-
This method is called by Kwalify::Validator#validate().
|
754
|
+
<p>You can extend Kwalify::Validator class (Ruby) or kwalify.Validator class (Java), and override Kwalify::Validator#validator_hook() method (Ruby) or kwalify.Validator#validateHook() method (Java).
|
755
|
+
This method is called by Kwalify::Validator#validate() (Ruby) or kwalify.Validator#validate() (Java).
|
702
756
|
</p>
|
703
|
-
<a name="
|
757
|
+
<a name="answers-schema.yaml"></a>
|
704
758
|
<div class="program_caption">
|
705
|
-
|
759
|
+
answers-schema.yaml : 'name:' is important.</div>
|
706
760
|
<pre class="program">type: map
|
707
761
|
mapping:
|
708
762
|
answers:
|
@@ -724,9 +778,9 @@ mapping:
|
|
724
778
|
reason:
|
725
779
|
type: str
|
726
780
|
</pre>
|
727
|
-
<a name="
|
781
|
+
<a name="answers-validator.rb"></a>
|
728
782
|
<div class="program_caption">
|
729
|
-
|
783
|
+
answers-validator.rb : validate script for Ruby</div>
|
730
784
|
<pre class="program">#!/usr/bin/env ruby
|
731
785
|
|
732
786
|
require 'kwalify'
|
@@ -736,7 +790,7 @@ require 'yaml'
|
|
736
790
|
class AnswersValidator < Kwalify::Validator
|
737
791
|
|
738
792
|
## load schema definition
|
739
|
-
@@schema = YAML.load_file('
|
793
|
+
@@schema = YAML.load_file('answers-schema.yaml')
|
740
794
|
|
741
795
|
def initialize()
|
742
796
|
super(@@schema)
|
@@ -792,7 +846,7 @@ end
|
|
792
846
|
</pre>
|
793
847
|
<div class="terminal_caption">
|
794
848
|
validate</div>
|
795
|
-
<pre class="terminal">$ ruby
|
849
|
+
<pre class="terminal">$ ruby answers-validator.rb document07a.yaml
|
796
850
|
Valid.
|
797
851
|
</pre>
|
798
852
|
<a name="document07b.yaml"></a>
|
@@ -800,18 +854,141 @@ Valid.
|
|
800
854
|
<code>document07b.yaml</code> : invalid document example</div>
|
801
855
|
<pre class="program">answers:
|
802
856
|
- name: Foo
|
803
|
-
answer:
|
857
|
+
answer: good
|
804
858
|
- name: Bar
|
805
|
-
answer:
|
859
|
+
answer: bad
|
806
860
|
- name: Baz
|
807
|
-
answer:
|
861
|
+
answer: not bad
|
808
862
|
</pre>
|
809
863
|
<div class="terminal_caption">
|
810
864
|
validate</div>
|
811
|
-
<pre class="terminal">$ ruby
|
865
|
+
<pre class="terminal">$ ruby answers-validator.rb document07b.yaml
|
812
866
|
*** INVALID!
|
813
867
|
- [/answers/1] : reason is required when answer is 'bad'.
|
814
868
|
</pre>
|
869
|
+
<p>You can validate some document by a Validator instance because Validator class and Validator#validate() method are stateless. If you use instance variables in custom validator_hook() method, it becomes to be stateful.
|
870
|
+
</p>
|
871
|
+
<p>Here is a Java program equivarent to 'answers-validator.rb'.
|
872
|
+
</p>
|
873
|
+
<a name="AnswersValidator.java"></a>
|
874
|
+
<div class="program_caption">
|
875
|
+
AnswersValidator.java : validate program for Java</div>
|
876
|
+
<pre class="program">import kwalify.Validator;
|
877
|
+
import kwalify.Rule;
|
878
|
+
import kwalify.Util;
|
879
|
+
import kwalify.YamlUtil;
|
880
|
+
import kwalify.YamlParser;
|
881
|
+
import kwalify.SyntaxException;
|
882
|
+
import kwalify.ValidationException;
|
883
|
+
|
884
|
+
import java.util.*;
|
885
|
+
import java.io.IOException;
|
886
|
+
|
887
|
+
|
888
|
+
/**
|
889
|
+
* validator class for answers
|
890
|
+
*/
|
891
|
+
public class AnswersValidator extends Validator {
|
892
|
+
|
893
|
+
/** schema string */
|
894
|
+
private static final String SCHEMA = ""
|
895
|
+
+ "type: map\n"
|
896
|
+
+ "mapping:\n"
|
897
|
+
+ " answers:\n"
|
898
|
+
+ " type: seq\n"
|
899
|
+
+ " sequence:\n"
|
900
|
+
+ " - type: map\n"
|
901
|
+
+ " name: Answer\n"
|
902
|
+
+ " mapping:\n"
|
903
|
+
+ " name:\n"
|
904
|
+
+ " type: str\n"
|
905
|
+
+ " required: yes\n"
|
906
|
+
+ " answer:\n"
|
907
|
+
+ " type: str\n"
|
908
|
+
+ " required: yes\n"
|
909
|
+
+ " enum:\n"
|
910
|
+
+ " - good\n"
|
911
|
+
+ " - not bad\n"
|
912
|
+
+ " - bad\n"
|
913
|
+
+ " reason:\n"
|
914
|
+
+ " type: str\n"
|
915
|
+
;
|
916
|
+
|
917
|
+
/** schema object */
|
918
|
+
private static Map schema = null;
|
919
|
+
static {
|
920
|
+
try {
|
921
|
+
schema = (Map)YamlUtil.load(SCHEMA);
|
922
|
+
} catch (SyntaxException ex) {
|
923
|
+
assert false;
|
924
|
+
}
|
925
|
+
}
|
926
|
+
|
927
|
+
/** construnctor */
|
928
|
+
public AnswersValidator() {
|
929
|
+
super(schema);
|
930
|
+
}
|
931
|
+
|
932
|
+
/** hook method called by Validator#validate() */
|
933
|
+
protected void validateHook(Object value, Rule rule, String path, List errors) {
|
934
|
+
String rule_name = rule.getName();
|
935
|
+
if (rule_name != null && rule_name.equals("Answer")) {
|
936
|
+
assert value instanceof Map;
|
937
|
+
Map val = (Map)value;
|
938
|
+
assert val.get("answer") != null;
|
939
|
+
if (val.get("answer").equals("bad")) {
|
940
|
+
String reason = (String)val.get("reason");
|
941
|
+
if (reason == null || reason.length() == 0) {
|
942
|
+
String msg = "reason is required when answer is 'bad'.";
|
943
|
+
errors.add(new ValidationException(msg, path));
|
944
|
+
}
|
945
|
+
}
|
946
|
+
}
|
947
|
+
}
|
948
|
+
|
949
|
+
/** main program */
|
950
|
+
public static void main(String[] args) throws IOException, SyntaxException {
|
951
|
+
// create validator
|
952
|
+
Validator validator = new AnswersValidator();
|
953
|
+
|
954
|
+
// load YAML document
|
955
|
+
String input;
|
956
|
+
if (args.length > 0) {
|
957
|
+
input = Util.readFile(args[0]);
|
958
|
+
} else {
|
959
|
+
input = Util.readInputStream(System.in);
|
960
|
+
}
|
961
|
+
YamlParser parser = new YamlParser(input);
|
962
|
+
Object document = parser.parse();
|
963
|
+
|
964
|
+
// validate and show errors
|
965
|
+
List errors = validator.validate(document);
|
966
|
+
if (errors == null || errors.size() == 0) {
|
967
|
+
System.out.println("Valid.");
|
968
|
+
} else {
|
969
|
+
System.out.println("*** INVALID!");
|
970
|
+
parser.setErrorsLineNumber(errors);
|
971
|
+
Collections.sort(errors);
|
972
|
+
for (Iterator it = errors.iterator(); it.hasNext(); ) {
|
973
|
+
ValidationException error = (ValidationException)it.next();
|
974
|
+
int linenum = error.getLineNumber();
|
975
|
+
String path = error.getPath();
|
976
|
+
String mesg = error.getMessage();
|
977
|
+
String s = "- line " + linenum + ": [" + path + "] " + mesg;
|
978
|
+
System.out.println(s);
|
979
|
+
}
|
980
|
+
}
|
981
|
+
}
|
982
|
+
}
|
983
|
+
</pre>
|
984
|
+
<div class="terminal_caption">
|
985
|
+
validate</div>
|
986
|
+
<pre class="terminal">$ java -classpath kwalify.jar AnswersValidator document07a.yaml
|
987
|
+
Valid.
|
988
|
+
$ java -classpath kwalify.jar AnswersValidator document07b.yaml
|
989
|
+
*** INVALID!
|
990
|
+
- line 4: [/answers/1] reason is required when answer is 'bad'.
|
991
|
+
</pre>
|
815
992
|
<br>
|
816
993
|
|
817
994
|
|
@@ -830,7 +1007,7 @@ require 'kwalify'
|
|
830
1007
|
require 'yaml'
|
831
1008
|
|
832
1009
|
## load schema definition
|
833
|
-
schema = YAML.load_file('
|
1010
|
+
schema = YAML.load_file('answers-schema.yaml')
|
834
1011
|
|
835
1012
|
## create validator for answers
|
836
1013
|
validator = Kwalify::Validator.new(schema) <strong>{ |value, rule, path, errors|</strong>
|
@@ -865,14 +1042,13 @@ end
|
|
865
1042
|
<div class="terminal_caption">
|
866
1043
|
validate</div>
|
867
1044
|
<pre class="terminal">$ ruby validate08.rb document07a.yaml
|
868
|
-
|
869
|
-
- [/] : not a sequence.
|
1045
|
+
Valid.
|
870
1046
|
</pre>
|
871
1047
|
<div class="terminal_caption">
|
872
1048
|
validate</div>
|
873
1049
|
<pre class="terminal">$ ruby validate08.rb document07b.yaml
|
874
1050
|
*** INVALID!
|
875
|
-
- [/] :
|
1051
|
+
- [/answers/1] : reason is required when answer is 'bad'.
|
876
1052
|
</pre>
|
877
1053
|
<br>
|
878
1054
|
|
@@ -974,7 +1150,7 @@ document12a.yaml#0: valid.
|
|
974
1150
|
<a name="document12b.yaml"></a>
|
975
1151
|
<div class="program_caption">
|
976
1152
|
<code>document12b.yaml</code> : invalid JSON document example</div>
|
977
|
-
<pre class="program">{
|
1153
|
+
<pre class="program">{
|
978
1154
|
"mail": "foo@mail.com",
|
979
1155
|
"age": twenty,
|
980
1156
|
"gender": "X",
|
@@ -1125,11 +1301,11 @@ tmp.update(a1) # merge
|
|
1125
1301
|
tmp["A"] = 15 # override
|
1126
1302
|
tmp["C"] = 30 # add
|
1127
1303
|
</pre>
|
1128
|
-
<p>This feature allows Kwalify to merge
|
1304
|
+
<p>This feature allows Kwalify to merge rule entries.
|
1129
1305
|
</p>
|
1130
1306
|
<a name="schema15.yaml"></a>
|
1131
1307
|
<div class="program_caption">
|
1132
|
-
<code>schema15.yaml</code> :
|
1308
|
+
<code>schema15.yaml</code> : merging rule entries example</div>
|
1133
1309
|
<pre class="program">type: map
|
1134
1310
|
mapping:
|
1135
1311
|
"group":
|
@@ -1146,11 +1322,11 @@ mapping:
|
|
1146
1322
|
type: map
|
1147
1323
|
mapping:
|
1148
1324
|
"name":
|
1149
|
-
<strong><<: *name # merge
|
1150
|
-
<strong>length: { max: 16 } # override
|
1325
|
+
<strong><<: *name</strong> # merge
|
1326
|
+
<strong>length: { max: 16 }</strong> # override
|
1151
1327
|
"email":
|
1152
|
-
<strong><<: *email # merge
|
1153
|
-
<strong>required: yes # add
|
1328
|
+
<strong><<: *email</strong> # merge
|
1329
|
+
<strong>required: yes</strong> # add
|
1154
1330
|
</pre>
|
1155
1331
|
<a name="document15a.yaml"></a>
|
1156
1332
|
<div class="program_caption">
|