active-fedora 5.5.0.rc1 → 5.5.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ 5.5.0 (Unreleased)
2
+ Added support for complex rdf structures.
3
+ Changed RdfDatastream to_solr so that it uses the dsid as the solr prefix, not the datastream class name
4
+
1
5
  5.4.0
2
6
  HYDRA-850 Added finder methods like Base.where().limit().order().first
3
7
  Added Base.delete_all and Base.destroy_all
@@ -54,26 +54,26 @@ module ActiveFedora
54
54
  # queue that is kept intact down through an inheritance hierarchy.
55
55
  #
56
56
  # class Topic < ActiveFedora::Base
57
- # before_delete :destroy_author
57
+ # before_destroy :destroy_author
58
58
  # end
59
59
  #
60
60
  # class Reply < Topic
61
- # before_delete :destroy_readers
61
+ # before_destroy :destroy_readers
62
62
  # end
63
63
  #
64
- # Now, when <tt>Topic#delete</tt> is run only +destroy_author+ is called. When <tt>Reply#delete</tt> is
64
+ # Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
65
65
  # run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the following situation
66
- # where the +before_delete+ method is overridden:
66
+ # where the +before_destroy+ method is overridden:
67
67
  #
68
68
  # class Topic < ActiveFedora::Base
69
- # def before_delete() destroy_author end
69
+ # def before_destroy() destroy_author end
70
70
  # end
71
71
  #
72
72
  # class Reply < Topic
73
- # def before_delete() destroy_readers end
73
+ # def before_destroy() destroy_readers end
74
74
  # end
75
75
  #
76
- # In that case, <tt>Reply#delete</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
76
+ # In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
77
77
  # So, use the callback macros when you want to ensure that a certain callback is called for the entire
78
78
  # hierarchy, and use the regular overwriteable methods when you want to leave it up to each descendant
79
79
  # to decide whether they want to call +super+ and trigger the inherited callbacks.
@@ -29,11 +29,6 @@ module ActiveFedora
29
29
  Deprecation.warn(RDFDatastream, "register_vocabularies no longer has any effect and will be removed in active-fedora 6.0", caller)
30
30
  end
31
31
 
32
- def prefix(name)
33
- name = name.to_s unless name.is_a? String
34
- pre = self.to_s.sub(/RDFDatastream$/i, '').underscore
35
- return "#{pre}__#{name}".to_sym
36
- end
37
32
  end
38
33
 
39
34
  attr_accessor :loaded
@@ -41,6 +36,12 @@ module ActiveFedora
41
36
  true
42
37
  end
43
38
 
39
+ def prefix(name)
40
+ name = name.to_s unless name.is_a? String
41
+ pre = dsid.underscore
42
+ return "#{pre}__#{name}".to_sym
43
+ end
44
+
44
45
  def content
45
46
  serialize
46
47
  end
@@ -67,7 +68,7 @@ module ActiveFedora
67
68
  if values
68
69
  Array(values).each do |val|
69
70
  val = val.to_s if val.kind_of? RDF::URI
70
- self.class.create_and_insert_terms(self.class.prefix(field_key), val, directive, solr_doc)
71
+ self.class.create_and_insert_terms(prefix(field_key), val, directive, solr_doc)
71
72
  end
72
73
  end
73
74
  end
@@ -1,6 +1,9 @@
1
1
  module ActiveFedora
2
2
  module RdfNode
3
3
  extend ActiveSupport::Concern
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :TermProxy
4
7
 
5
8
  ##
6
9
  # Get the subject for this rdf object
@@ -19,7 +22,7 @@ module ActiveFedora
19
22
  # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
20
23
  def get_values(subject, predicate)
21
24
  options = config_for_term_or_uri(predicate)
22
- return TermProxy.new(self, subject, options)
25
+ TermProxy.new(self, subject, predicate, options)
23
26
  end
24
27
 
25
28
 
@@ -31,26 +34,27 @@ module ActiveFedora
31
34
  end
32
35
 
33
36
  # if there are any existing statements with this predicate, replace them
37
+ # @param [RDF::URI] subject the subject to insert into the graph
34
38
  # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
35
-
39
+ # @param [Array,#to_s] values the value/values to insert into the graph
36
40
  def set_value(subject, predicate, values)
37
-
38
- #predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
41
+
39
42
  options = config_for_term_or_uri(predicate)
40
43
  predicate = options[:predicate]
41
44
 
42
45
  delete_predicate(subject, predicate)
43
-
44
46
  Array(values).each do |arg|
45
- arg = arg.to_s if arg.kind_of? RDF::Literal
46
- next if arg.kind_of?(String) && arg.empty?
47
+ if arg.respond_to?(:rdf_subject) # an RdfObject
48
+ graph.insert([subject, predicate, arg.rdf_subject ])
49
+ else
50
+ arg = arg.to_s if arg.kind_of? RDF::Literal
51
+ next if arg.kind_of?(String) && arg.empty?
47
52
 
48
- # If arg is a b-node, then copy it's statements onto the parent graph
49
- arg = merge_subgraph(arg) if arg.respond_to? :graph
50
- graph.insert([subject, predicate, arg])
53
+ graph.insert([subject, predicate, arg])
54
+ end
51
55
  end
52
56
 
53
- return TermProxy.new(self, subject, options)
57
+ TermProxy.new(self, subject, predicate, options)
54
58
  end
55
59
 
56
60
 
@@ -78,7 +82,7 @@ module ActiveFedora
78
82
  def append(subject, predicate, args)
79
83
  options = config_for_term_or_uri(predicate)
80
84
  graph.insert([subject, predicate, args])
81
- TermProxy.new(self, subject, options)
85
+ TermProxy.new(self, subject, options[:predicate], options)
82
86
  end
83
87
 
84
88
  def config_for_term_or_uri(term)
@@ -108,17 +112,9 @@ module ActiveFedora
108
112
 
109
113
  def method_missing(name, *args)
110
114
  if (md = /^([^=]+)=$/.match(name.to_s)) && pred = find_predicate(md[1])
111
- set_value(rdf_subject, pred, *args)
115
+ set_value(rdf_subject, pred, *args)
112
116
  elsif pred = find_predicate(name)
113
- klass = target_class(pred)
114
- if klass
115
- # return an array of klass.new from each of the values
116
- query(rdf_subject, pred).map do |solution|
117
- klass.new(graph, solution.value)
118
- end
119
- else
120
117
  get_values(rdf_subject, pred)
121
- end
122
118
  else
123
119
  super
124
120
  end
@@ -127,15 +123,6 @@ module ActiveFedora
127
123
  end
128
124
 
129
125
  private
130
- # If arg is a b-node, then copy it's statements onto the parent graph
131
- def merge_subgraph(rdf_object)
132
- rdf_object.graph.statements.each do |s|
133
- graph.insert(s)
134
- end
135
- # Return the arg to point at the new b-node
136
- rdf_object.rdf_subject
137
- end
138
-
139
126
  class Builder
140
127
  def initialize(parent)
141
128
  @parent = parent
@@ -189,55 +176,6 @@ module ActiveFedora
189
176
  end
190
177
  end
191
178
 
192
- class TermProxy
193
-
194
- attr_reader :graph, :subject, :predicate, :options
195
- delegate :class, :to_s, :==, :kind_of?, :each, :map, :empty?, :as_json, :is_a?, :to => :values
196
-
197
- def initialize(graph, subject, options)
198
- @graph = graph
199
-
200
- @subject = subject
201
- @predicate = options[:predicate]
202
- @options = options
203
- end
204
-
205
- def <<(*values)
206
- values.each { |value| graph.append(subject, predicate, value) }
207
- values
208
- end
209
-
210
- def delete(*values)
211
- values.each do |value|
212
- graph.delete_predicate(subject, predicate, value)
213
- end
214
-
215
- values
216
- end
217
-
218
- def values
219
- values = []
220
-
221
- graph.query(subject, predicate).each do |solution|
222
- v = solution.value
223
- v = v.to_s if v.is_a? RDF::Literal
224
- if options[:type] == :date
225
- v = Date.parse(v)
226
- end
227
- values << v
228
- end
229
-
230
- values
231
- end
232
-
233
- def method_missing(method, *args, &block)
234
- if values.respond_to? method
235
- values.send(method, *args, &block)
236
- else
237
- super
238
- end
239
- end
240
- end
241
179
  module ClassMethods
242
180
  def config
243
181
  @config ||= {}
@@ -0,0 +1,64 @@
1
+ module ActiveFedora
2
+ module RdfNode
3
+ class TermProxy
4
+
5
+ attr_reader :graph, :subject, :predicate, :options
6
+ delegate :class, :to_s, :==, :kind_of?, :each, :map, :empty?, :as_json, :is_a?, :to => :values
7
+
8
+ # @param graph RDF::Graph
9
+ # @param subject RDF::URI
10
+ # @param options Hash
11
+ def initialize(graph, subject, predicate, options)
12
+ @graph = graph
13
+ @subject = subject
14
+ @predicate = predicate
15
+ @options = options
16
+ end
17
+
18
+ def build
19
+ new_subject = RDF::Node.new
20
+ graph.graph.insert([subject, predicate, new_subject])
21
+ graph.target_class(predicate).new(graph.graph, new_subject)
22
+ end
23
+
24
+ def <<(*values)
25
+ values.each { |value| graph.append(subject, predicate, value) }
26
+ values
27
+ end
28
+
29
+ def delete(*values)
30
+ values.each do |value|
31
+ graph.delete_predicate(subject, predicate, value)
32
+ end
33
+
34
+ values
35
+ end
36
+
37
+ def values
38
+ values = []
39
+
40
+ graph.query(subject, predicate).each do |solution|
41
+ v = solution.value
42
+ v = v.to_s if v.is_a? RDF::Literal
43
+ if options[:type] == :date
44
+ v = Date.parse(v)
45
+ end
46
+ values << v
47
+ end
48
+ if options[:class_name]
49
+ values = values.map{ |found_subject| graph.target_class(predicate).new(graph.graph, found_subject)}
50
+ end
51
+
52
+ values
53
+ end
54
+
55
+ def method_missing(method, *args, &block)
56
+ if values.respond_to? method
57
+ values.send(method, *args, &block)
58
+ else
59
+ super
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -4,17 +4,20 @@ module ActiveFedora
4
4
 
5
5
  included do
6
6
  include RdfNode
7
+ attr_reader :rdf_subject, :graph
7
8
  end
8
9
 
9
10
  def graph
10
11
  @graph ||= RDF::Graph.new
11
- insert_type_assertion
12
12
  @graph
13
13
  end
14
14
 
15
- def initialize(graph=RDF::Graph.new, subject=nil)
15
+
16
+ def initialize(graph, subject=nil)
17
+ subject ||= RDF::Node.new
16
18
  @graph = graph
17
- @subject = subject
19
+ @rdf_subject = subject
20
+ insert_type_assertion
18
21
  end
19
22
 
20
23
  def get_values(subject, predicate)
@@ -26,7 +29,7 @@ module ActiveFedora
26
29
 
27
30
  def insert_type_assertion
28
31
  rdf_type = self.class.rdf_type
29
- @graph.insert([@subject, RDF.type, rdf_type]) if rdf_type
32
+ @graph.insert([@rdf_subject, RDF.type, rdf_type]) if rdf_type
30
33
  end
31
34
  end
32
35
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "5.5.0.rc1"
2
+ VERSION = "5.5.0.rc2"
3
3
  end
@@ -29,15 +29,15 @@ describe "Nested Rdf Objects" do
29
29
 
30
30
 
31
31
  it "should be able to nest a complex object" do
32
- comp = SpecDatastream::Component.new
32
+ comp = SpecDatastream::Component.new(ds.graph)
33
33
  comp.label = ["Alternator"]
34
34
  ds.parts = comp
35
35
  ds.parts.first.label.should == ["Alternator"]
36
36
  end
37
37
  it "should be able to nest many complex objects" do
38
- comp1 = SpecDatastream::Component.new
38
+ comp1 = SpecDatastream::Component.new ds.graph
39
39
  comp1.label = ["Alternator"]
40
- comp2 = SpecDatastream::Component.new
40
+ comp2 = SpecDatastream::Component.new ds.graph
41
41
  comp2.label = ["Crankshaft"]
42
42
  ds.parts = [comp1, comp2]
43
43
  ds.parts.first.label.should == ["Alternator"]
@@ -45,9 +45,9 @@ describe "Nested Rdf Objects" do
45
45
  end
46
46
 
47
47
  it "should be able to clear complex objects" do
48
- comp1 = SpecDatastream::Component.new
48
+ comp1 = SpecDatastream::Component.new ds.graph
49
49
  comp1.label = ["Alternator"]
50
- comp2 = SpecDatastream::Component.new
50
+ comp2 = SpecDatastream::Component.new ds.graph
51
51
  comp2.label = ["Crankshaft"]
52
52
  ds.parts = [comp1, comp2]
53
53
  ds.parts = []
@@ -63,6 +63,21 @@ _:g70350851833380 <http://purl.org/dc/terms/title> "Crankshaft" .
63
63
  END
64
64
  ds.parts.first.label.should == ["Alternator"]
65
65
  end
66
+
67
+ it "should build complex objects when a parent node doesn't exist" do
68
+ part = ds.parts.build
69
+ part.should be_kind_of SpecDatastream::Component
70
+ part.label = "Wheel bearing"
71
+ ds.parts.first.label.should == ['Wheel bearing']
72
+ end
73
+
74
+ it "should build complex objects when a parent node exists" do
75
+ ds.parts #this creates a parts node, but it shouldn't
76
+ part = ds.parts.build
77
+ part.should be_kind_of SpecDatastream::Component
78
+ part.label = "Wheel bearing"
79
+ ds.parts.first.label.should == ['Wheel bearing']
80
+ end
66
81
  end
67
82
 
68
83
  describe "with type" do
@@ -94,7 +109,7 @@ END
94
109
 
95
110
 
96
111
  it "should store the type of complex objects when type is specified" do
97
- comp = SpecDatastream::MediatorUser.new
112
+ comp = SpecDatastream::MediatorUser.new ds.graph
98
113
  comp.title = ["Doctor"]
99
114
  ds.mediator = comp
100
115
  ds.mediator.first.type.first.should be_instance_of RDF::URI
@@ -68,15 +68,15 @@ describe ActiveFedora::NtriplesRDFDatastream do
68
68
  subject.date_uploaded = Date.parse('2012-11-02')
69
69
  subject.date_uploaded.first.should be_kind_of Date
70
70
  solr_document = subject.to_solr
71
- solr_document["my_datastream__date_uploaded_dt"].should == ['2012-11-02T00:00:00Z']
71
+ solr_document["rdf__date_uploaded_dt"].should == ['2012-11-02T00:00:00Z']
72
72
  end
73
73
 
74
74
  it "should produce a solr document" do
75
75
  @subject = RdfTest.new(title: "War and Peace")
76
76
  solr_document = @subject.to_solr
77
- solr_document["my_datastream__title_display"].should == ["War and Peace"]
78
- solr_document["my_datastream__title_facet"].should == ["War and Peace"]
79
- solr_document["my_datastream__title_t"].should == ["War and Peace"]
77
+ solr_document["rdf__title_display"].should == ["War and Peace"]
78
+ solr_document["rdf__title_facet"].should == ["War and Peace"]
79
+ solr_document["rdf__title_t"].should == ["War and Peace"]
80
80
  end
81
81
 
82
82
  it "should set and recall values" do
@@ -67,16 +67,12 @@ describe ActiveFedora::NtriplesRDFDatastream do
67
67
 
68
68
  describe "some dummy instances" do
69
69
  before do
70
- class MyFoobarRDFDatastream < ActiveFedora::NtriplesRDFDatastream
71
- end
72
- class MyFoobarRdfDatastream < ActiveFedora::NtriplesRDFDatastream
73
- end
70
+ @one = ActiveFedora::RDFDatastream.new('fakepid', 'myFoobar')
71
+ @two = ActiveFedora::RDFDatastream.new('fakepid', 'myQuix')
74
72
  end
75
73
  it "should generate predictable prexies" do
76
- MyFoobarRDFDatastream.prefix("baz").should == :my_foobar__baz
77
- end
78
- it "should generate prefixes case-insensitively" do
79
- MyFoobarRDFDatastream.prefix("quux").should == MyFoobarRdfDatastream.prefix("quux")
74
+ @one .prefix("baz").should == :my_foobar__baz
75
+ @two.prefix("baz").should == :my_quix__baz
80
76
  end
81
77
  end
82
78
 
@@ -170,25 +166,25 @@ describe ActiveFedora::NtriplesRDFDatastream do
170
166
  end
171
167
  it "should iterate through @fields hash" do
172
168
  solr_doc = @subject.to_solr
173
- solr_doc["my_datastream__publisher_t"].should == ["publisher1"]
174
- solr_doc["my_datastream__publisher_sort"].should == ["publisher1"]
175
- solr_doc["my_datastream__publisher_display"].should == ["publisher1"]
176
- solr_doc["my_datastream__publisher_facet"].should == ["publisher1"]
177
- solr_doc["my_datastream__based_near_t"].sort.should == ["coverage1", "coverage2"]
178
- solr_doc["my_datastream__based_near_display"].sort.should == ["coverage1", "coverage2"]
179
- solr_doc["my_datastream__based_near_facet"].sort.should == ["coverage1", "coverage2"]
180
- solr_doc["my_datastream__created_sort"].should == ["2009-10-10"]
181
- solr_doc["my_datastream__created_display"].should == ["2009-10-10"]
182
- solr_doc["my_datastream__title_t"].should == ["fake-title"]
183
- solr_doc["my_datastream__title_sort"].should == ["fake-title"]
184
- solr_doc["my_datastream__title_display"].should == ["fake-title"]
185
- solr_doc["my_datastream__related_url_t"].should == ["http://example.org/"]
186
- solr_doc["my_datastream__empty_field_t"].should be_nil
169
+ solr_doc["solr_rdf__publisher_t"].should == ["publisher1"]
170
+ solr_doc["solr_rdf__publisher_sort"].should == ["publisher1"]
171
+ solr_doc["solr_rdf__publisher_display"].should == ["publisher1"]
172
+ solr_doc["solr_rdf__publisher_facet"].should == ["publisher1"]
173
+ solr_doc["solr_rdf__based_near_t"].sort.should == ["coverage1", "coverage2"]
174
+ solr_doc["solr_rdf__based_near_display"].sort.should == ["coverage1", "coverage2"]
175
+ solr_doc["solr_rdf__based_near_facet"].sort.should == ["coverage1", "coverage2"]
176
+ solr_doc["solr_rdf__created_sort"].should == ["2009-10-10"]
177
+ solr_doc["solr_rdf__created_display"].should == ["2009-10-10"]
178
+ solr_doc["solr_rdf__title_t"].should == ["fake-title"]
179
+ solr_doc["solr_rdf__title_sort"].should == ["fake-title"]
180
+ solr_doc["solr_rdf__title_display"].should == ["fake-title"]
181
+ solr_doc["solr_rdf__related_url_t"].should == ["http://example.org/"]
182
+ solr_doc["solr_rdf__empty_field_t"].should be_nil
187
183
 
188
184
  #should NOT have these
189
- solr_doc["my_datastream__narrator"].should be_nil
190
- solr_doc["my_datastream__empty_field"].should be_nil
191
- solr_doc["my_datastream__creator"].should be_nil
185
+ solr_doc["solr_rdf__narrator"].should be_nil
186
+ solr_doc["solr_rdf__empty_field"].should be_nil
187
+ solr_doc["solr_rdf__creator"].should be_nil
192
188
  end
193
189
 
194
190
  describe "with an actual object" do
@@ -233,16 +229,16 @@ describe ActiveFedora::NtriplesRDFDatastream do
233
229
  describe ".to_solr()" do
234
230
  it "should return the right fields" do
235
231
  @obj.to_solr.keys.count.should == 13
236
- @obj.to_solr.keys.should include("my_datastream__related_url_t", "my_datastream__publisher_t", "my_datastream__publisher_sort",
237
- "my_datastream__publisher_display", "my_datastream__publisher_facet", "my_datastream__created_sort",
238
- "my_datastream__created_display", "my_datastream__title_t", "my_datastream__title_sort", "my_datastream__title_display",
239
- "my_datastream__based_near_t", "my_datastream__based_near_facet", "my_datastream__based_near_display")
232
+ @obj.to_solr.keys.should include("solr_rdf__related_url_t", "solr_rdf__publisher_t", "solr_rdf__publisher_sort",
233
+ "solr_rdf__publisher_display", "solr_rdf__publisher_facet", "solr_rdf__created_sort",
234
+ "solr_rdf__created_display", "solr_rdf__title_t", "solr_rdf__title_sort", "solr_rdf__title_display",
235
+ "solr_rdf__based_near_t", "solr_rdf__based_near_facet", "solr_rdf__based_near_display")
240
236
 
241
237
  end
242
238
 
243
239
  it "should return the right values" do
244
- @obj.to_solr["my_datastream__related_url_t"].should == ["http://example.org/blogtastic/"]
245
- @obj.to_solr["my_datastream__based_near_t"].should == ["Tacoma, WA","Renton, WA"]
240
+ @obj.to_solr["solr_rdf__related_url_t"].should == ["http://example.org/blogtastic/"]
241
+ @obj.to_solr["solr_rdf__based_near_t"].should == ["Tacoma, WA","Renton, WA"]
246
242
  end
247
243
  end
248
244
  end
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: 5.5.0.rc1
4
+ version: 5.5.0.rc2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-01-15 00:00:00.000000000 Z
14
+ date: 2013-01-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rsolr
@@ -369,6 +369,7 @@ files:
369
369
  - lib/active_fedora/railtie.rb
370
370
  - lib/active_fedora/rdf_datastream.rb
371
371
  - lib/active_fedora/rdf_node.rb
372
+ - lib/active_fedora/rdf_node/term_proxy.rb
372
373
  - lib/active_fedora/rdf_object.rb
373
374
  - lib/active_fedora/rdf_xml_writer.rb
374
375
  - lib/active_fedora/rdfxml_rdf_datastream.rb