diff --git a/Rakefile b/Rakefile
index 522e5140c..cadb7b454 100644
--- a/Rakefile
+++ b/Rakefile
@@ -21,6 +21,7 @@ begin
gem.add_dependency('mime-types', '>= 1.16')
gem.add_dependency('multipart-post')
gem.add_dependency('nokogiri')
+ gem.add_dependency('yaml')
gem.add_development_dependency "rspec", ">= 1.2.9"
gem.add_development_dependency "mocha", ">= 1.2.9"
diff --git a/lib/active_fedora/metadata_datastream.rb b/lib/active_fedora/metadata_datastream.rb
index f95b5bc87..b87340b66 100644
--- a/lib/active_fedora/metadata_datastream.rb
+++ b/lib/active_fedora/metadata_datastream.rb
@@ -38,15 +38,15 @@ class MetadataDatastream < Datastream
# return xml.to_s
# end
#
- # # @tmpl ActiveFedora::MetadataDatastream
- # # @node Nokogiri::XML::Node
- # def self.from_xml(tmpl, node) # :nodoc:
- # node.xpath("./foxml:datastreamVersion[last()]/foxml:xmlContent/fields/node()").each do |f|
- # tmpl.send("#{f.name}_append", f.text) unless f.class == Nokogiri::XML::Text
- # end
- # tmpl.send(:dirty=, false)
- # tmpl
- # end
+ # @tmpl ActiveFedora::MetadataDatastream
+ # @node Nokogiri::XML::Node
+ def self.from_xml(tmpl, node) # :nodoc:
+ node.xpath("./foxml:datastreamVersion[last()]/foxml:xmlContent/fields/node()").each do |f|
+ tmpl.send("#{f.name}_append", f.text) unless f.class == Nokogiri::XML::Text
+ end
+ tmpl.send(:dirty=, false)
+ tmpl
+ end
# This method generates the various accessor and mutator methods on self for the datastream metadata attributes.
# each field will have the 3 magic methods:
diff --git a/lib/active_fedora/metadata_datastream_helper.rb b/lib/active_fedora/metadata_datastream_helper.rb
index 77732bf3a..5874c9cd1 100644
--- a/lib/active_fedora/metadata_datastream_helper.rb
+++ b/lib/active_fedora/metadata_datastream_helper.rb
@@ -12,16 +12,6 @@ def fields
@@classFields
end
- # @tmpl ActiveFedora::MetadataDatastream
- # @node Nokogiri::XML::Node
- def from_xml(tmpl, node) # :nodoc:
- node.xpath("./foxml:datastreamVersion[last()]/foxml:xmlContent/fields/node()").each do |f|
- tmpl.send("#{f.name}_append", f.text) unless f.class == Nokogiri::XML::Text
- end
- tmpl.send(:dirty=, false)
- tmpl
- end
-
end
def self.included(klass)
diff --git a/lib/active_fedora/nokogiri_datastream.rb b/lib/active_fedora/nokogiri_datastream.rb
index b2c1217ad..8b5f57d0c 100644
--- a/lib/active_fedora/nokogiri_datastream.rb
+++ b/lib/active_fedora/nokogiri_datastream.rb
@@ -1,18 +1,18 @@
require "nokogiri"
+require "om"
#this class represents a MetadataDatastream, a special case of ActiveFedora::Datastream
class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
-
+
include ActiveFedora::MetadataDatastreamHelper
-
- self.xml_model = Nokogiri::XML::Document
-
+ include OM::XML
+
attr_accessor :ng_xml
#constructor, calls up to ActiveFedora::Datastream's constructor
def initialize(attrs=nil)
super
@fields={}
- @ng_xml = self.class.xml_model.new()
+ self.class.from_xml(blob, self)
end
def to_solr(solr_doc = Solr::Document.new) # :nodoc:
@@ -27,34 +27,5 @@ def to_solr(solr_doc = Solr::Document.new) # :nodoc:
return solr_doc
end
-
- def to_xml(xml = REXML::Document.new("")) #:nodoc:
- fields.each_pair do |field,field_info|
- el = REXML::Element.new("#{field.to_s}")
- if field_info[:element_attrs]
- field_info[:element_attrs].each{|k,v| el.add_attribute(k.to_s, v.to_s)}
- end
- field_info[:values].each do |val|
- el = el.clone
- el.text = val.to_s
- if xml.class == REXML::Document
- xml.root.elements.add(el)
- else
- xml.add(el)
- end
- end
- end
- return xml.to_s
- end
-
- # @tmpl ActiveFedora::MetadataDatastream
- # @node Nokogiri::XML::Node
- def self.from_xml(tmpl, node) # :nodoc:
- node.xpath("./foxml:datastreamVersion[last()]/foxml:xmlContent/fields/node()").each do |f|
- tmpl.send("#{f.name}_append", f.text) unless f.class == Nokogiri::XML::Text
- end
- tmpl.send(:dirty=, false)
- tmpl
- end
end
\ No newline at end of file
diff --git a/lib/active_fedora/solr_service.rb b/lib/active_fedora/solr_service.rb
index 068a3133e..e56324c65 100644
--- a/lib/active_fedora/solr_service.rb
+++ b/lib/active_fedora/solr_service.rb
@@ -1,5 +1,6 @@
require 'solr'
require "active_fedora/solr_mapper"
+require "yaml"
module ActiveFedora
class SolrService
diff --git a/lib/hydra_libs/opinionated_mods_document.rb b/lib/hydra_libs/opinionated_mods_document.rb
index a767e63e4..9e4436cd1 100644
--- a/lib/hydra_libs/opinionated_mods_document.rb
+++ b/lib/hydra_libs/opinionated_mods_document.rb
@@ -1,2 +1,14 @@
-class OpinionatedModsDocument
+class OpinionatedModsDocument < Nokogiri::XML::Document
+
+ include OM::XML
+
+ self.schema_url = "http://www.loc.gov/standards/mods/v3/mods-3-2.xsd"
+
+ # Could add support for multiple root declarations.
+ # For now, assume that any modsCollections have already been broken up and fed in as individual mods documents
+ # root :mods_collection, :path=>"modsCollection",
+ # :attributes=>[],
+ # :subelements => :mods
+ root_property :mods, "mods", "http://www.loc.gov/mods/v3", :attributes=>["id", "version"]
+
end
\ No newline at end of file
diff --git a/spec/unit/mods_datastream_spec.rb b/spec/unit/mods_datastream_spec.rb
deleted file mode 100644
index ff16190cb..000000000
--- a/spec/unit/mods_datastream_spec.rb
+++ /dev/null
@@ -1,289 +0,0 @@
-require File.join( File.dirname(__FILE__), "../spec_helper" )
-
-require 'active_fedora'
-require 'hydra'
-
-describe ModsDatastream do
-
- before(:all) do
- @sample_fields = {:publisher => {:values => ["publisher1"], :type => :string},
- :coverage => {:values => ["coverage1", "coverage2"], :type => :text},
- :creation_date => {:values => "fake-date", :type => :date},
- :mydate => {:values => "fake-date", :type => :date},
- :empty_field => {:values => {}}
- }
- @sample_xml = XmlSimple.xml_in("coverage1coverage2fake-datefake-datepublisher1")
-
- end
-
- before(:each) do
- @test_ds = ModsDatastream.new
- end
-
- after(:each) do
- end
-
- describe '#new' do
- it 'should provide #new' do
- ModsDatastream.should respond_to(:new)
- @test_ds.ng_xml.should be_instance_of(OpinionatedModsDocument)
- end
- end
-
-
- it 'should provide .fields' do
- @test_ds.should respond_to(:fields)
- end
-
- describe '.save' do
- it "should provide .save" do
- @test_ds.should respond_to(:save)
- end
- it "should persist the product of .to_xml in fedora" do
- Fedora::Repository.instance.expects(:save)
- @test_ds.expects(:to_xml).returns("fake xml")
- @test_ds.expects(:blob=).with("fake xml")
- @test_ds.save
- end
- end
-
- describe '.to_xml' do
- it "should provide .to_xml" do
- @test_ds.should respond_to(:to_xml)
- end
- it 'should output the fields hash as XML' do
- @test_ds.expects(:fields).returns(@sample_fields)
- #sample_rexml = REXML::Document.new(sample_xml)
- #returned_rexml = REXML::Document.new(@test_ds.to_dc_xml)
- #returned_rexml.to_s.should == sample_rexml.to_s
- returned_xml = XmlSimple.xml_in(@test_ds.to_xml)
- returned_xml.should == @sample_xml
- end
-
- it 'should accept an optional REXML Document as an argument and insert its fields into that' do
- @test_ds.expects(:fields).returns(@sample_fields)
- rexml = REXML::Document.new("")
- rexml.root.elements.expects(:add).times(5)
- result = @test_ds.to_xml(rexml)
- end
- it 'should accept an optional REXML Document as an argument and insert its fields into that' do
- @test_ds.expects(:fields).returns(@sample_fields)
- rexml = REXML::Document.new("")
- result = @test_ds.to_xml(rexml)
- XmlSimple.xml_in(rexml.to_s).should == @sample_xml
- XmlSimple.xml_in(result).should == @sample_xml
- end
-
- it 'should add to root of REXML::Documents, but add directly to the elements if a REXML::Element is passed in' do
- @test_ds.expects(:fields).returns(@sample_fields).times(2)
- doc = REXML::Document.new("")
- el = REXML::Element.new("")
- doc.root.elements.expects(:add).times(5)
- el.expects(:add).times(5)
- @test_ds.to_xml(doc)
- @test_ds.to_xml(el)
- end
-
- end
-
- describe '.set_blob_for_save' do
- it "should provide .set_blob_for_save" do
- @test_ds.should respond_to(:set_blob_for_save)
- end
-
- it "should set the blob to to_xml" do
- @test_ds.expects(:blob=).with(@test_ds.to_xml)
- @test_ds.set_blob_for_save
- end
- end
-
- describe '#field' do
-
- before(:each) do
- class SpecDatastream < ActiveFedora::MetadataDatastream
- def initialize
- super
- field :publisher, :string
- field :coverage, :text
- field :creation_date, :date
- field :mydate, :date
- field :mycomplicated_field, :string, :multiple=>false, :encoding=>'LCSH', :element_attrs=>{:foo=>:bar, :baz=>:bat}
- end
- end
- end
-
- after(:each) do
- Object.send(:remove_const, :SpecDatastream)
- end
-
- it 'should add corresponding field to the @fields hash and set the field :type ' do
- sds = SpecDatastream.new
- sds.fields.should_not have_key(:bio)
- sds.field :bio, :text
- sds.fields.should have_key(:bio)
- sds.fields[:bio].should have_key(:type)
- sds.fields[:bio][:type].should == :text
- sds.fields[:mycomplicated_field][:element_attrs].should == {:foo=>:bar, :baz=>:bat}
- end
-
- # it "should insert custom element attrs into the xml stream" do
- # sds = SpecDatastream.new
- # sds.mycomplicated_field_values='foo'
- # sds.fields[:mycomplicated_field][:element_attrs].should == {:foo=>:bar, :baz=>:bat}
- # sds.to_xml.should == 'foo'
- # end
-
- it "should add getters and setters and appenders with field name" do
- local_test_ds = SpecDatastream.new
- local_test_ds.should respond_to(:publisher_values)
- local_test_ds.should respond_to(:publisher_append)
- local_test_ds.should respond_to(:publisher_values=)
- local_test_ds.publisher_values.class.should == Array
- local_test_ds.should respond_to(:coverage_values)
- local_test_ds.should respond_to(:coverage_values=)
- local_test_ds.should respond_to(:coverage_append)
- local_test_ds.should respond_to(:creation_date_values)
- local_test_ds.should respond_to(:creation_date_append)
- local_test_ds.should respond_to(:creation_date_values=)
- local_test_ds.should respond_to(:mydate_values)
- local_test_ds.should respond_to(:mydate_append)
- local_test_ds.should respond_to(:mydate_values=)
- end
-
- it "should track field values at instance level, not at class level" do
- local_test_ds1 = SpecDatastream.new
- local_test_ds2 = SpecDatastream.new
- local_test_ds1.publisher_values = ["publisher1", "publisher2"]
- local_test_ds2.publisher_values = ["publisherA", "publisherB"]
-
- local_test_ds2.publisher_values.should == ["publisherA", "publisherB"]
- local_test_ds1.publisher_values.should == ["publisher1", "publisher2"]
- end
-
- it "should allow you to add field values using <<" do
- local_test_ds1 = SpecDatastream.new
- local_test_ds1.publisher_values << "publisher1"
- local_test_ds1.publisher_values.should == ["publisher1"]
- end
-
- it "should create setter that always turns non-arrays into arrays" do
- local_test_ds = SpecDatastream.new
- local_test_ds.publisher_values = "Foo"
- local_test_ds.publisher_values.should == ["Foo"]
- end
-
- it "should create setter that sets datastream.dirty? to true" do
- local_test_ds = SpecDatastream.new
- local_test_ds.should_not be_dirty
- local_test_ds.publisher_values = "Foo"
- local_test_ds.should be_dirty
-
- # Note: If you use << to append values, the datastream will not be marked as dirty!
- #local_test_ds.dirty = false
-
- #local_test_ds.should_not be_dirty
- #local_test_ds.publisher_values << "Foo"
- #local_test_ds.should be_dirty
- end
-
- it "should add any extra opts to the field hash" do
- local_test_ds = SpecDatastream.new
- local_test_ds.field "myfield", :string, :foo => "foo", :bar => "bar"
- local_test_ds.fields[:myfield].should have_key(:foo)
- local_test_ds.fields[:myfield][:foo].should == "foo"
- local_test_ds.fields[:myfield].should have_key(:bar)
- local_test_ds.fields[:myfield][:bar].should == "bar"
- end
-
- end
-
- describe ".to_solr" do
-
- after(:all) do
- # Revert to default mappings after running tests
- ActiveFedora::SolrService.load_mappings
- end
-
- it "should provide .to_solr and return a SolrDocument" do
- @test_ds.should respond_to(:to_solr)
- @test_ds.to_solr.should be_kind_of(Solr::Document)
- end
-
- it "should optionally allow you to provide the Solr::Document to add fields to and return that document when done" do
- doc = Solr::Document.new
- @test_ds.to_solr(doc).should equal(doc)
- end
-
- it "should iterate through @fields hash" do
- @test_ds.expects(:fields).returns(@sample_fields)
- solr_doc = @test_ds.to_solr
-
- solr_doc[:publisher_t].should == "publisher1"
- solr_doc[:coverage_t].should == "coverage1"
- solr_doc[:creation_date_dt].should == "fake-date"
- solr_doc[:mydate_dt].should == "fake-date"
-
- solr_doc[:empty_field_t].should be_nil
- end
-
- it "should allow multiple values for a single field"
-
- it 'should append create keys in format field_name + _ + field_type' do
- @test_ds.stubs(:fields).returns(@sample_fields)
-
- #should have these
-
- @test_ds.to_solr[:publisher_t].should_not be_nil
- @test_ds.to_solr[:coverage_t].should_not be_nil
- @test_ds.to_solr[:creation_date_dt].should_not be_nil
-
- #should NOT have these
- @test_ds.to_solr[:narrator].should be_nil
- @test_ds.to_solr[:title].should be_nil
- @test_ds.to_solr[:empty_field].should be_nil
-
- end
-
- it "should use Solr mappings to generate field names" do
- ActiveFedora::SolrService.load_mappings(File.join(File.dirname(__FILE__), "..", "..", "config", "solr_mappings_af_0.1.yml"))
- @test_ds.stubs(:fields).returns(@sample_fields)
- solr_doc = @test_ds.to_solr
-
- #should have these
-
- solr_doc[:publisher_field].should == "publisher1"
- solr_doc[:coverage_field].should == "coverage1"
- solr_doc[:creation_date_date].should == "fake-date"
- solr_doc[:mydate_date].should == "fake-date"
-
- solr_doc[:publisher_t].should be_nil
- solr_doc[:coverage_t].should be_nil
- solr_doc[:creation_date_dt].should be_nil
-
- # Reload default mappings
- ActiveFedora::SolrService.load_mappings
- end
-
- it 'should append _dt to dates' do
- @test_ds.expects(:fields).returns(@sample_fields).at_least_once
-
- #should have these
-
- @test_ds.to_solr[:creation_date_dt].should_not be_nil
- @test_ds.to_solr[:mydate_dt].should_not be_nil
-
- #should NOT have these
-
- @test_ds.to_solr[:mydate].should be_nil
- @test_ds.to_solr[:creation_date_date].should be_nil
- end
-
- end
-
- describe '.fields' do
- it "should return a Hash" do
- @test_ds.fields.should be_instance_of(Hash)
- end
- end
-
-end
diff --git a/spec/unit/nokogiri_datastream_spec.rb b/spec/unit/nokogiri_datastream_spec.rb
index 2549936d6..325c1931f 100644
--- a/spec/unit/nokogiri_datastream_spec.rb
+++ b/spec/unit/nokogiri_datastream_spec.rb
@@ -15,7 +15,7 @@
end
before(:each) do
- @test_ds = ActiveFedora::NokogiriDatastream.new
+ @test_ds = ActiveFedora::NokogiriDatastream.new(:blob=>"")
end
after(:each) do
@@ -26,6 +26,10 @@
ActiveFedora::NokogiriDatastream.should respond_to(:new)
@test_ds.ng_xml.should be_instance_of(Nokogiri::XML::Document)
end
+ it 'should load xml from blob if provided' do
+ test_ds1 = ActiveFedora::NokogiriDatastream.new(:blob=>"")
+ test_ds1.ng_xml.to_xml.should == "\n\n \n\n"
+ end
end
@@ -49,33 +53,35 @@
it "should provide .to_xml" do
@test_ds.should respond_to(:to_xml)
end
- it 'should output the fields hash as XML' do
- @test_ds.expects(:fields).returns(@sample_fields)
- returned_xml = XmlSimple.xml_in(@test_ds.to_xml)
- returned_xml.should == @sample_xml
+
+ it "should ng_xml.to_xml" do
+ @test_ds.ng_xml.expects(:to_xml).returns("xml")
+ @test_ds.to_xml.should == "xml"
end
- it 'should accept an optional REXML Document as an argument and insert its fields into that' do
- @test_ds.expects(:fields).returns(@sample_fields)
- rexml = REXML::Document.new("")
- rexml.root.elements.expects(:add).times(5)
- result = @test_ds.to_xml(rexml)
+ it 'should accept an optional Nokogiri::XML Document as an argument and insert its fields into that (mocked test)' do
+ doc = Nokogiri::XML::Document.parse("")
+ doc.root.expects(:add_child).with(@test_ds.ng_xml.root)
+ @test_ds.to_xml(doc)
end
- it 'should accept an optional REXML Document as an argument and insert its fields into that' do
- @test_ds.expects(:fields).returns(@sample_fields)
- rexml = REXML::Document.new("")
- result = @test_ds.to_xml(rexml)
- XmlSimple.xml_in(rexml.to_s).should == @sample_xml
- XmlSimple.xml_in(result).should == @sample_xml
+
+ it 'should accept an optional Nokogiri::XML Document as an argument and insert its fields into that (functional test)' do
+ expected_result = XmlSimple.xml_in("")
+ doc = Nokogiri::XML::Document.parse("")
+ result = @test_ds.to_xml(doc)
+ XmlSimple.xml_in(doc.to_s).should == expected_result
+ XmlSimple.xml_in(result).should == expected_result
end
- it 'should add to root of REXML::Documents, but add directly to the elements if a REXML::Element is passed in' do
- @test_ds.expects(:fields).returns(@sample_fields).times(2)
- doc = REXML::Document.new("")
- el = REXML::Element.new("")
- doc.root.elements.expects(:add).times(5)
- el.expects(:add).times(5)
- @test_ds.to_xml(doc)
+ it 'should add to root of Nokogiri::XML::Documents, but add directly to the elements if a Nokogiri::XML::Node is passed in' do
+ mock_new_node = mock("new node")
+ mock_new_node.stubs(:to_xml).returns("foo")
+
+ doc = Nokogiri::XML::Document.parse("")
+ el = Nokogiri::XML::Node.new("test_element", Nokogiri::XML::Document.new)
+ doc.root.expects(:add_child).with(@test_ds.ng_xml.root).returns(mock_new_node)
+ el.expects(:add_child).with(@test_ds.ng_xml.root).returns(mock_new_node)
+ @test_ds.to_xml(doc).should
@test_ds.to_xml(el)
end
@@ -92,118 +98,6 @@
end
end
- describe '#field' do
-
- before(:each) do
- class SpecDatastream < ActiveFedora::MetadataDatastream
- def initialize
- super
- field :publisher, :string
- field :coverage, :text
- field :creation_date, :date
- field :mydate, :date
- field :mycomplicated_field, :string, :multiple=>false, :encoding=>'LCSH', :element_attrs=>{:foo=>:bar, :baz=>:bat}
- end
- end
- end
-
- after(:each) do
- Object.send(:remove_const, :SpecDatastream)
- end
-
-
- describe ".values" do
- it "should call ng_xml.values_for(field_name) OR call corresponding lookup method and build an array of values by calling .value on each node in the set"
- end
-
- describe ".values<<" do
- it "should call corresponding builder method"
- end
-
- describe ".values=" do
- it "should wipe out any existing nodes, use the corresponding builder, and insert new node(s) as the replacement"
- end
-
- it 'should add corresponding field to the @fields hash and set the field :type ' do
- sds = SpecDatastream.new
- sds.fields.should_not have_key(:bio)
- sds.field :bio, :text
- sds.fields.should have_key(:bio)
- sds.fields[:bio].should have_key(:type)
- sds.fields[:bio][:type].should == :text
- sds.fields[:mycomplicated_field][:element_attrs].should == {:foo=>:bar, :baz=>:bat}
- end
-
- # it "should insert custom element attrs into the xml stream" do
- # sds = SpecDatastream.new
- # sds.mycomplicated_field_values='foo'
- # sds.fields[:mycomplicated_field][:element_attrs].should == {:foo=>:bar, :baz=>:bat}
- # sds.to_xml.should == 'foo'
- # end
-
- it "should add getters and setters and appenders with field name" do
- local_test_ds = SpecDatastream.new
- local_test_ds.should respond_to(:publisher_values)
- local_test_ds.should respond_to(:publisher_append)
- local_test_ds.should respond_to(:publisher_values=)
- local_test_ds.publisher_values.class.should == Array
- local_test_ds.should respond_to(:coverage_values)
- local_test_ds.should respond_to(:coverage_values=)
- local_test_ds.should respond_to(:coverage_append)
- local_test_ds.should respond_to(:creation_date_values)
- local_test_ds.should respond_to(:creation_date_append)
- local_test_ds.should respond_to(:creation_date_values=)
- local_test_ds.should respond_to(:mydate_values)
- local_test_ds.should respond_to(:mydate_append)
- local_test_ds.should respond_to(:mydate_values=)
- end
-
- it "should track field values at instance level, not at class level" do
- local_test_ds1 = SpecDatastream.new
- local_test_ds2 = SpecDatastream.new
- local_test_ds1.publisher_values = ["publisher1", "publisher2"]
- local_test_ds2.publisher_values = ["publisherA", "publisherB"]
-
- local_test_ds2.publisher_values.should == ["publisherA", "publisherB"]
- local_test_ds1.publisher_values.should == ["publisher1", "publisher2"]
- end
-
- it "should allow you to add field values using <<" do
- local_test_ds1 = SpecDatastream.new
- local_test_ds1.publisher_values << "publisher1"
- local_test_ds1.publisher_values.should == ["publisher1"]
- end
-
- it "should create setter that always turns non-arrays into arrays" do
- local_test_ds = SpecDatastream.new
- local_test_ds.publisher_values = "Foo"
- local_test_ds.publisher_values.should == ["Foo"]
- end
-
- it "should create setter that sets datastream.dirty? to true" do
- local_test_ds = SpecDatastream.new
- local_test_ds.should_not be_dirty
- local_test_ds.publisher_values = "Foo"
- local_test_ds.should be_dirty
-
- # Note: If you use << to append values, the datastream will not be marked as dirty!
- #local_test_ds.dirty = false
-
- #local_test_ds.should_not be_dirty
- #local_test_ds.publisher_values << "Foo"
- #local_test_ds.should be_dirty
- end
-
- it "should add any extra opts to the field hash" do
- local_test_ds = SpecDatastream.new
- local_test_ds.field "myfield", :string, :foo => "foo", :bar => "bar"
- local_test_ds.fields[:myfield].should have_key(:foo)
- local_test_ds.fields[:myfield][:foo].should == "foo"
- local_test_ds.fields[:myfield].should have_key(:bar)
- local_test_ds.fields[:myfield][:bar].should == "bar"
- end
-
- end
describe ".to_solr" do