Class: JSONModelType
- Inherits:
-
Object
- Object
- JSONModelType
- Defined in:
- lib/aspace_client/jsonmodel_type.rb
Overview
A common base class for all JSONModel classes
Instance Attribute Summary collapse
-
#uri ⇒ Object
Returns the value of attribute uri.
Class Method Summary collapse
-
.add_validation(name, level = :error, &block) ⇒ Object
Add a custom validation to this model type.
-
.from_hash(hash, raise_errors = true, trusted = false) ⇒ Object
Create an instance of this JSONModel from the data contained in ‘hash’.
-
.from_json(s, raise_errors = true) ⇒ Object
Create an instance of this JSONModel from a JSON string.
-
.id_for(uri, opts = {}, noerror = false) ⇒ Object
The inverse of uri_for:.
-
.init(type, schema, mixins = []) ⇒ Object
Class instance variables store the bits specific to this model.
-
.record_type ⇒ Object
Return the type of this JSONModel class (a keyword like :archival_object).
-
.schema ⇒ Object
Return the JSON schema that defines this JSONModel class.
-
.schema_version ⇒ Object
Return the version number of this JSONModel’s schema.
- .to_s ⇒ Object
-
.type_of(path) ⇒ Object
Return the type of the schema property defined by ‘path’.
- .uri_and_remaining_options_for(id = nil, opts = {}) ⇒ Object
-
.uri_for(id = nil, opts = {}) ⇒ Object
Given a numeric internal ID and additional options produce a pair containing a URI reference.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, val) ⇒ Object
-
#_always_valid! ⇒ Object
Set this object instance to always pass validation.
-
#_exceptions ⇒ Object
Validate the current JSONModel instance and return a list of exceptions produced.
- #_warnings ⇒ Object
- #add_error(attribute, message) ⇒ Object
- #clear_errors ⇒ Object
- #has_key?(key) ⇒ Boolean
-
#id ⇒ Object
Return the internal ID of this JSONModel.
-
#initialize(params = {}, trusted = false) ⇒ JSONModelType
constructor
A new instance of JSONModelType.
- #inspect ⇒ Object
- #instance_data ⇒ Object
-
#replace(params) ⇒ Object
Replace the values of the current JSONModel instance with the contents of ‘params’, validating before accepting the replacement.
- #reset_from(another_jsonmodel) ⇒ Object
-
#to_hash(mode = nil) ⇒ Object
Produce a (possibly nested) hash from the values of this JSONModel.
-
#to_json(opts = {}) ⇒ Object
Produce a JSON string from the values of this JSONModel.
- #to_s ⇒ Object
-
#update(params) ⇒ Object
Update the values of the current JSONModel instance with the contents of ‘params’, validating before accepting the update.
Constructor Details
#initialize(params = {}, trusted = false) ⇒ JSONModelType
Returns a new instance of JSONModelType.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 176 def initialize(params = {}, trusted = false) set_data(params) @uri ||= params['uri'] # a hash to store transient instance data @instance_data = {} self.class.define_accessors(@data.keys) if trusted @validated = {} @cleaned_data = @data end end |
Instance Attribute Details
#uri ⇒ Object
Returns the value of attribute uri.
193 194 195 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 193 def uri @uri end |
Class Method Details
.add_validation(name, level = :error, &block) ⇒ Object
Add a custom validation to this model type.
The validation is a block that takes a hash of properties and returns an array of pairs like:
- [“propertyname”, “the problem with it”], …
54 55 56 57 58 59 60 61 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 54 def self.add_validation(name, level = :error, &block) raise "Validation name already taken: #{name}" if JSONModel.custom_validations[name] JSONModel.custom_validations[name] = block self.schema["validations"] ||= [] self.schema["validations"] << [level, name] end |
.from_hash(hash, raise_errors = true, trusted = false) ⇒ Object
Create an instance of this JSONModel from the data contained in ‘hash’.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 65 def self.from_hash(hash, raise_errors = true, trusted = false) hash["jsonmodel_type"] = self.record_type.to_s # If we're running in client mode, leave 'readonly' properties in place, # since they're intended for use by clients. Otherwise, we drop them. drop_system_properties = !JSONModel.client_mode? if trusted # We got this data from a trusted source (such as another JSONModel # that had already been validated itself). No need to double up self.new(hash, true) else cleaned = JSONSchemaUtils.drop_unknown_properties(hash, self.schema, drop_system_properties) cleaned = ASUtils.jsonmodels_to_hashes(cleaned) validate(cleaned, raise_errors) self.new(cleaned) end end |
.from_json(s, raise_errors = true) ⇒ Object
Create an instance of this JSONModel from a JSON string.
88 89 90 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 88 def self.from_json(s, raise_errors = true) self.from_hash(ASUtils.json_parse(s), raise_errors) end |
.id_for(uri, opts = {}, noerror = false) ⇒ Object
The inverse of uri_for:
JSONModel(:archival_object).id_for("/repositories/123/archival_objects/500", :repo_id => 123)
might yield 500
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 130 def self.id_for(uri, opts = {}, noerror = false) if not self.schema['uri'] if noerror return nil else raise "Missing a URI definition for class #{self.class}" end end pattern = self.schema['uri'] pattern = pattern.gsub(/\/:[a-zA-Z_]+\//, '/[^/ ]+/') # IDs are either positive integers, or importer-provided logical IDs id_regexp = /([0-9]+|import_[a-f0-9-]+)/ if uri =~ /#{pattern}\/#{id_regexp}(\#.*)?$/ return id_to_int($1) elsif uri =~ /#{pattern.gsub(/\[\^\/ \]\+\/tree/, '')}#{id_regexp}\/tree$/ return id_to_int($1) else if noerror nil else raise "Couldn't make an ID out of URI: #{uri}" end end end |
.init(type, schema, mixins = []) ⇒ Object
Class instance variables store the bits specific to this model
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 5 def self.init(type, schema, mixins = []) @record_type = type @schema = schema # In client mode, mix in some extra convenience methods for querying the # ArchivesSpace backend service via HTTP. if JSONModel.client_mode? require_relative 'jsonmodel_client' include JSONModel::Client end define_accessors(schema['properties'].keys) mixins.each do |mixin| include(mixin) end end |
.record_type ⇒ Object
Return the type of this JSONModel class (a keyword like :archival_object)
40 41 42 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 40 def self.record_type find_ancestor_class_instance(:@record_type) end |
.schema ⇒ Object
Return the JSON schema that defines this JSONModel class
27 28 29 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 27 def self.schema find_ancestor_class_instance(:@schema) end |
.schema_version ⇒ Object
Return the version number of this JSONModel’s schema
33 34 35 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 33 def self.schema_version self.schema['version'] end |
.to_s ⇒ Object
45 46 47 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 45 def self.to_s "JSONModel(:#{self.record_type})" end |
.type_of(path) ⇒ Object
Return the type of the schema property defined by ‘path’
For example, type_of(“names/items/type”) might return a JSONModel class
162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 162 def self.type_of(path) type = JSONSchemaUtils.schema_path_lookup(self.schema, path)["type"] ref = JSONModel.parse_jsonmodel_ref(type) if ref JSONModel.JSONModel(ref.first) else Kernel.const_get(type.capitalize) end end |
.uri_and_remaining_options_for(id = nil, opts = {}) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 93 def self.(id = nil, opts = {}) # Some schemas (like name schemas) don't have a URI because they don't # need endpoints. That's fine. if not self.schema['uri'] return nil end uri = self.schema['uri'] if not id.nil? uri += "/#{URI.escape(id.to_s)}" end self.substitute_parameters(uri, opts) end |
.uri_for(id = nil, opts = {}) ⇒ Object
Given a numeric internal ID and additional options produce a pair containing a URI reference. For example:
JSONModel(:archival_object).uri_for(500, :repo_id => 123)
might yield "/repositories/123/archival_objects/500"
117 118 119 120 121 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 117 def self.uri_for(id = nil, opts = {}) result = self.(id, opts) result ? result[0] : nil end |
Instance Method Details
#[](key) ⇒ Object
205 206 207 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 205 def [](key) @data[key.to_s] end |
#[]=(key, val) ⇒ Object
210 211 212 213 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 210 def []=(key, val) @validated = false @data[key.to_s] = val end |
#_always_valid! ⇒ Object
Set this object instance to always pass validation. Used so the frontend can create intentionally incomplete objects that will be filled out by the user.
269 270 271 272 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 269 def _always_valid! @always_valid = true self end |
#_exceptions ⇒ Object
Validate the current JSONModel instance and return a list of exceptions produced.
223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 223 def _exceptions return @validated if @validated && @errors.nil? exceptions = {} if not @always_valid exceptions = self.validate(@data, false) end if @errors exceptions[:errors] = (exceptions[:errors] or {}).merge(@errors) end exceptions end |
#_warnings ⇒ Object
255 256 257 258 259 260 261 262 263 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 255 def _warnings exceptions = self._exceptions if exceptions.has_key?(:warnings) exceptions[:warnings] else [] end end |
#add_error(attribute, message) ⇒ Object
246 247 248 249 250 251 252 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 246 def add_error(attribute, ) # reset validation @validated = false # call JSONModel::Client's version super end |
#clear_errors ⇒ Object
239 240 241 242 243 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 239 def clear_errors # reset validation @validated = false @errors = nil end |
#has_key?(key) ⇒ Boolean
216 217 218 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 216 def has_key?(key) @data.has_key?(key) end |
#id ⇒ Object
Return the internal ID of this JSONModel.
340 341 342 343 344 345 346 347 348 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 340 def id ref = JSONModel::parse_reference(self.uri) if ref ref[:id] else nil end end |
#inspect ⇒ Object
301 302 303 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 301 def inspect self.to_s end |
#instance_data ⇒ Object
200 201 202 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 200 def instance_data @instance_data end |
#replace(params) ⇒ Object
Replace the values of the current JSONModel instance with the contents of ‘params’, validating before accepting the replacement.
285 286 287 288 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 285 def replace(params) @validated = false set_data(params) end |
#reset_from(another_jsonmodel) ⇒ Object
291 292 293 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 291 def reset_from(another_jsonmodel) @data = another_jsonmodel.instance_eval { @data } end |
#to_hash(mode = nil) ⇒ Object
Produce a (possibly nested) hash from the values of this JSONModel. Any values that don’t appear in the JSON schema will not appear in the result.
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 309 def to_hash(mode = nil) mode = (mode || :validated) raise "Invalid .to_hash mode: #{mode}" unless [:trusted, :validated, :raw].include?(mode) return @data if mode == :raw if @validated and @cleaned_data return @cleaned_data end cleaned = JSONSchemaUtils.drop_unknown_properties(@data, self.class.schema) cleaned = ASUtils.jsonmodels_to_hashes(cleaned) if mode == :validated @validated = false self.validate(cleaned) end @cleaned_data = cleaned end |
#to_json(opts = {}) ⇒ Object
Produce a JSON string from the values of this JSONModel. Any values that don’t appear in the JSON schema will not appear in the result.
334 335 336 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 334 def to_json(opts = {}) ASUtils.to_json(self.to_hash(opts[:mode]), opts.is_a?(Hash) ? opts.merge(:max_nesting => false) : {}) end |
#to_s ⇒ Object
296 297 298 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 296 def to_s "#<JSONModel(:#{self.class.record_type}) #{@data.inspect}>" end |
#update(params) ⇒ Object
Update the values of the current JSONModel instance with the contents of ‘params’, validating before accepting the update.
277 278 279 280 |
# File 'lib/aspace_client/jsonmodel_type.rb', line 277 def update(params) @validated = false replace(ASUtils.deep_merge(@data, params)) end |