class IIIF::Service
Public Class Methods
from_ordered_hash(hsh, default_klass=ActiveSupport::OrderedHash)
click to toggle source
# File lib/iiif/service.rb, line 198 def self.from_ordered_hash(hsh, default_klass=ActiveSupport::OrderedHash) # Create a new object (new_object) type = nil if hsh.has_key?('@type') type = IIIF::Service.get_descendant_class_by_jld_type(hsh['@type']) end new_object = type.nil? ? default_klass.new : type.new hsh.keys.each do |key| new_key = key.underscore == key ? key : key.underscore if new_key == 'service' new_object[new_key] = IIIF::Service.from_ordered_hash(hsh[key], IIIF::Service) elsif new_key == 'resource' new_object[new_key] = IIIF::Service.from_ordered_hash(hsh[key], IIIF::Presentation::Resource) elsif hsh[key].kind_of?(Hash) new_object[new_key] = IIIF::Service.from_ordered_hash(hsh[key]) elsif hsh[key].kind_of?(Array) new_object[new_key] = [] hsh[key].each do |member| if new_key == 'service' new_object[new_key] << IIIF::Service.from_ordered_hash(member, IIIF::Service) elsif member.kind_of?(Hash) new_object[new_key] << IIIF::Service.from_ordered_hash(member) else new_object[new_key] << member # Again, no nested arrays, right? end end else new_object[new_key] = hsh[key] end end new_object end
new(hsh={})
click to toggle source
# File lib/iiif/service.rb, line 20 def initialize(hsh={}) @data = ActiveSupport::OrderedHash[hsh] self.define_methods_for_any_type_keys self.define_methods_for_array_only_keys self.define_methods_for_string_only_keys self.define_methods_for_int_only_keys self.define_methods_for_abstract_resource_only_keys self.snakeize_keys end
parse(s)
click to toggle source
Parse from a file path, string, or existing hash
# File lib/iiif/service.rb, line 33 def parse(s) ordered_hash = nil if s.kind_of?(String) && File.exists?(s) ordered_hash = ActiveSupport::OrderedHash[JSON.parse(IO.read(s))] elsif s.kind_of?(String) && !File.exists?(s) ordered_hash = ActiveSupport::OrderedHash[JSON.parse(s)] elsif s.kind_of?(Hash) ordered_hash = ActiveSupport::OrderedHash[s] else m = '#parse takes a path to a file, a JSON String, or a Hash, ' m += "argument was a #{s.class}." if s.kind_of?(String) m+= "If you were trying to point to a file, does it exist?" end raise ArgumentError, m end return IIIF::Service.from_ordered_hash(ordered_hash) end
Protected Class Methods
all_service_subclasses()
click to toggle source
All known subclasses of service.
# File lib/iiif/service.rb, line 242 def self.all_service_subclasses klass = IIIF::Service # !c.name.nil? filters out classes that rspec creates for some reason; # this condition isn't necessary when using the API, afaik descendants = ObjectSpace.each_object(Class).select { |c| c < klass && !c.name.nil? } end
get_descendant_class_by_jld_type(type)
click to toggle source
# File lib/iiif/service.rb, line 235 def self.get_descendant_class_by_jld_type(type) IIIF::Service.all_service_subclasses.select { |klass| klass.const_defined?(:TYPE) && klass.const_get(:TYPE) == type }.first end
Public Instance Methods
abstract_resource_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 16 def abstract_resource_only_keys; %w{ }; end
any_type_keys()
click to toggle source
# File lib/iiif/service.rb, line 13 def any_type_keys; %w{ }; end
array_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 15 def array_only_keys; %w{ }; end
hash_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 17 def hash_only_keys; %w{ }; end
int_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 18 def int_only_keys; %w{ }; end
required_keys()
click to toggle source
Anything goes! SHOULD have @id and profile, MAY have label Consider subclassing this for typical services…
# File lib/iiif/service.rb, line 12 def required_keys; %w{ }; end
string_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 14 def string_only_keys; %w{ }; end
to_json(opts={})
click to toggle source
Options
* pretty: (true|false). Should the JSON be pretty-printed? (default: false) * All options available in #to_ordered_hash
# File lib/iiif/service.rb, line 92 def to_json(opts={}) hsh = self.to_ordered_hash(opts) if opts.fetch(:pretty, false) JSON.pretty_generate(hsh) else hsh.to_json end end
to_ordered_hash(opts={})
click to toggle source
Options:
* force: (true|false). Skips validations. * sort_json_ld_keys: (true|false). Brings all properties starting with '@'. Default: true. to the top of the document and sorts them.
# File lib/iiif/service.rb, line 105 def to_ordered_hash(opts={}) force = opts.fetch(:force, false) sort_json_ld_keys = opts.fetch(:sort_json_ld_keys, true) unless force self.validate end export_hash = ActiveSupport::OrderedHash.new if sort_json_ld_keys self.keys.select { |k| k.start_with?('@') }.sort!.each do |k| export_hash[k] = self.data[k] end end sub_opts = { include_context: false, sort_json_ld_keys: sort_json_ld_keys, force: force } self.keys.each do |k| unless sort_json_ld_keys && k.start_with?('@') if self.data[k].respond_to?(:to_ordered_hash) #.respond_to?(:to_ordered_hash) export_hash[k] = self.data[k].to_ordered_hash(sub_opts) elsif self.data[k].kind_of?(Hash) export_hash[k] = ActiveSupport::OrderedHash.new self.data[k].each do |sub_k, v| if v.respond_to?(:to_ordered_hash) export_hash[k][sub_k] = v.to_ordered_hash(sub_opts) elsif v.kind_of?(Array) export_hash[k][sub_k] = [] v.each do |member| if member.respond_to?(:to_ordered_hash) export_hash[k][sub_k] << member.to_ordered_hash(sub_opts) else export_hash[k][sub_k] << member end end else export_hash[k][sub_k] = v end end elsif self.data[k].kind_of?(Array) export_hash[k] = [] self.data[k].each do |member| if member.respond_to?(:to_ordered_hash) export_hash[k] << member.to_ordered_hash(sub_opts) elsif member.kind_of?(Hash) hsh = ActiveSupport::OrderedHash.new export_hash[k] << hsh member.each do |sub_k,v| if v.respond_to?(:to_ordered_hash) hsh[sub_k] = v.to_ordered_hash(sub_opts) elsif v.kind_of?(Array) hsh[sub_k] = [] v.each do |sub_member| if sub_member.respond_to?(:to_ordered_hash) hsh[sub_k] << sub_member.to_ordered_hash(sub_opts) else hsh[sub_k] << sub_member end end else hsh[sub_k] = v end end else export_hash[k] << member # there are no nested arrays, right? end end else export_hash[k] = self.data[k] end end end export_hash.remove_empties export_hash.camelize_keys export_hash end
validate()
click to toggle source
# File lib/iiif/service.rb, line 53 def validate # TODO: # * check for required keys # * type check Array-only values # * type check String-only values # * type check Integer-only values # * type check AbstractResource-only values self.required_keys.each do |k| unless self.has_key?(k) m = "A(n) #{k} is required for each #{self.class}" raise IIIF::Presentation::MissingRequiredKeyError, m end end # Viewing Direction values if self.has_key?('viewing_direction') unless self.legal_viewing_direction_values.include?(self['viewing_direction']) m = "viewingDirection must be one of #{legal_viewing_direction_values}" raise IIIF::Presentation::IllegalValueError, m end end # Viewing Hint values if self.has_key?('viewing_hint') unless self.legal_viewing_hint_values.include?(self['viewing_hint']) m = "viewingHint for #{self.class} must be one of #{self.legal_viewing_hint_values}." raise IIIF::Presentation::IllegalValueError, m end end # Metadata is all hashes if self.has_key?('metadata') unless self['metadata'].all? { |entry| entry.kind_of?(Hash) } m = 'All entries in the metadata list must be a type of Hash' raise IIIF::Presentation::IllegalValueError, m end end end
Protected Instance Methods
data()
click to toggle source
# File lib/iiif/service.rb, line 253 def data @data end
data=(hsh)
click to toggle source
# File lib/iiif/service.rb, line 249 def data=(hsh) @data = hsh end
define_methods_for_abstract_resource_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 312 def define_methods_for_abstract_resource_only_keys # keys in this case is an array of hashes with { key: 'k', type: Class } abstract_resource_only_keys.each do |hsh| key = hsh[:key] type = hsh[:type] # Setters define_singleton_method("#{key}=") do |arg| unless arg.kind_of?(type) m = "#{key} must be an #{type}." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end if key.camelize(:lower) != key define_singleton_method("#{key.camelize(:lower)}=") do |arg| unless arg.kind_of?(type) m = "#{key} must be an #{type}." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end end # Getters define_singleton_method(key) do self[key] ||= [] self[key] end if key.camelize(:lower) != key define_singleton_method(key.camelize(:lower)) do self.send('[]', key) end end end end
define_methods_for_any_type_keys()
click to toggle source
# File lib/iiif/service.rb, line 257 def define_methods_for_any_type_keys any_type_keys.each do |key| # Setters define_singleton_method("#{key}=") do |arg| self.send('[]=', key, arg) end if key.camelize(:lower) != key define_singleton_method("#{key.camelize(:lower)}=") do |arg| self.send('[]=', key, arg) end end # Getters define_singleton_method(key) do self.send('[]', key) end if key.camelize(:lower) != key define_singleton_method(key.camelize(:lower)) do self.send('[]', key) end end end end
define_methods_for_array_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 280 def define_methods_for_array_only_keys array_only_keys.each do |key| # Setters define_singleton_method("#{key}=") do |arg| unless arg.kind_of?(Array) m = "#{key} must be an Array." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end if key.camelize(:lower) != key define_singleton_method("#{key.camelize(:lower)}=") do |arg| unless arg.kind_of?(Array) m = "#{key} must be an Array." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end end # Getters define_singleton_method(key) do self[key] ||= [] self[key] end if key.camelize(:lower) != key define_singleton_method(key.camelize(:lower)) do self.send('[]', key) end end end end
define_methods_for_int_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 380 def define_methods_for_int_only_keys int_only_keys.each do |key| # Setter define_singleton_method("#{key}=") do |arg| unless arg.kind_of?(Integer) && arg > 0 m = "#{key} must be a positive Integer." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end if key.camelize(:lower) != key define_singleton_method("#{key.camelize(:lower)}=") do |arg| unless arg.kind_of?(Integer) && arg > 0 m = "#{key} must be a positive Integer." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end end # Getter define_singleton_method(key) do self[key] ||= [] self[key] end if key.camelize(:lower) != key define_singleton_method(key.camelize(:lower)) do self.send('[]', key) end end end end
define_methods_for_string_only_keys()
click to toggle source
# File lib/iiif/service.rb, line 348 def define_methods_for_string_only_keys string_only_keys.each do |key| # Setter define_singleton_method("#{key}=") do |arg| unless arg.kind_of?(String) m = "#{key} must be an String." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end if key.camelize(:lower) != key define_singleton_method("#{key.camelize(:lower)}=") do |arg| unless arg.kind_of?(String) m = "#{key} must be an String." raise IIIF::Presentation::IllegalValueError, m end self.send('[]=', key, arg) end end # Getter define_singleton_method(key) do self[key] ||= [] self[key] end if key.camelize(:lower) != key define_singleton_method(key.camelize(:lower)) do self.send('[]', key) end end end end