class Genio::Parser::Format::JsonSchema
Attributes
current_schema[RW]
Public Instance Methods
class_name(name)
click to toggle source
Format
class name
Example¶ ↑
class_name("credit-card") # return "CreditCard" class_name("/path/to/payment.json") # return "Payment"
# File lib/genio/parser/format/json_schema.rb, line 249 def class_name(name) name, anchor = name.to_s.split("#", 2) name = File.basename(name, ".json") name = name + "_" + anchor if anchor.present? name.gsub(/[^\w]/, "_").camelcase end
file_name(name)
click to toggle source
Fix file name format
# File lib/genio/parser/format/json_schema.rb, line 257 def file_name(name) name.to_s.gsub(/-/, "_").underscore end
fix_unknown_service()
click to toggle source
Map operations based on the Request or Response types.
# File lib/genio/parser/format/json_schema.rb, line 262 def fix_unknown_service new_services = Types::Base.new services.each do |service_name, service| unless data_types[service_name] service.operations.each do |operation_name, operation| if data_types[operation.request] new_services[operation.request] ||= Types::Base.new( :operations => {} ) new_services[operation.request].operations[operation_name] = operation elsif data_types[operation.response] new_services[operation.response] ||= Types::Base.new( :operations => {} ) new_services[operation.response].operations[operation_name] = operation end end end end services.merge!(new_services) end
get_inline_schema_klass(names, schema, filename)
click to toggle source
# File lib/genio/parser/format/json_schema.rb, line 53 def get_inline_schema_klass(names, schema, filename) names.each do |name| schema = schema[name] if schema end if schema klass = class_name(class_name(names.join("_"))) data_types[klass] = {} data_types[klass] = parse_object(schema) klass else raise "Unable to find schema #{filename}" end end
inline_schema(filename)
click to toggle source
# File lib/genio/parser/format/json_schema.rb, line 36 def inline_schema(filename) file, names = filename.split("#", 2) names = names.split("/").delete_if(&:empty?) schema = self.current_schema if file.present? read_file(file) do |data| schema = JSON.parse(data, :object_class => Types::Base, :max_nesting => 100) store_schema(schema) do get_inline_schema_klass(names, schema, filename) end end else get_inline_schema_klass(names, schema, filename) end end
load(filename, force = false)
click to toggle source
Load schema
Example¶ ↑
schema.load("path/to/json_schema.json") schema.load("http://example.com/json_schema.json")
# File lib/genio/parser/format/json_schema.rb, line 16 def load(filename, force = false) if data_types[filename] || (!force and data_types[class_name(filename)]) class_name(filename) elsif filename =~ /#./ and self.current_schema inline_schema(filename) elsif files[filename] files[filename] else files[filename] = class_name(filename) parse_file(filename) end rescue Errno::ENOENT => error if force and data_types[class_name(filename)] logger.error error.message class_name(filename) else raise error end end
parse_file(filename)
click to toggle source
Parse Given schema file and return class name
# File lib/genio/parser/format/json_schema.rb, line 77 def parse_file(filename) klass = class_name(filename) read_file(filename) do |data| data = JSON.parse(data, :object_class => Types::Base, :max_nesting => 100) store_schema(data) do if data.resources # discovery format parse_resource(data) else data_types[klass] = {} data_types[klass] = parse_object(data) end end end klass end
parse_object(data)
click to toggle source
Parse object schema
# File lib/genio/parser/format/json_schema.rb, line 94 def parse_object(data) if data["$ref"] return self.data_types[self.load(data["$ref"], true)] end properties = Types::Base.new required_properties = data.required.is_a?(Array) ? data.required : [] # Parse each properties if data.properties data.properties.each do |name, options| properties[name] = parse_property(name, options) properties[name].required = true if required_properties.include? name end elsif data.type.is_a?(Array) data.type.each do |object| properties.merge!(parse_object(object).properties) if object.is_a? Hash end end # Load extends class. data.extends = if data.extends.is_a? String self.load(data.extends) elsif data.extends.is_a? Hash if data.extends["$ref"] self.load(data.extends["$ref"]) else properties.merge!(parse_object(data.extends).properties) nil end else data.extends = nil end ["oneOf", "anyOf", "allOf"].each do |name| data[name] = data[name].map do |schema| parse_property(name, schema) end if data[name].is_a? Array end # Parse array type if data.items array_type = parse_object(data.items) properties.merge!(array_type.properties) data.extends ||= array_type.extends data.array = true end data.properties = properties Types::DataType.new(data) end
parse_property(name, data)
click to toggle source
Parse property.
# File lib/genio/parser/format/json_schema.rb, line 148 def parse_property(name, data) data.array = true if data.type == "array" data.type = if data["$ref"] # Check the type is refer to another schema or not self.load(data["$ref"]) elsif data.additionalProperties and data.additionalProperties["$ref"] self.load(data.additionalProperties["$ref"]) elsif data.properties # Check the type has object definition or not klass_name = class_name(name) data_types[klass_name] = parse_object(data) klass_name elsif data.type.is_a? Array data.oneOf = data.type.map do |type| type = Types::Base.new( "type" => type ) unless type.is_a? Hash parse_object(type) || Types::Base.new( "type" => "self" ) end "object" elsif data.items # Parse array value type array_property = parse_property(name, data.items) array_property.type else data.merge!(parse_object(data)) data.type || "object" end Types::Property.new(data) rescue => error logger.error error.message Types::Property.new end
parse_resource(data)
click to toggle source
Parse resource schema
# File lib/genio/parser/format/json_schema.rb, line 179 def parse_resource(data) self.endpoint ||= data.rootUrl if data.schemas data.schemas.each do |name, options| data_types[class_name(name)] = true end data.schemas.each do |name, options| data_types[class_name(name)] = parse_object(options) end end parse_services(data.resources, data) end
parse_service(data, service)
click to toggle source
Parse each operation in service
# File lib/genio/parser/format/json_schema.rb, line 208 def parse_service(data, service) data["methods"] ||= {} data["methods"].each do |name, options| options.relative_path = options.path options.path = File.join(service.servicePath, options.path) options.type = options.httpMethod if options.request options.request_property = parse_property("#{name}_request", options.request) options.request = options.request_property.type end if options.response options.response_property = parse_property("#{name}_response", options.response) options.response = options.response_property.type end # Load service parameters if options.parameters.nil? and options.type == "GET" options.parameters = service.parameters end end data.operations = data["methods"] parse_services(data.resources, service) if data.resources Types::Service.new(data) end
parse_services(resources, data)
click to toggle source
# File lib/genio/parser/format/json_schema.rb, line 195 def parse_services(resources, data) # Parse Resources resources.each do |name, options| service = parse_service(options, data) service.path = File.join(data.servicePath, name) if services[class_name(name)] service.operations.merge!(services[class_name(name)].operations) end services[class_name(name)] = service end end
store_schema(schema) { || ... }
click to toggle source
# File lib/genio/parser/format/json_schema.rb, line 68 def store_schema(schema) backup = self.current_schema self.current_schema = schema yield ensure self.current_schema = backup end
update_ref_paths(data, paths = {})
click to toggle source
Update configured ref links
# File lib/genio/parser/format/json_schema.rb, line 237 def update_ref_paths(data, paths = {}) paths.each do |path, replace_path| replace_path = replace_path.sub(/\/?$/, "/") data = data.gsub(/("\$ref"\s*:\s*")#{Regexp.escape(path)}\/?/, "\\1#{replace_path}") end data end