active-fedora 9.3.0 → 9.4.0

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