ezid-client 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/VERSION +1 -1
- data/ezid-client.gemspec +2 -4
- data/lib/ezid/client.rb +1 -0
- data/lib/ezid/identifier.rb +6 -0
- data/lib/ezid/metadata.rb +158 -50
- data/lib/ezid/request.rb +1 -0
- data/lib/ezid/response.rb +1 -0
- data/lib/ezid/session.rb +1 -0
- data/lib/ezid/status.rb +6 -0
- data/spec/unit/identifier_spec.rb +21 -0
- data/spec/unit/metadata_spec.rb +14 -4
- metadata +6 -23
- data/lib/ezid/metadata_elements.rb +0 -145
- data/spec/unit/metadata_elements_spec.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 024d805940fcc9a0ccbe8ed0e6e80177d05393f6
|
4
|
+
data.tar.gz: e488fafa09132f630a2047cd4008fd653a9a221a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f32330825caf59ba03f3e7765226fe5f9aaef98877a12c9ac1396ac98a2511863f57f9b2619adea40d425b9b09ae5c97b311614d1b9e21a52ec4007217a9511
|
7
|
+
data.tar.gz: 4972d261b297f95f763499c92882fe1600238a3e5865bd510b41dc780ba33904f22b17f95fc1c87ff9aaeddfdb6e761b53c1159d9d011f920e7bfc7818a433e5
|
data/README.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/ezid-client.gemspec
CHANGED
@@ -19,9 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.required_ruby_version = "~> 2.0"
|
21
21
|
|
22
|
-
spec.
|
23
|
-
|
24
|
-
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
25
23
|
spec.add_development_dependency "rake"
|
26
|
-
spec.add_development_dependency "rspec", "~> 3.
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
27
25
|
end
|
data/lib/ezid/client.rb
CHANGED
data/lib/ezid/identifier.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
1
3
|
module Ezid
|
2
4
|
#
|
3
5
|
# Represents an EZID identifier as a resource.
|
@@ -5,10 +7,14 @@ module Ezid
|
|
5
7
|
# @api public
|
6
8
|
#
|
7
9
|
class Identifier
|
10
|
+
extend Forwardable
|
8
11
|
|
9
12
|
attr_reader :id, :client
|
10
13
|
attr_accessor :shoulder, :metadata
|
11
14
|
|
15
|
+
def_delegators :metadata, *(Metadata.elements.readers)
|
16
|
+
def_delegators :metadata, *(Metadata.elements.writers)
|
17
|
+
|
12
18
|
# Attributes to display on inspect
|
13
19
|
INSPECT_ATTRS = %w( id status target created )
|
14
20
|
|
data/lib/ezid/metadata.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
require "delegate"
|
2
|
-
|
2
|
+
require "singleton"
|
3
3
|
|
4
4
|
module Ezid
|
5
5
|
#
|
6
6
|
# EZID metadata collection for an identifier
|
7
7
|
#
|
8
|
+
# @note Although this API is not private, its direct use is discouraged.
|
9
|
+
# Instead use the metadata element accessors through Ezid::Identifier.
|
8
10
|
# @api public
|
9
11
|
#
|
10
12
|
class Metadata < SimpleDelegator
|
11
13
|
|
12
|
-
include MetadataElements
|
13
|
-
|
14
14
|
# EZID metadata field/value separator
|
15
15
|
ANVL_SEPARATOR = ": "
|
16
16
|
|
@@ -25,7 +25,7 @@ module Ezid
|
|
25
25
|
ESCAPE_NAMES_RE = /[%:\r\n]/
|
26
26
|
|
27
27
|
# Character sequence to unescape from EZID
|
28
|
-
# http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
28
|
+
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
29
29
|
UNESCAPE_RE = /%\h\h/
|
30
30
|
|
31
31
|
# A comment line
|
@@ -37,6 +37,99 @@ module Ezid
|
|
37
37
|
# A line ending
|
38
38
|
LINE_ENDING_RE = /\r?\n/
|
39
39
|
|
40
|
+
# A metadata element
|
41
|
+
Element = Struct.new(:name, :writer)
|
42
|
+
|
43
|
+
# Metadata profiles
|
44
|
+
PROFILES = {
|
45
|
+
"dc" => %w( creator title publisher date type ).freeze,
|
46
|
+
"datacite" => %w( creator title publisher publicationyear resourcetype ).freeze,
|
47
|
+
"erc" => %w( who what when ).freeze,
|
48
|
+
"crossref" => [].freeze
|
49
|
+
}.freeze
|
50
|
+
|
51
|
+
# EZID reserved metadata elements that have time values
|
52
|
+
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
53
|
+
RESERVED_TIME_ELEMENTS = %w( _created _updated )
|
54
|
+
|
55
|
+
# EZID reserved metadata elements that are read-only
|
56
|
+
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
57
|
+
RESERVED_READONLY_ELEMENTS = %w( _owner _ownergroup _shadows _shadowedby _datacenter _created _updated )
|
58
|
+
|
59
|
+
# EZID reserved metadata elements that may be set by clients
|
60
|
+
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
61
|
+
RESERVED_READWRITE_ELEMENTS = %w( _coowners _target _profile _status _export _crossref )
|
62
|
+
|
63
|
+
# All EZID reserved metadata elements
|
64
|
+
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
65
|
+
RESERVED_ELEMENTS = RESERVED_READONLY_ELEMENTS + RESERVED_READWRITE_ELEMENTS
|
66
|
+
|
67
|
+
# Metadata element registry
|
68
|
+
class ElementRegistry < SimpleDelegator
|
69
|
+
include Singleton
|
70
|
+
|
71
|
+
def initialize
|
72
|
+
super(Hash.new)
|
73
|
+
end
|
74
|
+
|
75
|
+
def readers
|
76
|
+
keys
|
77
|
+
end
|
78
|
+
|
79
|
+
def writers
|
80
|
+
keys.select { |k| self[k].writer }.map(&:to_s).map { |k| k.concat("=") }.map(&:to_sym)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.initialize!
|
85
|
+
register_elements
|
86
|
+
define_element_accessors
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.elements
|
90
|
+
ElementRegistry.instance
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.register_elements
|
94
|
+
register_profile_elements
|
95
|
+
register_reserved_elements
|
96
|
+
elements.freeze
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.define_element_accessors
|
100
|
+
elements.each do |accessor, element|
|
101
|
+
define_method(accessor) { reader(element.name) }
|
102
|
+
|
103
|
+
if element.writer
|
104
|
+
define_method("#{accessor}=") { |value| writer(element.name, value) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.register_element(accessor, element, opts={})
|
110
|
+
writer = opts.fetch(:writer, true)
|
111
|
+
elements[accessor] = Element.new(element, writer).freeze
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.register_profile_elements
|
115
|
+
PROFILES.each do |profile, profile_elements|
|
116
|
+
profile_elements.each do |element|
|
117
|
+
register_element("#{profile}_#{element}".to_sym, "#{profile}.#{element}")
|
118
|
+
end
|
119
|
+
register_element(profile.to_sym, profile) unless profile == "dc"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.register_reserved_elements
|
124
|
+
RESERVED_ELEMENTS.each do |element|
|
125
|
+
accessor = ((element == "_crossref") ? element : element.sub("_", "")).to_sym
|
126
|
+
register_element(accessor, element, writer: RESERVED_READWRITE_ELEMENTS.include?(element))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
private_class_method :register_element, :register_elements, :register_reserved_elements,
|
131
|
+
:register_profile_elements, :define_element_accessors
|
132
|
+
|
40
133
|
def initialize(data={})
|
41
134
|
super(coerce(data))
|
42
135
|
end
|
@@ -56,59 +149,74 @@ module Ezid
|
|
56
149
|
|
57
150
|
private
|
58
151
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
152
|
+
def reader(element)
|
153
|
+
value = self[element]
|
154
|
+
if RESERVED_TIME_ELEMENTS.include?(element)
|
155
|
+
time = value.to_i
|
156
|
+
value = (time == 0) ? nil : Time.at(time).utc
|
157
|
+
end
|
158
|
+
value
|
159
|
+
end
|
65
160
|
|
66
|
-
|
67
|
-
|
68
|
-
hsh.each_with_object({}) do |(n, v), memo|
|
69
|
-
memo[escape_name(n)] = escape_value(v)
|
161
|
+
def writer(element, value)
|
162
|
+
self[element] = value
|
70
163
|
end
|
71
|
-
end
|
72
164
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
165
|
+
# Coerce data into a Hash of elements
|
166
|
+
def coerce(data)
|
167
|
+
data.to_h
|
168
|
+
rescue NoMethodError
|
169
|
+
coerce_string(data)
|
170
|
+
end
|
77
171
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
172
|
+
# Escape elements hash keys and values
|
173
|
+
def escape_elements(hsh)
|
174
|
+
hsh.each_with_object({}) do |(n, v), memo|
|
175
|
+
memo[escape_name(n)] = escape_value(v)
|
176
|
+
end
|
177
|
+
end
|
82
178
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
# @return [String] the escaped string
|
88
|
-
def escape(re, s)
|
89
|
-
s.gsub(re) { |m| URI.encode_www_form_component(m.force_encoding(Encoding::UTF_8)) }
|
90
|
-
end
|
179
|
+
# Escape an element name
|
180
|
+
def escape_name(n)
|
181
|
+
escape(ESCAPE_NAMES_RE, n)
|
182
|
+
end
|
91
183
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
184
|
+
# Escape an element value
|
185
|
+
def escape_value(v)
|
186
|
+
escape(ESCAPE_VALUES_RE, v)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Escape string for sending to EZID host
|
190
|
+
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
191
|
+
# @param re [Regexp] the regular expression to match for escaping
|
192
|
+
# @param s [String] the string to escape
|
193
|
+
# @return [String] the escaped string
|
194
|
+
def escape(re, s)
|
195
|
+
s.gsub(re) { |m| URI.encode_www_form_component(m.force_encoding(Encoding::UTF_8)) }
|
196
|
+
end
|
197
|
+
|
198
|
+
# Unescape value from EZID host (or other source)
|
199
|
+
# @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies
|
200
|
+
# @param value [String] the value to unescape
|
201
|
+
# @return [String] the unescaped value
|
202
|
+
def unescape(value)
|
203
|
+
value.gsub(UNESCAPE_RE) { |m| URI.decode_www_form_component(m) }
|
204
|
+
end
|
205
|
+
|
206
|
+
# Coerce a string of metadata (e.g., from EZID host) into a Hash
|
207
|
+
# @note EZID host does not send comments or line continuations.
|
208
|
+
# @param data [String] the string to coerce
|
209
|
+
# @return [Hash] the hash of coerced data
|
210
|
+
def coerce_string(data)
|
211
|
+
data.gsub!(COMMENT_RE, "")
|
212
|
+
data.gsub!(LINE_CONTINUATION_RE, " ")
|
213
|
+
data.split(LINE_ENDING_RE).each_with_object({}) do |line, memo|
|
214
|
+
element, value = line.split(ANVL_SEPARATOR, 2)
|
215
|
+
memo[unescape(element.strip)] = unescape(value.strip)
|
216
|
+
end
|
110
217
|
end
|
111
|
-
end
|
112
218
|
|
113
219
|
end
|
114
220
|
end
|
221
|
+
|
222
|
+
Ezid::Metadata.initialize!
|
data/lib/ezid/request.rb
CHANGED
data/lib/ezid/response.rb
CHANGED
data/lib/ezid/session.rb
CHANGED
data/lib/ezid/status.rb
CHANGED
@@ -183,5 +183,26 @@ module Ezid
|
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
|
+
describe "boolean status methods" do
|
187
|
+
context "when the status is 'public'" do
|
188
|
+
before { allow(subject.metadata).to receive(:status) { Identifier::PUBLIC } }
|
189
|
+
it { is_expected.to be_public }
|
190
|
+
it { is_expected.not_to be_reserved }
|
191
|
+
it { is_expected.not_to be_unavailable }
|
192
|
+
end
|
193
|
+
context "when the status is 'reserved'" do
|
194
|
+
before { allow(subject.metadata).to receive(:status) { Identifier::RESERVED } }
|
195
|
+
it { is_expected.not_to be_public }
|
196
|
+
it { is_expected.to be_reserved }
|
197
|
+
it { is_expected.not_to be_unavailable }
|
198
|
+
end
|
199
|
+
context "when the status is 'unavailable'" do
|
200
|
+
before { allow(subject.metadata).to receive(:status) { Identifier::UNAVAILABLE } }
|
201
|
+
it { is_expected.not_to be_public }
|
202
|
+
it { is_expected.not_to be_reserved }
|
203
|
+
it { is_expected.to be_unavailable }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
186
207
|
end
|
187
208
|
end
|
data/spec/unit/metadata_spec.rb
CHANGED
@@ -3,11 +3,11 @@ module Ezid
|
|
3
3
|
|
4
4
|
describe "reserved elements" do
|
5
5
|
describe "readers" do
|
6
|
-
Metadata::RESERVED_ELEMENTS.each do |element|
|
7
|
-
next if element == "_crossref"
|
6
|
+
Metadata::RESERVED_ELEMENTS.each do |element|
|
8
7
|
it "should have a reader for '#{element}'" do
|
9
8
|
expect(subject).to receive(:reader).with(element)
|
10
|
-
|
9
|
+
reader = (element == "_crossref") ? element : element.sub("_", "")
|
10
|
+
subject.send(reader)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
describe "for time-based elements" do
|
@@ -27,7 +27,8 @@ module Ezid
|
|
27
27
|
next if element == "_crossref"
|
28
28
|
it "should have a writer for '#{element}'" do
|
29
29
|
expect(subject).to receive(:writer).with(element, "value")
|
30
|
-
|
30
|
+
writer = ((element == "_crossref") ? element : element.sub("_", "")).concat("=")
|
31
|
+
subject.send(writer, "value")
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -51,6 +52,15 @@ module Ezid
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
55
|
+
next if profile == "dc"
|
56
|
+
it "should have a reader for '#{profile}'" do
|
57
|
+
expect(subject).to receive(:reader).with(profile)
|
58
|
+
subject.send(profile)
|
59
|
+
end
|
60
|
+
it "should have a writer for '#{profile}'" do
|
61
|
+
expect(subject).to receive(:writer).with(profile, "value")
|
62
|
+
subject.send("#{profile}=", "value")
|
63
|
+
end
|
54
64
|
end
|
55
65
|
end
|
56
66
|
end
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ezid-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chandek-Stark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '4.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '4.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
19
|
+
version: '1.7'
|
34
20
|
type: :development
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
24
|
- - "~>"
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
26
|
+
version: '1.7'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +44,14 @@ dependencies:
|
|
58
44
|
requirements:
|
59
45
|
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: '3.
|
47
|
+
version: '3.1'
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: '3.
|
54
|
+
version: '3.1'
|
69
55
|
description: Ruby client for EZID API Version 2 (http://ezid.cdlib.org/doc/apidoc.html)
|
70
56
|
email:
|
71
57
|
- dchandekstark@gmail.com
|
@@ -88,7 +74,6 @@ files:
|
|
88
74
|
- lib/ezid/error.rb
|
89
75
|
- lib/ezid/identifier.rb
|
90
76
|
- lib/ezid/metadata.rb
|
91
|
-
- lib/ezid/metadata_elements.rb
|
92
77
|
- lib/ezid/request.rb
|
93
78
|
- lib/ezid/response.rb
|
94
79
|
- lib/ezid/session.rb
|
@@ -98,7 +83,6 @@ files:
|
|
98
83
|
- spec/spec_helper.rb
|
99
84
|
- spec/unit/client_spec.rb
|
100
85
|
- spec/unit/identifier_spec.rb
|
101
|
-
- spec/unit/metadata_elements_spec.rb
|
102
86
|
- spec/unit/metadata_spec.rb
|
103
87
|
homepage: https://github.com/duke-libraries/ezid-client
|
104
88
|
licenses:
|
@@ -130,5 +114,4 @@ test_files:
|
|
130
114
|
- spec/spec_helper.rb
|
131
115
|
- spec/unit/client_spec.rb
|
132
116
|
- spec/unit/identifier_spec.rb
|
133
|
-
- spec/unit/metadata_elements_spec.rb
|
134
117
|
- spec/unit/metadata_spec.rb
|
@@ -1,145 +0,0 @@
|
|
1
|
-
require "active_support"
|
2
|
-
|
3
|
-
module Ezid
|
4
|
-
#
|
5
|
-
# EZID metadata elements
|
6
|
-
#
|
7
|
-
# @note Intended to be used only as included in Ezid::Metadata.
|
8
|
-
#
|
9
|
-
module MetadataElements
|
10
|
-
extend ActiveSupport::Concern
|
11
|
-
|
12
|
-
# Metadata profiles
|
13
|
-
PROFILES = {
|
14
|
-
"dc" => %w( creator title publisher date type ).freeze,
|
15
|
-
"datacite" => %w( creator title publisher publicationyear resourcetype ).freeze,
|
16
|
-
"erc" => %w( who what when ).freeze,
|
17
|
-
"crossref" => [].freeze
|
18
|
-
}
|
19
|
-
|
20
|
-
# Elements for metadata profiles (values may include multiple elements)
|
21
|
-
PROFILE_ELEMENTS = PROFILES.keys - ["dc"]
|
22
|
-
|
23
|
-
# EZID reserved metadata elements that have time values
|
24
|
-
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
25
|
-
RESERVED_TIME_ELEMENTS = %w( _created _updated )
|
26
|
-
|
27
|
-
# EZID reserved metadata elements that are read-only
|
28
|
-
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
29
|
-
RESERVED_READONLY_ELEMENTS = %w( _owner _ownergroup _shadows _shadowedby _datacenter _created _updated )
|
30
|
-
|
31
|
-
# EZID reserved metadata elements that may be set by clients
|
32
|
-
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
33
|
-
RESERVED_READWRITE_ELEMENTS = %w( _coowners _target _profile _status _export _crossref )
|
34
|
-
|
35
|
-
# All EZID reserved metadata elements
|
36
|
-
# @see http://ezid.cdlib.org/doc/apidoc.html#internal-metadata
|
37
|
-
RESERVED_ELEMENTS = RESERVED_READONLY_ELEMENTS + RESERVED_READWRITE_ELEMENTS + RESERVED_TIME_ELEMENTS
|
38
|
-
|
39
|
-
included do
|
40
|
-
# "_crossref" does not get a reserved accessor because of the "crossref" element.
|
41
|
-
reserved_element_accessor *(RESERVED_READWRITE_ELEMENTS - ["_crossref"])
|
42
|
-
reserved_element_reader *(RESERVED_READONLY_ELEMENTS - RESERVED_TIME_ELEMENTS)
|
43
|
-
reserved_element_time_reader *RESERVED_TIME_ELEMENTS
|
44
|
-
|
45
|
-
profile_element_accessors
|
46
|
-
|
47
|
-
element_accessor *PROFILE_ELEMENTS
|
48
|
-
|
49
|
-
# "_crossref" does not get a reserved accessor because of the "crossref" element.
|
50
|
-
element_accessor "_crossref"
|
51
|
-
end
|
52
|
-
|
53
|
-
module ClassMethods
|
54
|
-
# Creates an accessor for each reserved element
|
55
|
-
# @see .reserved_element_reader
|
56
|
-
# @see .reserved_element_writer
|
57
|
-
# @param elements [Array<String>] a list of elements
|
58
|
-
def reserved_element_accessor(*elements)
|
59
|
-
reserved_element_reader(*elements)
|
60
|
-
reserved_element_writer(*elements)
|
61
|
-
end
|
62
|
-
|
63
|
-
# Creates a reader for each reserved element
|
64
|
-
# The leading underscore of the element is removed from the reader name
|
65
|
-
# -- e.g.
|
66
|
-
#
|
67
|
-
# def status
|
68
|
-
# reader("_status")
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# @param elements [Array<String>] a list of elements
|
72
|
-
def reserved_element_reader(*elements)
|
73
|
-
elements.each do |element|
|
74
|
-
define_method(element.sub("_", "")) { reader(element) }
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Creates a reader for each time-based reserved element
|
79
|
-
# The reader will return a Time instance for the value (or nil if not present)
|
80
|
-
# @see .reserved_element_reader
|
81
|
-
# @param elements [Array<String>] a list of elements
|
82
|
-
def reserved_element_time_reader(*elements)
|
83
|
-
elements.each do |element|
|
84
|
-
define_method(element.sub("_", "")) do
|
85
|
-
time = reader(element).to_i
|
86
|
-
return nil if time == 0 # value is nil or empty string
|
87
|
-
Time.at(time).utc
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# Creates a writer for each reserved element
|
93
|
-
# The leading underscore of the element is removed from the reader name
|
94
|
-
# -- e.g.
|
95
|
-
#
|
96
|
-
# def status=(value)
|
97
|
-
# writer("_status", value)
|
98
|
-
# end
|
99
|
-
#
|
100
|
-
# @param elements [Array<String>] a list of elements
|
101
|
-
def reserved_element_writer(*elements)
|
102
|
-
elements.each do |element|
|
103
|
-
define_method("#{element.sub('_', '')}=") do |value|
|
104
|
-
writer(element, value)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Creates a accessors for all metadata profile elements
|
110
|
-
def profile_element_accessors
|
111
|
-
PROFILES.each do |profile, elements|
|
112
|
-
elements.each do |element|
|
113
|
-
define_method("#{profile}_#{element}") do
|
114
|
-
reader("#{profile}.#{element}")
|
115
|
-
end
|
116
|
-
|
117
|
-
define_method("#{profile}_#{element}=") do |value|
|
118
|
-
writer("#{profile}.#{element}", value)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# Creates an accessor for each element
|
125
|
-
# @param elements [Array<String>] a list of elements
|
126
|
-
def element_accessor(*elements)
|
127
|
-
elements.each do |element|
|
128
|
-
define_method(element) { reader(element) }
|
129
|
-
define_method("#{element}=") { |value| writer(element, value) }
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
def reader(element)
|
137
|
-
self[element]
|
138
|
-
end
|
139
|
-
|
140
|
-
def writer(element, value)
|
141
|
-
self[element] = value
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
145
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require "delegate"
|
2
|
-
|
3
|
-
module Ezid
|
4
|
-
RSpec.describe MetadataElements do
|
5
|
-
|
6
|
-
before do
|
7
|
-
class TestMetadata < SimpleDelegator
|
8
|
-
def initialize
|
9
|
-
super(Hash.new)
|
10
|
-
end
|
11
|
-
include MetadataElements
|
12
|
-
end
|
13
|
-
end
|
14
|
-
after do
|
15
|
-
Ezid.remove_const(:TestMetadata)
|
16
|
-
end
|
17
|
-
|
18
|
-
describe "reserved reader" do
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "reserved writer" do
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "reserved time reader" do
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "reserved accessor" do
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "profile accessor" do
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "element accessor" do
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|