active-fedora 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
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>