Class: ArchivesSpaceTypeAttribute
- Inherits:
-
JSON::Schema::TypeAttribute
- Object
- JSON::Schema::TypeAttribute
- ArchivesSpaceTypeAttribute
- Defined in:
- common/archivesspace_json_schema.rb
Class Method Summary collapse
-
.validate(current_schema, data, fragments, validator, options = {}) ⇒ Object
-
.validation_error_for(expected_type, fragments, current_schema) ⇒ Object
This reuse business is a bit of a pain.
Class Method Details
.validate(current_schema, data, fragments, validator, options = {}) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'common/archivesspace_json_schema.rb', line 55 def self.validate(current_schema, data, fragments, validator, = {}) types = current_schema.schema['type'] if types == 'date' begin Date.parse(data) return rescue validation_error("The property '#{build_fragment(fragments)}' was not " + "a well-formed date (value: #{data})", fragments, current_schema, self, [:record_errors]) end end if types == 'object' && data.is_a?(Hash) && data.has_key?('ref') && current_schema.schema['subtype'] != 'ref' # Provide a helpful warning about potentially missing subtype definitions $stderr.puts("WARNING: Schema #{current_schema.inspect} appears to be missing a subtype definition of 'ref'") end # A bit crazy, sorry. If we're being asked to validate a hash whose # jsonmodel_type is marked against a different JSONModel schema, we're # wasting our time. Just stop straight away. if (data.is_a?(Hash) && data["jsonmodel_type"]) && (current_schema.schema.is_a?(Hash) && "#{current_schema.schema["type"]}".include?("JSONModel") && !"#{current_schema.schema["type"]}".include?("JSONModel(:#{data['jsonmodel_type']})")) raise validation_error_for(data['jsonmodel_type'], fragments, current_schema) end if JSONModel.parse_jsonmodel_ref(types) (model, qualifier) = JSONModel.parse_jsonmodel_ref(types) if qualifier == 'uri' || (qualifier == 'uri_or_object' && data.is_a?(String)) if JSONModel(model).id_for(data, {}, true).nil? validation_error("The property '#{build_fragment(fragments)}' of type " + "#{data.class} did not match the following type: #{types} in schema", fragments, current_schema, self, [:record_errors]) end elsif qualifier == 'uri_or_object' || qualifier == 'object' if data.is_a?(Hash) data["jsonmodel_type"] ||= model.to_s ValidatorCache.with_validator_for(JSONModel(model), data) do |subvalidator| # Urk. Validate the subrecord but pass in the fragments of the point # we're at in the parent record. subvalidator.instance_eval do @base_schema.validate(@data, fragments, ) end end else validation_error("The property '#{build_fragment(fragments)}' of type " + "#{data.class} did not match the following type: #{types} in schema", fragments, current_schema, self, [:record_errors]) end end else super end end |
.validation_error_for(expected_type, fragments, current_schema) ⇒ Object
This reuse business is a bit of a pain. The story here: JRuby backtraces are relatively expensive to create (relative to MRI Ruby), and JSON Schema validation is using exceptions as control flow here (sigh). During imports, these validation error are hit a lot, and calculating a backtrace every time is expensive.
So, we recycle.
43 44 45 46 47 48 49 50 51 52 |
# File 'common/archivesspace_json_schema.rb', line 43 def self.validation_error_for(expected_type, fragments, current_schema) Thread.current[:json_validation_cached_errors] ||= {} if !Thread.current[:json_validation_cached_errors][expected_type] msg = "ERROR: Schema type mismatch. Expected type: #{expected_type}" Thread.current[:json_validation_cached_errors][expected_type] = JSON::Schema::ValidationError.new(msg, fragments, self, current_schema) end Thread.current[:json_validation_cached_errors][expected_type].fragments = fragments Thread.current[:json_validation_cached_errors][expected_type] end |