active-fedora 9.0.0.rc3 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/History.txt +1054 -0
  3. data/active-fedora.gemspec +1 -1
  4. data/config/predicate_mappings.yml +2 -2
  5. data/lib/active_fedora.rb +3 -0
  6. data/lib/active_fedora/attached_files.rb +31 -14
  7. data/lib/active_fedora/base.rb +2 -0
  8. data/lib/active_fedora/caching_connection.rb +80 -0
  9. data/lib/active_fedora/callbacks.rb +13 -14
  10. data/lib/active_fedora/core.rb +9 -17
  11. data/lib/active_fedora/errors.rb +1 -1
  12. data/lib/active_fedora/fedora.rb +5 -1
  13. data/lib/active_fedora/file.rb +42 -39
  14. data/lib/active_fedora/ldp_cache.rb +46 -0
  15. data/lib/active_fedora/ldp_resource_service.rb +27 -0
  16. data/lib/active_fedora/loadable_from_json.rb +3 -1
  17. data/lib/active_fedora/log_subscriber.rb +38 -0
  18. data/lib/active_fedora/persistence.rb +22 -12
  19. data/lib/active_fedora/predicates.rb +3 -3
  20. data/lib/active_fedora/railtie.rb +3 -0
  21. data/lib/active_fedora/rdf.rb +0 -1
  22. data/lib/active_fedora/relation/finder_methods.rb +2 -3
  23. data/lib/active_fedora/validations.rb +1 -3
  24. data/lib/active_fedora/version.rb +1 -1
  25. data/lib/generators/active_fedora/config/solr/templates/jetty.yml +3 -2
  26. data/spec/fixtures/rails_root/config/predicate_mappings.yml +2 -2
  27. data/spec/integration/associations_spec.rb +19 -19
  28. data/spec/integration/attached_files_spec.rb +3 -3
  29. data/spec/integration/belongs_to_association_spec.rb +9 -9
  30. data/spec/integration/caching_spec.rb +59 -0
  31. data/spec/integration/collection_association_spec.rb +1 -1
  32. data/spec/integration/fedora_solr_sync_spec.rb +2 -2
  33. data/spec/integration/file_spec.rb +41 -43
  34. data/spec/integration/has_and_belongs_to_many_associations_spec.rb +8 -8
  35. data/spec/integration/has_many_associations_spec.rb +15 -15
  36. data/spec/integration/nested_attribute_spec.rb +2 -2
  37. data/spec/integration/relation_spec.rb +1 -1
  38. data/spec/integration/solr_instance_loader_spec.rb +2 -1
  39. data/spec/samples/special_thing.rb +2 -2
  40. data/spec/spec_helper.rb +1 -0
  41. data/spec/unit/attached_files_spec.rb +41 -5
  42. data/spec/unit/attributes_spec.rb +1 -1
  43. data/spec/unit/change_set_spec.rb +1 -1
  44. data/spec/unit/code_configurator_spec.rb +3 -3
  45. data/spec/unit/core_spec.rb +16 -1
  46. data/spec/unit/file_spec.rb +14 -10
  47. data/spec/unit/has_and_belongs_to_many_association_spec.rb +6 -6
  48. data/spec/unit/has_many_association_spec.rb +4 -4
  49. data/spec/unit/indexing_service_spec.rb +2 -2
  50. data/spec/unit/ldp_resource_spec.rb +17 -0
  51. data/spec/unit/logger_spec.rb +1 -1
  52. data/spec/unit/persistence_spec.rb +24 -20
  53. data/spec/unit/predicates_spec.rb +7 -7
  54. data/spec/unit/sparql_insert_spec.rb +2 -2
  55. data/spec/unit/validations_spec.rb +12 -2
  56. metadata +13 -8
  57. data/lib/active_fedora/rdf/rels_ext.rb +0 -26
@@ -0,0 +1,46 @@
1
+ module ActiveFedora
2
+ # = Active Fedora Ldp Cache
3
+ class LdpCache
4
+ module ClassMethods
5
+ # Enable the query cache within the block if Active Fedora is configured.
6
+ # If it's not, it will execute the given block.
7
+ def cache(&block)
8
+ connection = ActiveFedora.fedora.connection
9
+ connection.cache(&block)
10
+ end
11
+
12
+ # Disable the query cache within the block if Active Fedora is configured.
13
+ # If it's not, it will execute the given block.
14
+ def uncached(&block)
15
+ ActiveFedora.fedora.connection.uncached(&block)
16
+ end
17
+ end
18
+
19
+ def initialize(app)
20
+ @app = app
21
+ end
22
+
23
+ def call(env)
24
+ ActiveFedora.fedora.connection.enable_cache!
25
+
26
+ response = @app.call(env)
27
+ response[2] = Rack::BodyProxy.new(response[2]) do
28
+ reset_cache_settings
29
+ end
30
+
31
+ response
32
+ rescue Exception => e
33
+ reset_cache_settings
34
+ raise e
35
+ end
36
+
37
+ private
38
+
39
+ def reset_cache_settings
40
+ ActiveFedora.fedora.connection.clear_cache
41
+ ActiveFedora.fedora.connection.disable_cache!
42
+ end
43
+
44
+ end
45
+ end
46
+
@@ -0,0 +1,27 @@
1
+ module ActiveFedora
2
+ class LdpResourceService
3
+ attr_reader :connection
4
+
5
+ def initialize(conn)
6
+ @connection = conn
7
+ end
8
+
9
+ def build(klass, id)
10
+ if id
11
+ LdpResource.new(connection, to_uri(klass, id))
12
+ else
13
+ LdpResource.new(connection, nil, nil, ActiveFedora.fedora.host + ActiveFedora.fedora.base_path)
14
+ end
15
+ end
16
+
17
+ def update(change_set, klass, id)
18
+ SparqlInsert.new(change_set.changes).execute(to_uri(klass, id))
19
+ end
20
+
21
+ private
22
+ def to_uri(klass, id)
23
+ klass.id_to_uri(id)
24
+ end
25
+
26
+ end
27
+ end
@@ -15,9 +15,11 @@ module ActiveFedora
15
15
  @hash.fetch(terminology.first, [])
16
16
  end
17
17
 
18
+ # It is expected that the singular filter gets applied after fetching the value from this
19
+ # resource, so cast everything back to an array.
18
20
  def update_indexed_attributes hash
19
21
  hash.each do |k, v|
20
- @hash[k.first] = v
22
+ @hash[k.first] = Array(v)
21
23
  end
22
24
  end
23
25
 
@@ -0,0 +1,38 @@
1
+ module ActiveFedora
2
+ class LogSubscriber < ActiveSupport::LogSubscriber
3
+
4
+ def initialize
5
+ super
6
+ @odd = false
7
+ end
8
+
9
+ def ldp(event)
10
+ return unless logger.debug?
11
+
12
+ payload = event.payload
13
+
14
+ name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
15
+ id = payload[:id] || "[no id]"
16
+
17
+ if odd?
18
+ name = color(name, CYAN, true)
19
+ id = color(id, nil, true)
20
+ else
21
+ name = color(name, MAGENTA, true)
22
+ end
23
+
24
+ debug " #{name} #{id} Service: #{payload[:ldp_service]}"
25
+ end
26
+
27
+ def odd?
28
+ @odd = !@odd
29
+ end
30
+
31
+ def logger
32
+ ActiveFedora::Base.logger
33
+ end
34
+ end
35
+ end
36
+
37
+ ActiveFedora::LogSubscriber.attach_to :active_fedora
38
+
@@ -23,13 +23,12 @@ 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(options={})
27
- raise ReadOnlyRecord if readonly?
28
- new_record? ? create_record(options) : update_record(options)
26
+ def save(*args)
27
+ create_or_update(*args)
29
28
  end
30
29
 
31
- def save!(options={})
32
- save(options)
30
+ def save!(*args)
31
+ create_or_update(*args)
33
32
  end
34
33
 
35
34
  # Pushes the object and all of its new or dirty attached files into Fedora
@@ -43,7 +42,7 @@ module ActiveFedora
43
42
  #Deletes a Base object, also deletes the info indexed in Solr, and
44
43
  #the underlying inner_object. If this object is held in any relationships (ie inbound relationships
45
44
  #outside of this object it will remove it from those items rels-ext as well
46
- def delete
45
+ def delete(opts = {})
47
46
  return self if new_record?
48
47
 
49
48
  @destroyed = true
@@ -55,7 +54,7 @@ module ActiveFedora
55
54
 
56
55
  id = self.id ## cache so it's still available after delete
57
56
  # Clear out the ETag
58
- @ldp_source = LdpResource.new(conn, uri)
57
+ @ldp_source = build_ldp_resource(id)
59
58
  begin
60
59
  @ldp_source.delete
61
60
  rescue Ldp::NotFound
@@ -63,12 +62,15 @@ module ActiveFedora
63
62
  end
64
63
 
65
64
  ActiveFedora::SolrService.delete(id) if ENABLE_SOLR_UPDATES
65
+ if opts[:eradicate]
66
+ self.class.eradicate(id)
67
+ end
66
68
  freeze
67
69
  end
68
70
 
69
- def destroy
71
+ def destroy(*args)
70
72
  raise ReadOnlyRecord if readonly?
71
- delete
73
+ delete(*args)
72
74
  end
73
75
 
74
76
  def eradicate
@@ -133,6 +135,11 @@ module ActiveFedora
133
135
 
134
136
  private
135
137
 
138
+ def create_or_update(*args)
139
+ raise ReadOnlyRecord if readonly?
140
+ new_record? ? create_record(*args) : update_record(*args)
141
+ end
142
+
136
143
  # Deals with preparing new object to be saved to Fedora, then pushes it and its attached files into Fedora.
137
144
  def create_record(options = {})
138
145
  assign_rdf_subject
@@ -152,20 +159,23 @@ module ActiveFedora
152
159
  end
153
160
 
154
161
  def refresh
155
- @ldp_source = LdpResource.new(conn, uri)
162
+ @ldp_source = build_ldp_resource(id)
156
163
  @resource = nil
157
164
  end
158
165
 
159
166
  def execute_sparql_update
160
167
  change_set = ChangeSet.new(self, self.resource, self.changed_attributes.keys)
161
168
  return true if change_set.empty?
162
- SparqlInsert.new(change_set.changes).execute(uri)
169
+ ActiveFedora.fedora.ldp_resource_service.update(change_set, self.class, id)
163
170
  end
164
171
 
165
-
172
+ # Override to tie in an ID minting service
166
173
  def assign_id
167
174
  end
168
175
 
176
+ # This is only used when creating a new record. If the object doesn't have an id
177
+ # and assign_id can mint an id for the object, then assign it to the resource.
178
+ # Otherwise the resource will have the id assigned by the LDP server
169
179
  def assign_rdf_subject
170
180
  @ldp_source = if !id && new_id = assign_id
171
181
  LdpResource.new(ActiveFedora.fedora.connection, self.class.id_to_uri(new_id), @resource)
@@ -25,7 +25,7 @@ module ActiveFedora
25
25
  rel_predicate = nil
26
26
  end
27
27
  else
28
- xmlns="http://fedora.info/definitions/v4/rels-ext#"
28
+ xmlns="info:fedora/fedora-system:def/relations-external#"
29
29
  begin
30
30
  rel_predicate = predicate_lookup(predicate,xmlns)
31
31
  rescue UnregisteredPredicateError
@@ -52,7 +52,7 @@ module ActiveFedora
52
52
  # If predicate is a symbol, looks up the predicate in the predicate_mappings
53
53
  # If predicate is not a Symbol, returns the predicate untouched
54
54
  # @raise UnregisteredPredicateError if the predicate is a symbol but is not found in the predicate_mappings
55
- def self.predicate_lookup(predicate,namespace="http://fedora.info/definitions/v4/rels-ext#")
55
+ def self.predicate_lookup(predicate,namespace="info:fedora/fedora-system:def/relations-external#")
56
56
  if predicate.class == Symbol
57
57
  if predicate_mappings[namespace].has_key?(predicate)
58
58
  return predicate_mappings[namespace][predicate]
@@ -100,7 +100,7 @@ module ActiveFedora
100
100
  # @example
101
101
  # ActiveFedora::Predicates.set_predicates({
102
102
  # "http://projecthydra.org/ns/relations#"=>{has_profile:"hasProfile"},
103
- # "http://fedora.info/definitions/v4/rels-ext#"=>{
103
+ # "info:fedora/fedora-system:def/relations-external#"=>{
104
104
  # references:"references",
105
105
  # has_derivation: "cameFrom"
106
106
  # },
@@ -1,6 +1,9 @@
1
1
  module ActiveFedora
2
2
  class Railtie < Rails::Railtie
3
3
 
4
+ config.app_middleware.insert_after "::ActionDispatch::Callbacks",
5
+ "ActiveFedora::LdpCache"
6
+
4
7
  initializer 'active_fedora.autoload', before: :set_autoload_paths do |app|
5
8
  app.config.autoload_paths << 'app/models/datastreams'
6
9
  end
@@ -8,7 +8,6 @@ module ActiveFedora
8
8
  autoload :IndexingService
9
9
  autoload :Identifiable
10
10
  autoload :Persistence
11
- autoload :RelsExt
12
11
  autoload :ProjectHydra
13
12
  end
14
13
  end
@@ -188,7 +188,7 @@ module ActiveFedora
188
188
 
189
189
  def load_from_fedora(id, cast)
190
190
  raise ActiveFedora::ObjectNotFoundError if id.empty?
191
- resource = LdpResource.new(ActiveFedora.fedora.connection, klass.id_to_uri(id))
191
+ resource = ActiveFedora.fedora.ldp_resource_service.build(klass, id)
192
192
  raise ActiveFedora::ObjectNotFoundError if resource.new?
193
193
  class_to_load(resource, cast).allocate.init_with_resource(resource) # Triggers the find callback
194
194
  end
@@ -202,9 +202,8 @@ module ActiveFedora
202
202
  end
203
203
  end
204
204
 
205
- # TODO just use has_model
206
205
  def has_model_value(resource)
207
- Ldp::Orm.new(resource).value(ActiveFedora::RDF::Fcrepo::Model.hasModel).first.to_s
206
+ resource.graph.query([nil, ActiveFedora::RDF::Fcrepo::Model.hasModel, nil]).first.object.to_s
208
207
  end
209
208
 
210
209
  def find_with_ids(ids, cast)
@@ -69,7 +69,7 @@ module ActiveFedora
69
69
  output = super(context)
70
70
  errors.empty? && output
71
71
  end
72
-
72
+
73
73
  # Test to see if the given field is required
74
74
  # @param [Symbol] key a field
75
75
  # @return [Boolean] is it required or not
@@ -85,5 +85,3 @@ module ActiveFedora
85
85
  end
86
86
  end
87
87
  end
88
-
89
-
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "9.0.0.rc3"
2
+ VERSION = "9.0.0"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  default:
2
+ startup_wait: 90
2
3
  jetty_port: 8983
3
4
  java_opts:
4
- - "-XX:MaxPermSize=128m"
5
- - "-Xmx256m"
5
+ - "-Xmx512m"
6
+ - "-XX:MaxPermSize=128m"
@@ -1,7 +1,7 @@
1
- :default_namespace: http://fedora.info/definitions/v4/rels-ext#
1
+ :default_namespace: info:fedora/fedora-system:def/relations-external#
2
2
 
3
3
  :predicate_mapping:
4
- http://fedora.info/definitions/v4/rels-ext#:
4
+ info:fedora/fedora-system:def/relations-external#:
5
5
  :is_derivation_of: isDerivationOf
6
6
  :is_metadata_for: isMetadataFor
7
7
  :is_member_of_collection: isMemberOfCollection
@@ -28,13 +28,13 @@ describe ActiveFedora::Base do
28
28
  describe "complex example" do
29
29
  before do
30
30
  class Library < ActiveFedora::Base
31
- has_many :books, predicate: ActiveFedora::RDF::RelsExt.hasConstituent
31
+ has_many :books, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasConstituent
32
32
  end
33
33
 
34
34
  class Book < ActiveFedora::Base
35
- belongs_to :library, predicate: ActiveFedora::RDF::RelsExt.hasConstituent
36
- belongs_to :author, predicate: ActiveFedora::RDF::RelsExt.hasMember, class_name: 'Person'
37
- belongs_to :publisher, predicate: ActiveFedora::RDF::RelsExt.hasMember
35
+ belongs_to :library, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasConstituent
36
+ belongs_to :author, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasMember, class_name: 'Person'
37
+ belongs_to :publisher, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasMember
38
38
  end
39
39
 
40
40
  class Person < ActiveFedora::Base
@@ -335,10 +335,10 @@ describe ActiveFedora::Base do
335
335
  describe "single direction habtm" do
336
336
  before :all do
337
337
  class Course < ActiveFedora::Base
338
- has_and_belongs_to_many :textbooks, predicate: ActiveFedora::RDF::RelsExt.isPartOf
338
+ has_and_belongs_to_many :textbooks, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
339
339
  end
340
340
  class Textbook < ActiveFedora::Base
341
- has_many :courses, predicate: ActiveFedora::RDF::RelsExt.isPartOf
341
+ has_many :courses, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
342
342
  end
343
343
 
344
344
  end
@@ -395,7 +395,7 @@ describe ActiveFedora::Base do
395
395
  describe "for habtm" do
396
396
  before :all do
397
397
  class LibraryBook < ActiveFedora::Base
398
- has_and_belongs_to_many :pages, predicate: ActiveFedora::RDF::RelsExt.isPartOf, after_remove: :after_hook, before_remove: :before_hook
398
+ has_and_belongs_to_many :pages, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, after_remove: :after_hook, before_remove: :before_hook
399
399
 
400
400
  def before_hook(m)
401
401
  say_hi(m)
@@ -413,7 +413,7 @@ describe ActiveFedora::Base do
413
413
 
414
414
  end
415
415
  class Page < ActiveFedora::Base
416
- has_many :library_books, predicate: ActiveFedora::RDF::RelsExt.isPartOf
416
+ has_many :library_books, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
417
417
  end
418
418
 
419
419
  end
@@ -441,11 +441,11 @@ describe ActiveFedora::Base do
441
441
  describe "for has_many" do
442
442
  before :all do
443
443
  class LibraryBook < ActiveFedora::Base
444
- has_many :pages, predicate: ActiveFedora::RDF::RelsExt.isPartOf, after_remove: :say_hi
444
+ has_many :pages, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, after_remove: :say_hi
445
445
 
446
446
  end
447
447
  class Page < ActiveFedora::Base
448
- belongs_to :library_book, predicate: ActiveFedora::RDF::RelsExt.isPartOf
448
+ belongs_to :library_book, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
449
449
  end
450
450
  end
451
451
 
@@ -472,7 +472,7 @@ describe ActiveFedora::Base do
472
472
  describe "when an object doesn't have a property, and the class_name is predictable" do
473
473
  before (:all) do
474
474
  class Bauble < ActiveFedora::Base
475
- belongs_to :media_object, predicate: ActiveFedora::RDF::RelsExt.isPartOf
475
+ belongs_to :media_object, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
476
476
  end
477
477
  class MediaObject < ActiveFedora::Base
478
478
  has_many :baubles
@@ -491,7 +491,7 @@ describe ActiveFedora::Base do
491
491
  describe "when an object doesn't have a property, but has a class_name" do
492
492
  before :all do
493
493
  class MasterFile < ActiveFedora::Base
494
- belongs_to :media_object, predicate: ActiveFedora::RDF::RelsExt.isPartOf
494
+ belongs_to :media_object, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
495
495
  end
496
496
  class MediaObject < ActiveFedora::Base
497
497
  has_many :parts, class_name: 'MasterFile'
@@ -511,10 +511,10 @@ describe ActiveFedora::Base do
511
511
  describe "an object has an explicity property" do
512
512
  before :all do
513
513
  class Bauble < ActiveFedora::Base
514
- belongs_to :media_object, predicate: ActiveFedora::RDF::RelsExt.isPartOf
514
+ belongs_to :media_object, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
515
515
  end
516
516
  class MediaObject < ActiveFedora::Base
517
- has_many :baubles, predicate: ActiveFedora::RDF::RelsExt.hasEquivalent
517
+ has_many :baubles, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasEquivalent
518
518
  end
519
519
  end
520
520
 
@@ -531,7 +531,7 @@ describe ActiveFedora::Base do
531
531
  describe "an object doesn't have a property" do
532
532
  before :all do
533
533
  class Bauble < ActiveFedora::Base
534
- belongs_to :media_object, predicate: ActiveFedora::RDF::RelsExt.isPartOf
534
+ belongs_to :media_object, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
535
535
  end
536
536
 
537
537
  class MediaObject < ActiveFedora::Base
@@ -554,16 +554,16 @@ describe ActiveFedora::Base do
554
554
  describe "for habtm" do
555
555
  before :all do
556
556
  class Novel < ActiveFedora::Base
557
- has_and_belongs_to_many :contents, predicate: ActiveFedora::RDF::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
557
+ has_and_belongs_to_many :contents, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
558
558
  end
559
559
  class TextBook < ActiveFedora::Base
560
- has_and_belongs_to_many :contents, predicate: ActiveFedora::RDF::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
560
+ has_and_belongs_to_many :contents, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
561
561
  end
562
562
  class Text < ActiveFedora::Base
563
- has_many :books, predicate: ActiveFedora::RDF::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
563
+ has_many :books, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
564
564
  end
565
565
  class Image < ActiveFedora::Base
566
- has_many :books, predicate: ActiveFedora::RDF::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
566
+ has_many :books, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
567
567
  end
568
568
  end
569
569