Skip to content

Commit 3ad25b6

Browse files
committed
Making metadataPrefix a required argument.
Like it or not, the OAI-PMH spec states that metadataPrefix cannot be left out of GetRecord or ListRecords requests. ie. http://www.openarchives.org/OAI/openarchivesprotocol.html#GetRecord http://www.openarchives.org/OAI/openarchivesprotocol.html#ListRecords
1 parent 1354522 commit 3ad25b6

13 files changed

+250
-163
lines changed

lib/oai/provider/response.rb

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,29 @@
22
module OAI
33
module Provider
44
module Response
5-
5+
66
class Base
77
attr_reader :provider, :options
8-
8+
99
class << self
1010
attr_reader :valid_options, :default_options, :required_options
1111
def valid_parameters(*args)
1212
@valid_options ||= []
1313
@valid_options = (@valid_options + args.dup).uniq
1414
end
15-
15+
1616
def default_parameters(options = {})
1717
@default_options ||= {}
1818
@default_options.merge! options.dup
1919
end
20-
20+
2121
def required_parameters(*args)
2222
valid_parameters(*args)
2323
@required_options ||= []
2424
@required_options = (@required_options + args.dup).uniq
2525
end
26-
27-
end
26+
27+
end
2828
def initialize(provider, options = {})
2929
@provider = provider
3030
@options = internalize(options)
@@ -33,19 +33,19 @@ def initialize(provider, options = {})
3333
def response
3434
@builder = Builder::XmlMarkup.new
3535
@builder.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
36-
@builder.tag!('OAI-PMH', header) do
36+
@builder.tag!('OAI-PMH', header) do
3737
@builder.responseDate Time.now.utc.xmlschema
3838
#options parameter has been removed here because with it
39-
#the data won't validate against oai validators. Without, it
40-
#validates.
41-
@builder.request(provider.url) #-- OAI 2.0 Hack - removed request options
39+
#the data won't validate against oai validators. Without, it
40+
#validates.
41+
@builder.request(provider.url) #-- OAI 2.0 Hack - removed request options
4242
yield @builder
4343
end
4444
end
4545
private
46-
46+
4747
def header
48-
{
48+
{
4949
'xmlns' => "http://www.openarchives.org/OAI/2.0/",
5050
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
5151
'xsi:schemaLocation' => %{http://www.openarchives.org/OAI/2.0/
@@ -55,66 +55,66 @@ def header
5555
def extract_identifier(id)
5656
id.sub("#{provider.prefix}/", '')
5757
end
58-
58+
5959
def valid?
6060
return true if resumption?
61-
61+
6262
return true if self.class.valid_options.nil? and options.empty?
63-
64-
# check if the request includes an argument and there are no valid
63+
64+
# check if the request includes an argument and there are no valid
6565
# arguments for that verb (Identify, for example).
6666
raise OAI::ArgumentException.new if self.class.valid_options.nil? && !options.empty?
67-
67+
6868
if self.class.required_options
6969
return false unless (self.class.required_options - @options.keys).empty?
7070
end
7171
return false unless (@options.keys - self.class.valid_options).empty?
7272
populate_defaults
7373
end
74-
74+
7575
def populate_defaults
7676
self.class.default_options.each do |k,v|
7777
@options[k] = v.respond_to?(:call) ? v.call(self) : v if not @options[k]
7878
end
7979
end
80-
80+
8181
def resumption?
82-
if @options.keys.include?(:resumption_token)
82+
if @options.keys.include?(:resumption_token)
8383
return true if 1 == @options.keys.size
8484
raise OAI::ArgumentException.new
8585
end
8686
end
87-
87+
8888
# Convert our internal representations back into standard OAI options
8989
def externalize(value)
9090
value.to_s.gsub(/_[a-z]/) { |m| m.sub("_", '').capitalize }
9191
end
92-
92+
9393
def parse_date(value)
9494
return value if value.respond_to?(:strftime)
95-
95+
9696
Date.parse(value) # This will raise an exception for badly formatted dates
9797
Time.parse(value).utc # -- UTC Bug fix hack 8/08 not in core
9898
rescue
99-
raise OAI::ArgumentError.new
99+
raise OAI::ArgumentError.new
100100
end
101-
101+
102102
def internalize(hash = {})
103103
internal = {}
104104
hash.keys.each do |key|
105105
internal[key.to_s.gsub(/([A-Z])/, '_\1').downcase.intern] = hash[key].dup
106106
end
107-
107+
108108
# Convert date formated strings into internal time values
109109
# Convert date formated strings in dates.
110110
internal[:from] = parse_date(internal[:from]) if internal[:from]
111111
internal[:until] = parse_date(internal[:until]) if internal[:until]
112-
112+
113113
internal
114114
end
115-
115+
116116
end
117-
117+
118118
end
119119
end
120120
end
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
module OAI::Provider::Response
2-
2+
33
class GetRecord < RecordResponse
4-
required_parameters :identifier
5-
4+
required_parameters :identifier, :metadata_prefix
5+
66
def to_xml
77
id = extract_identifier(options.delete(:identifier))
88
unless record = provider.model.find(id, options)
@@ -11,17 +11,17 @@ def to_xml
1111

1212
response do |r|
1313
r.GetRecord do
14-
r.record do
14+
r.record do
1515
header_for record
1616
data_for record unless deleted?(record)
1717
about_for record unless deleted?(record)
1818
end
1919
end
2020
end
2121
end
22-
22+
2323
end
2424

2525
end
26-
27-
26+
27+

lib/oai/provider/response/list_records.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module OAI::Provider::Response
22

33
class ListRecords < RecordResponse
4-
4+
required_parameters :metadata_prefix
5+
56
def to_xml
67
result = provider.model.find(:all, options)
78
# result may be an array of records, or a partial result
@@ -27,8 +28,8 @@ def to_xml
2728
end
2829
end
2930
end
30-
31+
3132
end
32-
33+
3334
end
34-
35+

lib/oai/provider/response/record_response.rb

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ module OAI::Provider::Response
22
class RecordResponse < Base
33
def self.inherited(klass)
44
klass.valid_parameters :metadata_prefix, :from, :until, :set
5-
klass.default_parameters :metadata_prefix => "oai_dc",
5+
klass.default_parameters :metadata_prefix => "oai_dc",
66
:from => Proc.new {|x| Time.parse(x.provider.model.earliest.to_s) }, #-- OAI 2.0 hack - UTC
77
:until => Proc.new {|x| Time.parse(x.provider.model.latest.to_s) } #-- OAI 2.0 hack - UTC
88
end
9-
9+
1010
# emit record header
1111
def header_for(record)
1212
param = Hash.new
1313
param[:status] = 'deleted' if deleted?(record)
14-
@builder.header param do
14+
@builder.header param do
1515
@builder.identifier identifier_for(record)
1616
@builder.datestamp timestamp_for(record)
1717
sets_for(record).each do |set|
@@ -33,7 +33,7 @@ def about_for(record)
3333
return unless provider.model.respond_to? :about
3434

3535
about = provider.model.about(record)
36-
return if about.nil?
36+
return if about.nil?
3737

3838
unless about.is_a? Array
3939
about = [about]
@@ -42,43 +42,43 @@ def about_for(record)
4242
about.each do |a|
4343
@builder.about do
4444
@builder.target! << a
45-
end
45+
end
4646
end
4747
end
48-
48+
4949
private
50-
50+
5151
def identifier_for(record)
5252
"#{provider.prefix}/#{record.id}"
5353
end
54-
54+
5555
def timestamp_for(record)
5656
record.send(provider.model.timestamp_field).utc.xmlschema
5757
end
58-
58+
5959
def sets_for(record)
6060
return [] unless record.respond_to?(:sets) and record.sets
6161
record.sets.respond_to?(:each) ? record.sets : [record.sets]
6262
end
63-
63+
6464
def requested_format
65-
format =
65+
format =
6666
if options[:metadata_prefix]
6767
options[:metadata_prefix]
6868
elsif options[:resumption_token]
6969
OAI::Provider::ResumptionToken.extract_format(options[:resumption_token])
7070
end
7171
raise OAI::FormatException.new unless provider.format_supported?(format)
72-
72+
7373
format
7474
end
75-
75+
7676
def deleted?(record)
7777
return record.deleted? if record.respond_to?(:deleted?)
7878
return record.deleted if record.respond_to?(:deleted)
7979
return record.deleted_at if record.respond_to?(:deleted_at)
8080
false
8181
end
82-
82+
8383
end
8484
end

test/activerecord_provider/tc_ar_provider.rb

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ def test_metadata_formats_for_record
2020
end
2121

2222
def test_list_records
23-
assert_nothing_raised { REXML::Document.new(@provider.list_records) }
24-
doc = REXML::Document.new(@provider.list_records)
23+
assert_nothing_raised do
24+
REXML::Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
25+
end
26+
doc = REXML::Document.new(@provider.list_records(
27+
:metadata_prefix => 'oai_dc'))
2528
assert_equal 100, doc.elements['OAI-PMH/ListRecords'].to_a.size
2629
end
2730

@@ -33,16 +36,21 @@ def test_list_identifiers
3336

3437
def test_get_record
3538
record_id = DCField.find(:first).id
36-
assert_nothing_raised { REXML::Document.new(@provider.get_record(:identifier => "oai:test/#{record_id}")) }
37-
doc = REXML::Document.new(@provider.get_record(:identifier => "#{record_id}"))
39+
assert_nothing_raised do
40+
REXML::Document.new(@provider.get_record(
41+
:identifier => "oai:test/#{record_id}", :metadata_prefix => 'oai_dc'))
42+
end
43+
doc = REXML::Document.new(@provider.get_record(
44+
:identifier => "#{record_id}", :metadata_prefix => 'oai_dc'))
3845
assert_equal "oai:test/#{record_id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
3946
end
4047

4148
def test_deleted
4249
record = DCField.find(:first)
4350
record.deleted = true;
4451
record.save
45-
doc = REXML::Document.new(@provider.get_record(:identifier => "oai:test/#{record.id}"))
52+
doc = REXML::Document.new(@provider.get_record(
53+
:identifier => "oai:test/#{record.id}", :metadata_prefix => 'oai_dc'))
4654
assert_equal "oai:test/#{record.id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
4755
assert_equal 'deleted', doc.elements['OAI-PMH/GetRecord/record/header'].attributes["status"]
4856
end
@@ -57,14 +65,16 @@ def test_from
5765
from_param = Time.parse("January 1 2006")
5866

5967
doc = REXML::Document.new(
60-
@provider.list_records(:from => from_param)
61-
)
68+
@provider.list_records(
69+
:metadata_prefix => 'oai_dc', :from => from_param)
70+
)
6271
assert_equal DCField.find(:all, :conditions => ["updated_at >= ?", from_param]).size,
6372
doc.elements['OAI-PMH/ListRecords'].size
6473

6574
doc = REXML::Document.new(
66-
@provider.list_records(:from => Time.parse("May 30 2005"))
67-
)
75+
@provider.list_records(
76+
:metadata_prefix => 'oai_dc', :from => Time.parse("May 30 2005"))
77+
)
6878
assert_equal 20, doc.elements['OAI-PMH/ListRecords'].to_a.size
6979
end
7080

@@ -74,8 +84,9 @@ def test_until
7484
"id < #{first_id + 10}")
7585

7686
doc = REXML::Document.new(
77-
@provider.list_records(:until => Time.parse("June 1 2005"))
78-
)
87+
@provider.list_records(
88+
:metadata_prefix => 'oai_dc', :until => Time.parse("June 1 2005"))
89+
)
7990
assert_equal 10, doc.elements['OAI-PMH/ListRecords'].to_a.size
8091
end
8192

@@ -88,7 +99,9 @@ def test_from_and_until
8899
"id < #{first_id + 10}")
89100

90101
doc = REXML::Document.new(
91-
@provider.list_records(:from => Time.parse("June 3 2005"),
102+
@provider.list_records(
103+
:metadata_prefix => 'oai_dc',
104+
:from => Time.parse("June 3 2005"),
92105
:until => Time.parse("June 16 2005"))
93106
)
94107
assert_equal 40, doc.elements['OAI-PMH/ListRecords'].to_a.size
@@ -101,12 +114,12 @@ def test_handles_empty_collections
101114
test_identify
102115
test_metadata_formats
103116
# ListIdentifiers and ListRecords should return "noRecordsMatch" error code
104-
assert_raises(OAI::NoMatchException) {
117+
assert_raises(OAI::NoMatchException) do
105118
REXML::Document.new(@provider.list_identifiers)
106-
}
107-
assert_raises(OAI::NoMatchException) {
108-
REXML::Document.new(@provider.list_records)
109-
}
119+
end
120+
assert_raises(OAI::NoMatchException) do
121+
REXML::Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
122+
end
110123
end
111124

112125
def setup

0 commit comments

Comments
 (0)