active-fedora 9.3.0 → 9.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a9499d1539f4cfe6d15bd6240a7636945f49251
4
- data.tar.gz: 62c6f9a13eb35a9eaaf269680de4e6624b25fd5f
3
+ metadata.gz: 6ac63eb4554f1aae295bbaba4175725bdb50b2c8
4
+ data.tar.gz: 3a5503efabdbb3b403d6d3f546f1b5aa40e3072a
5
5
  SHA512:
6
- metadata.gz: 180ae74d2fd67d14b7d205b186cee646915b376257687fe7d9c85731ba5acd6bce8fe4a9990fb065200b2d954c9a10f3006960cec37ca27fbd41b12dc1761ee3
7
- data.tar.gz: 99a9bfb6277533275cab73575d3a6c474bed490d6ec51973fcc99ef6e124e23445f85bae8d78f62ca6f316dbe2849026ef6d96d5723e707755ea7c1c4ac23313
6
+ metadata.gz: dfe295788f5d242148d4b6ac81ad73ac95d6c564cf1c6cafbb5a9430e99453472c8e8af71d5a25f5a0cea1ace59a09191d7f53a5e5b990366bfc146c9c5f5829
7
+ data.tar.gz: 964c28d8d669bae563794d76d8b4b99a7d9f322f9482252ded396e685a15e37d254f5d179ccd956521db2787f8835da32919cb0a000c08b60c2b9b9f9a7dabb0
@@ -1,3 +1,17 @@
1
+ v9.4.0
2
+ 2015-09-01: Don't run type validators on destroy. [Trey Terrell] [pgwillia
3
+
4
+ 2015-08-29: Use Fcrepo 4 and LDP from RDF::Vocab. [Esmé Cowles]
5
+
6
+ 2015-08-28: Use premis:hasMessageDigest for checksum, falling back to
7
+ fedora:digest. [Esmé Cowles]
8
+
9
+ 2015-08-25: Update README to reflect dependency on Solr 4.10 [pgwillia]
10
+
11
+ 2015-08-19: Enable support for Hash URIs [Trey Terrell]
12
+
13
+ 2015-08-13: Stop using InboundRelationConnection [Justin Coyne]
14
+
1
15
  v9.3.0
2
16
  2015-08-06: Records should be able to be marshaled and loaded [Justin Coyne]
3
17
 
data/README.md CHANGED
@@ -9,7 +9,7 @@ Description
9
9
  ActiveFedora is a Ruby gem for creating and
10
10
  managing objects in the Fedora Repository Architecture
11
11
  ([http://fedora-commons.org](http://fedora-commons.org)). ActiveFedora
12
- is loosely based on “ActiveRecord” in Rails. Version 9.0+ works with Fedora 4 and prior versions work on Fedora 3.
12
+ is loosely based on “ActiveRecord” in Rails. Version 9.0+ works with Fedora 4 and prior versions work on Fedora 3. Version 9.2+ works with Solr 4.10.
13
13
 
14
14
  Getting Help
15
15
  ------------
@@ -149,7 +149,6 @@ module ActiveFedora
149
149
  message = "#{@reflection.class_name}(##{@reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
150
150
  raise ActiveFedora::AssociationTypeMismatch, message
151
151
  end
152
- type_validator.validate!(self, record)
153
152
  end
154
153
 
155
154
  def type_validator
@@ -184,6 +183,10 @@ module ActiveFedora
184
183
  end
185
184
  end
186
185
 
186
+ def run_type_validator(record)
187
+ type_validator.validate!(self, record)
188
+ end
189
+
187
190
  end
188
191
  end
189
192
  end
@@ -26,6 +26,7 @@ module ActiveFedora
26
26
  def replace(record)
27
27
  if record
28
28
  raise_on_type_mismatch(record)
29
+ run_type_validator(record)
29
30
  @updated = true
30
31
  end
31
32
 
@@ -5,6 +5,7 @@ module ActiveFedora
5
5
  def replace(record)
6
6
  if record
7
7
  raise_on_type_mismatch(record)
8
+ run_type_validator(record)
8
9
  # update_counters(record)
9
10
  replace_keys(record)
10
11
  set_inverse_instance(record)
@@ -157,6 +157,7 @@ module ActiveFedora
157
157
 
158
158
  records.flatten.each do |record|
159
159
  raise_on_type_mismatch(record)
160
+ run_type_validator(record)
160
161
  add_to_target(record) do |r|
161
162
  result &&= insert_record(record) unless owner.new_record?
162
163
  end
@@ -1,17 +1,20 @@
1
1
  module ActiveFedora::Associations
2
- ##
2
+ ##
3
3
  # Finds the objects which associate with a given record and are contained
4
4
  # within the given container. Uses #repository to find the objects.
5
5
  class ContainedFinder
6
- attr_reader :container, :repository
6
+ attr_reader :container, :repository, :proxy_class
7
7
  delegate :contained_ids, to: :container
8
8
  # @param [#contained_ids] container a container that records are stored
9
9
  # under.
10
10
  # @param [#translate_uri_to_id, #find] repository a repository to build
11
11
  # objects from.
12
- def initialize(container:, repository:)
12
+ # @param [ActiveFedora::Base] proxy_class class that represents an
13
+ # ore:Proxy
14
+ def initialize(container:, repository:, proxy_class:)
13
15
  @container = container
14
16
  @repository = repository
17
+ @proxy_class = proxy_class
15
18
  end
16
19
 
17
20
  # @param [ActiveFedora::Base] record a record which you want to find the
@@ -33,8 +36,14 @@ module ActiveFedora::Associations
33
36
  relation_subjects(record)
34
37
  end
35
38
 
39
+ # This could be done with Prefer InboundReferences, but that is
40
+ # a slow fedora call
36
41
  def relation_subjects(record)
37
- record.resource.query(object: record.rdf_subject).subjects.to_a
42
+ query = ActiveFedora::SolrQueryBuilder.construct_query_for_rel(
43
+ [[:has_model, proxy_class.to_class_uri], [:proxyFor, record.id]]
44
+ )
45
+ results = ActiveFedora::SolrService.query(query, fl: 'id')
46
+ results.map { |res| ::RDF::URI(ActiveFedora::Base.id_to_uri(res['id'])) }
38
47
  end
39
48
  end
40
49
 
@@ -35,6 +35,7 @@ module ActiveFedora
35
35
  def replace(record, *)
36
36
  if record
37
37
  raise_on_type_mismatch(record)
38
+ run_type_validator(record)
38
39
  remove_existing_target
39
40
  add_type_to_record(record, options[:type])
40
41
  add_to_container(record)
@@ -64,7 +64,7 @@ module ActiveFedora
64
64
  end
65
65
 
66
66
  def record_proxy_finder
67
- ContainedFinder.new(container: container, repository: composite_proxy_repository)
67
+ ContainedFinder.new(container: container, repository: composite_proxy_repository, proxy_class: proxy_class)
68
68
  end
69
69
 
70
70
  def composite_proxy_repository
@@ -26,6 +26,7 @@ module ActiveFedora
26
26
  elsif object.class.properties.keys.include?(key)
27
27
  predicate = graph.reflections.reflect_on_property(key).predicate
28
28
  result[predicate] = graph.query(subject: object.rdf_subject, predicate: predicate)
29
+ result[predicate] = child_graphs(result[predicate].objects) << result[predicate]
29
30
  elsif key == 'type'.freeze
30
31
  # working around https://github.com/ActiveTriples/ActiveTriples/issues/122
31
32
  predicate = ::RDF.type
@@ -35,5 +36,35 @@ module ActiveFedora
35
36
  end
36
37
  end
37
38
  end
39
+
40
+ private
41
+
42
+ # @return [RDF::Graph] A graph containing child graphs from changed
43
+ # attributes.
44
+ def child_graphs(objects)
45
+ child_graphs = ::RDF::Graph.new
46
+ objects.each do |object|
47
+ graph.query(subject: object).each do |statement|
48
+ # Have to filter out Fedora triples.
49
+ unless FedoraStatement.new(statement).internal?
50
+ child_graphs << statement
51
+ end
52
+ end
53
+ end
54
+ child_graphs
55
+ end
56
+ end
57
+
58
+ class FedoraStatement
59
+ attr_reader :value
60
+ def initialize(value)
61
+ @value = value
62
+ end
63
+
64
+ def internal?
65
+ value.object.to_s.start_with?("http://www.jcp.org") ||
66
+ value.object.to_s.start_with?("http://fedora.info") ||
67
+ value.predicate.to_s.start_with?("http://fedora.info")
68
+ end
38
69
  end
39
70
  end
@@ -13,10 +13,10 @@ module ActiveFedora
13
13
 
14
14
  def omit_uris
15
15
  [
16
- RDF::Fcrepo4.ServerManaged,
17
- RDF::Ldp.PreferContainment,
18
- RDF::Ldp.PreferEmptyContainer,
19
- RDF::Ldp.PreferMembership
16
+ ::RDF::Vocab::Fcrepo4.ServerManaged,
17
+ ::RDF::Vocab::LDP.PreferContainment,
18
+ ::RDF::Vocab::LDP.PreferEmptyContainer,
19
+ ::RDF::Vocab::LDP.PreferMembership
20
20
  ]
21
21
  end
22
22
 
@@ -22,7 +22,11 @@ module ActiveFedora
22
22
  end
23
23
 
24
24
  def connection
25
- @connection ||= InboundRelationConnection.new(CachingConnection.new(authorized_connection))
25
+ # The InboundRelationConnection does provide more data, useful for
26
+ # things like ldp:IndirectContainers, but it's imposes a significant
27
+ # performance penalty on every request
28
+ # @connection ||= InboundRelationConnection.new(CachingConnection.new(authorized_connection))
29
+ @connection ||= CachingConnection.new(authorized_connection)
26
30
  end
27
31
 
28
32
  def clean_connection
@@ -11,8 +11,8 @@ module ActiveFedora
11
11
  delegate :rdf_subject, :get_values, :type, to: :resource
12
12
 
13
13
  property :has_model, predicate: ActiveFedora::RDF::Fcrepo::Model.hasModel
14
- property :create_date, predicate: ActiveFedora::RDF::Fcrepo4.created
15
- property :modified_date, predicate: ActiveFedora::RDF::Fcrepo4.lastModified
14
+ property :create_date, predicate: ::RDF::Vocab::Fcrepo4.created
15
+ property :modified_date, predicate: ::RDF::Vocab::Fcrepo4.lastModified
16
16
 
17
17
  def create_date
18
18
  super.first
@@ -15,7 +15,9 @@ module ActiveFedora::File::Attributes
15
15
  end
16
16
 
17
17
  def digest
18
- response = metadata.ldp_source.graph.query(predicate: ActiveFedora::RDF::Fcrepo4.digest)
18
+ response = metadata.ldp_source.graph.query(predicate: RDF::Vocab::PREMIS.hasMessageDigest)
19
+ # fallback on old predicate for checksum
20
+ response = metadata.ldp_source.graph.query(predicate: RDF::Vocab::Fcrepo4.digest) if response.empty?
19
21
  response.map(&:object)
20
22
  end
21
23
 
@@ -18,7 +18,7 @@ module ActiveFedora
18
18
  end
19
19
 
20
20
  def status
21
- fixity_graph.query(predicate: ActiveFedora::RDF::Fcrepo4.status).map(&:object).first.to_s
21
+ fixity_graph.query(predicate: ::RDF::Vocab::Fcrepo4.status).map(&:object).first.to_s
22
22
  end
23
23
 
24
24
  private
@@ -1,4 +1,6 @@
1
1
  module ActiveFedora
2
+ # Use this connection judiciously, on fedora 4.3, these requests
3
+ # may be 3-5x slower, and make a graph that takes longer to parse.
2
4
  class InboundRelationConnection < SimpleDelegator
3
5
  def get(*args)
4
6
  result = __getobj__.get(*args) do |req|
@@ -14,7 +16,7 @@ module ActiveFedora
14
16
 
15
17
  def include_uris
16
18
  [
17
- RDF::Fcrepo4.InboundReferences
19
+ ::RDF::Vocab::Fcrepo4.InboundReferences
18
20
  ]
19
21
  end
20
22
  end
@@ -3,8 +3,6 @@ module ActiveFedora
3
3
  extend ActiveSupport::Autoload
4
4
  autoload :DatastreamIndexing
5
5
  autoload :Fcrepo
6
- autoload :Fcrepo4
7
- autoload :Ldp
8
6
  autoload :IndexingService
9
7
  autoload :Identifiable
10
8
  autoload :Persistence
@@ -20,7 +20,7 @@ module ActiveFedora
20
20
  query +=
21
21
  changes.map do |_, result|
22
22
  result.map do |statement|
23
- ::RDF::Query::Pattern.new(subject: subject, predicate: statement.predicate, object: statement.object).to_s
23
+ ::RDF::Query::Pattern.new(subject: pattern_subject(statement.subject), predicate: statement.predicate, object: statement.object).to_s
24
24
  end.join("\n")
25
25
  end.join("\n")
26
26
 
@@ -30,16 +30,51 @@ module ActiveFedora
30
30
 
31
31
  private
32
32
 
33
+ def pattern_subject(potential_subject)
34
+ if MaybeHashUri.new(potential_subject).hash?
35
+ potential_subject
36
+ else
37
+ subject
38
+ end
39
+ end
40
+
33
41
  def deletes(subject)
34
42
  patterns(subject).map do |pattern|
35
43
  "DELETE { #{pattern} }\n WHERE { #{pattern} } ;\n"
36
44
  end
37
45
  end
38
46
 
47
+ # Returns query patterns for finding all existing changed properties as well
48
+ # as well as their embedded hash-uri graphs.
49
+ #
50
+ # @return [Array<::RDF::Query::Pattern>]
39
51
  def patterns(subject)
40
- changes.map do |key, _|
41
- ::RDF::Query::Pattern.new(subject, key, :change).to_s
52
+ changes.flat_map do |key, result|
53
+ [
54
+ ::RDF::Query::Pattern.new(subject, key, :change).to_s,
55
+ hash_patterns(result)
56
+ ].flatten
57
+ end
58
+ end
59
+
60
+ def hash_patterns(graph)
61
+ graph = graph.select do |statement|
62
+ MaybeHashUri.new(statement.subject).hash?
42
63
  end
64
+ graph.map do |statement|
65
+ ::RDF::Query::Pattern.new(statement.subject, statement.predicate, :change).to_s
66
+ end
67
+ end
68
+ end
69
+
70
+ class MaybeHashUri
71
+ attr_reader :uri
72
+ def initialize(uri)
73
+ @uri = uri
74
+ end
75
+
76
+ def hash?
77
+ uri.to_s.include?("#")
43
78
  end
44
79
  end
45
80
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "9.3.0"
2
+ VERSION = "9.4.0"
3
3
  end
@@ -26,7 +26,7 @@ module ActiveFedora
26
26
  end
27
27
 
28
28
  def resources
29
- query(predicate: ActiveFedora::RDF::Fcrepo4.hasVersion)
29
+ query(predicate: ::RDF::Vocab::Fcrepo4.hasVersion)
30
30
  end
31
31
 
32
32
  private
@@ -44,11 +44,11 @@ module ActiveFedora
44
44
  end
45
45
 
46
46
  def label_query statement
47
- query(subject: statement.object).query(predicate: ActiveFedora::RDF::Fcrepo4.hasVersionLabel).first.object.to_s
47
+ query(subject: statement.object).query(predicate: ::RDF::Vocab::Fcrepo4.hasVersionLabel).first.object.to_s
48
48
  end
49
49
 
50
50
  def created_query statement
51
- query(subject: statement.object).query(predicate: ActiveFedora::RDF::Fcrepo4.created).first.object.to_s
51
+ query(subject: statement.object).query(predicate: ::RDF::Vocab::Fcrepo4.created).first.object.to_s
52
52
  end
53
53
 
54
54
  def fedora_versions
@@ -100,6 +100,12 @@ describe ActiveFedora::Base do
100
100
  bar.banana = true
101
101
  expect{foo.bars << bar}.not_to raise_error
102
102
  end
103
+ it "should NOT validate on destroy" do
104
+ bar.banana = true
105
+ foo.bars << bar
106
+ bar.banana = false
107
+ expect{foo.bars.destroy(bar)}.not_to raise_error
108
+ end
103
109
  end
104
110
 
105
111
  describe "complex example" do
@@ -151,16 +151,13 @@ describe "Indirect containers" do
151
151
  file2.title = "Derp"
152
152
  o.save!
153
153
  end
154
+
154
155
  it "has two related_objects" do
155
156
  expect(reloaded.related_objects).to eq [file, file2]
156
157
  end
157
- it "has inbound triples" do
158
- statement = file.reload.resource.query(predicate: ::RDF::URI.new('http://www.openarchives.org/ore/terms/proxyFor')).to_a.first
159
-
160
- expect(statement.object).to eq file.resource.rdf_subject
161
- end
162
158
  end
163
159
  end
160
+
164
161
  describe "remove" do
165
162
  it "should be able to remove" do
166
163
  o.related_objects = []
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe "nested hash resources" do
4
+ before do
5
+ class NestedResource < ActiveTriples::Resource
6
+ property :title, predicate: ::RDF::DC.title
7
+ ## Necessary to get AT to create hash URIs.
8
+ def initialize(uri, parent)
9
+ if uri.try(:node?)
10
+ uri = RDF::URI("#nested_#{uri.to_s.gsub('_:','')}")
11
+ elsif uri.start_with?("#")
12
+ uri = RDF::URI(uri)
13
+ end
14
+ super
15
+ end
16
+
17
+ def final_parent
18
+ parent
19
+ end
20
+ end
21
+ class ExampleOwner < ActiveFedora::Base
22
+ property :relation, predicate: ::RDF::DC.relation, class_name: NestedResource
23
+ accepts_nested_attributes_for :relation
24
+ end
25
+ end
26
+ after do
27
+ Object.send(:remove_const, :NestedResource)
28
+ Object.send(:remove_const, :ExampleOwner)
29
+ end
30
+ it "should be able to nest resources" do
31
+ obj = ExampleOwner.new
32
+ obj.attributes = {
33
+ :relation_attributes => [
34
+ {
35
+ :title => "Test"
36
+ }
37
+ ]
38
+ }
39
+ obj.save!
40
+
41
+ expect(obj.reload.relation.first.title).to eq ["Test"]
42
+ end
43
+ end
@@ -46,6 +46,15 @@ describe ActiveFedora::ChangeSet do
46
46
  base.title = nil
47
47
  expect(subject[RDF::DC.title].to_a).to eq []
48
48
  end
49
+ it "should include hash URIs" do
50
+ # This is useful as an alternative to blank nodes.
51
+ hash_uri = RDF::URI(base.uri.to_s + "#test")
52
+ base.resource << RDF::Statement.new(hash_uri, RDF::DC.title, "good")
53
+ base.title = [RDF::URI(hash_uri)]
54
+ expect(subject[RDF::DC.title].to_a).not_to eq []
55
+ # Include the title reference and the title for the hash URI
56
+ expect(subject[RDF::DC.title].to_a.length).to eq 2
57
+ end
49
58
  end
50
59
 
51
60
  it { is_expected.to_not be_empty }
@@ -230,6 +230,16 @@ describe ActiveFedora::File do
230
230
  expect(parent.reload.abcd.digest.first).to be_kind_of RDF::URI
231
231
  end
232
232
  end
233
+ context "with pre-4.3.0 predicate" do
234
+ before do
235
+ graph = ActiveTriples::Resource.new
236
+ graph << RDF::Statement.new(file.uri, RDF::Vocab::Fcrepo4.digest, RDF::URI.new("urn:sha1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15"))
237
+ allow(file).to receive_message_chain(:metadata, :ldp_source, :graph).and_return(graph)
238
+ end
239
+ it "falls back on fedora:digest if premis:hasMessageDigest is not present" do
240
+ expect(file.digest.first).to be_kind_of RDF::URI
241
+ end
242
+ end
233
243
  end
234
244
 
235
245
  describe "#save" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active-fedora
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.3.0
4
+ version: 9.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zumwalt
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-08-07 00:00:00.000000000 Z
13
+ date: 2015-09-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rsolr
@@ -394,11 +394,9 @@ files:
394
394
  - lib/active_fedora/rdf.rb
395
395
  - lib/active_fedora/rdf/datastream_indexing.rb
396
396
  - lib/active_fedora/rdf/fcrepo.rb
397
- - lib/active_fedora/rdf/fcrepo4.rb
398
397
  - lib/active_fedora/rdf/field_map.rb
399
398
  - lib/active_fedora/rdf/field_map_entry.rb
400
399
  - lib/active_fedora/rdf/indexing_service.rb
401
- - lib/active_fedora/rdf/ldp.rb
402
400
  - lib/active_fedora/rdf/ntriples_rdf_datastream.rb
403
401
  - lib/active_fedora/rdf/persistence.rb
404
402
  - lib/active_fedora/rdf/project_hydra.rb
@@ -500,6 +498,7 @@ files:
500
498
  - spec/integration/marshal_spec.rb
501
499
  - spec/integration/model_spec.rb
502
500
  - spec/integration/nested_attribute_spec.rb
501
+ - spec/integration/nested_hash_resources_spec.rb
503
502
  - spec/integration/ntriples_datastream_spec.rb
504
503
  - spec/integration/om_datastream_spec.rb
505
504
  - spec/integration/persistence_spec.rb
@@ -605,7 +604,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
605
604
  version: '0'
606
605
  requirements: []
607
606
  rubyforge_project:
608
- rubygems_version: 2.4.5
607
+ rubygems_version: 2.4.8
609
608
  signing_key:
610
609
  specification_version: 4
611
610
  summary: A convenience libary for manipulating documents in the Fedora Repository.
@@ -1,13 +0,0 @@
1
- require 'rdf'
2
- module ActiveFedora::RDF
3
- class Fcrepo4 < RDF::StrictVocabulary("http://fedora.info/definitions/v4/repository#")
4
- property :created
5
- property :digest
6
- property :hasVersion
7
- property :hasVersionLabel
8
- property :lastModified
9
- property :status
10
- property :ServerManaged
11
- property :InboundReferences
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- require 'rdf'
2
- class ActiveFedora::RDF::Ldp < RDF::StrictVocabulary("http://www.w3.org/ns/ldp#")
3
- # Property definitions
4
- property :contains
5
- property :member
6
- property :PreferContainment
7
- property :PreferEmptyContainer
8
- property :PreferMembership
9
- end