Skip to content

Commit 379d650

Browse files
committed
Merge pull request #73 from barmintor/rubydora-72
rubydora-72: Make use of ds profiles on create and update
2 parents 9fb5f35 + 39d7a65 commit 379d650

File tree

7 files changed

+55
-17
lines changed

7 files changed

+55
-17
lines changed

lib/rubydora/datastream.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,9 @@ def current_version?
290290
def create
291291
check_if_read_only
292292
run_callbacks :create do
293-
repository.add_datastream to_api_params.merge({ :pid => pid, :dsid => dsid, :content => content })
293+
p = repository.add_datastream( to_api_params.merge({ :pid => pid, :dsid => dsid, :content => content })) || {}
294294
reset_profile_attributes
295+
self.profile= p unless p.empty?
295296
self.class.new(digital_object, dsid, @options)
296297
end
297298
end
@@ -303,8 +304,9 @@ def save
303304
run_callbacks :save do
304305
raise RubydoraError.new("Unable to save #{self.inspect} without content") unless has_content?
305306
return create if new?
306-
repository.modify_datastream to_api_params.merge({ :pid => pid, :dsid => dsid })
307+
p = repository.modify_datastream(to_api_params.merge({ :pid => pid, :dsid => dsid })) || {}
307308
reset_profile_attributes
309+
self.profile= p unless p.empty?
308310
self.class.new(digital_object, dsid, @options)
309311
end
310312
end

lib/rubydora/digital_object.rb

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,13 @@ def fetch dsid
185185
# persist the object to Fedora, either as a new object
186186
# by modifing the existing object
187187
#
188-
# also will save all `:dirty?` datastreams that already exist
188+
# also will save all `:changed?` datastreams that already exist
189189
# new datastreams must be directly saved
190190
#
191191
# @return [Rubydora::DigitalObject] a new copy of this object
192192
def save
193193
check_if_read_only
194+
mod_time = nil
194195
run_callbacks :save do
195196
if self.new?
196197
self.pid = repository.ingest to_api_params.merge(:pid => pid)
@@ -199,13 +200,16 @@ def save
199200
p = to_api_params
200201
unless p.empty?
201202
mod_time = repository.modify_object p.merge(:pid => pid)
202-
self.lastModifiedDate = mod_time
203203
changed_attributes.clear
204204
end
205205
end
206206
end
207-
208-
self.datastreams.select { |dsid, ds| ds.changed? }.each { |dsid, ds| ds.save }
207+
mod_time = save_datastreams(mod_time)
208+
# mod_time will be nil on new objects with no ds changes
209+
unless mod_time.nil?
210+
self.lastModifiedDate = mod_time
211+
changed_attributes.delete 'lastModifiedDate'
212+
end
209213
self
210214
end
211215

@@ -272,5 +276,16 @@ def attribute_will_change! *args
272276
super
273277
end
274278

279+
# save changed datastreams
280+
# @param [String] memo_time : the time before changes, or nil
281+
# @return [String] the time of the last datastream change, or nil if no changes
282+
def save_datastreams(memo_time=nil)
283+
mod_time = memo_time
284+
self.datastreams.select { |dsid, ds| ds.changed? }.each do |dsid, ds|
285+
ds.save
286+
mod_time = ProfileParser.canonicalize_date(ds.dsCreateDate)
287+
end
288+
mod_time
289+
end
275290
end
276291
end

lib/rubydora/profile_parser.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ def self.canonicalize_date_string(input)
7979
input
8080
end
8181
end
82-
82+
def self.canonicalize_date(input)
83+
if input.is_a? Time
84+
canonicalize_date_string(input.utc.strftime("%Y-%m-%dT%H:%M:%S.%3NZ"))
85+
else
86+
canonicalize_date_string(input.to_s)
87+
end
88+
end
8389
end
8490
end

lib/rubydora/rest_api_client.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def add_datastream options = {}
340340
run_hook :before_add_datastream, :pid => pid, :dsid => dsid, :file => file, :options => options
341341
str = file.respond_to?(:read) ? file.read : file
342342
file.rewind if file.respond_to?(:rewind)
343-
client[datastream_url(pid, dsid, query_options)].post(str, :content_type => content_type.to_s, :multipart => true)
343+
ProfileParser.parse_datastream_profile(client[datastream_url(pid, dsid, query_options)].post(str, :content_type => content_type.to_s, :multipart => true))
344344
rescue Exception => exception
345345
rescue_with_handler(exception) || raise
346346
end
@@ -365,7 +365,7 @@ def modify_datastream options = {}
365365
run_hook :before_modify_datastream, :pid => pid, :dsid => dsid, :file => file, :content_type => content_type, :options => options
366366
str = file.respond_to?(:read) ? file.read : file
367367
file.rewind if file.respond_to?(:rewind)
368-
client[datastream_url(pid, dsid, query_options)].put(str, rest_client_options)
368+
ProfileParser.parse_datastream_profile(client[datastream_url(pid, dsid, query_options)].put(str, rest_client_options))
369369

370370
rescue Exception => exception
371371
rescue_with_handler(exception) || raise

spec/lib/datastream_spec.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@
385385
describe "update" do
386386
before(:each) do
387387
@datastream = Rubydora::Datastream.new @mock_object, 'dsid'
388-
@mock_api.stub(:datastream).and_return <<-XML
388+
@mock_api.should_receive(:datastream).once.and_return <<-XML
389389
<datastreamProfile>
390390
<dsLocation>some:uri</dsLocation>
391391
<dsLabel>label</dsLabel>
@@ -416,9 +416,10 @@
416416

417417
describe "update when content is changed" do
418418
it "should update the datastream when the content is changed" do
419-
@mock_api.should_receive(:modify_datastream).with(hash_including(:content => 'test'))
419+
@mock_api.should_receive(:modify_datastream).with(hash_including(:content => 'test')).and_return({'dsLocation' => 'some:uri', 'dsLabel' => 'label', 'dsSize' => 4})
420420
@datastream.content = "test"
421421
@datastream.save
422+
@datastream.dsSize.should == 4
422423
end
423424

424425
it "should be marked as changed when the content is updated" do

spec/lib/digital_object_spec.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,17 @@ class MyCustomDatastreamClass < Rubydora::Datastream; end
243243
describe "saving an object's datastreams" do
244244
before do
245245
@new_ds = double(Rubydora::Datastream)
246-
@new_ds.stub(:new? => true, :changed? => true, :content_changed? => true, :content => 'XXX')
246+
@new_ds.stub(:new? => true, :changed? => true, :content_changed? => true, :content => 'XXX', :dsCreateDate => '12345')
247247
@new_empty_ds = double(Rubydora::Datastream)
248-
@new_empty_ds.stub(:new? => true, :changed? => false, :content_changed? => false, :content => nil)
248+
@new_empty_ds.stub(:new? => true, :changed? => false, :content_changed? => false, :content => nil, :dsCreateDate => '12345')
249249
@existing_ds = double(Rubydora::Datastream)
250-
@existing_ds.stub(:new? => false, :changed? => false, :content_changed? => false, :content => 'YYY')
250+
@existing_ds.stub(:new? => false, :changed? => false, :content_changed? => false, :content => 'YYY', :dsCreateDate => '12345')
251251
@changed_attr_ds = double(Rubydora::Datastream)
252-
@changed_attr_ds.stub(:new? => false, :changed? => true, :content_changed? => false, :content => 'YYY')
252+
@changed_attr_ds.stub(:new? => false, :changed? => true, :content_changed? => false, :content => 'YYY', :dsCreateDate => '12345')
253253
@changed_ds = double(Rubydora::Datastream)
254-
@changed_ds.stub(:new? => false, :changed? => true, :content_changed? => true, :content => 'ZZZ')
254+
@changed_ds.stub(:new? => false, :changed? => true, :content_changed? => true, :content => 'ZZZ', :dsCreateDate => '2012-01-02:05:15:45.100Z')
255255
@changed_empty_ds = double(Rubydora::Datastream)
256-
@changed_empty_ds.stub(:new? => false, :changed? => true, :content_changed? => true, :content => nil)
256+
@changed_empty_ds.stub(:new? => false, :changed? => true, :content_changed? => true, :content => nil, :dsCreateDate => '12345')
257257

258258
end
259259
it "should save a new datastream with content" do
@@ -266,6 +266,8 @@ class MyCustomDatastreamClass < Rubydora::Datastream; end
266266
@object.stub(:datastreams) { { :changed_ds => @changed_ds } }
267267
@changed_ds.should_receive(:save)
268268
@object.save
269+
# object date should be canonicalized and updated
270+
@object.lastModifiedDate.should == '2012-01-02:05:15:45.1Z'
269271
end
270272

271273
it "should save a datastream whose attributes have changed" do

spec/lib/integration_test_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,18 @@
175175
ds.content
176176
end
177177

178+
it "should cache object's lastModifiedDate from ds changes" do
179+
@repository.ping.should == true
180+
obj = @repository.find_or_initialize('test:1')
181+
obj.save
182+
obj.label = "abc"
183+
obj.datastreams["my_ds"].content = "XXX"
184+
obj.save
185+
obj.label = "123"
186+
obj.save
187+
end
188+
189+
178190
describe "with transactions" do
179191
it "should work on ingest" do
180192
@repository.find('transactions:1').delete rescue nil

0 commit comments

Comments
 (0)