json-schema 2.7.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +70 -12
  3. data/lib/json-schema/attribute.rb +10 -0
  4. data/lib/json-schema/attributes/allof.rb +1 -1
  5. data/lib/json-schema/attributes/anyof.rb +1 -1
  6. data/lib/json-schema/attributes/const.rb +15 -0
  7. data/lib/json-schema/attributes/dependencies.rb +0 -6
  8. data/lib/json-schema/attributes/dependencies_v4.rb +11 -0
  9. data/lib/json-schema/attributes/divisibleby.rb +1 -1
  10. data/lib/json-schema/attributes/formats/custom.rb +1 -1
  11. data/lib/json-schema/attributes/formats/date.rb +1 -1
  12. data/lib/json-schema/attributes/formats/date_time.rb +1 -1
  13. data/lib/json-schema/attributes/formats/date_time_v4.rb +1 -1
  14. data/lib/json-schema/attributes/formats/ip.rb +1 -1
  15. data/lib/json-schema/attributes/formats/time.rb +1 -1
  16. data/lib/json-schema/attributes/formats/uri.rb +1 -1
  17. data/lib/json-schema/attributes/limit.rb +0 -127
  18. data/lib/json-schema/attributes/limits/items.rb +15 -0
  19. data/lib/json-schema/attributes/limits/length.rb +15 -0
  20. data/lib/json-schema/attributes/limits/max_items.rb +15 -0
  21. data/lib/json-schema/attributes/limits/max_length.rb +15 -0
  22. data/lib/json-schema/attributes/limits/max_properties.rb +15 -0
  23. data/lib/json-schema/attributes/limits/maximum.rb +15 -0
  24. data/lib/json-schema/attributes/limits/maximum_inclusive.rb +11 -0
  25. data/lib/json-schema/attributes/limits/min_items.rb +15 -0
  26. data/lib/json-schema/attributes/limits/min_length.rb +15 -0
  27. data/lib/json-schema/attributes/limits/min_properties.rb +15 -0
  28. data/lib/json-schema/attributes/limits/minimum.rb +15 -0
  29. data/lib/json-schema/attributes/limits/minimum_inclusive.rb +11 -0
  30. data/lib/json-schema/attributes/limits/numeric.rb +16 -0
  31. data/lib/json-schema/attributes/limits/properties.rb +15 -0
  32. data/lib/json-schema/attributes/not.rb +1 -1
  33. data/lib/json-schema/attributes/oneof.rb +2 -2
  34. data/lib/json-schema/attributes/properties.rb +0 -8
  35. data/lib/json-schema/attributes/properties_v4.rb +13 -0
  36. data/lib/json-schema/attributes/ref.rb +1 -17
  37. data/lib/json-schema/attributes/type.rb +0 -10
  38. data/lib/json-schema/attributes/type_v4.rb +1 -1
  39. data/lib/json-schema/schema/reader.rb +1 -1
  40. data/lib/json-schema/schema/validator.rb +2 -1
  41. data/lib/json-schema/schema.rb +2 -2
  42. data/lib/json-schema/util/array_set.rb +4 -4
  43. data/lib/json-schema/util/uri.rb +42 -0
  44. data/lib/json-schema/util/uuid.rb +0 -1
  45. data/lib/json-schema/validator.rb +72 -88
  46. data/lib/json-schema/validators/draft6.rb +57 -0
  47. data/lib/json-schema/validators/hyper-draft3.rb +13 -0
  48. data/lib/json-schema/validators/hyper-draft6.rb +13 -0
  49. data/lib/json-schema.rb +1 -2
  50. data/resources/draft-03.json +173 -173
  51. data/resources/draft-06.json +150 -0
  52. metadata +31 -10
@@ -43,9 +43,9 @@ module JSON
43
43
  end
44
44
 
45
45
  if validation_error_count == one_of.length
46
- message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match any of the required schemas"
46
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match any of the required schemas"
47
47
  else
48
- message = "The property '#{build_fragment(fragments)}' of type #{data.class} matched more than one of the required schemas"
48
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} matched more than one of the required schemas"
49
49
  end
50
50
 
51
51
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors]) if message
@@ -62,13 +62,5 @@ module JSON
62
62
  end
63
63
  end
64
64
  end
65
-
66
- class PropertiesV4Attribute < PropertiesAttribute
67
- # draft4 relies on its own RequiredAttribute validation at a higher level, rather than
68
- # as an attribute of individual properties.
69
- def self.required?(schema, options)
70
- options[:strict] == true
71
- end
72
- end
73
65
  end
74
66
  end
@@ -0,0 +1,13 @@
1
+ require 'json-schema/attributes/properties'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertiesV4Attribute < PropertiesAttribute
6
+ # draft4 relies on its own RequiredAttribute validation at a higher level, rather than
7
+ # as an attribute of individual properties.
8
+ def self.required?(schema, options)
9
+ options[:strict] == true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -22,23 +22,7 @@ module JSON
22
22
  def self.get_referenced_uri_and_schema(s, current_schema, validator)
23
23
  uri,schema = nil,nil
24
24
 
25
- temp_uri = JSON::Util::URI.parse(s['$ref'])
26
- temp_uri.defer_validation do
27
- if temp_uri.relative?
28
- temp_uri.merge!(current_schema.uri)
29
- # Check for absolute path
30
- path, fragment = s['$ref'].split("#")
31
- if path.nil? || path == ''
32
- temp_uri.path = current_schema.uri.path
33
- elsif path[0,1] == "/"
34
- temp_uri.path = Pathname.new(path).cleanpath.to_s
35
- else
36
- temp_uri.join!(path)
37
- end
38
- temp_uri.fragment = fragment
39
- end
40
- temp_uri.fragment = "" if temp_uri.fragment.nil? || temp_uri.fragment.empty?
41
- end
25
+ temp_uri = JSON::Util::URI.normalize_ref(s['$ref'], current_schema.uri)
42
26
 
43
27
  # Grab the parent schema from the schema list
44
28
  schema_key = temp_uri.to_s.split("#")[0] + "#"
@@ -68,16 +68,6 @@ module JSON
68
68
  def self.list_types(types)
69
69
  types.map { |type| type.is_a?(String) ? type : '(schema)' }.join(', ')
70
70
  end
71
-
72
- # Lookup Schema type of given class instance
73
- def self.type_of_data(data)
74
- type, _ = TYPE_CLASS_MAPPINGS.map { |k,v| [k,v] }.sort_by { |(_, v)|
75
- -Array(v).map { |klass| klass.ancestors.size }.max
76
- }.find { |(_, v)|
77
- Array(v).any? { |klass| data.kind_of?(klass) }
78
- }
79
- type
80
- end
81
71
  end
82
72
  end
83
73
  end
@@ -17,7 +17,7 @@ module JSON
17
17
  message = format(
18
18
  "The property '%s' of type %s did not match %s: %s",
19
19
  build_fragment(fragments),
20
- data.class,
20
+ type_of_data(data),
21
21
  union ? 'one or more of the following types' : 'the following type',
22
22
  types
23
23
  )
@@ -118,7 +118,7 @@ module JSON
118
118
 
119
119
  def read_uri(uri)
120
120
  if accept_uri?(uri)
121
- open(uri.to_s).read
121
+ URI.open(uri.to_s).read
122
122
  else
123
123
  raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
124
124
  end
@@ -14,7 +14,8 @@ module JSON
14
14
  end
15
15
 
16
16
  def extend_schema_definition(schema_uri)
17
- validator = JSON::Validator.validator_for(schema_uri)
17
+ warn "[DEPRECATION NOTICE] The preferred way to extend a Validator is by subclassing, rather than #extend_schema_definition. This method will be removed in version >= 3."
18
+ validator = JSON::Validator.validator_for_uri(schema_uri)
18
19
  @attributes.merge!(validator.attributes)
19
20
  end
20
21
 
@@ -21,7 +21,7 @@ module JSON
21
21
 
22
22
  # If there is a $schema on this schema, use it to determine which validator to use
23
23
  if @schema['$schema']
24
- @validator = JSON::Validator.validator_for(@schema['$schema'])
24
+ @validator = JSON::Validator.validator_for_uri(@schema['$schema'])
25
25
  elsif parent_validator
26
26
  @validator = parent_validator
27
27
  else
@@ -52,7 +52,7 @@ module JSON
52
52
  def to_array_schema
53
53
  array_schema = { 'type' => 'array', 'items' => schema }
54
54
  array_schema['$schema'] = schema['$schema'] unless schema['$schema'].nil?
55
- JSON::Schema.new(array_schema, uri, validator)
55
+ self.class.new(array_schema, uri, validator)
56
56
  end
57
57
 
58
58
  def to_s
@@ -7,14 +7,14 @@ class ArraySet < Array
7
7
  def include?(obj)
8
8
  if !defined? @values
9
9
  @values = Set.new
10
- self.each { |x| @values << convert_to_float_if_fixnum(x) }
10
+ self.each { |x| @values << convert_to_float_if_numeric(x) }
11
11
  end
12
- @values.include?(convert_to_float_if_fixnum(obj))
12
+ @values.include?(convert_to_float_if_numeric(obj))
13
13
  end
14
14
 
15
15
  private
16
16
 
17
- def convert_to_float_if_fixnum(value)
18
- value.is_a?(Fixnum) ? value.to_f : value
17
+ def convert_to_float_if_numeric(value)
18
+ value.is_a?(Numeric) ? value.to_f : value
19
19
  end
20
20
  end
@@ -23,6 +23,43 @@ module JSON
23
23
  normalized_uri
24
24
  end
25
25
 
26
+ def self.absolutize_ref(ref, base)
27
+ ref_uri = strip_fragment(ref.dup)
28
+
29
+ return ref_uri if ref_uri.absolute?
30
+ return parse(base) if ref_uri.path.empty?
31
+
32
+ uri = strip_fragment(base.dup).join(ref_uri.path)
33
+ normalized_uri(uri)
34
+ end
35
+
36
+ def self.normalize_ref(ref, base)
37
+ ref_uri = parse(ref)
38
+ base_uri = parse(base)
39
+
40
+ ref_uri.defer_validation do
41
+ if ref_uri.relative?
42
+ ref_uri.merge!(base_uri)
43
+
44
+ # Check for absolute path
45
+ path, fragment = ref.to_s.split("#")
46
+ if path.nil? || path == ''
47
+ ref_uri.path = base_uri.path
48
+ elsif path[0,1] == "/"
49
+ ref_uri.path = Pathname.new(path).cleanpath.to_s
50
+ else
51
+ ref_uri.join!(path)
52
+ end
53
+
54
+ ref_uri.fragment = fragment
55
+ end
56
+
57
+ ref_uri.fragment = "" if ref_uri.fragment.nil? || ref_uri.fragment.empty?
58
+ end
59
+
60
+ ref_uri
61
+ end
62
+
26
63
  def self.parse(uri)
27
64
  if uri.is_a?(Addressable::URI)
28
65
  return uri.dup
@@ -63,6 +100,11 @@ module JSON
63
100
 
64
101
  Addressable::URI.unescape(parsed_uri.path)
65
102
  end
103
+
104
+ def self.clear_cache
105
+ @parse_cache = {}
106
+ @normalize_cache = {}
107
+ end
66
108
  end
67
109
  end
68
110
  end
@@ -241,7 +241,6 @@ module JSON
241
241
  alias urn to_uri
242
242
 
243
243
  # Convert into 128-bit unsigned integer
244
- # Typically a Bignum instance, but can be a Fixnum.
245
244
  def to_int
246
245
  tmp = self.raw_bytes.unpack "C*"
247
246
  tmp.inject do |r, i|
@@ -4,6 +4,7 @@ require 'bigdecimal'
4
4
  require 'digest/sha1'
5
5
  require 'date'
6
6
  require 'thread'
7
+ require 'timeout'
7
8
  require 'yaml'
8
9
 
9
10
  require 'json-schema/schema/reader'
@@ -41,28 +42,24 @@ module JSON
41
42
  @options = @@default_opts.clone.merge(opts)
42
43
  @errors = []
43
44
 
44
- validator = JSON::Validator.validator_for_name(@options[:version])
45
- @options[:version] = validator
46
- @options[:schema_reader] ||= JSON::Validator.schema_reader
45
+ configured_validator = self.class.validator_for_name(@options[:version])
46
+ @options[:schema_reader] ||= self.class.schema_reader
47
47
 
48
48
  @validation_options = @options[:record_errors] ? {:record_errors => true} : {}
49
49
  @validation_options[:insert_defaults] = true if @options[:insert_defaults]
50
50
  @validation_options[:strict] = true if @options[:strict] == true
51
51
  @validation_options[:clear_cache] = true if !@@cache_schemas || @options[:clear_cache]
52
52
 
53
- @@mutex.synchronize { @base_schema = initialize_schema(schema_data) }
53
+ @@mutex.synchronize { @base_schema = initialize_schema(schema_data, configured_validator) }
54
54
  @original_data = data
55
55
  @data = initialize_data(data)
56
56
  @@mutex.synchronize { build_schemas(@base_schema) }
57
57
 
58
58
  # validate the schema, if requested
59
59
  if @options[:validate_schema]
60
- if @base_schema.schema["$schema"]
61
- base_validator = JSON::Validator.validator_for_name(@base_schema.schema["$schema"])
62
- end
63
- metaschema = base_validator ? base_validator.metaschema : validator.metaschema
64
60
  # Don't clear the cache during metaschema validation!
65
- self.class.validate!(metaschema, @base_schema.schema, {:clear_cache => false})
61
+ meta_validator = self.class.new(@base_schema.validator.metaschema, @base_schema.schema, {:clear_cache => false})
62
+ meta_validator.validate
66
63
  end
67
64
 
68
65
  # If the :fragment option is set, try and validate against the fragment
@@ -73,38 +70,35 @@ module JSON
73
70
 
74
71
  def schema_from_fragment(base_schema, fragment)
75
72
  schema_uri = base_schema.uri
76
- fragments = fragment.split("/")
73
+ fragments = fragment.split("/").map { |f| f.gsub('~0', '~').gsub('~1', '/') }
77
74
 
78
75
  # ensure the first element was a hash, per the fragment spec
79
76
  if fragments.shift != "#"
80
77
  raise JSON::Schema::SchemaError.new("Invalid fragment syntax in :fragment option")
81
78
  end
82
79
 
80
+ schema_fragment = base_schema.schema
83
81
  fragments.each do |f|
84
- if base_schema.is_a?(JSON::Schema) #test if fragment is a JSON:Schema instance
85
- if !base_schema.schema.has_key?(f)
86
- raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
87
- end
88
- base_schema = base_schema.schema[f]
89
- elsif base_schema.is_a?(Hash)
90
- if !base_schema.has_key?(f)
91
- raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
92
- end
93
- base_schema = JSON::Schema.new(base_schema[f],schema_uri,@options[:version])
94
- elsif base_schema.is_a?(Array)
95
- if base_schema[f.to_i].nil?
96
- raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
97
- end
98
- base_schema = JSON::Schema.new(base_schema[f.to_i],schema_uri,@options[:version])
99
- else
100
- raise JSON::Schema::SchemaError.new("Invalid schema encountered when resolving :fragment option")
82
+ case schema_fragment
83
+ when Hash
84
+ schema_fragment = schema_fragment[f]
85
+ when Array
86
+ schema_fragment = schema_fragment[f.to_i]
101
87
  end
102
88
  end
103
89
 
90
+ unless schema_fragment.is_a?(Hash)
91
+ raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
92
+ end
93
+
94
+ schema = JSON::Schema.new(schema_fragment, schema_uri, base_schema.validator)
95
+
104
96
  if @options[:list]
105
- base_schema.to_array_schema
97
+ schema.to_array_schema
98
+ elsif schema.is_a?(Hash)
99
+ JSON::Schema.new(schema, schema_uri, @options[:version])
106
100
  else
107
- base_schema
101
+ schema
108
102
  end
109
103
  end
110
104
 
@@ -123,33 +117,25 @@ module JSON
123
117
  end
124
118
  ensure
125
119
  if @validation_options[:clear_cache] == true
126
- Validator.clear_cache
120
+ self.class.clear_cache
127
121
  end
128
122
  if @validation_options[:insert_defaults]
129
- JSON::Validator.merge_missing_values(@data, @original_data)
123
+ self.class.merge_missing_values(@data, @original_data)
130
124
  end
131
125
  end
132
126
 
133
127
  def load_ref_schema(parent_schema, ref)
134
- schema_uri = absolutize_ref_uri(ref, parent_schema.uri)
128
+ schema_uri = JSON::Util::URI.absolutize_ref(ref, parent_schema.uri)
135
129
  return true if self.class.schema_loaded?(schema_uri)
136
130
 
131
+ validator = self.class.validator_for_uri(schema_uri, false)
132
+ schema_uri = JSON::Util::URI.file_uri(validator.metaschema) if validator
133
+
137
134
  schema = @options[:schema_reader].read(schema_uri)
138
135
  self.class.add_schema(schema)
139
136
  build_schemas(schema)
140
137
  end
141
138
 
142
- def absolutize_ref_uri(ref, parent_schema_uri)
143
- ref_uri = JSON::Util::URI.strip_fragment(ref)
144
-
145
- return ref_uri if ref_uri.absolute?
146
- # This is a self reference and thus the schema does not need to be re-loaded
147
- return parent_schema_uri if ref_uri.path.empty?
148
-
149
- uri = JSON::Util::URI.strip_fragment(parent_schema_uri.dup)
150
- Util::URI.normalized_uri(uri.join(ref_uri.path))
151
- end
152
-
153
139
  # Build all schemas with IDs, mapping out the namespace
154
140
  def build_schemas(parent_schema)
155
141
  schema = parent_schema.schema
@@ -225,7 +211,7 @@ module JSON
225
211
  schema_uri = parent_schema.uri.dup
226
212
  schema = JSON::Schema.new(obj, schema_uri, parent_schema.validator)
227
213
  if obj['id']
228
- Validator.add_schema(schema)
214
+ self.class.add_schema(schema)
229
215
  end
230
216
  build_schemas(schema)
231
217
  end
@@ -258,10 +244,14 @@ module JSON
258
244
  end
259
245
 
260
246
  def validate!(schema, data,opts={})
261
- validator = JSON::Validator.new(schema, data, opts)
247
+ validator = new(schema, data, opts)
262
248
  validator.validate
263
249
  end
264
- alias_method 'validate2', 'validate!'
250
+
251
+ def validate2(schema, data, opts={})
252
+ warn "[DEPRECATION NOTICE] JSON::Validator#validate2 has been replaced by JSON::Validator#validate! and will be removed in version >= 3. Please use the #validate! method instead."
253
+ validate!(schema, data, opts)
254
+ end
265
255
 
266
256
  def validate_json!(schema, data, opts={})
267
257
  validate!(schema, data, opts.merge(:json => true))
@@ -277,7 +267,7 @@ module JSON
277
267
 
278
268
  def fully_validate_schema(schema, opts={})
279
269
  data = schema
280
- schema = JSON::Validator.validator_for_name(opts[:version]).metaschema
270
+ schema = validator_for_name(opts[:version]).metaschema
281
271
  fully_validate(schema, data, opts)
282
272
  end
283
273
 
@@ -299,6 +289,7 @@ module JSON
299
289
 
300
290
  def clear_cache
301
291
  @@schemas = {}
292
+ JSON::Util::URI.clear_cache
302
293
  end
303
294
 
304
295
  def schemas
@@ -337,28 +328,34 @@ module JSON
337
328
  @@default_validator
338
329
  end
339
330
 
340
- def validator_for_uri(schema_uri)
331
+ def validator_for_uri(schema_uri, raise_not_found=true)
341
332
  return default_validator unless schema_uri
342
333
  u = JSON::Util::URI.parse(schema_uri)
343
334
  validator = validators["#{u.scheme}://#{u.host}#{u.path}"]
344
- if validator.nil?
335
+ if validator.nil? && raise_not_found
345
336
  raise JSON::Schema::SchemaError.new("Schema not found: #{schema_uri}")
346
337
  else
347
338
  validator
348
339
  end
349
340
  end
350
341
 
351
- def validator_for_name(schema_name)
342
+ def validator_for_name(schema_name, raise_not_found=true)
352
343
  return default_validator unless schema_name
353
- validator = validators_for_names([schema_name]).first
354
- if validator.nil?
344
+ schema_name = schema_name.to_s
345
+ validator = validators.values.detect do |v|
346
+ Array(v.names).include?(schema_name)
347
+ end
348
+ if validator.nil? && raise_not_found
355
349
  raise JSON::Schema::SchemaError.new("The requested JSON schema version is not supported")
356
350
  else
357
351
  validator
358
352
  end
359
353
  end
360
354
 
361
- alias_method :validator_for, :validator_for_uri
355
+ def validator_for(schema_uri)
356
+ warn "[DEPRECATION NOTICE] JSON::Validator#validator_for has been replaced by JSON::Validator#validator_for_uri and will be removed in version >= 3. Please use the #validator_for_uri method instead."
357
+ validator_for_uri(schema_uri)
358
+ end
362
359
 
363
360
  def register_validator(v)
364
361
  @@validators["#{v.uri.scheme}://#{v.uri.host}#{v.uri.path}"] = v
@@ -368,21 +365,24 @@ module JSON
368
365
  @@default_validator = v
369
366
  end
370
367
 
371
- def register_format_validator(format, validation_proc, versions = ["draft1", "draft2", "draft3", "draft4", nil])
368
+ def register_format_validator(format, validation_proc, versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
372
369
  custom_format_validator = JSON::Schema::CustomFormat.new(validation_proc)
373
- validators_for_names(versions).each do |validator|
370
+ versions.each do |version|
371
+ validator = validator_for_name(version)
374
372
  validator.formats[format.to_s] = custom_format_validator
375
373
  end
376
374
  end
377
375
 
378
- def deregister_format_validator(format, versions = ["draft1", "draft2", "draft3", "draft4", nil])
379
- validators_for_names(versions).each do |validator|
376
+ def deregister_format_validator(format, versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
377
+ versions.each do |version|
378
+ validator = validator_for_name(version)
380
379
  validator.formats[format.to_s] = validator.default_formats[format.to_s]
381
380
  end
382
381
  end
383
382
 
384
- def restore_default_formats(versions = ["draft1", "draft2", "draft3", "draft4", nil])
385
- validators_for_names(versions).each do |validator|
383
+ def restore_default_formats(versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
384
+ versions.each do |version|
385
+ validator = validator_for_name(version)
386
386
  validator.formats = validator.default_formats.clone
387
387
  end
388
388
  end
@@ -487,22 +487,6 @@ module JSON
487
487
  @@serializer = lambda{|o| YAML.dump(o) }
488
488
  end
489
489
  end
490
-
491
- private
492
-
493
- def validators_for_names(names)
494
- names = names.map { |name| name.to_s }
495
- [].tap do |memo|
496
- validators.each do |_, validator|
497
- if (validator.names & names).any?
498
- memo << validator
499
- end
500
- end
501
- if names.include?('')
502
- memo << default_validator
503
- end
504
- end
505
- end
506
490
  end
507
491
 
508
492
  private
@@ -527,16 +511,16 @@ module JSON
527
511
  @@fake_uuid_generator.call(schema)
528
512
  end
529
513
 
530
- def initialize_schema(schema)
514
+ def initialize_schema(schema, default_validator)
531
515
  if schema.is_a?(String)
532
516
  begin
533
517
  # Build a fake URI for this
534
518
  schema_uri = JSON::Util::URI.parse(fake_uuid(schema))
535
- schema = JSON::Schema.new(JSON::Validator.parse(schema), schema_uri, @options[:version])
519
+ schema = JSON::Schema.new(JSON::Validator.parse(schema), schema_uri, default_validator)
536
520
  if @options[:list] && @options[:fragment].nil?
537
521
  schema = schema.to_array_schema
538
522
  end
539
- Validator.add_schema(schema)
523
+ self.class.add_schema(schema)
540
524
  rescue JSON::Schema::JsonParseError
541
525
  # Build a uri for it
542
526
  schema_uri = Util::URI.normalized_uri(schema)
@@ -548,13 +532,13 @@ module JSON
548
532
  schema = schema.to_array_schema
549
533
  end
550
534
 
551
- Validator.add_schema(schema)
535
+ self.class.add_schema(schema)
552
536
  else
553
537
  schema = self.class.schema_for_uri(schema_uri)
554
538
  if @options[:list] && @options[:fragment].nil?
555
539
  schema = schema.to_array_schema
556
540
  schema.uri = JSON::Util::URI.parse(fake_uuid(serialize(schema.schema)))
557
- Validator.add_schema(schema)
541
+ self.class.add_schema(schema)
558
542
  end
559
543
  schema
560
544
  end
@@ -562,11 +546,11 @@ module JSON
562
546
  elsif schema.is_a?(Hash)
563
547
  schema_uri = JSON::Util::URI.parse(fake_uuid(serialize(schema)))
564
548
  schema = JSON::Schema.stringify(schema)
565
- schema = JSON::Schema.new(schema, schema_uri, @options[:version])
549
+ schema = JSON::Schema.new(schema, schema_uri, default_validator)
566
550
  if @options[:list] && @options[:fragment].nil?
567
551
  schema = schema.to_array_schema
568
552
  end
569
- Validator.add_schema(schema)
553
+ self.class.add_schema(schema)
570
554
  else
571
555
  raise JSON::Schema::SchemaParseError, "Invalid schema - must be either a string or a hash"
572
556
  end
@@ -577,18 +561,18 @@ module JSON
577
561
  def initialize_data(data)
578
562
  if @options[:parse_data]
579
563
  if @options[:json]
580
- data = JSON::Validator.parse(data)
564
+ data = self.class.parse(data)
581
565
  elsif @options[:uri]
582
566
  json_uri = Util::URI.normalized_uri(data)
583
- data = JSON::Validator.parse(custom_open(json_uri))
567
+ data = self.class.parse(custom_open(json_uri))
584
568
  elsif data.is_a?(String)
585
569
  begin
586
- data = JSON::Validator.parse(data)
570
+ data = self.class.parse(data)
587
571
  rescue JSON::Schema::JsonParseError
588
572
  begin
589
573
  json_uri = Util::URI.normalized_uri(data)
590
- data = JSON::Validator.parse(custom_open(json_uri))
591
- rescue JSON::Schema::JsonLoadError
574
+ data = self.class.parse(custom_open(json_uri))
575
+ rescue JSON::Schema::JsonLoadError, JSON::Schema::UriError
592
576
  # Silently discard the error - use the data as-is
593
577
  end
594
578
  end
@@ -601,7 +585,7 @@ module JSON
601
585
  uri = Util::URI.normalized_uri(uri) if uri.is_a?(String)
602
586
  if uri.absolute? && Util::URI::SUPPORTED_PROTOCOLS.include?(uri.scheme)
603
587
  begin
604
- open(uri.to_s).read
588
+ URI.open(uri.to_s).read
605
589
  rescue OpenURI::HTTPError, Timeout::Error => e
606
590
  raise JSON::Schema::JsonLoadError, e.message
607
591
  end
@@ -0,0 +1,57 @@
1
+ require 'json-schema/schema/validator'
2
+
3
+ module JSON
4
+ class Schema
5
+
6
+ class Draft6 < Validator
7
+ def initialize
8
+ super
9
+ @attributes = {
10
+ "type" => JSON::Schema::TypeV4Attribute,
11
+ "allOf" => JSON::Schema::AllOfAttribute,
12
+ "anyOf" => JSON::Schema::AnyOfAttribute,
13
+ "oneOf" => JSON::Schema::OneOfAttribute,
14
+ "not" => JSON::Schema::NotAttribute,
15
+ "disallow" => JSON::Schema::DisallowAttribute,
16
+ "format" => JSON::Schema::FormatAttribute,
17
+ "maximum" => JSON::Schema::MaximumAttribute,
18
+ "minimum" => JSON::Schema::MinimumAttribute,
19
+ "minItems" => JSON::Schema::MinItemsAttribute,
20
+ "maxItems" => JSON::Schema::MaxItemsAttribute,
21
+ "minProperties" => JSON::Schema::MinPropertiesAttribute,
22
+ "maxProperties" => JSON::Schema::MaxPropertiesAttribute,
23
+ "uniqueItems" => JSON::Schema::UniqueItemsAttribute,
24
+ "minLength" => JSON::Schema::MinLengthAttribute,
25
+ "maxLength" => JSON::Schema::MaxLengthAttribute,
26
+ "multipleOf" => JSON::Schema::MultipleOfAttribute,
27
+ "enum" => JSON::Schema::EnumAttribute,
28
+ "properties" => JSON::Schema::PropertiesV4Attribute,
29
+ "required" => JSON::Schema::RequiredAttribute,
30
+ "pattern" => JSON::Schema::PatternAttribute,
31
+ "patternProperties" => JSON::Schema::PatternPropertiesAttribute,
32
+ "additionalProperties" => JSON::Schema::AdditionalPropertiesAttribute,
33
+ "items" => JSON::Schema::ItemsAttribute,
34
+ "additionalItems" => JSON::Schema::AdditionalItemsAttribute,
35
+ "dependencies" => JSON::Schema::DependenciesV4Attribute,
36
+ "extends" => JSON::Schema::ExtendsAttribute,
37
+ "const" => JSON::Schema::ConstAttribute,
38
+ "$ref" => JSON::Schema::RefAttribute
39
+ }
40
+ @default_formats = {
41
+ 'date-time' => DateTimeV4Format,
42
+ 'ipv4' => IP4Format,
43
+ 'ipv6' => IP6Format,
44
+ 'uri' => UriFormat
45
+ }
46
+ @formats = @default_formats.clone
47
+ @uri = JSON::Util::URI.parse("http://json-schema.org/draft/schema#")
48
+ @names = ["draft6", "http://json-schema.org/draft/schema#"]
49
+ @metaschema_name = "draft-06.json"
50
+ end
51
+
52
+ JSON::Validator.register_validator(self.new)
53
+ JSON::Validator.register_default_validator(self.new)
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,13 @@
1
+ module JSON
2
+ class Schema
3
+
4
+ class HyperDraft3 < Draft3
5
+ def initialize
6
+ super
7
+ @uri = JSON::Util::URI.parse("http://json-schema.org/draft-03/hyper-schema#")
8
+ end
9
+
10
+ JSON::Validator.register_validator(self.new)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module JSON
2
+ class Schema
3
+
4
+ class HyperDraft6 < Draft6
5
+ def initialize
6
+ super
7
+ @uri = JSON::Util::URI.parse("http://json-schema.org/draft-06/hyper-schema#")
8
+ end
9
+
10
+ JSON::Validator.register_validator(self.new)
11
+ end
12
+ end
13
+ end
data/lib/json-schema.rb CHANGED
@@ -14,6 +14,5 @@ require 'json-schema/schema'
14
14
  require 'json-schema/schema/reader'
15
15
  require 'json-schema/validator'
16
16
 
17
- Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/*.rb")].each {|file| require file }
18
- Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/formats/*.rb")].each {|file| require file }
17
+ Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/**/*.rb")].each {|file| require file }
19
18
  Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].sort!.each {|file| require file }