oai 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/README.md +28 -23
  2. data/Rakefile +14 -40
  3. data/examples/providers/dublin_core.rb +63 -63
  4. data/lib/oai/client.rb +131 -97
  5. data/lib/oai/client/list_identifiers.rb +1 -0
  6. data/lib/oai/client/list_records.rb +6 -5
  7. data/lib/oai/client/list_sets.rb +6 -5
  8. data/lib/oai/client/record.rb +6 -7
  9. data/lib/oai/client/response.rb +7 -4
  10. data/lib/oai/client/resumable.rb +42 -0
  11. data/lib/oai/harvester/shell.rb +40 -41
  12. data/lib/oai/provider.rb +85 -67
  13. data/lib/oai/provider/metadata_format/oai_dc.rb +5 -6
  14. data/lib/oai/provider/model/activerecord_caching_wrapper.rb +23 -25
  15. data/lib/oai/provider/model/activerecord_wrapper.rb +99 -51
  16. data/lib/oai/provider/response.rb +33 -31
  17. data/lib/oai/provider/response/get_record.rb +7 -7
  18. data/lib/oai/provider/response/list_records.rb +5 -4
  19. data/lib/oai/provider/response/record_response.rb +14 -14
  20. data/test/activerecord_provider/config/connection.rb +8 -4
  21. data/test/activerecord_provider/database/{ar_migration.rb → 0001_oaipmh_tables.rb} +17 -12
  22. data/test/activerecord_provider/helpers/providers.rb +2 -3
  23. data/test/activerecord_provider/helpers/set_provider.rb +10 -22
  24. data/test/activerecord_provider/helpers/transactional_test_case.rb +34 -0
  25. data/test/activerecord_provider/models/dc_field.rb +4 -4
  26. data/test/activerecord_provider/models/dc_set.rb +3 -2
  27. data/test/activerecord_provider/models/exclusive_set_dc_field.rb +11 -0
  28. data/test/activerecord_provider/tc_ar_provider.rb +67 -28
  29. data/test/activerecord_provider/tc_ar_sets_provider.rb +104 -18
  30. data/test/activerecord_provider/tc_caching_paging_provider.rb +6 -10
  31. data/test/activerecord_provider/tc_simple_paging_provider.rb +7 -11
  32. data/test/activerecord_provider/test_helper.rb +10 -0
  33. data/test/client/helpers/provider.rb +44 -47
  34. data/test/client/helpers/test_wrapper.rb +4 -16
  35. data/test/client/tc_http_client.rb +90 -2
  36. data/test/client/tc_list_identifiers.rb +22 -3
  37. data/test/client/tc_list_records.rb +17 -4
  38. data/test/client/tc_list_sets.rb +17 -2
  39. data/test/provider/models.rb +32 -30
  40. data/test/provider/tc_exceptions.rb +30 -20
  41. data/test/provider/tc_functional_tokens.rb +11 -6
  42. data/test/provider/tc_provider.rb +58 -24
  43. data/test/provider/tc_resumption_tokens.rb +6 -6
  44. data/test/provider/tc_simple_provider.rb +51 -26
  45. data/test/provider/test_helper.rb +7 -0
  46. metadata +67 -128
  47. data/test/activerecord_provider/config/database.yml +0 -6
  48. data/test/activerecord_provider/database/oaipmhtest +0 -0
@@ -1,7 +1,9 @@
1
1
  module OAI
2
2
 
3
- # An OAI::Response contains entries and a resumption token. If a resumption token is present,
3
+ # An OAI::Response contains entries and a resumption token. If a resumption token is present,
4
4
  # then you must use it to fetch the rest of the entries for your query. For example:
5
+ #
6
+ # ```ruby
5
7
  # # List all records in a given set
6
8
  # client = OAI::Client.new 'http://my-oai-provider.example.com/oai'
7
9
  # response = client.list_records :set => 'my_set_name'
@@ -13,14 +15,15 @@ module OAI
13
15
  # # Note: You do not need to pass the options hash again, just the verb and the resumption token
14
16
  # response = client.list_records :resumption_token => token if token
15
17
  # end
16
-
18
+ # ```
17
19
  class Response
18
20
  include OAI::XPath
19
- attr_reader :doc, :resumption_token
21
+ attr_reader :doc, :resumption_token, :resumption_block
20
22
 
21
- def initialize(doc)
23
+ def initialize(doc, &resumption_block)
22
24
  @doc = doc
23
25
  @resumption_token = xpath(doc, './/resumptionToken')
26
+ @resumption_block = resumption_block
24
27
 
25
28
  # throw an exception if there was an error
26
29
  error = xpath_first(doc, './/error')
@@ -0,0 +1,42 @@
1
+ module OAI
2
+ module Resumable
3
+
4
+ class ResumptionWrapper
5
+ include Enumerable
6
+
7
+ def initialize(response)
8
+ @response = response
9
+ @resumption_block = response.resumption_block
10
+ end
11
+
12
+ def each(&block)
13
+ yield_from_response &block
14
+ while resumable?
15
+ @response = @resumption_block.call @response
16
+ yield_from_response &block
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def yield_from_response(&block)
23
+ @response.each do |obj|
24
+ block.call(obj)
25
+ end
26
+ end
27
+
28
+ def resumable?
29
+ @response.resumption_token and not @response.resumption_token.empty?
30
+ end
31
+
32
+ end
33
+
34
+ def full
35
+ if @resumption_block.nil?
36
+ raise NotImplementedError.new("Resumption block not provided")
37
+ end
38
+ ResumptionWrapper.new(self)
39
+ end
40
+
41
+ end
42
+ end
@@ -1,13 +1,12 @@
1
1
  module OAI
2
2
  module Harvester
3
- # = OAI::Harvester::Shell
4
- #
5
3
  # A OAI-PMH client shell allowing OAI Harvesting to be configured in
6
- # an interactive manner. Typing 'oai' on the command line starts the
4
+ # an interactive manner. Typing `oai` on the command line starts the
7
5
  # shell. The first time the shell is run it will prompt for the following
8
6
  # configuration details:
9
- # 1. A storage directory for all harvested records. Harvests will be
10
- # stored under this directory in a directory structure based on the
7
+ #
8
+ # 1. A storage directory for all harvested records. Harvests will be
9
+ # stored under this directory in a directory structure based on the
11
10
  # date of the harvest.
12
11
  # 2. A log file directory.
13
12
  # 3. Email address(es) for sending daily harvesting activity reports.
@@ -21,15 +20,15 @@ module OAI
21
20
  #
22
21
  # The shell automatically pulls down the list of sets in the repository, and
23
22
  # the supported metadata prefixes. Making it very simple to setup harvests.
24
- #
23
+ #
25
24
  class Shell
26
25
  include Readline
27
-
26
+
28
27
  def initialize(config)
29
28
  @conf = config
30
29
  @conf.sites ||= {} # Initialize sites hash there isn't one
31
30
  end
32
-
31
+
33
32
  def start
34
33
  unless @conf.storage
35
34
  banner "Entering first-time setup"
@@ -54,9 +53,9 @@ module OAI
54
53
  end
55
54
  end
56
55
  end
57
-
56
+
58
57
  private
59
-
58
+
60
59
  def help
61
60
  banner "Commands:"
62
61
  puts "\tharvest site [date] - Harvest site(s) manually"
@@ -68,7 +67,7 @@ module OAI
68
67
  puts "\tedit [site] - Change settings for a provider site"
69
68
  puts "\texit - Exit the harvester shell.\n\n"
70
69
  end
71
-
70
+
72
71
  def harvest(options)
73
72
  site, *date = options.split(/\s/)
74
73
  if @conf.sites.keys.include?(site)
@@ -80,7 +79,7 @@ module OAI
80
79
  puts "Couldn't parse the date supplied"
81
80
  return
82
81
  end
83
- else
82
+ else
84
83
  date = nil
85
84
  end
86
85
  harvester = Harvest.new(@conf, @conf.storage, date)
@@ -91,7 +90,7 @@ module OAI
91
90
  end
92
91
  puts # blank line
93
92
  end
94
-
93
+
95
94
  def list(args = nil)
96
95
  if 'config' == args
97
96
  banner "Current Configuration"
@@ -104,7 +103,7 @@ module OAI
104
103
  end
105
104
  puts # blank line
106
105
  end
107
-
106
+
108
107
  def info(args)
109
108
  banner "Provider Site Information"
110
109
  sites = args.split(/[,\s|\s|,]/)
@@ -115,21 +114,21 @@ module OAI
115
114
  rescue
116
115
  puts args + " doesn't appear to be configured, use list to see configured repositories."
117
116
  end
118
-
117
+
119
118
  def new
120
119
  banner "Define New Harvesting Site"
121
120
  name, site = form
122
121
  @conf.sites[name] = site
123
122
  @conf.save
124
123
  end
125
-
124
+
126
125
  def edit(name)
127
126
  banner "Edit Harvesting Site"
128
127
  name, site = form(name)
129
128
  @conf.sites[name] = site
130
129
  @conf.save
131
130
  end
132
-
131
+
133
132
  def remove(site)
134
133
  if 'Y' == readline("Remove #{site}? (Y/N): ").upcase
135
134
  @conf.sites.delete(site)
@@ -149,14 +148,14 @@ module OAI
149
148
  end
150
149
  end
151
150
  site = @conf.sites[name] || {}
152
-
151
+
153
152
  # URL
154
153
  url = prompt("url", site['url'])
155
154
  while(not (site['url'] = verify(url)))
156
155
  puts "Trouble contacting provider, bad url?"
157
156
  url = prompt("url", site['url'])
158
157
  end
159
-
158
+
160
159
  # Metadata formats
161
160
  formats = metadata(site['url'])
162
161
  report "Repository supports [#{formats.join(', ')}] metadata formats."
@@ -187,15 +186,15 @@ module OAI
187
186
  puts "Must be daily, weekly, or monthly"
188
187
  period = expand_period(prompt("period", "daily"))
189
188
  end
190
-
189
+
191
190
  site['period'] = period
192
-
191
+
193
192
  return [name, site]
194
- rescue
193
+ rescue
195
194
  puts "Problem adding/updating provider, aborting. (#{$!})"
196
195
  end
197
196
  end
198
-
197
+
199
198
  def config
200
199
  begin
201
200
  directory = prompt("storage directory", @conf.storage)
@@ -205,7 +204,7 @@ module OAI
205
204
 
206
205
  email = @conf.email.join(', ') rescue nil
207
206
  @conf.email = parse_emails(prompt("email", email))
208
-
207
+
209
208
  @conf.mail_server = prompt("mail server", @conf.mail_server)
210
209
 
211
210
  logfile = prompt("log file(s) directory", @conf.logfile)
@@ -215,22 +214,22 @@ module OAI
215
214
  @conf.storage = directory
216
215
  @conf.logfile = logfile
217
216
  @conf.save
218
- rescue
217
+ rescue
219
218
  nil
220
219
  end
221
220
  end
222
-
221
+
223
222
  def display(key, value, split = 40)
224
223
  (split - key.size).times { print " " } if key.size < split
225
224
  puts "#{key}: #{value}"
226
225
  end
227
-
226
+
228
227
  def banner(str)
229
228
  puts "\n#{str}"
230
229
  str.size.times { print "-" }
231
230
  puts "\n"
232
231
  end
233
-
232
+
234
233
  def report(str)
235
234
  puts "\n#{str}\n"
236
235
  end
@@ -240,7 +239,7 @@ module OAI
240
239
  print "\t"
241
240
  end
242
241
  end
243
-
242
+
244
243
  def prompt(text, default = nil, split = 20)
245
244
  prompt_text = "#{text} [#{default}]: "
246
245
  (split - prompt_text.size).times { print " " } if prompt_text.size < split
@@ -248,7 +247,7 @@ module OAI
248
247
  raise RuntimeError.new("Exit loop") unless value
249
248
  return value.empty? ? default : value
250
249
  end
251
-
250
+
252
251
  def verify(url)
253
252
  begin
254
253
  client = OAI::Client.new(url, :redirects => false)
@@ -264,7 +263,7 @@ module OAI
264
263
  end
265
264
  end
266
265
  end
267
-
266
+
268
267
  def metadata(url)
269
268
  formats = []
270
269
  client = OAI::Client.new url
@@ -274,7 +273,7 @@ module OAI
274
273
  end
275
274
  formats
276
275
  end
277
-
276
+
278
277
  def sets(url)
279
278
  sets = []
280
279
  client = OAI::Client.new url
@@ -292,35 +291,35 @@ module OAI
292
291
  end
293
292
  true
294
293
  end
295
-
294
+
296
295
  def expand_period(str)
297
296
  return str if Config::PERIODS.include?(str)
298
297
  Config::PERIODS.each { |p| return p if p =~ /^#{str}/}
299
298
  nil
300
299
  end
301
-
300
+
302
301
  def parse_emails(emails)
303
302
  return nil unless emails
304
303
  addresses = emails.split(/[,\s|\s|,]/)
305
304
  end
306
-
305
+
307
306
  def list_config
308
307
  display("storage directory", @conf.storage, 20)
309
308
  display("email", @conf.email.join(', '), 20) if @conf.email
310
309
  display("mail server", @conf.mail_server, 20) if @conf.mail_server
311
310
  display("log location", @conf.logfile, 20) if @conf.logfile
312
311
  end
313
-
312
+
314
313
  def list_sites
315
314
  banner "Sites"
316
315
  @conf.sites.each_key { |site| print_site(site) }
317
316
  end
318
-
317
+
319
318
  def print_site(site)
320
319
  puts site
321
320
  @conf.sites[site].each { |k,v| display(k, v, 15)}
322
321
  end
323
-
322
+
324
323
  def setup_cron
325
324
  banner "Scheduling Automatic Harvesting"
326
325
  puts "To activate automatic harvesting you must add an entry to"
@@ -330,9 +329,9 @@ module OAI
330
329
  puts "Windows users should use WinAt to schedule"
331
330
  puts "#{$0} to run every night.\n\n\n"
332
331
  end
333
-
332
+
334
333
  end
335
334
 
336
335
  end
337
- end
338
-
336
+ end
337
+
@@ -11,21 +11,21 @@ end
11
11
 
12
12
  %w{ response metadata_format resumption_token model partial_result
13
13
  response/record_response response/identify response/get_record
14
- response/list_identifiers response/list_records
14
+ response/list_identifiers response/list_records
15
15
  response/list_metadata_formats response/list_sets response/error
16
16
  }.each { |lib| require File.dirname(__FILE__) + "/provider/#{lib}" }
17
-
17
+
18
18
  if defined?(ActiveRecord)
19
19
  require File.dirname(__FILE__) + "/provider/model/activerecord_wrapper"
20
20
  require File.dirname(__FILE__) + "/provider/model/activerecord_caching_wrapper"
21
21
  end
22
22
 
23
- # = OAI::Provider
23
+ # # OAI::Provider
24
24
  #
25
- # Open Archives Initiative - Protocol for Metadata Harvesting see
26
- # http://www.openarchives.org/
25
+ # Open Archives Initiative - Protocol for Metadata Harvesting see
26
+ # <http://www.openarchives.org/>
27
27
  #
28
- # == Features
28
+ # ## Features
29
29
  # * Easily setup a simple repository
30
30
  # * Simple integration with ActiveRecord
31
31
  # * Dublin Core metadata format included
@@ -33,13 +33,14 @@ end
33
33
  # * Adaptable to any data source
34
34
  # * Simple resumption token support
35
35
  #
36
- # == Usage
36
+ # ## Usage
37
37
  #
38
- # To create a functional provider either subclass Provider::Base,
38
+ # To create a functional provider either subclass {OAI::Provider::Base},
39
39
  # or reconfigure the defaults.
40
- #
41
- # === Sub classing a provider
42
40
  #
41
+ # ### Sub classing a provider
42
+ #
43
+ # ```ruby
43
44
  # class MyProvider < Oai::Provider
44
45
  # repository_name 'My little OAI provider'
45
46
  # repository_url 'http://localhost/provider'
@@ -47,9 +48,11 @@ end
47
48
  # admin_email 'root@localhost' # String or Array
48
49
  # source_model MyModel.new # Subclass of OAI::Provider::Model
49
50
  # end
51
+ # ```
50
52
  #
51
- # === Configuring the default provider
53
+ # ### Configuring the default provider
52
54
  #
55
+ # ```ruby
53
56
  # class Oai::Provider::Base
54
57
  # repository_name 'My little OAI Provider'
55
58
  # repository_url 'http://localhost/provider'
@@ -58,23 +61,27 @@ end
58
61
  # sample_identifier 'oai:pubmedcentral.gov:13900'
59
62
  # source_model MyModel.new
60
63
  # end
64
+ # ```
61
65
  #
62
66
  # The provider does allow a URL to be passed in at request processing time
63
67
  # in case the repository URL cannot be determined ahead of time.
64
68
  #
65
- # == Integrating with frameworks
69
+ # ## Integrating with frameworks
66
70
  #
67
- # === Camping
71
+ # ### Camping
68
72
  #
69
73
  # In the Models module of your camping application post model definition:
70
- #
74
+ #
75
+ # ```ruby
71
76
  # class CampingProvider < OAI::Provider::Base
72
77
  # repository_name 'Camping Test OAI Repository'
73
78
  # source_model ActiveRecordWrapper.new(YOUR_ACTIVE_RECORD_MODEL)
74
79
  # end
80
+ # ```
75
81
  #
76
82
  # In the Controllers module:
77
83
  #
84
+ # ```ruby
78
85
  # class Oai
79
86
  # def get
80
87
  # @headers['Content-Type'] = 'text/xml'
@@ -82,15 +89,17 @@ end
82
89
  # provider.process_request(@input.merge(:url => "http:"+URL(Oai).to_s))
83
90
  # end
84
91
  # end
92
+ # ```
85
93
  #
86
94
  # The provider will be available at "/oai"
87
95
  #
88
- # === Rails
96
+ # ### Rails
89
97
  #
90
98
  # At the bottom of environment.rb create a OAI Provider:
91
99
  #
100
+ # ```ruby
92
101
  # # forgive the standard blog example.
93
- #
102
+ #
94
103
  # require 'oai'
95
104
  # class BlogProvider < OAI::Provider::Base
96
105
  # repository_name 'My little OAI Provider'
@@ -100,9 +109,11 @@ end
100
109
  # source_model OAI::Provider::ActiveRecordWrapper.new(Post)
101
110
  # sample_identifier 'oai:pubmedcentral.gov:13900'
102
111
  # end
112
+ # ```
103
113
  #
104
114
  # Create a custom controller:
105
115
  #
116
+ # ```ruby
106
117
  # class OaiController < ApplicationController
107
118
  # def index
108
119
  # # Remove controller and action from the options. Rails adds them automatically.
@@ -112,50 +123,54 @@ end
112
123
  # render :text => response, :content_type => 'text/xml'
113
124
  # end
114
125
  # end
126
+ # ```
115
127
  #
116
- # Special thanks to Jose Hales-Garcia for this solution.
128
+ # Special thanks to Jose Hales-Garcia for this solution.
117
129
  #
118
- # == Supporting custom metadata formats
130
+ # ## Supporting custom metadata formats
119
131
  #
120
- # See Oai::Metadata for details.
121
- #
122
- # == ActiveRecord Integration
132
+ # See {OAI::MetadataFormat} for details.
123
133
  #
124
- # ActiveRecord integration is provided by the ActiveRecordWrapper class.
134
+ # ## ActiveRecord Integration
135
+ #
136
+ # ActiveRecord integration is provided by the `ActiveRecordWrapper` class.
125
137
  # It takes one required paramater, the class name of the AR class to wrap,
126
138
  # and optional hash of options.
127
139
  #
128
140
  # Valid options include:
129
- # * timestamp_field - Specifies the model field to use as the update
130
- # filter. Defaults to 'updated_at'.
131
- # * limit - Maximum number of records to return in each page/set.
132
- # Defaults to 100. The wrapper will paginate the result via resumption tokens.
133
- # Caution: specifying too large a limit will adversely affect performance.
134
- #
141
+ #
142
+ # * `timestamp_field` - Specifies the model field to use as the update
143
+ # filter. Defaults to `updated_at`.
144
+ # * `limit` - Maximum number of records to return in each page/set.
145
+ # Defaults to 100.
146
+ # The wrapper will paginate the result via resumption tokens.
147
+ # _Caution: specifying too large a limit will adversely affect performance._
148
+ #
135
149
  # Mapping from a ActiveRecord object to a specific metadata format follows
136
150
  # this set of rules:
137
151
  #
138
- # 1. Does Model#to_{metadata_prefix} exist? If so just return the result.
139
- # 2. Does the model provide a map via Model.map_{metadata_prefix}? If so
152
+ # 1. Does `Model#to_{metadata_prefix}` exist? If so just return the result.
153
+ # 2. Does the model provide a map via `Model.map_{metadata_prefix}`? If so
140
154
  # use the map to generate the xml document.
141
155
  # 3. Loop thru the fields of the metadata format and check to see if the
142
156
  # model responds to either the plural, or singular of the field.
143
157
  #
144
158
  # For maximum control of the xml metadata generated, it's usually best to
145
- # provide a 'to_{metadata_prefix}' in the model. If using Builder be sure
146
- # not to include any instruct! in the xml object.
147
- #
148
- # === Explicit creation example
159
+ # provide a `to_{metadata_prefix}` in the model. If using Builder be sure
160
+ # not to include any `instruct!` in the xml object.
149
161
  #
162
+ # ### Explicit creation example
163
+ #
164
+ # ```ruby
150
165
  # class Post < ActiveRecord::Base
151
166
  # def to_oai_dc
152
167
  # xml = Builder::XmlMarkup.new
153
- # xml.tag!("oai_dc:dc",
168
+ # xml.tag!("oai_dc:dc",
154
169
  # 'xmlns:oai_dc' => "http://www.openarchives.org/OAI/2.0/oai_dc/",
155
170
  # 'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
156
171
  # 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
157
- # 'xsi:schemaLocation' =>
158
- # %{http://www.openarchives.org/OAI/2.0/oai_dc/
172
+ # 'xsi:schemaLocation' =>
173
+ # %{http://www.openarchives.org/OAI/2.0/oai_dc/
159
174
  # http://www.openarchives.org/OAI/2.0/oai_dc.xsd}) do
160
175
  # xml.tag!('oai_dc:title', title)
161
176
  # xml.tag!('oai_dc:description', text)
@@ -166,24 +181,27 @@ end
166
181
  # end
167
182
  # xml.target!
168
183
  # end
169
- # end
184
+ # end
185
+ # ```
170
186
  #
171
- # === Mapping Example
187
+ # ### Mapping Example
172
188
  #
189
+ # ```ruby
173
190
  # # Extremely contrived mapping
174
191
  # class Post < ActiveRecord::Base
175
192
  # def self.map_oai_dc
176
- # {:subject => :tags,
177
- # :description => :text,
178
- # :creator => :user,
193
+ # {:subject => :tags,
194
+ # :description => :text,
195
+ # :creator => :user,
179
196
  # :contibutor => :comments}
180
197
  # end
181
198
  # end
199
+ # ```
182
200
  #
183
201
  module OAI::Provider
184
202
  class Base
185
203
  include OAI::Provider
186
-
204
+
187
205
  class << self
188
206
  attr_reader :formats
189
207
  attr_accessor :name, :url, :prefix, :email, :delete_support, :granularity, :model, :identifier, :description
@@ -192,11 +210,11 @@ module OAI::Provider
192
210
  @formats ||= {}
193
211
  @formats[format.prefix] = format
194
212
  end
195
-
213
+
196
214
  def format_supported?(prefix)
197
215
  @formats.keys.include?(prefix)
198
216
  end
199
-
217
+
200
218
  def format(prefix)
201
219
  if @formats[prefix].nil?
202
220
  raise OAI::FormatException.new
@@ -205,8 +223,8 @@ module OAI::Provider
205
223
  end
206
224
  end
207
225
 
208
- protected
209
-
226
+ protected
227
+
210
228
  def inherited(klass)
211
229
  self.instance_variables.each do |iv|
212
230
  klass.instance_variable_set(iv, self.instance_variable_get(iv))
@@ -217,12 +235,12 @@ module OAI::Provider
217
235
  alias_method :repository_url, :url=
218
236
  alias_method :record_prefix, :prefix=
219
237
  alias_method :admin_email, :email=
220
- alias_method :deletion_support, :delete_support=
221
- alias_method :update_granularity, :granularity=
238
+ alias_method :deletion_support, :delete_support=
239
+ alias_method :update_granularity, :granularity=
222
240
  alias_method :source_model, :model=
223
241
  alias_method :sample_id, :identifier=
224
242
  alias_method :extra_description, :description=
225
-
243
+
226
244
  end
227
245
 
228
246
  # Default configuration of a repository
@@ -235,7 +253,7 @@ module OAI::Provider
235
253
  Base.sample_id '13900'
236
254
 
237
255
  Base.register_format(OAI::Provider::Metadata::DublinCore.instance)
238
-
256
+
239
257
  # Equivalent to '&verb=Identify', returns information about the repository
240
258
  def identify(options = {})
241
259
  Response::Identify.new(self.class, options).to_xml
@@ -246,33 +264,33 @@ module OAI::Provider
246
264
  def list_sets(options = {})
247
265
  Response::ListSets.new(self.class, options).to_xml
248
266
  end
249
-
267
+
250
268
  # Equivalent to '&verb=ListMetadataFormats', returns a list of metadata formats
251
269
  # supported by the repository.
252
270
  def list_metadata_formats(options = {})
253
271
  Response::ListMetadataFormats.new(self.class, options).to_xml
254
272
  end
255
273
 
256
- # Equivalent to '&verb=ListIdentifiers', returns a list of record headers that
274
+ # Equivalent to '&verb=ListIdentifiers', returns a list of record headers that
257
275
  # meet the supplied criteria.
258
276
  def list_identifiers(options = {})
259
277
  Response::ListIdentifiers.new(self.class, options).to_xml
260
278
  end
261
-
262
- # Equivalent to '&verb=ListRecords', returns a list of records that meet the
279
+
280
+ # Equivalent to '&verb=ListRecords', returns a list of records that meet the
263
281
  # supplied criteria.
264
282
  def list_records(options = {})
265
283
  Response::ListRecords.new(self.class, options).to_xml
266
284
  end
267
-
285
+
268
286
  # Equivalent to '&verb=GetRecord', returns a record matching the required
269
- # :identifier option
287
+ # :identifier option
270
288
  def get_record(options = {})
271
289
  Response::GetRecord.new(self.class, options).to_xml
272
290
  end
273
-
274
- # xml_response = process_verb('ListRecords', :from => 'October 1, 2005',
275
- # :until => 'November 1, 2005')
291
+
292
+ # xml_response = process_verb('ListRecords', :from => 'October 1, 2005',
293
+ # :until => 'November 1, 2005')
276
294
  #
277
295
  # If you are implementing a web interface using process_request is the
278
296
  # preferred way.
@@ -281,14 +299,14 @@ module OAI::Provider
281
299
 
282
300
  # Allow the request to pass in a url
283
301
  self.class.url = params['url'] ? params.delete('url') : self.class.url
284
-
302
+
285
303
  verb = params.delete('verb') || params.delete(:verb)
286
-
304
+
287
305
  unless verb and OAI::Const::VERBS.keys.include?(verb)
288
306
  raise OAI::VerbException.new
289
307
  end
290
-
291
- send(methodize(verb), params)
308
+
309
+ send(methodize(verb), params)
292
310
 
293
311
  rescue => err
294
312
  if err.respond_to?(:code)
@@ -298,12 +316,12 @@ module OAI::Provider
298
316
  end
299
317
  end
300
318
  end
301
-
319
+
302
320
  # Convert valid OAI-PMH verbs into ruby method calls
303
321
  def methodize(verb)
304
322
  verb.gsub(/[A-Z]/) {|m| "_#{m.downcase}"}.sub(/^\_/,'')
305
323
  end
306
-
324
+
307
325
  end
308
-
326
+
309
327
  end