From e7fe965458a42d540dd3a54e08367bbbfc251a41 Mon Sep 17 00:00:00 2001 From: Gabriel Gironda Date: Wed, 5 Nov 2014 18:38:42 -0600 Subject: [PATCH] Refactor ref schema URI construction. This refactors JSON::Validator#load_ref_schema to not implement a lot of logic that Pathname and URI are already capable of, and splits some of it into a separate method for clarity. Some JSON::Validator class methods are also added to hide away the specific implementation of how already loaded schemas are kept around. * Refactor JSON::Validator#load_schema_ref to move absolute URI construction to its own method, and to bail ASAP if the schema is already loaded. * Add JSON::Validator#absolutize_ref_uri to handle logic around constructing an absolute URI to a schema based on the ref URI and its parent schema URI. * Add JSON::Validator.schema_for_uri to fetch an already loaded schema for a given URI. * Add JSON::Validator.schema_loaded? predicate method for testing whether a schema is already loaded. * Move some existing code to use the new class methods. --- lib/json-schema/validator.rb | 53 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/json-schema/validator.rb b/lib/json-schema/validator.rb index da880290..f39a5917 100644 --- a/lib/json-schema/validator.rb +++ b/lib/json-schema/validator.rb @@ -122,36 +122,29 @@ def validate() end end + def load_ref_schema(parent_schema, ref) + schema_uri = absolutize_ref_uri(ref, parent_schema.uri) - def load_ref_schema(parent_schema,ref) - uri = URI.parse(ref) - if uri.relative? - uri = parent_schema.uri.clone + return true if self.class.schema_loaded?(schema_uri) - # Check for absolute path - path = ref.split("#")[0] + schema_data = self.class.parse(open(schema_uri.to_s).read) + schema = JSON::Schema.new(schema_data, schema_uri, @options[:version]) + self.class.add_schema(schema) + build_schemas(schema) + end - # This is a self reference and thus the schema does not need to be re-loaded - if path.nil? || path == '' - return - end + def absolutize_ref_uri(ref, parent_schema_uri) + ref_uri = URI.parse(ref) - if path && path[0,1] == '/' - uri.path = Pathname.new(path).cleanpath.to_s - else - uri = parent_schema.uri.merge(path) - end - uri.fragment = '' - end + return ref_uri if ref_uri.absolute? + # This is a self reference and thus the schema does not need to be re-loaded + return parent_schema_uri if ref_uri.path.empty? - if Validator.schemas[uri.to_s].nil? - schema = JSON::Schema.new(JSON::Validator.parse(open(uri.to_s.chomp('#')).read), uri, @options[:version]) - Validator.add_schema(schema) - build_schemas(schema) - end + uri = parent_schema_uri.clone + uri.fragment = '' + uri.merge(Pathname(ref_uri.path).cleanpath.to_s) end - # Build all schemas with IDs, mapping out the namespace def build_schemas(parent_schema) # Build ref schemas if they exist @@ -318,7 +311,15 @@ def schemas end def add_schema(schema) - @@schemas[schema.uri.to_s] = schema if @@schemas[schema.uri.to_s].nil? + @@schemas[schema.uri.to_s] ||= schema + end + + def schema_for_uri(uri) + @@schemas[uri.to_s] + end + + def schema_loaded?(schema_uri) + @@schemas.has_key?(schema_uri.to_s) end def cache_schemas=(val) @@ -526,7 +527,7 @@ def initialize_schema(schema) rescue # Build a uri for it schema_uri = normalized_uri(schema) - if Validator.schemas[schema_uri.to_s].nil? + if !self.class.schema_loaded?(schema_uri) schema = JSON::Validator.parse(open(schema_uri.to_s).read) if @options[:list] && @options[:fragment].nil? schema = schema_to_list(schema) @@ -534,7 +535,7 @@ def initialize_schema(schema) schema = JSON::Schema.new(schema,schema_uri,@options[:version]) Validator.add_schema(schema) else - schema = Validator.schemas[schema_uri.to_s] + schema = self.class.schema_for_uri(schema_uri) if @options[:list] && @options[:fragment].nil? schema = schema_to_list(schema.schema) schema_uri = URI.parse(fake_uuid(serialize(schema)))