active-fedora 1.1.8 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,6 +31,11 @@ export FEDORA_HOME=/path/to/hydra/jetty/fedora/default
31
31
  $FEDORA_HOME/client/bin/fedora-ingest-demos.sh localhost 8983 fedoraAdmin fedoraAdmin http
32
32
  <pre>
33
33
 
34
+ You must ingest one fixture using the import_fixture rake task provided by the hydra project:
35
+ <pre>
36
+ rake hydra:import_fixture pid=hydrangea:fixture_mods_article1
37
+ </pre>
38
+
34
39
  Now you're ready to run
35
40
 
36
41
  <pre>
data/Rakefile CHANGED
@@ -21,7 +21,7 @@ begin
21
21
  gem.add_dependency('mime-types', '>= 1.16')
22
22
  gem.add_dependency('multipart-post')
23
23
  gem.add_dependency('nokogiri')
24
- gem.add_dependency('om', '>= 0.1.5')
24
+ gem.add_dependency('om', '>= 0.1.7')
25
25
  # gem.add_dependency('yaml')
26
26
 
27
27
  gem.add_development_dependency "rspec", ">= 1.2.9"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.8
1
+ 1.1.9
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{active-fedora}
8
- s.version = "1.1.8"
8
+ s.version = "1.1.9"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Matt Zumwalt", "McClain Looney"]
12
- s.date = %q{2010-06-23}
12
+ s.date = %q{2010-07-02}
13
13
  s.description = %q{ActiveFedora provides for creating and managing objects in the Fedora Repository Architecture.}
14
14
  s.email = %q{matt.zumwalt@yourmediashelf.com}
15
15
  s.extra_rdoc_files = [
@@ -209,8 +209,7 @@ Gem::Specification.new do |s|
209
209
  "lib/fedora/generic_search.rb",
210
210
  "lib/fedora/repository.rb",
211
211
  "lib/hydra.rb",
212
- "lib/hydra/mods_article.rb",
213
- "lib/hydra/opinionated_mods_document.rb",
212
+ "lib/hydra/sample_mods_datastream.rb",
214
213
  "lib/ruby-fedora.rb",
215
214
  "lib/util/class_level_inheritable_attributes.rb",
216
215
  "script/console",
@@ -226,6 +225,7 @@ Gem::Specification.new do |s|
226
225
  "spec/fixtures/mods_articles/hydrangea_article1.xml",
227
226
  "spec/fixtures/oh_qdc.xml",
228
227
  "spec/fixtures/test_12.foxml.xml",
228
+ "spec/hydrangea_fixture_mods_article1.foxml.xml",
229
229
  "spec/integration/base_file_management_spec.rb",
230
230
  "spec/integration/base_loader_spec.rb",
231
231
  "spec/integration/base_spec.rb",
@@ -235,6 +235,7 @@ Gem::Specification.new do |s|
235
235
  "spec/integration/fedora_object_spec.rb",
236
236
  "spec/integration/full_featured_model_spec.rb",
237
237
  "spec/integration/model_spec.rb",
238
+ "spec/integration/mods_article_integration_spec.rb",
238
239
  "spec/integration/rels_ext_datastream_spec.rb",
239
240
  "spec/integration/repository_spec.rb",
240
241
  "spec/integration/rf_fedora_object_spec.rb",
@@ -294,6 +295,7 @@ Gem::Specification.new do |s|
294
295
  "spec/integration/fedora_object_spec.rb",
295
296
  "spec/integration/full_featured_model_spec.rb",
296
297
  "spec/integration/model_spec.rb",
298
+ "spec/integration/mods_article_integration_spec.rb",
297
299
  "spec/integration/rels_ext_datastream_spec.rb",
298
300
  "spec/integration/repository_spec.rb",
299
301
  "spec/integration/rf_fedora_object_spec.rb",
@@ -343,7 +345,7 @@ Gem::Specification.new do |s|
343
345
  s.add_runtime_dependency(%q<mime-types>, [">= 1.16"])
344
346
  s.add_runtime_dependency(%q<multipart-post>, [">= 0"])
345
347
  s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
346
- s.add_runtime_dependency(%q<om>, [">= 0.1.5"])
348
+ s.add_runtime_dependency(%q<om>, [">= 0.1.7"])
347
349
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
348
350
  s.add_development_dependency(%q<mocha>, [">= 1.2.9"])
349
351
  s.add_development_dependency(%q<ruby-debug>, [">= 0"])
@@ -353,7 +355,7 @@ Gem::Specification.new do |s|
353
355
  s.add_dependency(%q<mime-types>, [">= 1.16"])
354
356
  s.add_dependency(%q<multipart-post>, [">= 0"])
355
357
  s.add_dependency(%q<nokogiri>, [">= 0"])
356
- s.add_dependency(%q<om>, [">= 0.1.5"])
358
+ s.add_dependency(%q<om>, [">= 0.1.7"])
357
359
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
358
360
  s.add_dependency(%q<mocha>, [">= 1.2.9"])
359
361
  s.add_dependency(%q<ruby-debug>, [">= 0"])
@@ -364,7 +366,7 @@ Gem::Specification.new do |s|
364
366
  s.add_dependency(%q<mime-types>, [">= 1.16"])
365
367
  s.add_dependency(%q<multipart-post>, [">= 0"])
366
368
  s.add_dependency(%q<nokogiri>, [">= 0"])
367
- s.add_dependency(%q<om>, [">= 0.1.5"])
369
+ s.add_dependency(%q<om>, [">= 0.1.7"])
368
370
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
369
371
  s.add_dependency(%q<mocha>, [">= 1.2.9"])
370
372
  s.add_dependency(%q<ruby-debug>, [">= 0"])
@@ -172,7 +172,7 @@ module ActiveFedora
172
172
  def metadata_streams
173
173
  results = []
174
174
  datastreams.each_value do |ds|
175
- if ds.kind_of?(ActiveFedora::MetadataDatastream)
175
+ if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.kind_of?(ActiveFedora::NokogiriDatastream)
176
176
  results<<ds
177
177
  end
178
178
  end
@@ -356,8 +356,9 @@ module ActiveFedora
356
356
  # Nokogiri Datstreams use a new syntax for .from_xml (tmpl is optional!) and expects the actual xml content rather than the foxml datstream xml
357
357
  # NB: Base.deserialize, or a separately named method, should set any other info from the foxml if necessary though by this point it's all been grabbed elsewhere...
358
358
  if ds.kind_of?(ActiveFedora::NokogiriDatastream)
359
- node = node.search('./foxml:datastreamVersion[last()]/foxml:xmlContent/*').first
360
- proto.datastreams[name]=ds.class.from_xml(node, ds)
359
+ xml_content = Fedora::Repository.instance.fetch_custom(pid, "datastreams/#{name}/content")
360
+ # node = node.search('./foxml:datastreamVersion[last()]/foxml:xmlContent/*').first
361
+ proto.datastreams[name]=ds.class.from_xml(xml_content, ds)
361
362
  else
362
363
  proto.datastreams[name]=ds.class.from_xml(ds, node)
363
364
  end
@@ -395,8 +396,9 @@ module ActiveFedora
395
396
  # el.text = value
396
397
  # fields_xml << el
397
398
  # end
398
- datastreams.each_value do |ds|
399
- ds.to_xml(fields_xml) if ds.included_modules.include?(ActiveFedora::MetadataDatastreamHelper) || ds.kind_of?(ActiveFedora::RelsExtDatastream)
399
+
400
+ datastreams.each_value do |ds|
401
+ ds.to_xml(fields_xml) if ds.class.included_modules.include?(ActiveFedora::MetadataDatastreamHelper) || ds.kind_of?(ActiveFedora::RelsExtDatastream)
400
402
  end
401
403
  return xml.to_s
402
404
  end
@@ -437,24 +439,20 @@ module ActiveFedora
437
439
  # or
438
440
  # m.update_attributes({:fubar=>'baz'}, :datastreams=>["my_ds", "my_other_ds"])
439
441
  def update_attributes(params={}, opts={})
440
- params.each do |k,v|
441
- if v == :delete || v == "" || v == nil
442
- v = []
443
- end
444
- if opts[:datastreams]
445
- ds_array = []
446
- opts[:datastreams].each do |dsname|
447
- ds_array << datastreams[dsname]
448
- end
449
- else
450
- ds_array = datastreams.values
451
- end
452
- ds_array.each do |d|
453
- if d.fields[k.to_sym]
454
- d.send("#{k}_values=", v)
455
- end
442
+ result = {}
443
+ if opts[:datastreams]
444
+ ds_array = []
445
+ opts[:datastreams].each do |dsname|
446
+ ds_array << datastreams[dsname]
456
447
  end
448
+ else
449
+ ds_array = metadata_streams
450
+ end
451
+ ds_array.each do |d|
452
+ ds_result = d.update_attributes(params,opts)
453
+ result[d.dsid] = ds_result
457
454
  end
455
+ return result
458
456
  end
459
457
 
460
458
  # A convenience method for updating indexed attributes. The passed in hash
@@ -481,40 +479,35 @@ module ActiveFedora
481
479
  ds_array << datastreams[dsname]
482
480
  end
483
481
  else
484
- ds_array = datastreams.values
482
+ ds_array = metadata_streams
483
+ end
484
+ result = {}
485
+ ds_array.each do |d|
486
+ result[d.dsid] = d.update_indexed_attributes(params,opts)
485
487
  end
488
+ return result
489
+ end
490
+
491
+ def update_datastream_attributes(params={}, opts={})
486
492
  result = params.dup
487
- params.each do |key,value|
488
- result[key] = value.dup
489
- ds_array.each do |dstream|
490
- if dstream.fields[key.to_sym]
491
- aname="#{key}_values"
492
- curval = dstream.send("#{aname}")
493
- cpv=value.dup#copy this, we'll need the original for the next ds
494
- cpv.delete_if do |y,z|
495
- if curval[y.to_i] and y.to_i > -1
496
- curval[y.to_i]=z
497
- true
498
- else
499
- false
500
- end
501
- end
502
- cpv.each do |y,z|
503
- curval<<z #just append everything left
504
- if y == "-1"
505
- new_array_index = curval.length - 1
506
- result[key][new_array_index.to_s] = params[key]["-1"]
507
- end
508
- end
509
- curval.delete_if {|x| x == :delete || x == "" || x == nil}
510
- dstream.send("#{aname}=", curval) #write it back to the ds
511
- end
493
+ params.each_pair do |dsid, ds_params|
494
+ if datastreams_in_memory.include?(dsid)
495
+ result[dsid] = datastreams_in_memory[dsid].update_attributes(ds_params)
496
+ else
497
+ result.delete(dsid)
512
498
  end
513
- result[key].delete("-1")
514
499
  end
515
500
  return result
516
501
  end
517
502
 
503
+ def get_values_from_datastream(dsid,field_key,default=[])
504
+ if datastreams_in_memory.include?(dsid)
505
+ return datastreams_in_memory[dsid].get_values(field_key,default)
506
+ else
507
+ return nil
508
+ end
509
+ end
510
+
518
511
  def self.pids_from_uris(uris)
519
512
  if uris.class == String
520
513
  return uris.gsub("info:fedora/", "")
@@ -557,10 +550,11 @@ module ActiveFedora
557
550
 
558
551
  # Pushes the object and all of its new or dirty datastreams into Fedora
559
552
  def update
560
- result = Fedora::Repository.instance.save(@inner_object)
553
+ result = Fedora::Repository.instance.save(@inner_object)
561
554
  datastreams_in_memory.each do |k,ds|
562
555
  if ds.dirty? || ds.new_object?
563
- if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.instance_of?(ActiveFedora::RelsExtDatastream)
556
+ if ds.class.included_modules.include?(ActiveFedora::MetadataDatastreamHelper) || ds.instance_of?(ActiveFedora::RelsExtDatastream)
557
+ # if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.kind_of?(ActiveFedora::NokogiriDatastream) || ds.instance_of?(ActiveFedora::RelsExtDatastream)
564
558
  @metadata_is_dirty = true
565
559
  end
566
560
  result = ds.save
@@ -4,40 +4,112 @@ module ActiveFedora
4
4
 
5
5
  include ActiveFedora::MetadataDatastreamHelper
6
6
 
7
- self.xml_model = ActiveFedora::MetadataDatastream
7
+ # .to_solr and .to_xml (among other things) are provided by ActiveFedora::MetadataDatastream
8
+ self.xml_model = ActiveFedora::MetadataDatastream
9
+
10
+ def update_attributes(params={},opts={})
11
+ result = params.dup
12
+ params.each do |k,v|
13
+ if v == :delete || v == "" || v == nil
14
+ v = []
15
+ end
16
+ if self.fields.has_key?(k.to_sym)
17
+ result[k] = set_value(k, v)
18
+ else
19
+ result.delete(k)
20
+ end
21
+ end
22
+ return result
23
+ end
24
+
25
+ # An ActiveRecord-ism to udpate metadata values.
26
+ #
27
+ # The passed in hash must look like this :
28
+ # {:name=>{"0"=>"a","1"=>"b"}}
29
+ #
30
+ # This will attempt to set the values for any field named fubar in the datastream.
31
+ # If there is no field by that name, it returns an empty hash and doesn't change the object at all.
32
+ # If there is a field by that name, it will set the values for field of name :name having the value [a,b]
33
+ # and it returns a hash with the field name, value index, and the value as it was set.
34
+ #
35
+ # An index of -1 will insert a new value. any existing value at the relevant index
36
+ # will be overwritten.
37
+ #
38
+ # As in update_attributes, this overwrites _all_ available fields by default.
39
+ #
40
+ # Example Usage:
41
+ #
42
+ # ds.update_attributes({:myfield=>{"0"=>"a","1"=>"b"},:myotherfield=>{"-1"=>"c"}})
43
+ #
44
+ def update_indexed_attributes(params={}, opts={})
45
+ # remove any fields from params that this datastream doesn't recognize
46
+ params.delete_if {|field_name,new_values| !self.fields.include?(field_name.to_sym) }
47
+
48
+ result = params.dup
49
+ params.each do |field_name,new_values|
50
+ field_accessor_method = "#{field_name}_values"
51
+
52
+ if new_values.kind_of?(Hash)
53
+ result[field_name] = new_values.dup
54
+
55
+ current_values = instance_eval(field_accessor_method)
56
+
57
+ # current_values = get_values(field_name) # for some reason this leaves current_values unset?
58
+
59
+ new_values.delete_if do |y,z|
60
+ if current_values[y.to_i] and y.to_i > -1
61
+ current_values[y.to_i]=z
62
+ true
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ new_values.each do |y,z|
69
+ result[field_name].delete(y)
70
+ current_values<<z #just append everything left
71
+ new_array_index = current_values.length - 1
72
+ result[field_name][new_array_index.to_s] = z
73
+ end
74
+ current_values.delete_if {|x| x == :delete || x == "" || x == nil}
75
+ #set_value(field_name, current_values)
76
+ instance_eval("#{field_accessor_method}=(current_values)") #write it back to the ds
77
+ # result[field_name].delete("-1")
78
+ else
79
+ values = instance_eval("#{field_name}_values=(new_values)")
80
+ result[field_name] = {"0"=>values}
81
+ end
82
+ end
83
+ return result
84
+ end
85
+
86
+
87
+ def get_values(field_name, default=[])
88
+ field_accessor_method = "#{field_name}_values"
89
+ if respond_to? field_accessor_method
90
+ values = self.send(field_accessor_method)
91
+ else
92
+ values = []
93
+ end
94
+ if values.empty?
95
+ if default.nil?
96
+ return default
97
+ else
98
+ return default
99
+ end
100
+ else
101
+ return values
102
+ end
103
+ end
104
+
105
+ def set_value(field_name, values)
106
+ field_accessor_method = "#{field_name}_values="
107
+ if respond_to? field_accessor_method
108
+ values = self.send(field_accessor_method, values)
109
+ return self.send("#{field_name}_values")
110
+ end
111
+ end
8
112
 
9
- # def to_solr(solr_doc = Solr::Document.new) # :nodoc:
10
- # fields.each do |field_key, field_info|
11
- # if field_info.has_key?(:values) && !field_info[:values].nil?
12
- # field_symbol = generate_solr_symbol(field_key, field_info[:type])
13
- # field_info[:values].each do |val|
14
- # solr_doc << Solr::Field.new(field_symbol => val)
15
- # end
16
- # end
17
- # end
18
- #
19
- # return solr_doc
20
- # end
21
- #
22
- # def to_xml(xml = REXML::Document.new("<fields />")) #:nodoc:
23
- # fields.each_pair do |field,field_info|
24
- # el = REXML::Element.new("#{field.to_s}")
25
- # if field_info[:element_attrs]
26
- # field_info[:element_attrs].each{|k,v| el.add_attribute(k.to_s, v.to_s)}
27
- # end
28
- # field_info[:values].each do |val|
29
- # el = el.clone
30
- # el.text = val.to_s
31
- # if xml.class == REXML::Document
32
- # xml.root.elements.add(el)
33
- # else
34
- # xml.add(el)
35
- # end
36
- # end
37
- # end
38
- # return xml.to_s
39
- # end
40
- #
41
113
  # @tmpl ActiveFedora::MetadataDatastream
42
114
  # @node Nokogiri::XML::Node
43
115
  def self.from_xml(tmpl, node) # :nodoc:
@@ -49,7 +49,9 @@ module ActiveFedora::MetadataDatastreamHelper
49
49
  end
50
50
 
51
51
  def to_xml(xml = Nokogiri::XML::Document.parse("<fields />")) #:nodoc:
52
- if xml.instance_of?(Nokogiri::XML::Document)
52
+ if xml.instance_of?(Nokogiri::XML::Builder)
53
+ xml_insertion_point = xml.doc.root
54
+ elsif xml.instance_of?(Nokogiri::XML::Document)
53
55
  xml_insertion_point = xml.root
54
56
  else
55
57
  xml_insertion_point = xml
@@ -5,7 +5,8 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
5
5
 
6
6
  include ActiveFedora::MetadataDatastreamHelper
7
7
  include OM::XML
8
-
8
+ # extend(OM::XML::Container::ClassMethods)
9
+
9
10
  attr_accessor :ng_xml
10
11
 
11
12
  #constructor, calls up to ActiveFedora::Datastream's constructor
@@ -14,11 +15,41 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
14
15
  @fields={}
15
16
  self.class.from_xml(blob, self)
16
17
  end
18
+
19
+ # @xml String, File or Nokogiri::XML::Node
20
+ # @tmpl ActiveFedora::MetadataDatastream
21
+ # Careful! If you call this from a constructor, be sure to provide something 'ie. self' as the @tmpl. Otherwise, you will get an infinite loop!
22
+ def self.from_xml(xml, tmpl=self.new) # :nodoc:
23
+ if xml.kind_of? Nokogiri::XML::Node
24
+ tmpl.ng_xml = xml
25
+ else
26
+ tmpl.ng_xml = Nokogiri::XML::Document.parse(xml)
27
+ end
28
+ tmpl.send(:dirty=, false)
29
+ return tmpl
30
+ end
31
+
32
+ # class << self
33
+ # from_xml_original = self.instance_method(:from_xml)
34
+ #
35
+ # define_method(:from_xml, xml, tmpl=self.new) do
36
+ # from_xml_original.bind(self).call(xml, tmpl)
37
+ # tmpl.send(:dirty=, false)
38
+ # end
39
+ #
40
+ # # def from_xml_custom(xml, tmpl=self.new)
41
+ # # from_xml_original(xml, tmpl)
42
+ # # tmpl.send(:dirty=, false)
43
+ # # end
44
+ # #
45
+ # # alias_method :from_xml_original, :from_xml
46
+ # # alias_method :from_xml, :from_xml_custom
47
+ # end
17
48
 
18
49
 
19
50
  def to_xml(xml = self.ng_xml)
20
51
  ng_xml = self.ng_xml
21
- if ng_xml.root.nil? && self.class.respond_to?(:root_property_ref) && !self.class.root_property_ref.nil?
52
+ if ng_xml.respond_to?(:root) && ng_xml.root.nil? && self.class.respond_to?(:root_property_ref) && !self.class.root_property_ref.nil?
22
53
  ng_xml = self.class.generate(self.class.root_property_ref, "")
23
54
  if xml.root.nil?
24
55
  xml = ng_xml
@@ -89,5 +120,23 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
89
120
  solr_doc << Solr::Field.new(hierarchical_field_name => node.text)
90
121
  end
91
122
  end
123
+
124
+ def update_indexed_attributes(params={}, opts={})
125
+ # remove any fields from params that this datastream doesn't recognize
126
+ params.delete_if do |field_key,new_values|
127
+ if field_key.kind_of?(String)
128
+ true
129
+ else
130
+ self.class.accessor_xpath(*OM.destringify(field_key) ).nil?
131
+ end
132
+ end
133
+ result = update_properties( params )
134
+ self.dirty = true
135
+ return result
136
+ end
137
+
138
+ def get_values(field_key,default=[])
139
+ property_values(*field_key)
140
+ end
92
141
 
93
142
  end