Skip to content

Commit

Permalink
Rename Loader -> Reader
Browse files Browse the repository at this point in the history
  • Loading branch information
pd committed Dec 2, 2014
1 parent 13f906c commit d824d30
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 83 deletions.
14 changes: 7 additions & 7 deletions README.textile
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ errors = JSON::Validator.fully_validate(schema, {"a" => "23"})

</pre>

h2. Controlling Remote Schema Loading
h2. Controlling Remote Schema Reading

In some cases, you may wish to prevent the JSON Schema library from making HTTP calls or reading local files in order to resolve <code>$ref</code> schemas. If you fully control all schemas which should be used by validation, this could be accomplished by registering all referenced schemas with the validator in advance:

Expand All @@ -380,20 +380,20 @@ schema = JSON::Schema.new(some_schema_definition, Addressable::URI.parse('http:/
JSON::Validator.add_schema(schema)
</pre>

If more extensive control is necessary, the <code>JSON::Schema::Loader</code> instance used can be configured in a few ways:
If more extensive control is necessary, the <code>JSON::Schema::Reader</code> instance used can be configured in a few ways:

<pre>
# Change the default schema loader used
JSON::Validator.schema_loader = JSON::Schema::Loader.new(:accept_uri => true, :accept_file => false)
# Change the default schema reader used
JSON::Validator.schema_reader = JSON::Schema::Reader.new(:accept_uri => true, :accept_file => false)

# For this validation call, use a loader which only accepts URIs from my-website.com
schema_loader = JSON::Schema::Loader.new(
schema_loader = JSON::Schema::Reader.new(
:accept_uri => proc { |uri| uri.host == 'my-website.com' }
)
JSON::Validator.validate(some_schema, some_object, :schema_loader => schema_loader)
JSON::Validator.validate(some_schema, some_object, :schema_reader => schema_reader)
</pre>

The <code>JSON::Schema::Loader</code> interface requires only an object which responds to <code>load(string)</code> and returns a <code>JSON::Schema</code> instance. See the "API documentation":http://www.rubydoc.info/github/ruby-json-schema/json-schema/master/JSON/Schema/Loader for more information.
The <code>JSON::Schema::Reader</code> interface requires only an object which responds to <code>read(string)</code> and returns a <code>JSON::Schema</code> instance. See the "API documentation":http://www.rubydoc.info/github/ruby-json-schema/json-schema/master/JSON/Schema/Reader for more information.

h2. JSON Backends

Expand Down
3 changes: 2 additions & 1 deletion lib/json-schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@

require 'json-schema/util/array_set'
require 'json-schema/schema'
require 'json-schema/schema/loader'
require 'json-schema/schema/reader'
require 'json-schema/validator'

Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/*.rb")].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/formats/*.rb")].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].sort!.each {|file| require file }
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

module JSON
class Schema
# Raised by {JSON::Schema::Loader} when one of its settings indicate
# a schema should not be loaded.
class LoadRefused < StandardError
# Raised by {JSON::Schema::Reader} when one of its settings indicate
# a schema should not be readed.
class ReadRefused < StandardError
# @return [String] the requested schema location which was refused
attr_reader :location

Expand All @@ -16,20 +16,20 @@ class LoadRefused < StandardError
def initialize(location, type)
@location = location
@type = type
super("Load of #{type == :uri ? 'URI' : type} at #{location} refused!")
super("Read of #{type == :uri ? 'URI' : type} at #{location} refused!")
end
end

# When an unregistered schema is encountered, the {JSON::Schema::Loader} is
# When an unregistered schema is encountered, the {JSON::Schema::Reader} is
# used to fetch its contents and register it with the {JSON::Validator}.
#
# This default loader will load schemas from the filesystem or from a URI.
class Loader
# The behavior of the schema loader can be controlled by providing
# callbacks to determine whether to permit loading referenced schemas.
# This default reader will read schemas from the filesystem or from a URI.
class Reader
# The behavior of the schema reader can be controlled by providing
# callbacks to determine whether to permit reading referenced schemas.
# The options +accept_uri+ and +accept_file+ should be procs which
# accept a +URI+ or +Pathname+ object, and return a boolean value
# indicating whether to load the referenced schema.
# indicating whether to read the referenced schema.
#
# URIs using the +file+ scheme will be normalized into +Pathname+ objects
# and passed to the +accept_file+ callback.
Expand All @@ -39,13 +39,13 @@ class Loader
# @option options [Boolean, #call] accept_file (true)
#
# @example Reject all unregistered schemas
# JSON::Validator.schema_loader = JSON::Schema::Loader.new(
# JSON::Validator.schema_reader = JSON::Schema::Reader.new(
# :accept_uri => false,
# :accept_file => false
# )
#
# @example Only permit URIs from certain hosts
# JSON::Validator.schema_loader = JSON::Schema::Loader.new(
# JSON::Validator.schema_reader = JSON::Schema::Reader.new(
# :accept_file => false,
# :accept_uri => proc { |uri| ['mycompany.com', 'json-schema.org'].include?(uri.host) }
# )
Expand All @@ -54,12 +54,12 @@ def initialize(options = {})
@accept_file = options.fetch(:accept_file, true)
end

# @param location [#to_s] The location from which to load the schema
# @param location [#to_s] The location from which to read the schema
# @return [JSON::Schema]
# @raise [JSON::Schema::LoadRefused] if +accept_uri+ or +accept_file+
# indicated the schema should not be loaded
# @raise [JSON::Schema::ReadRefused] if +accept_uri+ or +accept_file+
# indicated the schema should not be readed
# @raise [JSON::ParserError] if the schema was not a valid JSON object
def load(location)
def read(location)
uri = Addressable::URI.parse(location.to_s)
body = if uri.scheme.nil? || uri.scheme == 'file'
uri = Addressable::URI.convert_path(uri.path)
Expand Down Expand Up @@ -97,15 +97,15 @@ def read_uri(uri)
if accept_uri?(uri)
open(uri.to_s).read
else
raise JSON::Schema::LoadRefused.new(uri.to_s, :uri)
raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
end
end

def read_file(pathname)
if accept_file?(pathname)
File.read(Addressable::URI.unescape(pathname.to_s))
else
raise JSON::Schema::LoadRefused.new(pathname.to_s, :file)
raise JSON::Schema::ReadRefused.new(pathname.to_s, :file)
end
end
end
Expand Down
38 changes: 19 additions & 19 deletions lib/json-schema/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
require 'thread'
require 'yaml'

require 'json-schema/schema/loader'
require 'json-schema/schema/reader'
require 'json-schema/errors/schema_error'
require 'json-schema/errors/json_parse_error'

Expand Down Expand Up @@ -40,7 +40,7 @@ def initialize(schema_data, data, opts={})

validator = JSON::Validator.validator_for_name(@options[:version])
@options[:version] = validator
@options[:schema_loader] ||= JSON::Validator.schema_loader
@options[:schema_reader] ||= JSON::Validator.schema_reader

@validation_options = @options[:record_errors] ? {:record_errors => true} : {}
@validation_options[:insert_defaults] = true if @options[:insert_defaults]
Expand Down Expand Up @@ -126,12 +126,12 @@ def validate()
end
end

def load_ref_schema(parent_schema, ref)
def read_ref_schema(parent_schema, ref)
schema_uri = absolutize_ref_uri(ref, parent_schema.uri)

return true if self.class.schema_loaded?(schema_uri)
return true if self.class.schema_readed?(schema_uri)

schema = @options[:schema_loader].load(schema_uri)
schema = @options[:schema_reader].read(schema_uri)
self.class.add_schema(schema)
build_schemas(schema)
end
Expand All @@ -140,7 +140,7 @@ def absolutize_ref_uri(ref, parent_schema_uri)
ref_uri = Addressable::URI.parse(ref)

return ref_uri if ref_uri.absolute?
# This is a self reference and thus the schema does not need to be re-loaded
# This is a self reference and thus the schema does not need to be re-readed
return parent_schema_uri if ref_uri.path.empty?

uri = parent_schema_uri.clone
Expand All @@ -154,12 +154,12 @@ def build_schemas(parent_schema)

# Build ref schemas if they exist
if schema["$ref"]
load_ref_schema(parent_schema, schema["$ref"])
read_ref_schema(parent_schema, schema["$ref"])
end

case schema["extends"]
when String
load_ref_schema(parent_schema, schema["extends"])
read_ref_schema(parent_schema, schema["extends"])
when Array
schema['extends'].each do |type|
handle_schema(parent_schema, type)
Expand Down Expand Up @@ -217,7 +217,7 @@ def build_schemas(parent_schema)

end

# Either load a reference schema or create a new schema
# Either read a reference schema or create a new schema
def handle_schema(parent_schema, obj)
if obj.is_a?(Hash)
schema_uri = parent_schema.uri.clone
Expand Down Expand Up @@ -292,12 +292,12 @@ def fully_validate_uri(schema, data, opts={})
fully_validate(schema, data, opts.merge(:uri => true))
end

def schema_loader
@@schema_loader ||= JSON::Schema::Loader.new
def schema_reader
@@schema_reader ||= JSON::Schema::Reader.new
end

def schema_loader=(loader)
@@schema_loader = loader
def schema_reader=(reader)
@@schema_reader = reader
end

def clear_cache
Expand All @@ -316,7 +316,7 @@ def schema_for_uri(uri)
@@schemas[uri.to_s]
end

def schema_loaded?(schema_uri)
def schema_readed?(schema_uri)
@@schemas.has_key?(schema_uri.to_s)
end

Expand Down Expand Up @@ -407,7 +407,7 @@ def json_backend=(backend)

def parse(s)
if defined?(MultiJson)
MultiJson.respond_to?(:adapter) ? MultiJson.load(s) : MultiJson.decode(s)
MultiJson.respond_to?(:adapter) ? MultiJson.read(s) : MultiJson.decode(s)
else
case @@json_backend.to_s
when 'json'
Expand Down Expand Up @@ -447,12 +447,12 @@ def merge_missing_values(source, destination)
@@available_json_backends << 'json'
@@json_backend = 'json'
else
# Try force-loading json for rubies > 1.9.2
# Try force-reading json for rubies > 1.9.2
begin
require 'json'
@@available_json_backends << 'json'
@@json_backend = 'json'
rescue LoadError
rescue ReadError
end
end

Expand Down Expand Up @@ -515,8 +515,8 @@ def initialize_schema(schema)
rescue
# Build a uri for it
schema_uri = normalized_uri(schema)
if !self.class.schema_loaded?(schema_uri)
schema = @options[:schema_loader].load(schema_uri)
if !self.class.schema_readed?(schema_uri)
schema = @options[:schema_reader].read(schema_uri)
schema = JSON::Schema.stringify(schema)

if @options[:list] && @options[:fragment].nil?
Expand Down
40 changes: 20 additions & 20 deletions test/test_schema_loader.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require File.expand_path('../test_helper', __FILE__)
require 'webmock'

class TestSchemaLoader < Minitest::Test
class TestSchemaReader < Minitest::Test
ADDRESS_SCHEMA_URI = 'http://json-schema.org/address'
ADDRESS_SCHEMA_PATH = File.expand_path('../schemas/address_microformat.json', __FILE__)

Expand All @@ -25,62 +25,62 @@ def stub_address_request(body = File.read(ADDRESS_SCHEMA_PATH))
def test_accept_all_uris
stub_address_request

loader = JSON::Schema::Loader.new
schema = loader.load(ADDRESS_SCHEMA_URI)
reader = JSON::Schema::Reader.new
schema = reader.read(ADDRESS_SCHEMA_URI)

assert_equal schema.uri, Addressable::URI.parse("#{ADDRESS_SCHEMA_URI}#")
end

def test_accept_all_files
loader = JSON::Schema::Loader.new
schema = loader.load(ADDRESS_SCHEMA_PATH)
reader = JSON::Schema::Reader.new
schema = reader.read(ADDRESS_SCHEMA_PATH)

assert_equal schema.uri, Addressable::URI.convert_path(ADDRESS_SCHEMA_PATH + '#')
end

def test_refuse_all_uris
loader = JSON::Schema::Loader.new(:accept_uri => false)
refute loader.accept_uri?(Addressable::URI.parse('http://foo.com'))
reader = JSON::Schema::Reader.new(:accept_uri => false)
refute reader.accept_uri?(Addressable::URI.parse('http://foo.com'))
end

def test_refuse_all_files
loader = JSON::Schema::Loader.new(:accept_file => false)
refute loader.accept_file?(Pathname.new('/foo/bar/baz'))
reader = JSON::Schema::Reader.new(:accept_file => false)
refute reader.accept_file?(Pathname.new('/foo/bar/baz'))
end

def test_accept_uri_proc
loader = JSON::Schema::Loader.new(
reader = JSON::Schema::Reader.new(
:accept_uri => proc { |uri| uri.host == 'json-schema.org' }
)

assert loader.accept_uri?(Addressable::URI.parse('http://json-schema.org/address'))
refute loader.accept_uri?(Addressable::URI.parse('http://sub.json-schema.org/address'))
assert reader.accept_uri?(Addressable::URI.parse('http://json-schema.org/address'))
refute reader.accept_uri?(Addressable::URI.parse('http://sub.json-schema.org/address'))
end

def test_accept_file_proc
test_root = Pathname.new(__FILE__).expand_path.dirname

loader = JSON::Schema::Loader.new(
reader = JSON::Schema::Reader.new(
:accept_file => proc { |path| path.to_s.start_with?(test_root.to_s) }
)

assert loader.accept_file?(test_root.join('anything.json'))
refute loader.accept_file?(test_root.join('..', 'anything.json'))
assert reader.accept_file?(test_root.join('anything.json'))
refute reader.accept_file?(test_root.join('..', 'anything.json'))
end

def test_file_scheme
loader = JSON::Schema::Loader.new(:accept_uri => true, :accept_file => false)
assert_raises(JSON::Schema::LoadRefused) do
loader.load('file://' + ADDRESS_SCHEMA_PATH)
reader = JSON::Schema::Reader.new(:accept_uri => true, :accept_file => false)
assert_raises(JSON::Schema::ReadRefused) do
reader.read('file://' + ADDRESS_SCHEMA_PATH)
end
end

def test_parse_error
stub_address_request('this is totally not valid JSON!')

loader = JSON::Schema::Loader.new
reader = JSON::Schema::Reader.new
assert_raises(JSON::ParserError) do
loader.load(ADDRESS_SCHEMA_URI)
reader.read(ADDRESS_SCHEMA_URI)
end
end
end
Loading

0 comments on commit d824d30

Please sign in to comment.