lib/ezid/identifier.rb in ezid-client-1.3.0 vs lib/ezid/identifier.rb in ezid-client-1.4.0
- old
+ new
@@ -4,102 +4,179 @@
#
# @api public
#
class Identifier
- attr_reader :client
- attr_accessor :id, :shoulder, :metadata, :state
+ attr_accessor :id, :shoulder, :persisted, :deleted
+ private :persisted=, :persisted, :deleted=, :deleted
- private :state, :state=, :id=
-
- # Attributes to display on inspect
- INSPECT_ATTRS = %w( id status target created ).freeze
-
class << self
attr_accessor :defaults
# Creates or mints an identifier (depending on arguments)
# @see #save
+ # @overload create(id, metadata=nil)
+ # Creates an identifier
+ # @param id [String] the identifier to create
+ # @param metadata [Hash] the metadata to set on the identifier
+ # @overload create(metadata=nil)
+ # Mints an identifier
+ # @deprecated Use {.mint} instead
+ # @param metadata [Hash] the metadata to set on the identifier
# @return [Ezid::Identifier] the new identifier
# @raise [Ezid::Error]
- def create(attrs = {})
- identifier = new(attrs)
- identifier.save
+ def create(*args)
+ raise ArgumentError, "`mint` receives 0-2 arguments." if args.size > 2
+ if args.first.is_a?(Hash)
+ warn "[DEPRECATION] Sending a hash as the first argument to `create` is deprecated and will raise an exception in 2.0. Use `create(id, metadata)` or `mint(metadata)` instead. (called from #{caller.first})"
+ metadata = args.first
+ id = metadata.delete(:id)
+ else
+ id, metadata = args
+ end
+ if id.nil?
+ warn "[DEPRECATION] Calling `create` without an id will raise an exception in 2.0. Use `mint` instead. (called from #{caller.first})"
+ shoulder = metadata.delete(:shoulder)
+ mint(shoulder, metadata)
+ else
+ new(id, metadata) { |i| i.save }
+ end
end
+ # Mints a new identifier
+ # @overload mint(shoulder, metadata=nil)
+ # @param shoulder [String] the EZID shoulder on which to mint
+ # @param metadata [Hash] the metadata to set on the identifier
+ # @overload mint(metadata=nil)
+ # @param metadata [Hash] the metadata to set on the identifier
+ # @return [Ezid::Identifier] the new identifier
+ # @raise [Ezid::Error]
+ def mint(*args)
+ raise ArgumentError, "`mint` receives 0-2 arguments." if args.size > 2
+ metadata = args.last.is_a?(Hash) ? args.pop : nil
+ new(metadata) do |i|
+ i.shoulder = args.first
+ i.save
+ end
+ end
+
+ # Modifies the metadata of an existing identifier.
+ # @param id [String] the EZID identifier
+ # @param metadata [Hash] the metadata to update on the identifier
+ # @return [Ezid::Identifier] the identifier
+ # @raise [Ezid::IdentifierNotFoundError]
+ def modify(id, metadata)
+ i = allocate
+ i.id = id
+ i.update_metadata(metadata)
+ i.modify!
+ end
+
# Retrieves an identifier
+ # @param id [String] the EZID identifier to find
# @return [Ezid::Identifier] the identifier
- # @raise [Ezid::Error] if the identifier does not exist in EZID
+ # @raise [Ezid::IdentifierNotFoundError] if the identifier does not exist in EZID
def find(id)
- identifier = new(id: id)
- identifier.load_metadata
+ i = allocate
+ i.id = id
+ i.load_metadata
end
end
self.defaults = {}
- def initialize(args={})
- @client = args.delete(:client) || Client.new
- @id = args.delete(:id)
- @shoulder = args.delete(:shoulder)
- @state = :new
- self.metadata = Metadata.new args.delete(:metadata)
- update_metadata self.class.defaults.merge(args) # deprecate?
+ def initialize(*args)
+ raise ArgumentError, "`new` receives 0-2 arguments." if args.size > 2
+ data = args.last.is_a?(Hash) ? args.pop : nil
+ @id = args.first
+ apply_default_metadata
+ if data
+ if shoulder = data.delete(:shoulder)
+ warn "[DEPRECATION] The `:shoulder` hash option is deprecated and will raise an exception in 2.0. Use `Ezid::Identifier.mint(shoulder, metadata)` to mint an identifier. (called by #{caller.first})"
+ @shoulder = shoulder
+ end
+ if anvl = data.delete(:metadata)
+ update_metadata(anvl)
+ end
+ update_metadata(data)
+ end
+ yield self if block_given?
end
def inspect
- attrs = if deleted?
- "id=\"#{id}\" DELETED"
- else
- INSPECT_ATTRS.map { |attr| "#{attr}=#{send(attr).inspect}" }.join(", ")
- end
- "#<#{self.class.name} #{attrs}>"
+ id_val = if id.nil?
+ "NEW"
+ elsif deleted?
+ "#{id} [DELETED]"
+ else
+ id
+ end
+ "#<#{self.class.name} id=#{id_val}>"
end
def to_s
id
end
# Returns the identifier metadata
- # @param load [Boolean] - flag to load the metadata from EZID if stale (default: `true`)
# @return [Ezid::Metadata] the metadata
- def metadata(load = true)
- load_metadata if load && stale?
- @metadata
+ def metadata(_=nil)
+ if !_.nil?
+ warn "[DEPRECATION] The parameter of `metadata` is deprecated and will be removed in 2.0. (called from #{caller.first})"
+ end
+ @metadata ||= Metadata.new
end
+ def remote_metadata
+ @remote_metadata ||= Metadata.new
+ end
+
# Persist the identifer and/or metadata to EZID.
# If the identifier is already persisted, this is an update operation;
# Otherwise, create (if it has an id) or mint (if it has a shoulder)
# the identifier.
# @return [Ezid::Identifier] the identifier
# @raise [Ezid::Error] if the identifier is deleted, or the host responds
# with an error status.
def save
raise Error, "Cannot save a deleted identifier." if deleted?
persist
- reset
+ reset_metadata
+ self
end
+ # Force a modification of the EZID identifier -- i.e.,
+ # assumes previously persisted without confirmation.
+ # @return [Ezid::Identifier] the identifier
+ # @raise [Ezid::Error] if `id` is nil
+ # @raise [Ezid::IdentifierNotFoundError] if EZID identifier does not exist.
+ def modify!
+ raise Error, "Cannot modify an identifier without and id." if id.nil?
+ modify
+ persists!
+ reset_metadata
+ self
+ end
+
# Updates the metadata
# @param attrs [Hash] the metadata
# @return [Ezid::Identifier] the identifier
def update_metadata(attrs={})
- attrs.each { |k, v| send("#{k}=", v) }
+ metadata.update(attrs)
self
end
# Is the identifier persisted?
# @return [Boolean]
def persisted?
- state == :persisted
+ !!persisted
end
# Has the identifier been deleted?
# @return [Boolean]
def deleted?
- state == :deleted
+ !!deleted
end
# Updates the metadata and saves the identifier
# @param data [Hash] a hash of metadata
# @return [Ezid::Identifier] the identifier
@@ -109,40 +186,44 @@
save
end
# @deprecated Use {#load_metadata} instead.
def reload
- warn "[DEPRECATION] `reload` is deprecated and will be removed in version 2.0. Use `load_metadata` instead."
+ warn "[DEPRECATION] `reload` is deprecated and will be removed in version 2.0. Use `load_metadata` instead. (called from #{caller.first})"
load_metadata
end
- # Loads the metadata from EZID (local changes will be lost!)
+ # Loads the metadata from EZID
# @return [Ezid::Identifier] the identifier
# @raise [Ezid::Error]
def load_metadata
response = client.get_identifier_metadata(id)
- self.metadata = Metadata.new(response.metadata)
- self.state = :persisted
+ # self.remote_metadata = Metadata.new(response.metadata)
+ remote_metadata.replace(response.metadata)
+ persists!
self
end
# Empties the (local) metadata (changes will be lost!)
# @return [Ezid::Identifier] the identifier
def reset
- clear_metadata
+ warn "[DEPRECATION] `reset` is deprecated and will be removed in 2.0. Use `reset_metadata` instead. (called from #{caller.first})"
+ reset_metadata
self
end
# Deletes the identifier from EZID
# @see http://ezid.cdlib.org/doc/apidoc.html#operation-delete-identifier
# @return [Ezid::Identifier] the identifier
# @raise [Ezid::Error]
def delete
raise Error, "Only persisted, reserved identifiers may be deleted: #{inspect}." unless deletable?
client.delete_identifier(id)
- self.state = :deleted
- reset
+ reset_metadata
+ self.deleted = true
+ self.persisted = false
+ self
end
# Is the identifier reserved?
# @return [Boolean]
def reserved?
@@ -188,28 +269,38 @@
# @return [String] the new status
def public!
self.status = Status::PUBLIC
end
+ def client
+ @client ||= Client.new
+ end
+
+ def reset_metadata
+ metadata.clear unless metadata.empty?
+ remote_metadata.clear unless remote_metadata.empty?
+ end
+
protected
- def method_missing(method, *args)
- metadata.send(method, *args)
+ def method_missing(*args)
+ local_or_remote_metadata(*args)
rescue NoMethodError
super
end
private
- def stale?
- persisted? && metadata(false).empty?
+ def local_or_remote_metadata(*args)
+ value = metadata.send(*args)
+ if value.nil? && persisted?
+ load_metadata if remote_metadata.empty?
+ value = remote_metadata.send(*args)
+ end
+ value
end
- def clear_metadata
- metadata(false).clear
- end
-
def modify
client.modify_identifier(id, metadata)
end
def create_or_mint
@@ -225,10 +316,18 @@
client.create_identifier(id, metadata)
end
def persist
persisted? ? modify : create_or_mint
- self.state = :persisted
+ persists!
+ end
+
+ def persists!
+ self.persisted = true
+ end
+
+ def apply_default_metadata
+ update_metadata(self.class.defaults)
end
end
end