lib/ezid/metadata.rb in ezid-client-0.9.1 vs lib/ezid/metadata.rb in ezid-client-0.10.0
- old
+ new
@@ -1,11 +1,10 @@
require "delegate"
-require "singleton"
module Ezid
#
- # EZID metadata collection for an identifier
+ # EZID metadata collection for an identifier.
#
# @note Although this API is not private, its direct use is discouraged.
# Instead use the metadata element accessors through Ezid::Identifier.
# @api public
#
@@ -62,75 +61,57 @@
# All EZID reserved metadata elements
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
RESERVED_ELEMENTS = RESERVED_READONLY_ELEMENTS + RESERVED_READWRITE_ELEMENTS
- # Metadata element registry
- class ElementRegistry < SimpleDelegator
- include Singleton
-
- def initialize
- super(Hash.new)
- end
-
- def readers
- keys
- end
-
- def writers
- keys.select { |k| self[k].writer }.map(&:to_s).map { |k| k.concat("=") }.map(&:to_sym)
- end
- end
-
def self.initialize!
register_elements
- define_element_accessors
end
- def self.elements
- ElementRegistry.instance
+ def self.registered_elements
+ @@registered_elements ||= {}
end
def self.register_elements
register_profile_elements
register_reserved_elements
- elements.freeze
end
- def self.define_element_accessors
- elements.each do |accessor, element|
- define_method(accessor) { reader(element.name) }
-
- if element.writer
- define_method("#{accessor}=") { |value| writer(element.name, value) }
- end
+ def self.register_element(accessor, opts={})
+ if element = registered_elements[accessor.to_sym]
+ raise Error, "Element \"#{element.name}\" already registered under key :#{accessor}"
end
+ writer = opts.fetch(:writer, true)
+ name = opts.fetch(:name, accessor.to_s)
+ registered_elements[accessor.to_sym] = Element.new(name, writer).freeze
end
- def self.register_element(accessor, element, opts={})
- writer = opts.fetch(:writer, true)
- elements[accessor] = Element.new(element, writer).freeze
+ def self.register_profile_element(profile, element)
+ register_element("#{profile}_#{element}", name: "#{profile}.#{element}")
end
- def self.register_profile_elements
- PROFILES.each do |profile, profile_elements|
- profile_elements.each do |element|
- register_element("#{profile}_#{element}".to_sym, "#{profile}.#{element}")
+ def self.register_profile_elements(profile = nil)
+ if profile
+ PROFILES[profile].each { |element| register_profile_element(profile, element) }
+ else
+ PROFILES.keys.each do |profile|
+ register_profile_elements(profile)
+ register_element(profile) unless profile == "dc"
end
- register_element(profile.to_sym, profile) unless profile == "dc"
end
end
def self.register_reserved_elements
RESERVED_ELEMENTS.each do |element|
- accessor = ((element == "_crossref") ? element : element.sub("_", "")).to_sym
- register_element(accessor, element, writer: RESERVED_READWRITE_ELEMENTS.include?(element))
+ accessor = (element == "_crossref") ? element : element.sub("_", "")
+ register_element(accessor, name: element, writer: RESERVED_READWRITE_ELEMENTS.include?(element))
end
end
- private_class_method :register_element, :register_elements, :register_reserved_elements,
- :register_profile_elements, :define_element_accessors
+ private_class_method :register_elements,
+ :register_reserved_elements,
+ :register_profile_elements
def initialize(data={})
super(coerce(data))
end
@@ -145,18 +126,49 @@
def to_s
to_anvl
end
+ def registered_elements
+ self.class.registered_elements
+ end
+
+ protected
+
+ def method_missing(method, *args)
+ return registered_reader(method) if registered_reader?(method, *args)
+ return registered_writer(method, *args) if registered_writer?(method, *args)
+ super
+ end
+
private
+ def registered_reader?(accessor, *args)
+ args.empty? && registered_elements.include?(accessor)
+ end
+
+ def registered_reader(accessor)
+ reader registered_elements[accessor].name
+ end
+
def reader(element)
value = self[element]
if RESERVED_TIME_ELEMENTS.include?(element)
time = value.to_i
value = (time == 0) ? nil : Time.at(time).utc
end
value
+ end
+
+ def registered_writer?(method, *args)
+ return false unless method.to_s.end_with?("=") && args.size == 1
+ accessor = method.to_s.sub("=", "").to_sym
+ registered_elements.include?(accessor) && registered_elements[accessor].writer
+ end
+
+ def registered_writer(method, *args)
+ accessor = method.to_s.sub("=", "").to_sym
+ writer(registered_elements[accessor].name, *args)
end
def writer(element, value)
self[element] = value
end