lib/ezid/metadata.rb in ezid-client-1.1.1 vs lib/ezid/metadata.rb in ezid-client-1.2.0
- old
+ new
@@ -1,178 +1,115 @@
-require "forwardable"
+require "hashie"
module Ezid
#
# EZID metadata collection for an identifier.
#
# @api private
#
- class Metadata
- extend Forwardable
+ class Metadata < Hashie::Mash
- attr_reader :elements
-
- def_delegators :elements, :[], :[]=, :each, :clear, :to_h, :empty?
-
- class << self
- def metadata_reader(element, alias_as=nil)
- define_method element do
- get(element)
- end
- if alias_as
- alias_method alias_as, element
- end
- end
-
- 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, "#{element}=".to_sym
- end
- end
-
- def metadata_accessor(element, alias_as=nil)
- metadata_reader element, alias_as
- metadata_writer element, alias_as
- end
-
- 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
ANVL_SEPARATOR = ": "
-
+ # EZID metadata field value separator
ELEMENT_VALUE_SEPARATOR = " | "
-
# Characters to escape in element values on output to EZID
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
ESCAPE_VALUES_RE = /[%\r\n]/
-
# Characters to escape in element names on output to EZID
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
ESCAPE_NAMES_RE = /[%:\r\n]/
-
# Character sequence to unescape from EZID
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
UNESCAPE_RE = /%\h\h/
-
# A comment line
COMMENT_RE = /^#.*(\r?\n)?/
-
# A line continuation
LINE_CONTINUATION_RE = /\r?\n\s+/
-
# A line ending
LINE_ENDING_RE = /\r?\n/
-
# 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)
+ READONLY = %w( _owner _ownergroup _shadows _shadowedby _datacenter _created _updated ).freeze
+ # EZID metadata profiles
# @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
+ PROFILES = %w( dc datacite erc ).freeze
+ RESERVED_ALIASES = [ :coowners=, :export=, :profile=, :status=, :target=,
+ :coowners, :export, :profile, :status, :target,
+ :datacenter, :owner, :ownergroup, :shadowedby, :shadows ]
- # 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
-
- # 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
-
- # Accessors for
- metadata_accessor :crossref
- metadata_accessor :datacite
- metadata_accessor :erc
-
def initialize(data={})
- @elements = coerce(data)
+ super coerce(data)
end
+ def elements
+ warn "[DEPRECATION] `elements` is deprecated and will be removed in ezid-client 2.0." \
+ " Use the Ezid::Metadata instance itself instead."
+ self
+ end
+
def created
- to_time _created
+ to_time(_created)
end
def updated
- to_time _updated
+ to_time(_updated)
end
# 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 = elements.dup
+ hsh = to_h
hsh.reject! { |k, v| READONLY.include?(k) } unless include_readonly
- lines = 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
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]
+ protected
+
+ def method_missing(name, *args, &block)
+ if reserved_alias?(name)
+ reserved_alias(name, *args)
+ elsif profile_accessor?(name)
+ profile_accessor(name, *args)
+ else
+ super
+ end
end
- def set(element, value)
- self[element.to_s] = value
+ private
+
+ def reserved_alias?(name)
+ RESERVED_ALIASES.include?(name)
end
- protected
+ def reserved_alias(name, *args)
+ send("_#{name}", *args)
+ end
- def method_missing(method, *args)
- return get(method) if args.size == 0
- if element = method.to_s[/^([^=]+)=$/, 1]
- return set(element, *args)
+ def profile_accessor?(name)
+ PROFILES.include? name.to_s.split("_").first
+ end
+
+ def profile_accessor(name, *args)
+ key = name.to_s.sub("_", ".")
+ if key.end_with?("=")
+ self[key[0..-2]] = args.first
+ else
+ self[key]
end
- super
end
- private
-
def to_time(value)
time = value.to_i
(time == 0) ? nil : Time.at(time).utc
end
@@ -204,6 +141,5 @@
end
end
end
end
-