json-schema 2.8.1 → 6.1.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -11
  3. data/lib/json-schema/attribute.rb +15 -16
  4. data/lib/json-schema/attributes/additionalitems.rb +1 -0
  5. data/lib/json-schema/attributes/additionalproperties.rb +4 -7
  6. data/lib/json-schema/attributes/allof.rb +33 -6
  7. data/lib/json-schema/attributes/anyof.rb +4 -4
  8. data/lib/json-schema/attributes/const.rb +15 -0
  9. data/lib/json-schema/attributes/dependencies.rb +1 -0
  10. data/lib/json-schema/attributes/disallow.rb +2 -1
  11. data/lib/json-schema/attributes/divisibleby.rb +1 -1
  12. data/lib/json-schema/attributes/enum.rb +3 -3
  13. data/lib/json-schema/attributes/extends.rb +10 -8
  14. data/lib/json-schema/attributes/format.rb +2 -1
  15. data/lib/json-schema/attributes/formats/custom.rb +5 -7
  16. data/lib/json-schema/attributes/formats/date.rb +2 -1
  17. data/lib/json-schema/attributes/formats/date_time.rb +4 -3
  18. data/lib/json-schema/attributes/formats/date_time_v4.rb +2 -1
  19. data/lib/json-schema/attributes/formats/ip.rb +3 -3
  20. data/lib/json-schema/attributes/formats/time.rb +1 -1
  21. data/lib/json-schema/attributes/formats/uri.rb +2 -1
  22. data/lib/json-schema/attributes/items.rb +1 -0
  23. data/lib/json-schema/attributes/limit.rb +2 -2
  24. data/lib/json-schema/attributes/limits/numeric.rb +1 -1
  25. data/lib/json-schema/attributes/maxdecimal.rb +2 -2
  26. data/lib/json-schema/attributes/not.rb +2 -2
  27. data/lib/json-schema/attributes/oneof.rb +9 -11
  28. data/lib/json-schema/attributes/pattern.rb +1 -1
  29. data/lib/json-schema/attributes/patternproperties.rb +2 -1
  30. data/lib/json-schema/attributes/properties.rb +10 -10
  31. data/lib/json-schema/attributes/properties_v4.rb +2 -2
  32. data/lib/json-schema/attributes/propertynames.rb +23 -0
  33. data/lib/json-schema/attributes/ref.rb +19 -18
  34. data/lib/json-schema/attributes/required.rb +6 -5
  35. data/lib/json-schema/attributes/type.rb +11 -10
  36. data/lib/json-schema/attributes/type_v4.rb +3 -3
  37. data/lib/json-schema/attributes/uniqueitems.rb +1 -1
  38. data/lib/json-schema/errors/validation_error.rb +10 -10
  39. data/lib/json-schema/schema/reader.rb +4 -2
  40. data/lib/json-schema/schema/validator.rb +4 -4
  41. data/lib/json-schema/schema.rb +13 -14
  42. data/lib/json-schema/util/array_set.rb +2 -4
  43. data/lib/json-schema/util/uri.rb +100 -77
  44. data/lib/json-schema/util/uuid.rb +204 -226
  45. data/lib/json-schema/validator.rb +173 -156
  46. data/lib/json-schema/validators/draft1.rb +21 -23
  47. data/lib/json-schema/validators/draft2.rb +22 -24
  48. data/lib/json-schema/validators/draft3.rb +26 -28
  49. data/lib/json-schema/validators/draft4.rb +34 -36
  50. data/lib/json-schema/validators/draft6.rb +36 -36
  51. data/lib/json-schema/validators/hyper-draft1.rb +2 -3
  52. data/lib/json-schema/validators/hyper-draft2.rb +2 -3
  53. data/lib/json-schema/validators/hyper-draft3.rb +2 -3
  54. data/lib/json-schema/validators/hyper-draft4.rb +2 -3
  55. data/lib/json-schema/validators/hyper-draft6.rb +2 -3
  56. data/lib/json-schema.rb +3 -3
  57. data/resources/draft-06.json +12 -12
  58. metadata +60 -32
@@ -3,8 +3,10 @@ require 'pathname'
3
3
  require 'bigdecimal'
4
4
  require 'digest/sha1'
5
5
  require 'date'
6
- require 'thread'
6
+ require 'timeout'
7
+ require 'stringio'
7
8
  require 'yaml'
9
+ require 'delegate'
8
10
 
9
11
  require 'json-schema/schema/reader'
10
12
  require 'json-schema/errors/schema_error'
@@ -14,21 +16,22 @@ require 'json-schema/errors/json_parse_error'
14
16
  require 'json-schema/util/uri'
15
17
 
16
18
  module JSON
17
-
18
19
  class Validator
19
-
20
20
  @@schemas = {}
21
21
  @@cache_schemas = true
22
22
  @@default_opts = {
23
- :list => false,
24
- :version => nil,
25
- :validate_schema => false,
26
- :record_errors => false,
27
- :errors_as_objects => false,
28
- :insert_defaults => false,
29
- :clear_cache => false,
30
- :strict => false,
31
- :parse_data => true
23
+ list: false,
24
+ version: nil,
25
+ validate_schema: false,
26
+ record_errors: false,
27
+ errors_as_objects: false,
28
+ insert_defaults: false,
29
+ clear_cache: false,
30
+ strict: false,
31
+ allPropertiesRequired: false,
32
+ noAdditionalProperties: false,
33
+ parse_data: true,
34
+ parse_integer: true,
32
35
  }
33
36
  @@validators = {}
34
37
  @@default_validator = nil
@@ -37,32 +40,31 @@ module JSON
37
40
  @@serializer = nil
38
41
  @@mutex = Mutex.new
39
42
 
40
- def initialize(schema_data, data, opts={})
43
+ def initialize(schema_data, opts = {})
41
44
  @options = @@default_opts.clone.merge(opts)
42
- @errors = []
43
45
 
44
- validator = self.class.validator_for_name(@options[:version])
45
- @options[:version] = validator
46
+ configured_validator = self.class.validator_for_name(@options[:version])
46
47
  @options[:schema_reader] ||= self.class.schema_reader
47
48
 
48
- @validation_options = @options[:record_errors] ? {:record_errors => true} : {}
49
+ @validation_options = @options[:record_errors] ? { record_errors: true } : {}
49
50
  @validation_options[:insert_defaults] = true if @options[:insert_defaults]
50
- @validation_options[:strict] = true if @options[:strict] == true
51
+ if @options[:strict] == true
52
+ @validation_options[:allPropertiesRequired] = true
53
+ @validation_options[:noAdditionalProperties] = true
54
+ else
55
+ @validation_options[:allPropertiesRequired] = true if @options[:allPropertiesRequired]
56
+ @validation_options[:noAdditionalProperties] = true if @options[:noAdditionalProperties]
57
+ end
51
58
  @validation_options[:clear_cache] = true if !@@cache_schemas || @options[:clear_cache]
52
59
 
53
- @@mutex.synchronize { @base_schema = initialize_schema(schema_data) }
54
- @original_data = data
55
- @data = initialize_data(data)
60
+ @@mutex.synchronize { @base_schema = initialize_schema(schema_data, configured_validator) }
56
61
  @@mutex.synchronize { build_schemas(@base_schema) }
57
62
 
58
63
  # validate the schema, if requested
59
64
  if @options[:validate_schema]
60
- if @base_schema.schema["$schema"]
61
- base_validator = self.class.validator_for_name(@base_schema.schema["$schema"])
62
- end
63
- metaschema = base_validator ? base_validator.metaschema : validator.metaschema
64
65
  # Don't clear the cache during metaschema validation!
65
- self.class.validate!(metaschema, @base_schema.schema, {:clear_cache => false})
66
+ meta_validator = self.class.new(@base_schema.validator.metaschema, { clear_cache: false })
67
+ meta_validator.validate(@base_schema.schema)
66
68
  end
67
69
 
68
70
  # If the :fragment option is set, try and validate against the fragment
@@ -73,52 +75,74 @@ module JSON
73
75
 
74
76
  def schema_from_fragment(base_schema, fragment)
75
77
  schema_uri = base_schema.uri
76
- fragments = fragment.split("/")
78
+ fragments = fragment.split('/').map { |f| f.gsub('~0', '~').gsub('~1', '/') }
77
79
 
78
80
  # ensure the first element was a hash, per the fragment spec
79
- if fragments.shift != "#"
80
- raise JSON::Schema::SchemaError.new("Invalid fragment syntax in :fragment option")
81
+ if fragments.shift != '#'
82
+ raise JSON::Schema::SchemaError, 'Invalid fragment syntax in :fragment option'
81
83
  end
82
84
 
85
+ schema_fragment = base_schema.schema
83
86
  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")
87
+ case schema_fragment
88
+ when Hash
89
+ schema_fragment = schema_fragment[f]
90
+ when Array
91
+ schema_fragment = schema_fragment[f.to_i]
101
92
  end
102
93
  end
103
94
 
95
+ unless schema_fragment.is_a?(Hash)
96
+ raise JSON::Schema::SchemaError, 'Invalid fragment resolution for :fragment option'
97
+ end
98
+
99
+ schema = JSON::Schema.new(schema_fragment, schema_uri, base_schema.validator)
100
+
104
101
  if @options[:list]
105
- base_schema.to_array_schema
106
- elsif base_schema.is_a?(Hash)
107
- JSON::Schema.new(base_schema, schema_uri, @options[:version])
102
+ schema.to_array_schema
103
+ elsif schema.is_a?(Hash)
104
+ JSON::Schema.new(schema, schema_uri, @options[:version])
108
105
  else
109
- base_schema
106
+ schema
110
107
  end
111
108
  end
112
109
 
110
+ class ErrorRecorder < SimpleDelegator
111
+ def initialize(sub)
112
+ @errors = []
113
+
114
+ super
115
+ end
116
+
117
+ def validation_error(error)
118
+ @errors.push(error)
119
+ end
120
+
121
+ def validation_errors
122
+ @errors
123
+ end
124
+
125
+ def with_errors
126
+ self
127
+ end
128
+ end
129
+
130
+ def with_errors
131
+ ErrorRecorder.new(self)
132
+ end
133
+
113
134
  # Run a simple true/false validation of data against a schema
114
- def validate
115
- @base_schema.validate(@data,[],self,@validation_options)
135
+ def validate(data)
136
+ original_data = data
137
+ data = initialize_data(data)
138
+ error_recorder = with_errors
139
+ @base_schema.validate(data, [], error_recorder, @validation_options)
116
140
 
117
141
  if @options[:record_errors]
118
142
  if @options[:errors_as_objects]
119
- @errors.map{|e| e.to_hash}
143
+ error_recorder.validation_errors.map { |e| e.to_hash }
120
144
  else
121
- @errors.map{|e| e.to_string}
145
+ error_recorder.validation_errors.map { |e| e.to_string }
122
146
  end
123
147
  else
124
148
  true
@@ -128,7 +152,7 @@ module JSON
128
152
  self.class.clear_cache
129
153
  end
130
154
  if @validation_options[:insert_defaults]
131
- self.class.merge_missing_values(@data, @original_data)
155
+ self.class.merge_missing_values(data, original_data)
132
156
  end
133
157
  end
134
158
 
@@ -149,13 +173,13 @@ module JSON
149
173
  schema = parent_schema.schema
150
174
 
151
175
  # Build ref schemas if they exist
152
- if schema["$ref"]
153
- load_ref_schema(parent_schema, schema["$ref"])
176
+ if schema['$ref']
177
+ load_ref_schema(parent_schema, schema['$ref'])
154
178
  end
155
179
 
156
- case schema["extends"]
180
+ case schema['extends']
157
181
  when String
158
- load_ref_schema(parent_schema, schema["extends"])
182
+ load_ref_schema(parent_schema, schema['extends'])
159
183
  when Array
160
184
  schema['extends'].each do |type|
161
185
  handle_schema(parent_schema, type)
@@ -163,12 +187,12 @@ module JSON
163
187
  end
164
188
 
165
189
  # Check for schemas in union types
166
- ["type", "disallow"].each do |key|
167
- if schema[key].is_a?(Array)
168
- schema[key].each do |type|
169
- if type.is_a?(Hash)
170
- handle_schema(parent_schema, type)
171
- end
190
+ %w[type disallow].each do |key|
191
+ next unless schema[key].is_a?(Array)
192
+
193
+ schema[key].each do |type|
194
+ if type.is_a?(Hash)
195
+ handle_schema(parent_schema, type)
172
196
  end
173
197
  end
174
198
  end
@@ -177,7 +201,8 @@ module JSON
177
201
  # are themselves schemas.
178
202
  %w[definitions properties patternProperties].each do |key|
179
203
  next unless value = schema[key]
180
- value.each do |k, inner_schema|
204
+
205
+ value.each do |_k, inner_schema|
181
206
  handle_schema(parent_schema, inner_schema)
182
207
  end
183
208
  end
@@ -185,20 +210,22 @@ module JSON
185
210
  # Schema properties whose values are themselves schemas.
186
211
  %w[additionalProperties additionalItems dependencies extends].each do |key|
187
212
  next unless schema[key].is_a?(Hash)
213
+
188
214
  handle_schema(parent_schema, schema[key])
189
215
  end
190
216
 
191
217
  # Schema properties whose values may be an array of schemas.
192
218
  %w[allOf anyOf oneOf not].each do |key|
193
219
  next unless value = schema[key]
220
+
194
221
  Array(value).each do |inner_schema|
195
222
  handle_schema(parent_schema, inner_schema)
196
223
  end
197
224
  end
198
225
 
199
226
  # Items are always schemas
200
- if schema["items"]
201
- items = schema["items"].clone
227
+ if schema['items']
228
+ items = schema['items'].clone
202
229
  items = [items] unless items.is_a?(Array)
203
230
 
204
231
  items.each do |item|
@@ -207,10 +234,9 @@ module JSON
207
234
  end
208
235
 
209
236
  # Convert enum to a ArraySet
210
- if schema["enum"].is_a?(Array)
211
- schema["enum"] = ArraySet.new(schema["enum"])
237
+ if schema['enum'].is_a?(Array)
238
+ schema['enum'] = ArraySet.new(schema['enum'])
212
239
  end
213
-
214
240
  end
215
241
 
216
242
  # Either load a reference schema or create a new schema
@@ -225,66 +251,55 @@ module JSON
225
251
  end
226
252
  end
227
253
 
228
- def validation_error(error)
229
- @errors.push(error)
230
- end
231
-
232
- def validation_errors
233
- @errors
234
- end
235
-
236
-
237
254
  class << self
238
- def validate(schema, data,opts={})
239
- begin
240
- validate!(schema, data, opts)
241
- rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError
242
- return false
243
- end
255
+ def validate(schema, data, opts = {})
256
+ validate!(schema, data, opts)
257
+ rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError
258
+ false
244
259
  end
245
260
 
246
- def validate_json(schema, data, opts={})
247
- validate(schema, data, opts.merge(:json => true))
261
+ def validate_json(schema, data, opts = {})
262
+ validate(schema, data, opts.merge(json: true))
248
263
  end
249
264
 
250
- def validate_uri(schema, data, opts={})
251
- validate(schema, data, opts.merge(:uri => true))
265
+ def validate_uri(schema, data, opts = {})
266
+ validate(schema, data, opts.merge(uri: true))
252
267
  end
253
268
 
254
- def validate!(schema, data,opts={})
255
- validator = new(schema, data, opts)
256
- validator.validate
269
+ def validate!(schema, data, opts = {})
270
+ validator = new(schema, opts)
271
+ validator.validate(data)
257
272
  end
258
273
 
259
- def validate2(schema, data, opts={})
260
- 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."
274
+ def validate2(schema, data, opts = {})
275
+ 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.'
261
276
  validate!(schema, data, opts)
262
277
  end
263
278
 
264
- def validate_json!(schema, data, opts={})
265
- validate!(schema, data, opts.merge(:json => true))
279
+ def validate_json!(schema, data, opts = {})
280
+ validate!(schema, data, opts.merge(json: true))
266
281
  end
267
282
 
268
- def validate_uri!(schema, data, opts={})
269
- validate!(schema, data, opts.merge(:uri => true))
283
+ def validate_uri!(schema, data, opts = {})
284
+ validate!(schema, data, opts.merge(uri: true))
270
285
  end
271
286
 
272
- def fully_validate(schema, data, opts={})
273
- validate!(schema, data, opts.merge(:record_errors => true))
287
+ def fully_validate(schema, data, opts = {})
288
+ validate!(schema, data, opts.merge(record_errors: true))
274
289
  end
275
290
 
276
- def fully_validate_schema(schema, opts={})
291
+ def fully_validate_schema(schema, opts = {})
277
292
  data = schema
278
293
  schema = validator_for_name(opts[:version]).metaschema
279
294
  fully_validate(schema, data, opts)
280
295
  end
281
296
 
282
- def fully_validate_json(schema, data, opts={})
283
- fully_validate(schema, data, opts.merge(:json => true))
297
+ def fully_validate_json(schema, data, opts = {})
298
+ fully_validate(schema, data, opts.merge(json: true))
284
299
  end
285
300
 
286
- def fully_validate_uri(schema, data, opts={})
287
- fully_validate(schema, data, opts.merge(:uri => true))
301
+ def fully_validate_uri(schema, data, opts = {})
302
+ fully_validate(schema, data, opts.merge(uri: true))
288
303
  end
289
304
 
290
305
  def schema_reader
@@ -297,7 +312,6 @@ module JSON
297
312
 
298
313
  def clear_cache
299
314
  @@schemas = {}
300
- JSON::Util::URI.clear_cache
301
315
  end
302
316
 
303
317
  def schemas
@@ -324,8 +338,8 @@ module JSON
324
338
  end
325
339
 
326
340
  def cache_schemas=(val)
327
- warn "[DEPRECATION NOTICE] Schema caching is now a validation option. Schemas will still be cached if this is set to true, but this method will be removed in version >= 3. Please use the :clear_cache validation option instead."
328
- @@cache_schemas = val == true ? true : false
341
+ warn '[DEPRECATION NOTICE] Schema caching is now a validation option. Schemas will still be cached if this is set to true, but this method will be removed in version >= 3. Please use the :clear_cache validation option instead.'
342
+ @@cache_schemas = val == true
329
343
  end
330
344
 
331
345
  def validators
@@ -336,32 +350,34 @@ module JSON
336
350
  @@default_validator
337
351
  end
338
352
 
339
- def validator_for_uri(schema_uri, raise_not_found=true)
353
+ def validator_for_uri(schema_uri, raise_not_found = true)
340
354
  return default_validator unless schema_uri
355
+
341
356
  u = JSON::Util::URI.parse(schema_uri)
342
357
  validator = validators["#{u.scheme}://#{u.host}#{u.path}"]
343
358
  if validator.nil? && raise_not_found
344
- raise JSON::Schema::SchemaError.new("Schema not found: #{schema_uri}")
359
+ raise JSON::Schema::SchemaError, "Schema not found: #{schema_uri}"
345
360
  else
346
361
  validator
347
362
  end
348
363
  end
349
364
 
350
- def validator_for_name(schema_name, raise_not_found=true)
365
+ def validator_for_name(schema_name, raise_not_found = true)
351
366
  return default_validator unless schema_name
367
+
352
368
  schema_name = schema_name.to_s
353
369
  validator = validators.values.detect do |v|
354
370
  Array(v.names).include?(schema_name)
355
371
  end
356
372
  if validator.nil? && raise_not_found
357
- raise JSON::Schema::SchemaError.new("The requested JSON schema version is not supported")
373
+ raise JSON::Schema::SchemaError, 'The requested JSON schema version is not supported'
358
374
  else
359
375
  validator
360
376
  end
361
377
  end
362
378
 
363
379
  def validator_for(schema_uri)
364
- 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."
380
+ 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.'
365
381
  validator_for_uri(schema_uri)
366
382
  end
367
383
 
@@ -373,7 +389,7 @@ module JSON
373
389
  @@default_validator = v
374
390
  end
375
391
 
376
- def register_format_validator(format, validation_proc, versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
392
+ def register_format_validator(format, validation_proc, versions = (@@validators.flat_map { |_k, v| v.names.first } + [nil]))
377
393
  custom_format_validator = JSON::Schema::CustomFormat.new(validation_proc)
378
394
  versions.each do |version|
379
395
  validator = validator_for_name(version)
@@ -381,14 +397,14 @@ module JSON
381
397
  end
382
398
  end
383
399
 
384
- def deregister_format_validator(format, versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
400
+ def deregister_format_validator(format, versions = (@@validators.flat_map { |_k, v| v.names.first } + [nil]))
385
401
  versions.each do |version|
386
402
  validator = validator_for_name(version)
387
403
  validator.formats[format.to_s] = validator.default_formats[format.to_s]
388
404
  end
389
405
  end
390
406
 
391
- def restore_default_formats(versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
407
+ def restore_default_formats(versions = (@@validators.flat_map { |_k, v| v.names.first } + [nil]))
392
408
  versions.each do |version|
393
409
  validator = validator_for_name(version)
394
410
  validator.formats = validator.default_formats.clone
@@ -405,14 +421,14 @@ module JSON
405
421
 
406
422
  def json_backend=(backend)
407
423
  if defined?(MultiJson)
408
- backend = backend == 'json' ? 'json_gem' : backend
424
+ backend = 'json_gem' if backend == 'json'
409
425
  MultiJson.respond_to?(:use) ? MultiJson.use(backend) : MultiJson.engine = backend
410
426
  else
411
427
  backend = backend.to_s
412
428
  if @@available_json_backends.include?(backend)
413
429
  @@json_backend = backend
414
430
  else
415
- raise JSON::Schema::JsonParseError.new("The JSON backend '#{backend}' could not be found.")
431
+ raise JSON::Schema::JsonParseError, "The JSON backend '#{backend}' could not be found."
416
432
  end
417
433
  end
418
434
  end
@@ -422,26 +438,26 @@ module JSON
422
438
  begin
423
439
  MultiJson.respond_to?(:adapter) ? MultiJson.load(s) : MultiJson.decode(s)
424
440
  rescue MultiJson::ParseError => e
425
- raise JSON::Schema::JsonParseError.new(e.message)
441
+ raise JSON::Schema::JsonParseError, e.message
426
442
  end
427
443
  else
428
444
  case @@json_backend.to_s
429
445
  when 'json'
430
446
  begin
431
- JSON.parse(s, :quirks_mode => true)
447
+ JSON.parse(s, quirks_mode: true)
432
448
  rescue JSON::ParserError => e
433
- raise JSON::Schema::JsonParseError.new(e.message)
449
+ raise JSON::Schema::JsonParseError, e.message
434
450
  end
435
451
  when 'yajl'
436
452
  begin
437
453
  json = StringIO.new(s)
438
454
  parser = Yajl::Parser.new
439
- parser.parse(json) or raise JSON::Schema::JsonParseError.new("The JSON could not be parsed by yajl")
455
+ parser.parse(json) or raise(JSON::Schema::JsonParseError, 'The JSON could not be parsed by yajl')
440
456
  rescue Yajl::ParseError => e
441
- raise JSON::Schema::JsonParseError.new(e.message)
457
+ raise JSON::Schema::JsonParseError, e.message
442
458
  end
443
459
  else
444
- raise JSON::Schema::JsonParseError.new("No supported JSON parsers found. The following parsers are suported:\n * yajl-ruby\n * json")
460
+ raise JSON::Schema::JsonParseError, "No supported JSON parsers found. The following parsers are suported:\n * yajl-ruby\n * json"
445
461
  end
446
462
  end
447
463
  end
@@ -465,8 +481,8 @@ module JSON
465
481
  end
466
482
  end
467
483
 
468
- if !defined?(MultiJson)
469
- if Gem::Specification::find_all_by_name('json').any?
484
+ unless defined?(MultiJson)
485
+ if Gem::Specification.find_all_by_name('json').any?
470
486
  require 'json'
471
487
  @@available_json_backends << 'json'
472
488
  @@json_backend = 'json'
@@ -480,34 +496,33 @@ module JSON
480
496
  end
481
497
  end
482
498
 
483
-
484
- if Gem::Specification::find_all_by_name('yajl-ruby').any?
499
+ if Gem::Specification.find_all_by_name('yajl-ruby').any?
485
500
  require 'yajl'
486
501
  @@available_json_backends << 'yajl'
487
502
  @@json_backend = 'yajl'
488
503
  end
489
504
 
490
- if @@json_backend == 'yajl'
491
- @@serializer = lambda{|o| Yajl::Encoder.encode(o) }
492
- elsif @@json_backend == 'json'
493
- @@serializer = lambda{|o| JSON.dump(o) }
494
- else
495
- @@serializer = lambda{|o| YAML.dump(o) }
496
- end
505
+ @@serializer = if @@json_backend == 'yajl'
506
+ ->(o) { Yajl::Encoder.encode(o) }
507
+ elsif @@json_backend == 'json'
508
+ ->(o) { JSON.dump(o) }
509
+ else
510
+ ->(o) { YAML.dump(o) }
511
+ end
497
512
  end
498
513
  end
499
514
 
500
515
  private
501
516
 
502
- if Gem::Specification::find_all_by_name('uuidtools').any?
517
+ if Gem::Specification.find_all_by_name('uuidtools').any?
503
518
  require 'uuidtools'
504
- @@fake_uuid_generator = lambda{|s| UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, s).to_s }
519
+ @@fake_uuid_generator = ->(s) { UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, s).to_s }
505
520
  else
506
521
  require 'json-schema/util/uuid'
507
- @@fake_uuid_generator = lambda{|s| JSON::Util::UUID.create_v5(s,JSON::Util::UUID::Nil).to_s }
522
+ @@fake_uuid_generator = ->(s) { JSON::Util::UUID.create_v5(s, JSON::Util::UUID::Nil).to_s }
508
523
  end
509
524
 
510
- def serialize schema
525
+ def serialize(schema)
511
526
  if defined?(MultiJson)
512
527
  MultiJson.respond_to?(:dump) ? MultiJson.dump(schema) : MultiJson.encode(schema)
513
528
  else
@@ -515,16 +530,16 @@ module JSON
515
530
  end
516
531
  end
517
532
 
518
- def fake_uuid schema
533
+ def fake_uuid(schema)
519
534
  @@fake_uuid_generator.call(schema)
520
535
  end
521
536
 
522
- def initialize_schema(schema)
537
+ def initialize_schema(schema, default_validator)
523
538
  if schema.is_a?(String)
524
539
  begin
525
540
  # Build a fake URI for this
526
541
  schema_uri = JSON::Util::URI.parse(fake_uuid(schema))
527
- schema = JSON::Schema.new(self.class.parse(schema), schema_uri, @options[:version])
542
+ schema = JSON::Schema.new(JSON::Validator.parse(schema), schema_uri, default_validator)
528
543
  if @options[:list] && @options[:fragment].nil?
529
544
  schema = schema.to_array_schema
530
545
  end
@@ -532,7 +547,15 @@ module JSON
532
547
  rescue JSON::Schema::JsonParseError
533
548
  # Build a uri for it
534
549
  schema_uri = Util::URI.normalized_uri(schema)
535
- if !self.class.schema_loaded?(schema_uri)
550
+ if self.class.schema_loaded?(schema_uri)
551
+ schema = self.class.schema_for_uri(schema_uri)
552
+ if @options[:list] && @options[:fragment].nil?
553
+ schema = schema.to_array_schema
554
+ schema.uri = JSON::Util::URI.parse(fake_uuid(serialize(schema.schema)))
555
+ self.class.add_schema(schema)
556
+ end
557
+ schema
558
+ else
536
559
  schema = @options[:schema_reader].read(schema_uri)
537
560
  schema = JSON::Schema.stringify(schema)
538
561
 
@@ -541,26 +564,18 @@ module JSON
541
564
  end
542
565
 
543
566
  self.class.add_schema(schema)
544
- else
545
- schema = self.class.schema_for_uri(schema_uri)
546
- if @options[:list] && @options[:fragment].nil?
547
- schema = schema.to_array_schema
548
- schema.uri = JSON::Util::URI.parse(fake_uuid(serialize(schema.schema)))
549
- self.class.add_schema(schema)
550
- end
551
- schema
552
567
  end
553
568
  end
554
569
  elsif schema.is_a?(Hash)
555
570
  schema_uri = JSON::Util::URI.parse(fake_uuid(serialize(schema)))
556
571
  schema = JSON::Schema.stringify(schema)
557
- schema = JSON::Schema.new(schema, schema_uri, @options[:version])
572
+ schema = JSON::Schema.new(schema, schema_uri, default_validator)
558
573
  if @options[:list] && @options[:fragment].nil?
559
574
  schema = schema.to_array_schema
560
575
  end
561
576
  self.class.add_schema(schema)
562
577
  else
563
- raise JSON::Schema::SchemaParseError, "Invalid schema - must be either a string or a hash"
578
+ raise JSON::Schema::SchemaParseError, 'Invalid schema - must be either a string or a hash'
564
579
  end
565
580
 
566
581
  schema
@@ -575,7 +590,9 @@ module JSON
575
590
  data = self.class.parse(custom_open(json_uri))
576
591
  elsif data.is_a?(String)
577
592
  begin
578
- data = self.class.parse(data)
593
+ # Check if the string is valid integer
594
+ strict_convert = data.match?(/\A[+-]?\d+\z/) && !@options[:parse_integer]
595
+ data = self.class.parse(data) unless strict_convert
579
596
  rescue JSON::Schema::JsonParseError
580
597
  begin
581
598
  json_uri = Util::URI.normalized_uri(data)
@@ -593,7 +610,7 @@ module JSON
593
610
  uri = Util::URI.normalized_uri(uri) if uri.is_a?(String)
594
611
  if uri.absolute? && Util::URI::SUPPORTED_PROTOCOLS.include?(uri.scheme)
595
612
  begin
596
- open(uri.to_s).read
613
+ URI.open(uri.to_s).read
597
614
  rescue OpenURI::HTTPError, Timeout::Error => e
598
615
  raise JSON::Schema::JsonLoadError, e.message
599
616
  end