lib/ezid/metadata.rb in ezid-client-1.0.1 vs lib/ezid/metadata.rb in ezid-client-1.1.0

- old
+ new

@@ -1,44 +1,56 @@ -require "delegate" +require "forwardable" module Ezid # # EZID metadata collection for an identifier. # # @api private # - class Metadata < SimpleDelegator + class Metadata + extend Forwardable + + attr_reader :elements + + def_delegators :elements, :[], :[]=, :each, :clear, :to_h, :empty? class << self - def metadata_reader(method, alias_as=nil) - define_method method do - self[method.to_s] + def metadata_reader(element, alias_as=nil) + define_method element do + get(element) end if alias_as - alias_method alias_as, method + alias_method alias_as, element end end - def metadata_writer(method, alias_as=nil) - define_method "#{method}=" do |value| - self[method.to_s] = value + def metadata_writer(element, alias_as=nil) + define_method "#{element}=" do |value| + set(element, value) end if alias_as - alias_method "#{alias_as}=".to_sym, "#{method}=".to_sym + alias_method "#{alias_as}=".to_sym, "#{element}=".to_sym end end - def metadata_accessor(method, alias_as=nil) - metadata_reader method, alias_as - metadata_writer method, alias_as + def metadata_accessor(element, alias_as=nil) + metadata_reader element, alias_as + metadata_writer element, alias_as end - def metadata_profile(profile, *methods) - methods.each do |method| - element = [profile, method].join(".") - alias_as = [profile, method].join("_") - metadata_accessor element, alias_as + def metadata_profile(profile, *elements) + elements.each do |element| + profile_element = [profile, element].join(".") + method = [profile, element].join("_") + + define_method method do + get(profile_element) + end + + define_method "#{method}=" do |value| + set(profile_element, value) + end end end end # EZID metadata field/value separator @@ -69,35 +81,47 @@ # EZID reserved metadata elements that are read-only # @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata READONLY = %w( _owner _ownergroup _shadows _shadowedby _datacenter _created _updated ) + # EZID metadata profiles - a hash of (profile => elements) + # @see http://ezid.cdlib.org/doc/apidoc.html#metadata-profiles + # @note crossref is not included because it is a simple element + PROFILES = { + dc: [:creator, :title, :publisher, :date, :type], + datacite: [:creator, :title, :publisher, :publicationyear, :resourcetype], + erc: [:who, :what, :when] + } + + PROFILES.each do |profile, elements| + metadata_profile profile, *elements + end + + # Accessors for EZID internal metadata elements metadata_accessor :_coowners, :coowners metadata_accessor :_crossref metadata_accessor :_export, :export metadata_accessor :_profile, :profile metadata_accessor :_status, :status metadata_accessor :_target, :target - metadata_accessor :crossref - metadata_accessor :datacite - metadata_accessor :erc - + # Readers for EZID read-only internal metadata elements metadata_reader :_created metadata_reader :_datacenter, :datacenter metadata_reader :_owner, :owner metadata_reader :_ownergroup, :ownergroup metadata_reader :_shadowedby, :shadowedby metadata_reader :_shadows, :shadows metadata_reader :_updated - metadata_profile :dc, :creator, :title, :publisher, :date, :type - metadata_profile :datacite, :creator, :title, :publisher, :publicationyear, :resourcetype - metadata_profile :erc, :who, :what, :when + # Accessors for + metadata_accessor :crossref + metadata_accessor :datacite + metadata_accessor :erc def initialize(data={}) - super coerce(data) + @elements = coerce(data) end def created to_time _created end @@ -108,20 +132,42 @@ # Output metadata in EZID ANVL format # @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies # @return [String] the ANVL output def to_anvl(include_readonly = true) - hsh = __getobj__.dup + hsh = elements.dup hsh.reject! { |k, v| READONLY.include?(k) } unless include_readonly - elements = hsh.map do |name, value| + lines = hsh.map do |name, value| element = [escape(ESCAPE_NAMES_RE, name), escape(ESCAPE_VALUES_RE, value)] element.join(ANVL_SEPARATOR) end - elements.join("\n").force_encoding(Encoding::UTF_8) + lines.join("\n").force_encoding(Encoding::UTF_8) end + def inspect + "#<#{self.class.name} elements=#{elements.inspect}>" + end + def to_s to_anvl + end + + def get(element) + self[element.to_s] + end + + def set(element, value) + self[element.to_s] = value + end + + protected + + def method_missing(method, *args) + return get(method) if args.size == 0 + if element = method.to_s[/^([^=]+)=$/, 1] + return set(element, *args) + end + super end private def to_time(value)