active-fedora 1.2.6 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.6
1
+ 1.2.7
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{active-fedora}
8
- s.version = "1.2.6"
8
+ s.version = "1.2.7"
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-10-27}
12
+ s.date = %q{2010-11-14}
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 = [
@@ -220,6 +220,7 @@ Gem::Specification.new do |s|
220
220
  "solr/config/solrconfig-1.5.xml",
221
221
  "spec/fixtures/changeme155.xml",
222
222
  "spec/fixtures/dino.jpg",
223
+ "spec/fixtures/dino_jpg_no_file_ext",
223
224
  "spec/fixtures/hydrangea_fixture_mods_article1.foxml.xml",
224
225
  "spec/fixtures/minivan.jpg",
225
226
  "spec/fixtures/mods_articles/hydrangea_article1.xml",
@@ -238,6 +239,7 @@ Gem::Specification.new do |s|
238
239
  "spec/integration/metadata_datastream_helper_spec.rb",
239
240
  "spec/integration/model_spec.rb",
240
241
  "spec/integration/mods_article_integration_spec.rb",
242
+ "spec/integration/nokogiri_datastream_spec.rb",
241
243
  "spec/integration/rels_ext_datastream_spec.rb",
242
244
  "spec/integration/repository_spec.rb",
243
245
  "spec/integration/rf_fedora_object_spec.rb",
@@ -300,6 +302,7 @@ Gem::Specification.new do |s|
300
302
  "spec/integration/metadata_datastream_helper_spec.rb",
301
303
  "spec/integration/model_spec.rb",
302
304
  "spec/integration/mods_article_integration_spec.rb",
305
+ "spec/integration/nokogiri_datastream_spec.rb",
303
306
  "spec/integration/rels_ext_datastream_spec.rb",
304
307
  "spec/integration/repository_spec.rb",
305
308
  "spec/integration/rf_fedora_object_spec.rb",
@@ -249,10 +249,19 @@ module ActiveFedora
249
249
  # Add the given file as a datastream in the object
250
250
  #
251
251
  # @param [File] file the file to add
252
- # @param [Hash] opts options: :dsid, :label
252
+ # @param [Hash] opts options: :dsid, :label, :mimeType
253
253
  def add_file_datastream(file, opts={})
254
254
  label = opts.has_key?(:label) ? opts[:label] : ""
255
- ds = ActiveFedora::Datastream.new(:dsLabel => label, :controlGroup => 'M', :blob => file)
255
+ attrs = {:dsLabel => label, :controlGroup => 'M', :blob => file}
256
+ if opts.has_key?(:mime_type)
257
+ attrs.merge!({:mimeType=>opts[:mime_type]})
258
+ elsif opts.has_key?(:mimeType)
259
+ attrs.merge!({:mimeType=>opts[:mimeType]})
260
+ elsif opts.has_key?(:content_type)
261
+ attrs.merge!({:mimeType=>opts[:content_type]})
262
+ end
263
+
264
+ ds = ActiveFedora::Datastream.new(attrs)
256
265
  opts.has_key?(:dsid) ? ds.dsid=(opts[:dsid]) : nil
257
266
  add_datastream(ds)
258
267
  end
@@ -345,6 +354,12 @@ module ActiveFedora
345
354
  unless named_datastreams_desc.has_key?(name) && named_datastreams_desc[name].has_key?(:type)
346
355
  raise "Failed to add datastream. Named datastream #{name} not defined for object #{pid}."
347
356
  end
357
+
358
+ if opts.has_key?(:mime_type)
359
+ opts.merge!({:content_type=>opts[:mime_type]})
360
+ elsif opts.has_key?(:mimeType)
361
+ opts.merge!({:content_type=>opts[:mimeType]})
362
+ end
348
363
  opts.merge!(named_datastreams_desc[name])
349
364
 
350
365
  label = opts.has_key?(:label) ? opts[:label] : ""
@@ -366,8 +381,8 @@ module ActiveFedora
366
381
  if opts[:blob].respond_to?(:content_type)&&!opts[:blob].content_type.nil? && !opts.has_key?(:content_type)
367
382
  opts.merge!({:content_type=>opts[:blob].content_type})
368
383
  end
369
-
370
- raise "The blob must respond to content_type or the hash must have :content_type property set" unless opts.has_key?(:content_type)
384
+
385
+ raise "The blob must respond to content_type or the hash must have :content_type or :mime_type property set" unless opts.has_key?(:content_type)
371
386
 
372
387
  #throw error for mimeType mismatch
373
388
  if named_datastreams_desc[name].has_key?(:mimeType) && !named_datastreams_desc[name][:mimeType].eql?(opts[:content_type])
@@ -10,8 +10,11 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
10
10
  include Solrizer::XML::TerminologyBasedSolrizer # this adds support for calling .to_solr
11
11
 
12
12
  # extend(OM::XML::Container::ClassMethods)
13
+
14
+ alias_method(:om_term_values, :term_values) unless method_defined?(:om_term_values)
15
+ alias_method(:om_update_values, :update_values) unless method_defined?(:om_update_values)
13
16
 
14
- attr_accessor :ng_xml
17
+ attr_accessor :ng_xml, :internal_solr_doc
15
18
 
16
19
  #constructor, calls up to ActiveFedora::Datastream's constructor
17
20
  def initialize(attrs=nil)
@@ -79,9 +82,20 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
79
82
  return xml.to_xml {|config| config.no_declaration}
80
83
  end
81
84
 
82
- #overriding this method just so metadatahelper method does not get called
85
+ # ** Experimental **
86
+ #
87
+ # This method is called by ActiveFedora::Base.load_instance_from_solr
88
+ # in order to initialize a nokogiri datastreams values from a solr document.
89
+ # This method merely sets the internal_solr_doc to the document passed in.
90
+ # Then any calls to get_values get values from the solr document on demand
91
+ # instead of directly from the xml stored in Fedora. This should be used
92
+ # for read-only purposes only, and instances where you want to improve performance by
93
+ # getting data from solr instead of Fedora.
94
+ #
95
+ # See ActiveFedora::Base.load_instance_from_solr and +get_values_from_solr+ for more information.
83
96
  def from_solr(solr_doc)
84
- #do nothing for now
97
+ #just initialize internal_solr_doc since any value retrieval will be done via lazy loading on this doc on-demand
98
+ @internal_solr_doc = solr_doc
85
99
  end
86
100
 
87
101
  def solrize_accessor(accessor_name, accessor_info, opts={})
@@ -109,7 +123,6 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
109
123
  solrize_accessor(child_accessor_name, child_accessor_info, opts={:solr_doc=>solr_doc, :parents=>parents+[{accessor_name=>nodeset.index(node)}] })
110
124
  end
111
125
  end
112
-
113
126
  end
114
127
 
115
128
  def solrize_node(node, accessor_pointer, solr_doc = Solr::Document.new)
@@ -124,7 +137,195 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
124
137
  solr_doc << Solr::Field.new(hierarchical_field_name => node.text)
125
138
  end
126
139
  end
127
-
140
+
141
+ # ** Experimental **
142
+ # This method is called by +get_values+ if this datastream has been initialized by calling from_solr method via
143
+ # ActiveFedora::Base.load_instance_from_solr. This method retrieves values from a preinitialized @internal_solr_doc instead of xml.
144
+ # This makes the datastream read-only and this method is not intended to be used in any other case.
145
+ #
146
+ # Values are retrieved from the @internal_solr_doc on-demand instead of via xml preloaded into memory.
147
+ # A term_pointer is passed in and if it contains hierarchical indexes it will detect which solr field values need to be returned.
148
+ #
149
+ # ====Example 1 (non-hierarchical term_pointer):
150
+ #
151
+ # term_pointer = [:image, :title_set, :title]
152
+ #
153
+ # Returns value of "image_title_set_title_t" in @internal_solr_doc
154
+ #
155
+ # ====Example 2 (hierarchical term_pointer that contains one or more indexes):
156
+ # term_pointer = [:image, {:title_set=>1}, :title]
157
+ #
158
+ # relevant xml:
159
+ # <image>
160
+ # <title_set>
161
+ # <title>Title 1</title>
162
+ # </title_set>
163
+ # </image>
164
+ # <image>
165
+ # <title_set>
166
+ # <title>Title 2</title>
167
+ # </title_set>
168
+ # <title_set>
169
+ # <title>Title 3</title>
170
+ # </title_set>
171
+ # </image>
172
+ #
173
+ # Repeating element nodes are indexed and will be stored in solr as follows:
174
+ # image_0_title_set_0_title_t = "Title 1"
175
+ # image_1_title_set_0_title_t = "Title 2"
176
+ # image_1_title_set_1_title_t = "Title 3"
177
+ #
178
+ # Even though no image element index is specified, only the second image element has two title_set elements so the expected return value is
179
+ # ["Title 3"]
180
+ #
181
+ # While loading from solr the xml hierarchy is not immediately apparent so we must detect first how many image elements with a title_set element exist
182
+ # and then check which of those elements have a second title element.
183
+ #
184
+ # As this nokogiri datastream is indexed in solr, a value at each level in the tree will be stored independently and therefore
185
+ # if 'image_0_title_set_0_title_t' exists in solr 'image_0_title_set_t' will also exist in solr.
186
+ # So, we will build up the relevant solr names incrementally for a given term_pointer. The last element in the
187
+ # solr_name will not contain an index.
188
+ #
189
+ # It then will do the following:
190
+ # Because no index is supplied for :image it will detect which indexes exist in solr
191
+ # image_0_title_set_t (found key and add 'image_0_title_set' to base solr_name list)
192
+ # image_1_title_set_t (found key and add 'image_0_title_set' to base solr_name list)
193
+ # image_2_title_set_t (not found and stop checking indexes for image)
194
+ # After iteration 1:
195
+ # bases = ["image_0_title_set","image_1_title_set"]
196
+ #
197
+ # Two image nodes were found and next sees index of 1 supplied for title_set so just uses index of 1 building off bases found in previous iteration
198
+ # image_0_title_set_1_title_t (not found remove 'image_0_title_set' from base solr_name list)
199
+ # image_1_title_set_1_title_t (found and replace 'image_1_title_set' with new base 'image_1_title_set_1_title')
200
+ #
201
+ # After iteration 2:
202
+ # bases = ["image_1_title_set_1_title"]
203
+ # It always looks ahead one element so we check if any elements are after title. There are not any other elements so we are done iterating.
204
+ # returns @internal_solr_doc["image_1_title_set_1_title_t"]
205
+ # @param [Array] term_pointer Term pointer similar to an xpath ie. [:image, :title_set, :title]
206
+ # @return [Array] If no values are found an empty Array is returned.
207
+ def get_values_from_solr(*term_pointer)
208
+ values = []
209
+ solr_doc = @internal_solr_doc
210
+ return values if solr_doc.nil?
211
+ begin
212
+ term = self.class.terminology.retrieve_term(*OM.pointers_to_flat_array(term_pointer, false))
213
+ #check if hierarchical term pointer
214
+ if is_hierarchical_term_pointer?(*term_pointer)
215
+ # if we are hierarchical need to detect all possible node values that exist
216
+ # we do this by building up the possible solr names parent by parent and/or child by child
217
+ # if an index is supplied for any node in the pointer it will be used
218
+ # otherwise it will include all nodes and indexes that exist in solr
219
+ bases = []
220
+ #add first item in term_pointer as start of bases
221
+ # then iterate through possible nodes that might exist
222
+ term_pointer.first.kind_of?(Hash) ? bases << term_pointer.first.keys.first : bases << term_pointer.first
223
+ for i in 1..(term_pointer.length-1)
224
+ #iterate in reverse so that we can modify the bases array while iterating
225
+ (bases.length-1).downto(0) do |j|
226
+ current_last = (term_pointer[i].kind_of?(Hash) ? term_pointer[i].keys.first : term_pointer[i])
227
+ if (term_pointer[i-1].kind_of?(Hash))
228
+ #just use index supplied instead of trying possibilities
229
+ index = term_pointer[i-1].values.first
230
+ solr_name_base = OM::XML::Terminology.term_hierarchical_name({bases[j]=>index},current_last)
231
+ solr_name = generate_solr_symbol(solr_name_base, term.data_type)
232
+ bases.delete_at(j)
233
+ #insert the new solr name base if found
234
+ bases.insert(j,solr_name_base) if has_solr_name?(solr_name,solr_doc)
235
+ else
236
+ #detect how many nodes exist
237
+ index = 0
238
+ current_base = bases[j]
239
+ bases.delete_at(j)
240
+ solr_name_base = OM::XML::Terminology.term_hierarchical_name({current_base=>index},current_last)
241
+ solr_name = generate_solr_symbol(solr_name_base, term.data_type)
242
+ #check for indexes that exist until we find all nodes
243
+ while has_solr_name?(solr_name,solr_doc) do
244
+ #only reinsert if it exists
245
+ bases.insert(j,solr_name_base)
246
+ index = index + 1
247
+ solr_name_base = OM::XML::Terminology.term_hierarchical_name({current_base=>index},current_last)
248
+ solr_name = generate_solr_symbol(solr_name_base, term.data_type)
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ #all existing applicable solr_names have been found and we can now grab all values and build up our value array
255
+ bases.each do |base|
256
+ field_name = generate_solr_symbol(base.to_sym, term.data_type)
257
+ value = (solr_doc[field_name].nil? ? solr_doc[field_name.to_s]: solr_doc[field_name])
258
+ unless value.nil?
259
+ value.is_a?(Array) ? values.concat(value) : values << value
260
+ end
261
+ end
262
+ else
263
+ #this is not hierarchical and we can simply look for the solr name created using the terms without any indexes
264
+ generic_field_name_base = OM::XML::Terminology.term_generic_name(*term_pointer)
265
+ generic_field_name = generate_solr_symbol(generic_field_name_base, term.data_type)
266
+ value = (solr_doc[generic_field_name].nil? ? solr_doc[generic_field_name.to_s]: solr_doc[generic_field_name])
267
+ unless value.nil?
268
+ value.is_a?(Array) ? values.concat(value) : values << value
269
+ end
270
+ end
271
+ rescue Exception => e
272
+ #just do nothing since term does not exist and return emtpy values
273
+ raise e
274
+ end
275
+ values
276
+ end
277
+
278
+ def generate_solr_symbol(base, data_type)
279
+ Solrizer::XML::TerminologyBasedSolrizer.default_field_mapper.solr_name(base.to_sym, data_type)
280
+ end
281
+
282
+ # ** Experimental **
283
+ #@return [Boolean] true if either the key for name exists in solr or if its string value exists
284
+ #@param [String] name Name of key to look for
285
+ #@param [Solr::Document] solr_doc Solr doc to query
286
+ def has_solr_name?(name, solr_doc=Solr::Document.new)
287
+ !solr_doc[name].nil? || !solr_doc[name.to_s].nil?
288
+ end
289
+
290
+ # ** Experimental **
291
+ #@return true if the term_pointer contains an index
292
+ # ====Example:
293
+ # [:image, {:title_set=>1}, :title] return true
294
+ # [:image, :title_set, :title] return false
295
+ def is_hierarchical_term_pointer?(*term_pointer)
296
+ if term_pointer.length>1
297
+ term_pointer.each do |pointer|
298
+ if pointer.kind_of?(Hash)
299
+ return true
300
+ end
301
+ end
302
+ end
303
+ return false
304
+ end
305
+
306
+ # Update field values within the current datastream
307
+ # @param [Hash] params The params specifying which fields to update and their new values. Format: term_pointer => {index => value, ...}
308
+ # term_pointer must be a valind OM Term pointer (ie. [:name]). Strings will be ignored.
309
+ # @param [Hash] opts This is not currently used by the datastream-level update_indexed_attributes method
310
+ #
311
+ # Example:
312
+ # @mods_ds.update_indexed_attributes( {[{":person"=>"0"}, "role"]=>{"0"=>"role1", "1"=>"role2", "2"=>"role3"} })
313
+ # => {"person_0_role"=>{"0"=>"role1", "1"=>"role2", "2"=>"role3"}}
314
+ #
315
+ # @mods_ds.to_xml will return something like this:
316
+ # <mods>
317
+ # <mods:name type="person">
318
+ # <mods:role>
319
+ # <mods:roleTerm>role1</mods:roleTerm>
320
+ # </mods:role>
321
+ # <mods:role>
322
+ # <mods:roleTerm>role2</mods:roleTerm>
323
+ # </mods:role>
324
+ # <mods:role>
325
+ # <mods:roleTerm>role3</mods:roleTerm>
326
+ # </mods:role>
327
+ # </mods:name>
328
+ # </mods>
128
329
  def update_indexed_attributes(params={}, opts={})
129
330
  if self.class.terminology.nil?
130
331
  raise "No terminology is set for this NokogiriDatastream class. Cannot perform update_indexed_attributes"
@@ -134,6 +335,7 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
134
335
  current_params = params.clone
135
336
  current_params.delete_if do |term_pointer,new_values|
136
337
  if term_pointer.kind_of?(String)
338
+ logger.warn "WARNING: #{dsid} ignoring {#{term_pointer.inspect} => #{new_values.inspect}} because #{term_pointer.inspect} is a String (only valid OM Term Pointers will be used). Make sure your html has the correct field_selector tags in it."
137
339
  true
138
340
  else
139
341
  !self.class.terminology.has_term?(*OM.destringify(term_pointer))
@@ -153,4 +355,24 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
153
355
  term_values(*field_key)
154
356
  end
155
357
 
156
- end
358
+ # Override the method in OM::XML::TermValueOperators so that returns an error if we have loaded from solr since it should be read-only
359
+ #
360
+ # example term values hash: {[{":person"=>"0"}, "role", "text"]=>{"0"=>"role1", "1"=>"role2", "2"=>"role3"}, [{:person=>1}, :family_name]=>"Andronicus", [{"person"=>"1"},:given_name]=>["Titus"],[{:person=>1},:role,:text]=>["otherrole1","otherrole2"] }
361
+ def update_values(params={})
362
+ if @internal_solr_doc
363
+ raise "No update performed, this object was initialized via Solr instead of Fedora and is therefore read-only. Please utilize ActiveFedora::Base.load_instance to first load object via Fedora instead."
364
+ else
365
+ om_update_values(params)
366
+ end
367
+ end
368
+
369
+ #override OM::XML::term_values so can lazy load from solr if this datastream initialized using +from_solr+
370
+ def term_values(*term_pointer)
371
+ if @internal_solr_doc
372
+ #lazy load values from solr on demand
373
+ get_values_from_solr(*term_pointer)
374
+ else
375
+ om_term_values(*term_pointer)
376
+ end
377
+ end
378
+ end
@@ -586,6 +586,22 @@ module ActiveFedora
586
586
  self.send(:define_method,:"#{append_method_name}") {|object| add_named_relationship(name,object)}
587
587
  self.send(:define_method,:"#{remove_method_name}") {|object| remove_named_relationship(name,object)}
588
588
  end
589
+
590
+ # ** EXPERIMENTAL **
591
+ # Similar to +create_named_relationship_methods+ except we are merely creating an alias for outbound portion of bidirectional
592
+ #
593
+ # ====Example
594
+ # has_bidirectional_relationship "members", :has_collection_member, :is_member_of_collection
595
+ #
596
+ # Method members_outbound_append and members_outbound_remove added
597
+ # This method will create members_append which does same thing as members_outbound_append
598
+ # and will create members_remove which does same thing as members_outbound_remove
599
+ def create_bidirectional_named_relationship_methods(name,outbound_name)
600
+ append_method_name = "#{name.to_s.downcase}_append"
601
+ remove_method_name = "#{name.to_s.downcase}_remove"
602
+ self.send(:define_method,:"#{append_method_name}") {|object| add_named_relationship(outbound_name,object)}
603
+ self.send(:define_method,:"#{remove_method_name}") {|object| remove_named_relationship(outbound_name,object)}
604
+ end
589
605
 
590
606
  def create_inbound_relationship_finders(name, predicate, opts = {})
591
607
  class_eval <<-END
@@ -650,6 +666,7 @@ module ActiveFedora
650
666
  end
651
667
 
652
668
  # Generates relationship finders for predicates that point in both directions
669
+ # and registers predicate relationships for each direction.
653
670
  #
654
671
  # @name Name of the relationship method(s) to create
655
672
  # @outbound_predicate Predicate used in outbound relationships
@@ -659,9 +676,12 @@ module ActiveFedora
659
676
  def create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts={})
660
677
  inbound_method_name = name.to_s+"_inbound"
661
678
  outbound_method_name = name.to_s+"_outbound"
662
- create_outbound_relationship_finders(outbound_method_name, outbound_predicate, opts)
663
- create_inbound_relationship_finders(inbound_method_name, inbound_predicate, opts)
664
-
679
+ has_relationship(outbound_method_name, outbound_predicate, opts)
680
+ has_relationship(inbound_method_name, inbound_predicate, opts.merge!(:inbound=>true))
681
+
682
+ #create methods that mirror the outbound append and remove with our bidirectional name, assume just add and remove locally
683
+ create_bidirectional_named_relationship_methods(name,outbound_method_name)
684
+
665
685
  class_eval <<-END
666
686
  def #{name}(opts={})
667
687
  if opts[:response_format] == :solr || opts[:response_format] == :load_from_solr
@@ -188,11 +188,14 @@ module Fedora
188
188
  # remote service and resources.
189
189
  def http
190
190
  http = Net::HTTP.new(@site.host, @site.port)
191
- if(@site.is_a?(URI::HTTPS) && !SSL_CLIENT_CERT_FILE.nil? && !SSL_CLIENT_KEY_FILE.nil? && !SSL_CLIENT_KEY_PASS.nil?)
191
+ if(@site.is_a?(URI::HTTPS))
192
192
  http.use_ssl = true
193
- http.cert = OpenSSL::X509::Certificate.new( File.read(SSL_CLIENT_CERT_FILE) )
194
- http.key = OpenSSL::PKey::RSA.new( File.read(SSL_CLIENT_KEY_FILE), SSL_CLIENT_KEY_PASS )
195
193
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
194
+
195
+ if (defined?(SSL_CLIENT_CERT_FILE) && !SSL_CLIENT_CERT_FILE.nil? && defined?(SSL_CLIENT_KEY_FILE) && !SSL_CLIENT_KEY_FILE.nil? && defined?(SSL_CLIENT_KEY_PASS) && !SSL_CLIENT_KEY_PASS.nil?)
196
+ http.cert = OpenSSL::X509::Certificate.new( File.read(SSL_CLIENT_CERT_FILE) )
197
+ http.key = OpenSSL::PKey::RSA.new( File.read(SSL_CLIENT_KEY_FILE), SSL_CLIENT_KEY_PASS )
198
+ end
196
199
  end
197
200
  http
198
201
  end
@@ -212,4 +215,4 @@ module Fedora
212
215
  (@site.user || @site.password ? { 'Authorization' => 'Basic ' + ["#{@site.user}:#{ @site.password}"].pack('m').delete("\r\n") } : {})
213
216
  end
214
217
  end
215
- end
218
+ end
@@ -89,13 +89,31 @@ xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/
89
89
  <displayForm>NAME AS IT APPEARS</displayForm>
90
90
  <affiliation>FACULTY, UNIVERSITY</affiliation>
91
91
  <role>
92
- <roleTerm authority="marcrelator" type="text">creator</roleTerm>
92
+ <roleTerm authority="marcrelator" type="text">Creator</roleTerm>
93
93
  </role>
94
+ </name>
95
+ <name type="personal">
96
+ <namePart type="family">Lacks</namePart>
97
+ <namePart type="given">Henrietta</namePart>
98
+ <displayForm>HeLa</displayForm>
99
+ <affiliation>Baltimore</affiliation>
94
100
  <role>
95
- <roleTerm type="text">submitter</roleTerm>
101
+ <roleTerm authority="marcrelator" type="text">Contributor</roleTerm>
96
102
  </role>
97
103
  </name>
98
-
104
+ <name type="corporate">
105
+ <namePart>NSF</namePart>
106
+ <role>
107
+ <roleTerm authority="marcrelator" type="text">Funder</roleTerm>
108
+ </role>
109
+ </name>
110
+ <name type="conference">
111
+ <namePart>some conference</namePart>
112
+ <role>
113
+ <roleTerm authority="marcrelator" type="text">Host</roleTerm>
114
+ </role>
115
+ </name>
116
+
99
117
  <typeOfResource>text</typeOfResource>
100
118
  <genre authority="local">journal article</genre>
101
119
 
@@ -158,7 +176,7 @@ xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/
158
176
  <foxml:xmlContent>
159
177
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
160
178
  <rdf:Description rdf:about="info:fedora/hydrangea:fixture_mods_article1">
161
- <hasModel xmlns="info:fedora/fedora-system:def/relations-external#" rdf:resource="info:fedora/afmodel:ModsArticle"></hasModel>
179
+ <hasModel xmlns="info:fedora/fedora-system:def/relations-external#" rdf:resource="info:fedora/afmodel:HydrangeaArticle"></hasModel>
162
180
  </rdf:Description>
163
181
  </rdf:RDF>
164
182
  </foxml:xmlContent>
@@ -167,13 +185,42 @@ xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/
167
185
  <foxml:datastream ID="rightsMetadata" STATE="A" CONTROL_GROUP="X" VERSIONABLE="true">
168
186
  <foxml:datastreamVersion ID="rightsMetadata.0" LABEL="" CREATED="2010-06-17T19:56:23.335Z" MIMETYPE="text/xml" SIZE="19">
169
187
  <foxml:xmlContent>
170
- <fields>
171
- <discover_access_group>public</discover_access_group>
172
- <read_access_group>public</read_access_group>
173
- <edit_access_group>researcher</edit_access_group>
174
- <edit_access_group>archivist</edit_access_group>
175
- <edit_access>researcher1</edit_access>
176
- </fields>
188
+ <rightsMetadata xmlns="http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1">
189
+ <copyright>
190
+ <human>(c)2009 The Hydra Project</human>
191
+ <human type="someSpecialisedType">Blah Blah</human>
192
+ <human type="aDifferentType">More blah</human>
193
+ <machine><a rel="license" href="http://creativecommons.org/licenses/publicdomain/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/publicdomain/88x31.png" /></a><br />This work is in the <a rel="license" href="http://creativecommons.org/licenses/publicdomain/">Public Domain</a>.</machine>
194
+ </copyright>
195
+ <access type="discover">
196
+ <human></human>
197
+ <machine>
198
+ <policy>hydra-policy:4502</policy>
199
+ <group>public</group>
200
+ </machine>
201
+ </access>
202
+ <access type="read">
203
+ <human></human>
204
+ <machine>
205
+ <group>public</group>
206
+ </machine>
207
+ </access>
208
+ <access type="edit">
209
+ <human></human>
210
+ <machine>
211
+ <person>researcher1</person>
212
+ <group>archivist</group>
213
+ </machine>
214
+ </access>
215
+ <access type="etc">
216
+ <!-- etc -->
217
+ </access>
218
+ <use>
219
+ <human>You are free to re-distribute this object, but you cannot change it or sell it. </human>
220
+ <machine><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-nd/3.0/us/88x31.png" /></a><br />This <span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Sound" rel="dc:type">work</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/us/">Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License</a>.</machine>
221
+ </use>
222
+
223
+ </rightsMetadata>
177
224
  </foxml:xmlContent>
178
225
  </foxml:datastreamVersion>
179
226
  </foxml:datastream>