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)