Class: Genio::Parser::Format::JsonSchema
- Includes:
- Logging
- Defined in:
- lib/genio/parser/format/json_schema.rb
Instance Attribute Summary collapse
-
#current_schema ⇒ Object
Returns the value of attribute current_schema.
Attributes inherited from Base
#data_types, #endpoint, #enum_types, #files, #options, #services
Instance Method Summary collapse
-
#class_name(name) ⇒ Object
Format class name === Example class_name(“credit-card”) # return “CreditCard” class_name(“/path/to/payment.json”) # return “Payment”.
-
#file_name(name) ⇒ Object
Fix file name format.
-
#fix_unknown_service ⇒ Object
Map operations based on the Request or Response types.
- #get_inline_schema_klass(names, schema, filename) ⇒ Object
- #inline_schema(filename) ⇒ Object
-
#load(filename, force = false) ⇒ Object
Load schema == Example schema.load(“path/to/json_schema.json”) schema.load(“example.com/json_schema.json”).
-
#parse_file(filename) ⇒ Object
Parse Given schema file and return class name.
-
#parse_object(data) ⇒ Object
Parse object schema.
-
#parse_property(name, data) ⇒ Object
Parse property.
-
#parse_resource(data) ⇒ Object
Parse resource schema.
-
#parse_service(data, service) ⇒ Object
Parse each operation in service.
- #parse_services(resources, data) ⇒ Object
- #store_schema(schema) ⇒ Object
-
#update_ref_paths(data, paths = {}) ⇒ Object
Update configured ref links.
Methods included from Logging
Methods inherited from Base
#expand_path, #initialize, #load_files, #open, #read_file, #to_iodocs
Constructor Details
This class inherits a constructor from Genio::Parser::Format::Base
Instance Attribute Details
#current_schema ⇒ Object
Returns the value of attribute current_schema.
10 11 12 |
# File 'lib/genio/parser/format/json_schema.rb', line 10 def current_schema @current_schema end |
Instance Method Details
#class_name(name) ⇒ Object
Format class name
Example
class_name("credit-card") # return "CreditCard"
class_name("/path/to/payment.json") # return "Payment"
249 250 251 252 253 254 |
# 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) ⇒ Object
Fix file name format
257 258 259 |
# File 'lib/genio/parser/format/json_schema.rb', line 257 def file_name(name) name.to_s.gsub(/-/, "_").underscore end |
#fix_unknown_service ⇒ Object
Map operations based on the Request or Response types.
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# 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) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# 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) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# 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) ⇒ Object
Load schema
Example
schema.load("path/to/json_schema.json")
schema.load("http://example.com/json_schema.json")
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# 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. class_name(filename) else raise error end end |
#parse_file(filename) ⇒ Object
Parse Given schema file and return class name
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# 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) ⇒ Object
Parse object schema
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# 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, | properties[name] = parse_property(name, ) 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) ⇒ Object
Parse property.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# 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. Types::Property.new end |
#parse_resource(data) ⇒ Object
Parse resource schema
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# 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, | data_types[class_name(name)] = true end data.schemas.each do |name, | data_types[class_name(name)] = parse_object() end end parse_services(data.resources, data) end |
#parse_service(data, service) ⇒ Object
Parse each operation in service
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/genio/parser/format/json_schema.rb', line 208 def parse_service(data, service) data["methods"] ||= {} data["methods"].each do |name, | .relative_path = .path .path = File.join(service.servicePath, .path) .type = .httpMethod if .request .request_property = parse_property("#{name}_request", .request) .request = .request_property.type end if .response .response_property = parse_property("#{name}_response", .response) .response = .response_property.type end # Load service parameters if .parameters.nil? and .type == "GET" .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) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/genio/parser/format/json_schema.rb', line 195 def parse_services(resources, data) # Parse Resources resources.each do |name, | service = parse_service(, 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) ⇒ Object
68 69 70 71 72 73 74 |
# 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 = {}) ⇒ Object
Update configured ref links
237 238 239 240 241 242 243 |
# 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 |