active-fedora 9.0.8 → 9.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/History.txt +0 -57
  3. data/README.md +38 -24
  4. data/active-fedora.gemspec +1 -1
  5. data/lib/active_fedora.rb +1 -0
  6. data/lib/active_fedora/associations.rb +1 -1
  7. data/lib/active_fedora/attached_files.rb +1 -1
  8. data/lib/active_fedora/attributes.rb +36 -10
  9. data/lib/active_fedora/attributes/property_builder.rb +1 -0
  10. data/lib/active_fedora/clean_connection.rb +40 -0
  11. data/lib/active_fedora/fedora.rb +4 -0
  12. data/lib/active_fedora/file.rb +5 -5
  13. data/lib/active_fedora/indexing.rb +14 -0
  14. data/lib/active_fedora/indexing/map.rb +46 -0
  15. data/lib/active_fedora/persistence.rb +4 -4
  16. data/lib/active_fedora/rdf/datastream_indexing.rb +4 -0
  17. data/lib/active_fedora/rdf/fcrepo4.rb +1 -0
  18. data/lib/active_fedora/rdf/indexing_service.rb +18 -11
  19. data/lib/active_fedora/rdf/ldp.rb +3 -0
  20. data/lib/active_fedora/rdf/rdf_datastream.rb +12 -1
  21. data/lib/active_fedora/solr_query_builder.rb +1 -1
  22. data/lib/active_fedora/solr_service.rb +1 -1
  23. data/lib/active_fedora/version.rb +1 -1
  24. data/spec/integration/attributes_spec.rb +49 -3
  25. data/spec/integration/clean_connection_spec.rb +21 -0
  26. data/spec/integration/field_to_solr_name_spec.rb +11 -7
  27. data/spec/integration/has_and_belongs_to_many_associations_spec.rb +30 -26
  28. data/spec/integration/has_many_associations_spec.rb +6 -2
  29. data/spec/integration/json_serialization_spec.rb +11 -5
  30. data/spec/integration/nested_attribute_spec.rb +3 -1
  31. data/spec/integration/ntriples_datastream_spec.rb +23 -17
  32. data/spec/integration/persistence_spec.rb +3 -1
  33. data/spec/integration/relation_delegation_spec.rb +3 -1
  34. data/spec/integration/scoped_query_spec.rb +3 -1
  35. data/spec/integration/solr_instance_loader_spec.rb +4 -2
  36. data/spec/unit/attributes_spec.rb +52 -12
  37. data/spec/unit/base_active_model_spec.rb +5 -3
  38. data/spec/unit/base_spec.rb +4 -2
  39. data/spec/unit/callback_spec.rb +4 -2
  40. data/spec/unit/core_spec.rb +4 -2
  41. data/spec/unit/ntriples_datastream_spec.rb +24 -20
  42. data/spec/unit/query_result_builder_spec.rb +1 -1
  43. data/spec/unit/rdf/indexing_service_spec.rb +19 -17
  44. data/spec/unit/rdf_resource_datastream_spec.rb +14 -10
  45. data/spec/unit/simple_datastream_spec.rb +3 -1
  46. data/spec/unit/solr_query_builder_spec.rb +1 -1
  47. data/spec/unit/validations_spec.rb +4 -2
  48. metadata +12 -7
@@ -23,8 +23,8 @@ module ActiveFedora
23
23
  # @param [Hash] options
24
24
  # @option options [Boolean] :update_index (true) set false to skip indexing
25
25
  # @return [Boolean] true if save was successful, otherwise false
26
- def save(*args)
27
- create_or_update(*args)
26
+ def save(*options)
27
+ create_or_update(*options)
28
28
  end
29
29
 
30
30
  def save!(*args)
@@ -72,9 +72,9 @@ module ActiveFedora
72
72
  # Delete the object from Fedora and Solr. Run any before/after/around callbacks for destroy
73
73
  # @param [Hash] opts
74
74
  # @option opts [Boolean] :eradicate if passed in, eradicate the tombstone from Fedora
75
- def destroy(*args)
75
+ def destroy(*opts)
76
76
  raise ReadOnlyRecord if readonly?
77
- delete(*args)
77
+ delete(*opts)
78
78
  end
79
79
 
80
80
  def eradicate
@@ -26,6 +26,10 @@ module ActiveFedora::RDF
26
26
  def indexer
27
27
  ActiveFedora::RDF::IndexingService
28
28
  end
29
+
30
+ def index_config
31
+ @index_config ||= ActiveFedora::Indexing::Map.new
32
+ end
29
33
  end
30
34
 
31
35
  protected
@@ -7,5 +7,6 @@ module ActiveFedora::RDF
7
7
  property :hasVersionLabel
8
8
  property :lastModified
9
9
  property :status
10
+ property :ServerManaged
10
11
  end
11
12
  end
@@ -4,7 +4,6 @@ module ActiveFedora::RDF
4
4
  attr_reader :object
5
5
 
6
6
  # @param obj [#resource, #rdf_subject] the object to build an solr document for. Its class must respond to 'properties'
7
- # @param prefix_method [Lambda] This method gets the original name of the field and the options passed in. It should return the name of the field in the solr document
8
7
  def initialize(obj)
9
8
  @object = obj
10
9
  end
@@ -22,9 +21,8 @@ module ActiveFedora::RDF
22
21
 
23
22
  def add_assertions(prefix_method, solr_doc = {})
24
23
  fields.each do |field_key, field_info|
25
- values = resource.get_values(field_key)
26
24
  solr_field_key = solr_document_field_name(field_key, prefix_method)
27
- Array(values).each do |val|
25
+ Array(field_info[:values]).each do |val|
28
26
  append_to_solr_doc(solr_doc, solr_field_key, field_info, val)
29
27
  end
30
28
  end
@@ -70,22 +68,31 @@ module ActiveFedora::RDF
70
68
  object.class.properties
71
69
  end
72
70
 
71
+ def index_config
72
+ object.class.index_config
73
+ end
74
+
73
75
  # returns a Hash, e.g.: {field => { values: [], type: :something, behaviors: [] }, ...}
74
76
  def fields
75
77
  field_map = {}.with_indifferent_access
76
78
 
77
- properties.each do |name, config|
78
- type = config[:type]
79
- behaviors = config[:behaviors]
79
+ index_config.each do |name, index_field_config|
80
+ type = index_field_config.data_type
81
+ behaviors = index_field_config.behaviors
80
82
  next unless type and behaviors
81
- next if config[:class_name] && config[:class_name] < ActiveFedora::Base
82
- resource.query(subject: object.rdf_subject, predicate: config[:predicate]).each_statement do |statement|
83
- field_map[name] ||= { values: [], type: type, behaviors: behaviors}
84
- field_map[name][:values] << statement.object.to_s
85
- end
83
+ next if kind_of_af_base?(name)
84
+ field_map[name] = { values: find_values(name), type: type, behaviors: behaviors}
86
85
  end
87
86
  field_map
88
87
  end
89
88
 
89
+ def kind_of_af_base?(name)
90
+ config = properties[name.to_s]
91
+ config && config[:class_name] && config[:class_name] < ActiveFedora::Base
92
+ end
93
+
94
+ def find_values(name)
95
+ object.send(name) || []
96
+ end
90
97
  end
91
98
  end
@@ -3,4 +3,7 @@ class ActiveFedora::RDF::Ldp < RDF::StrictVocabulary("http://www.w3.org/ns/ldp#"
3
3
  # Property definitions
4
4
  property :contains
5
5
  property :member
6
+ property :PreferContainment
7
+ property :PreferEmptyContainer
8
+ property :PreferMembership
6
9
  end
@@ -16,6 +16,17 @@ module ActiveFedora
16
16
  @subject_block ||= lambda { |ds| parent_uri(ds) }
17
17
  end
18
18
 
19
+ def property(name, *args, &block)
20
+ super
21
+ add_attribute_indexing_config(name, &block) if block_given?
22
+ end
23
+
24
+ def add_attribute_indexing_config(name, &block)
25
+ Deprecation.warn(RDFDatastream, "Adding indexing to datastreams is deprecated")
26
+ # TODO the hash can be initalized to return on of these
27
+ index_config[name] ||= ActiveFedora::Indexing::Map::IndexObject.new &block
28
+ end
29
+
19
30
  # Trim the last segment off the URI to get the parents uri
20
31
  def parent_uri(ds)
21
32
  m = /^(.*)\/[^\/]*$/.match(ds.uri)
@@ -27,7 +38,7 @@ module ActiveFedora
27
38
  end
28
39
 
29
40
  ##
30
- # @param [Class] an object to set as the resource class, Must be a descendant of
41
+ # @param [Class] klass an object to set as the resource class, Must be a descendant of
31
42
  # ActiveTriples::Resource and include ActiveFedora::RDF::Persistence.
32
43
  #
33
44
  # @return [Class] the object resource class
@@ -21,7 +21,7 @@ module ActiveFedora
21
21
  end
22
22
 
23
23
  # Create a query with a clause for each key, value
24
- # @param [Hash, Array<Array<String>>] args key is the predicate, value is the target_uri
24
+ # @param [Hash, Array<Array<String>>] field_pairs key is the predicate, value is the target_uri
25
25
  # @param [String] join_with ('AND') the value we're joining the clauses with
26
26
  # @example
27
27
  # construct_query_for_rel [[:has_model, "info:fedora/afmodel:ComplexCollection"], [:has_model, "info:fedora/afmodel:ActiveFedora_Base"]], 'OR'
@@ -89,7 +89,7 @@ module ActiveFedora
89
89
  end
90
90
 
91
91
  # Create a query with a clause for each key, value
92
- # @param [Hash, Array<Array<String>>] args key is the predicate, value is the target_uri
92
+ # @param [Hash, Array<Array<String>>] field_pairs key is the predicate, value is the target_uri
93
93
  # @param [String] join_with ('AND') the value we're joining the clauses with
94
94
  # @example
95
95
  # construct_query_for_rel [[:has_model, "info:fedora/afmodel:ComplexCollection"], [:has_model, "info:fedora/afmodel:ActiveFedora_Base"]], 'OR'
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "9.0.8"
2
+ VERSION = "9.1.0.rc1"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
+
3
4
  describe "delegating attributes" do
4
5
  before :all do
5
6
  class PropertiesDatastream < ActiveFedora::OmDatastream
@@ -13,12 +14,18 @@ describe "delegating attributes" do
13
14
  has_metadata 'foo', type: ActiveFedora::SimpleDatastream do |m|
14
15
  m.field "title", :string
15
16
  end
16
- has_attributes :title, datastream: 'foo', multiple: false
17
+ Deprecation.silence(ActiveFedora::Attributes) do
18
+ has_attributes :title, datastream: 'foo', multiple: false
19
+ end
17
20
  end
18
21
  class RdfObject < ActiveFedora::Base
19
22
  contains 'foo', class_name: 'PropertiesDatastream'
20
- has_attributes :depositor, datastream: :foo, multiple: false
21
- has_attributes :wrangler, datastream: :foo, multiple: true
23
+ Deprecation.silence(ActiveFedora::Attributes) do
24
+ has_attributes :depositor, datastream: :foo, multiple: false do |index|
25
+ index.as :stored_searchable
26
+ end
27
+ has_attributes :wrangler, datastream: :foo, multiple: true
28
+ end
22
29
  property :resource_type, predicate: ::RDF::DC.type do |index|
23
30
  index.as :stored_searchable, :facetable
24
31
  end
@@ -31,6 +38,45 @@ describe "delegating attributes" do
31
38
  Object.send(:remove_const, :PropertiesDatastream)
32
39
  end
33
40
 
41
+ describe "#index_config" do
42
+ context "on a class with properties" do
43
+ subject { RdfObject.index_config }
44
+ it "should have configuration " do
45
+ expect(subject[:resource_type].behaviors).to eq [:stored_searchable, :facetable]
46
+ expect(subject[:depositor].behaviors).to eq [:stored_searchable]
47
+ end
48
+ end
49
+
50
+ context "when a class inherits properties" do
51
+ before do
52
+ class InheritedObject < RdfObject
53
+ end
54
+ end
55
+
56
+ after do
57
+ Object.send(:remove_const, :InheritedObject)
58
+ end
59
+
60
+ subject { InheritedObject.index_config }
61
+
62
+ it "should have configuration " do
63
+ expect(subject[:resource_type].behaviors).to eq [:stored_searchable, :facetable]
64
+ expect(subject[:depositor].behaviors).to eq [:stored_searchable]
65
+ end
66
+
67
+ context "when the inherited config is modifed" do
68
+ before do
69
+ InheritedObject.index_config[:resource_type].behaviors.delete(:stored_searchable)
70
+ end
71
+ subject { RdfObject.index_config }
72
+
73
+ it "the parent config is unchanged" do
74
+ expect(subject[:resource_type].behaviors).to eq [:stored_searchable, :facetable]
75
+ end
76
+ end
77
+ end
78
+ end
79
+
34
80
  context "with a simple datastream" do
35
81
  describe "save" do
36
82
  subject do
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActiveFedora::CleanConnection do
4
+ subject { ActiveFedora.fedora.clean_connection }
5
+ describe "#get" do
6
+ context "when given an existing resource uri" do
7
+ let(:uri) { asset.rdf_subject }
8
+ let(:asset) do
9
+ ActiveFedora::Base.create do |a|
10
+ a.resource << [a.rdf_subject, RDF::DC.title, "test"]
11
+ end
12
+ end
13
+ let(:result) { subject.get(uri) }
14
+ it "should return a clean graph" do
15
+ graph = result.graph
16
+ expect(graph.statements.to_a.length).to eq 1
17
+ expect(graph.statements.to_a.first).to eq [asset.rdf_subject, RDF::DC.title, "test"]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,16 +5,20 @@ describe "An object with RDF backed attributes" do
5
5
  before do
6
6
  class TestOne < ActiveFedora::Base
7
7
  class MyMetadata < ActiveFedora::NtriplesRDFDatastream
8
- property :title, predicate: ::RDF::DC.title do |index|
9
- index.as :stored_searchable
10
- end
11
- property :date_uploaded, predicate: ::RDF::DC.dateSubmitted do |index|
12
- index.type :date
13
- index.as :stored_searchable, :sortable
8
+ Deprecation.silence(ActiveFedora::RDFDatastream) do
9
+ property :title, predicate: ::RDF::DC.title do |index|
10
+ index.as :stored_searchable
11
+ end
12
+ property :date_uploaded, predicate: ::RDF::DC.dateSubmitted do |index|
13
+ index.type :date
14
+ index.as :stored_searchable, :sortable
15
+ end
14
16
  end
15
17
  end
16
18
  has_metadata 'descMetadata', type: MyMetadata
17
- has_attributes :title, :date_uploaded, datastream: 'descMetadata'
19
+ Deprecation.silence(ActiveFedora::Attributes) do
20
+ has_attributes :title, :date_uploaded, datastream: 'descMetadata'
21
+ end
18
22
  end
19
23
  end
20
24
 
@@ -355,7 +355,9 @@ describe ActiveFedora::Base do
355
355
  has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
356
356
  m.field "title", :string
357
357
  end
358
- has_attributes :title, datastream: 'foo'
358
+ Deprecation.silence(ActiveFedora::Attributes) do
359
+ has_attributes :title, datastream: 'foo'
360
+ end
359
361
  end
360
362
 
361
363
  class Component < ActiveFedora::Base
@@ -363,32 +365,34 @@ describe ActiveFedora::Base do
363
365
  has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
364
366
  m.field "description", :string
365
367
  end
366
- has_attributes :description, datastream: 'foo'
368
+ Deprecation.silence(ActiveFedora::Attributes) do
369
+ has_attributes :description, datastream: 'foo'
370
+ end
367
371
  end
372
+ end
368
373
 
369
- after do
370
- Object.send(:remove_const, :Item)
371
- Object.send(:remove_const, :Component)
372
- end
374
+ after do
375
+ Object.send(:remove_const, :Item)
376
+ Object.send(:remove_const, :Component)
377
+ end
373
378
 
374
- describe "From the has_and_belongs_to_many side" do
375
- describe "dependent records" do
376
- let(:component) { Component.create(items: [Item.new(title: 'my title')]) }
379
+ describe "From the has_and_belongs_to_many side" do
380
+ describe "dependent records" do
381
+ let(:component) { Component.create(items: [Item.new(title: 'my title')]) }
377
382
 
378
- it "should be saved" do
379
- component.reload
380
- expect(component.items.first.title).to eq 'my title'
381
- end
383
+ it "should be saved" do
384
+ component.reload
385
+ expect(component.items.first.title).to eq 'my title'
382
386
  end
387
+ end
383
388
 
384
- describe "shifting" do
385
- let(:component) { Component.new }
386
- let(:item) { Item.create }
389
+ describe "shifting" do
390
+ let(:component) { Component.new }
391
+ let(:item) { Item.create }
387
392
 
388
- it "should set item_ids" do
389
- component.items << item
390
- expect(component.item_ids).to eq [item.id]
391
- end
393
+ it "should set item_ids" do
394
+ component.items << item
395
+ expect(component.item_ids).to eq [item.id]
392
396
  end
393
397
  end
394
398
 
@@ -408,14 +412,14 @@ describe ActiveFedora::Base do
408
412
  end
409
413
  end
410
414
  end
415
+ end
411
416
 
412
- describe "From the has_many side" do
413
- let(:item) { Item.create(components: [Component.new(description: 'my description')]) }
417
+ describe "From the has_many side" do
418
+ let(:item) { Item.create(components: [Component.new(description: 'my description')]) }
414
419
 
415
- it "should save dependent records" do
416
- item.reload
417
- expect(item.components.first.description).to eq 'my description'
418
- end
420
+ it "should save dependent records" do
421
+ item.reload
422
+ expect(item.components.first.description).to eq 'my description'
419
423
  end
420
424
  end
421
425
  end
@@ -276,14 +276,18 @@ describe "Autosave" do
276
276
  has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
277
277
  m.field "title", :string
278
278
  end
279
- has_attributes :title, datastream: 'foo'
279
+ Deprecation.silence(ActiveFedora::Attributes) do
280
+ has_attributes :title, datastream: 'foo'
281
+ end
280
282
  end
281
283
  class Component < ActiveFedora::Base
282
284
  belongs_to :item, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
283
285
  has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
284
286
  m.field "description", :string
285
287
  end
286
- has_attributes :description, datastream: 'foo'
288
+ Deprecation.silence(ActiveFedora::Attributes) do
289
+ has_attributes :description, datastream: 'foo'
290
+ end
287
291
  end
288
292
  end
289
293
 
@@ -12,8 +12,10 @@ describe "Objects should be serialized to JSON" do
12
12
  m.field "foo", :text
13
13
  m.field "bar", :text
14
14
  end
15
- has_attributes :foo, datastream: 'descMetadata', multiple: true
16
- has_attributes :bar, datastream: 'descMetadata', multiple: false
15
+ Deprecation.silence(ActiveFedora::Attributes) do
16
+ has_attributes :foo, datastream: 'descMetadata', multiple: true
17
+ has_attributes :bar, datastream: 'descMetadata', multiple: false
18
+ end
17
19
  property :title, predicate: ::RDF::DC.title
18
20
  end
19
21
  end
@@ -43,8 +45,10 @@ describe "Objects should be serialized to JSON" do
43
45
  end
44
46
 
45
47
  class DummyResource < ActiveFedora::RDFDatastream
46
- property :license, predicate: ::RDF::DC[:license], class_name: DummySubnode do |index|
47
- index.as :searchable, :displayable
48
+ Deprecation.silence(ActiveFedora::RDFDatastream) do
49
+ property :license, predicate: ::RDF::DC[:license], class_name: DummySubnode do |index|
50
+ index.as :searchable, :displayable
51
+ end
48
52
  end
49
53
  def serialization_format
50
54
  :ntriples
@@ -53,7 +57,9 @@ describe "Objects should be serialized to JSON" do
53
57
 
54
58
  class DummyAsset < ActiveFedora::Base
55
59
  has_metadata 'descMetadata', type: DummyResource
56
- has_attributes :relation, datastream: 'descMetadata', at: [:license, :relation], multiple: false
60
+ Deprecation.silence(ActiveFedora::Attributes) do
61
+ has_attributes :relation, datastream: 'descMetadata', at: [:license, :relation], multiple: false
62
+ end
57
63
  end
58
64
  end
59
65
 
@@ -8,7 +8,9 @@ describe "NestedAttribute behavior" do
8
8
  m.field "uno", :string
9
9
  m.field "dos", :string
10
10
  end
11
- has_attributes :uno, :dos, datastream: 'someData', multiple: false
11
+ Deprecation.silence(ActiveFedora::Attributes) do
12
+ has_attributes :uno, :dos, datastream: 'someData', multiple: false
13
+ end
12
14
  end
13
15
 
14
16
  # base Car class, used in test for association updates and :allow_destroy flag
@@ -7,27 +7,31 @@ describe ActiveFedora::NtriplesRDFDatastream do
7
7
  property :size
8
8
  end
9
9
 
10
- class MyDatastream < ActiveFedora::NtriplesRDFDatastream
11
- property :title, predicate: ::RDF::DC.title do |index|
12
- index.as :stored_searchable, :facetable
13
- end
14
- property :date_uploaded, predicate: ::RDF::DC.dateSubmitted do |index|
15
- index.type :date
16
- index.as :stored_searchable, :sortable
17
- end
18
- property :filesize, predicate: FileVocabulary.size do |index|
19
- index.type :integer
20
- index.as :stored_sortable
10
+ Deprecation.silence(ActiveFedora::RDFDatastream) do
11
+ class MyDatastream < ActiveFedora::NtriplesRDFDatastream
12
+ property :title, predicate: ::RDF::DC.title do |index|
13
+ index.as :stored_searchable, :facetable
14
+ end
15
+ property :date_uploaded, predicate: ::RDF::DC.dateSubmitted do |index|
16
+ index.type :date
17
+ index.as :stored_searchable, :sortable
18
+ end
19
+ property :filesize, predicate: FileVocabulary.size do |index|
20
+ index.type :integer
21
+ index.as :stored_sortable
22
+ end
23
+ property :part, predicate: ::RDF::DC.hasPart
24
+ property :based_near, predicate: ::RDF::FOAF.based_near
25
+ property :related_url, predicate: ::RDF::RDFS.seeAlso
21
26
  end
22
- property :part, predicate: ::RDF::DC.hasPart
23
- property :based_near, predicate: ::RDF::FOAF.based_near
24
- property :related_url, predicate: ::RDF::RDFS.seeAlso
25
27
  end
26
28
 
27
29
  class RdfTest < ActiveFedora::Base
28
30
  has_metadata 'rdf', type: MyDatastream
29
- has_attributes :based_near, :related_url, :part, :date_uploaded, datastream: 'rdf', multiple: true
30
- has_attributes :title, :filesize, datastream: 'rdf', multiple: false
31
+ Deprecation.silence(ActiveFedora::Attributes) do
32
+ has_attributes :based_near, :related_url, :part, :date_uploaded, datastream: 'rdf', multiple: true
33
+ has_attributes :title, :filesize, datastream: 'rdf', multiple: false
34
+ end
31
35
  end
32
36
  @subject = RdfTest.new
33
37
  end
@@ -216,7 +220,9 @@ describe ActiveFedora::NtriplesRDFDatastream do
216
220
  end
217
221
  class Foobar < ActiveFedora::Base
218
222
  has_metadata 'rdf', type: TitleDatastream
219
- has_attributes :title, datastream: 'rdf', multiple: true
223
+ Deprecation.silence(ActiveFedora::Attributes) do
224
+ has_attributes :title, datastream: 'rdf', multiple: true
225
+ end
220
226
  end
221
227
  @subject = Foobar.new
222
228
  @subject.title = ["title1", "title2", "title3"]