active-fedora 5.4.0 → 5.5.0.rc1

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.
data/Gemfile CHANGED
@@ -10,4 +10,3 @@ group :development, :test do
10
10
  end
11
11
 
12
12
  gem 'jruby-openssl', :platform=> :jruby
13
- gem 'nom-xml', '>=0.5.1'
@@ -17,7 +17,8 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.add_dependency('rsolr')
19
19
  s.add_dependency('om', '~> 1.8.0')
20
- s.add_dependency('solrizer', '~>2.0.0')
20
+ s.add_dependency('nom-xml', '>=0.5.1')
21
+ s.add_dependency('solrizer', '~>2.1.0.rc1')
21
22
  s.add_dependency("activeresource", '>= 3.0.0')
22
23
  s.add_dependency("activesupport", '>= 3.0.0')
23
24
  s.add_dependency("builder", '~> 3.0.0')
@@ -6,4 +6,4 @@ searchable:
6
6
  displayable: _display
7
7
  facetable: _facet
8
8
  sortable: _sort
9
- unstemmed_searchable: _unstem_search
9
+ unstemmed_searchable: _unstem_search
@@ -14,4 +14,4 @@ searchable:
14
14
  displayable: _display
15
15
  facetable: _facet
16
16
  sortable: _sort
17
- unstemmed_searchable: _unstem_search
17
+ unstemmed_searchable: _unstem_search
data/lib/active_fedora.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  require "loggable"
2
2
  require 'active_support'
3
- require 'active_fedora/solr_service'
3
+ require "solrizer"
4
+ require 'active_fedora/file_configurator'
4
5
  require 'active_fedora/rubydora_connection'
5
6
  require 'active_support/core_ext/class/attribute'
6
7
  require 'active_support/core_ext/object'
7
8
  require 'active_support/core_ext/hash/indifferent_access'
8
9
  require 'rdf'
9
10
 
10
- SOLR_DOCUMENT_ID = ActiveFedora::SolrService.id_field unless defined?(SOLR_DOCUMENT_ID)
11
+ SOLR_DOCUMENT_ID = ActiveFedora::FileConfigurator.id_field unless defined?(SOLR_DOCUMENT_ID)
11
12
  ENABLE_SOLR_UPDATES = true unless defined?(ENABLE_SOLR_UPDATES)
12
13
 
13
14
  module ActiveFedora #:nodoc:
@@ -52,12 +53,15 @@ module ActiveFedora #:nodoc:
52
53
  autoload :QualifiedDublinCoreDatastream
53
54
  autoload :Querying
54
55
  autoload :RDFDatastream
56
+ autoload :RdfNode
57
+ autoload :RdfObject
55
58
  autoload :RdfxmlRDFDatastream
56
59
  autoload :Relation
57
60
  autoload :RelsExtDatastream
58
61
  autoload :ServiceDefinitions
59
62
  autoload :SemanticNode
60
63
  autoload :SimpleDatastream
64
+ autoload :SolrService
61
65
  autoload :NestedAttributes
62
66
  autoload :FixtureLoader
63
67
  autoload :FixtureExporter
@@ -4,11 +4,10 @@ module ActiveFedora
4
4
  class Datastream < Rubydora::Datastream
5
5
  extend Deprecation
6
6
  attr_writer :digital_object
7
- attr_accessor :last_modified, :fields
7
+ attr_accessor :last_modified
8
8
 
9
9
  def initialize(digital_object=nil, dsid=nil, options={})
10
10
  ## When you use the versions feature of rubydora (0.5.x), you need to have a 3 argument constructor
11
- self.fields={}
12
11
  super
13
12
  end
14
13
 
@@ -46,6 +46,7 @@ module ActiveFedora
46
46
  # url: http://127.0.0.1:8983/fedora2
47
47
  #
48
48
 
49
+ include Solrizer::FieldNameMapper
49
50
  attr_accessor :config_env
50
51
  attr_reader :config_options, :fedora_config_path, :solr_config_path
51
52
 
@@ -100,6 +101,7 @@ module ActiveFedora
100
101
 
101
102
  load_fedora_config
102
103
  load_solr_config
104
+ load_solrizer_config
103
105
  @config_loaded = true
104
106
  end
105
107
 
@@ -148,6 +150,20 @@ module ActiveFedora
148
150
  @solr_config = {:url=> get_solr_url(config[ActiveFedora.environment.to_sym].symbolize_keys)}
149
151
  end
150
152
 
153
+ def load_solrizer_config
154
+ if solrizer_config_path
155
+ logger.warn "loading_solrizer_config at #{solrizer_config_path}, this overwrites the default field mapper class."
156
+ ActiveFedora::SolrService.load_mappings
157
+ end
158
+ end
159
+
160
+ def solrizer_config_path
161
+ begin
162
+ get_config_path('solr_mappings')
163
+ rescue ActiveFedora::ConfigurationError
164
+ end
165
+ end
166
+
151
167
  # Given the solr_config that's been loaded for this environment,
152
168
  # determine which solr url to use
153
169
  def get_solr_url(solr_config)
@@ -194,9 +210,12 @@ module ActiveFedora
194
210
 
195
211
  # Last choice, check for the default config file
196
212
  config_path = File.join(ActiveFedora.root, "config", "#{config_type}.yml")
197
- logger.warn "Using the default #{config_type}.yml that comes with active-fedora. If you want to override this, pass the path to #{config_type}.yml to ActiveFedora - ie. ActiveFedora.init(:#{config_type}_config_path => '/path/to/#{config_type}.yml') - or set Rails.root and put #{config_type}.yml into \#{Rails.root}/config."
198
- return config_path if File.file? config_path
199
- raise ConfigurationError "Couldn't load #{config_type} config file!"
213
+ if File.file? config_path
214
+ logger.warn "Using the default #{config_type}.yml that comes with active-fedora. If you want to override this, pass the path to #{config_type}.yml to ActiveFedora - ie. ActiveFedora.init(:#{config_type}_config_path => '/path/to/#{config_type}.yml') - or set Rails.root and put #{config_type}.yml into \#{Rails.root}/config."
215
+ return config_path
216
+ else
217
+ raise ConfigurationError, "Couldn't load #{config_type} config file!"
218
+ end
200
219
  end
201
220
 
202
221
  # Checks the existing fedora_config.path to see if there is a solr.yml there
@@ -285,7 +285,7 @@ module ActiveFedora
285
285
  end
286
286
 
287
287
  def generate_solr_symbol(base, data_type)
288
- Solrizer::XML::TerminologyBasedSolrizer.default_field_mapper.solr_name(base.to_sym, data_type)
288
+ Solrizer.default_field_mapper.solr_name(base.to_sym, data_type)
289
289
  end
290
290
 
291
291
  # ** Experimental **
@@ -2,10 +2,15 @@ require "nom"
2
2
 
3
3
  module ActiveFedora
4
4
  class NomDatastream < Datastream
5
- def self.set_terminology &block
5
+ def self.set_terminology(options = {}, &block)
6
+ @terminology_options = options || {}
6
7
  @terminology = block
7
8
  end
8
9
 
10
+ def self.terminology_options
11
+ @terminology_options
12
+ end
13
+
9
14
  def self.terminology
10
15
  @terminology
11
16
  end
@@ -27,7 +32,7 @@ module ActiveFedora
27
32
  def ng_xml
28
33
  @ng_xml ||= begin
29
34
  xml = Nokogiri::XML content
30
- xml.set_terminology &self.class.terminology
35
+ xml.set_terminology self.class.terminology_options, &self.class.terminology
31
36
  xml.nom!
32
37
  xml
33
38
  end
@@ -35,7 +40,7 @@ module ActiveFedora
35
40
 
36
41
  def ng_xml= ng_xml
37
42
  @ng_xml = ng_xml
38
- @ng_xml.set_terminology &self.class.terminology
43
+ @ng_xml.set_terminology self.class.terminology_options, &self.class.terminology
39
44
  content_will_change!
40
45
  @ng_xml
41
46
  end
@@ -7,6 +7,7 @@ module ActiveFedora
7
7
  #Fields can still be overridden if more specificity is desired (see ActiveFedora::Datastream#fields method).
8
8
  class QualifiedDublinCoreDatastream < OmDatastream
9
9
 
10
+ attr_accessor :fields
10
11
  class_attribute :class_fields
11
12
  self.class_fields = []
12
13
 
@@ -31,6 +32,7 @@ module ActiveFedora
31
32
  #when this method returns. Each term is marked as a multivalue string.
32
33
  def initialize(digital_object=nil, dsid=nil, options={})
33
34
  super
35
+ self.fields={}
34
36
  DCTERMS.each do |el|
35
37
  field el, :string, :multiple=>true
36
38
  end
@@ -1,46 +1,22 @@
1
1
  module ActiveFedora
2
2
  class RDFDatastream < Datastream
3
3
 
4
+ include Solrizer::Common
5
+
4
6
  before_save do
5
7
  if content.blank?
6
8
  logger.warn "Cowardly refusing to save a datastream with empty content: #{self.inspect}"
7
9
  false
8
10
  end
9
11
  end
12
+ include RdfNode
10
13
 
11
- # this enables a cleaner API for solr integration
12
- class IndexObject
13
- attr_accessor :data_type, :behaviors
14
- def initialize
15
- @behaviors = [:searchable]
16
- @data_type = :string
17
- end
18
- def as(*args)
19
- @behaviors = args
20
- end
21
- def type(sym)
22
- @data_type = sym
23
- end
24
- def defaults
25
- :noop
26
- end
27
- end
28
-
29
14
  class << self
30
- attr_accessor :vocabularies
31
- def config
32
- ActiveFedora::Predicates.predicate_config
33
- end
34
- def prefix(name)
35
- name = name.to_s unless name.is_a? String
36
- pre = self.to_s.sub(/RDFDatastream$/i, '').underscore
37
- return "#{pre}__#{name}".to_sym
38
- end
39
-
40
15
  ##
41
16
  # Register a ruby block that evaluates to the subject of the graph
42
17
  # By default, the block returns the current object's pid
43
18
  # @yield [ds] 'ds' is the datastream instance
19
+ # This should override the method in rdf_object, which just creates a b-node by default
44
20
  def rdf_subject &block
45
21
  if block_given?
46
22
  return @subject_block = block
@@ -50,117 +26,20 @@ module ActiveFedora
50
26
  end
51
27
 
52
28
  def register_vocabularies(*vocabs)
53
- @vocabularies ||= {}
54
- vocabs.each do |v|
55
- if v.is_a?(RDF::Vocabulary) or (v.respond_to? :property and v.respond_to? :to_uri)
56
- @vocabularies[v.to_uri] = v
57
- else
58
- raise "not an RDF vocabulary: #{v}"
59
- end
60
- end
61
- ActiveFedora::Predicates.vocabularies(@vocabularies)
62
- @vocabularies
29
+ Deprecation.warn(RDFDatastream, "register_vocabularies no longer has any effect and will be removed in active-fedora 6.0", caller)
63
30
  end
64
31
 
65
- def map_predicates(&block)
66
- yield self
67
- end
68
- def method_missing(name, *args, &block)
69
- args = args.first if args.respond_to? :first
70
- raise "mapping must specify RDF vocabulary as :in argument" unless args.has_key? :in
71
- vocab = args[:in]
72
- predicate = args.fetch(:to, name)
73
- raise "Vocabulary '#{vocab.inspect}' does not define property '#{predicate.inspect}'" unless vocab.respond_to? predicate
74
- indexing = false
75
- if block_given?
76
- # needed for solrizer integration
77
- indexing = true
78
- iobj = IndexObject.new
79
- yield iobj
80
- data_type = iobj.data_type
81
- behaviors = iobj.behaviors
82
- end
83
- # needed for AF::Predicates integration & drives all other
84
- # functionality below
85
- vocab = vocab.to_s
86
- name = self.prefix(name)
87
- if config
88
- if config[:predicate_mapping].has_key? vocab
89
- config[:predicate_mapping][vocab][name] = predicate
90
- else
91
- config[:predicate_mapping][vocab] = { name => predicate }
92
- end
93
- # stuff data_type and behaviors in there for to_solr support
94
- config[:predicate_mapping][vocab]["#{name}__type".to_sym] = data_type if indexing
95
- config[:predicate_mapping][vocab]["#{name}__behaviors".to_sym] = behaviors if indexing
96
- else
97
- config = {
98
- :default_namespace => vocab,
99
- :predicate_mapping => {
100
- vocab => { name => predicate }
101
- }
102
- }
103
- # stuff data_type and behaviors in there for to_solr support
104
- config[:predicate_mapping][vocab]["#{name}__type".to_sym] = data_type if indexing
105
- config[:predicate_mapping][vocab]["#{name}__behaviors".to_sym] = behaviors if indexing
106
- end
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
107
36
  end
108
37
  end
109
38
 
110
-
111
- class TermProxy
112
-
113
- attr_reader :graph, :subject, :predicate
114
- delegate :class, :to_s, :==, :kind_of?, :each, :map, :empty?, :as_json, :is_a?, :to => :values
115
-
116
- def initialize(graph, subject, predicate)
117
- @graph = graph
118
-
119
- @subject = subject
120
- @predicate = predicate
121
- end
122
-
123
- def <<(*values)
124
- values.each { |value| graph.append(subject, predicate, value) }
125
- values
126
- end
127
-
128
- def delete(*values)
129
- values.each do |value|
130
- graph.delete_predicate(subject, predicate, value)
131
- end
132
-
133
- values
134
- end
135
-
136
- def values
137
- values = []
138
-
139
- graph.query(subject, predicate).each do |solution|
140
- v = solution.value
141
- v = v.to_s if v.is_a? RDF::Literal
142
- values << v
143
- end
144
-
145
- values
146
- end
147
-
148
- def method_missing(method, *args, &block)
149
-
150
- if values.respond_to? method
151
- values.send(method, *args, &block)
152
- else
153
- super
154
- end
155
- end
156
- end
157
-
158
39
  attr_accessor :loaded
159
40
  def metadata?
160
41
  true
161
42
  end
162
- def ensure_loaded
163
- end
164
43
 
165
44
  def content
166
45
  serialize
@@ -180,57 +59,21 @@ module ActiveFedora
180
59
  super || content_changed?
181
60
  end
182
61
 
183
- # returns a Hash, e.g.: {field => {:values => [], :type => :something, :behaviors => []}, ...}
184
- def fields
185
- field_map = {}
186
-
187
- rdf_subject = self.rdf_subject
188
- query = RDF::Query.new do
189
- pattern [rdf_subject, :predicate, :value]
190
- end
191
-
192
- query.execute(graph).each do |solution|
193
- predicate = solution.predicate
194
- value = solution.value
195
-
196
- vocab_sym, name = predicate.qname
197
- uri, vocab = self.class.vocabularies.select { |ns, v| v.__prefix__ == vocab_sym }.first
198
- next unless vocab
199
-
200
- config = self.class.config[:predicate_mapping][vocab.to_s]
201
-
202
- name, indexed_as = config.select { |k, v| name.to_s == v.to_s && k.to_s.split("__")[0] == self.class.prefix(name).to_s.split("__")[0]}.first
203
- next unless name and config.has_key?("#{name}__type".to_sym) and config.has_key?("#{name}__behaviors".to_sym)
204
- type = config["#{name}__type".to_sym]
205
- behaviors = config["#{name}__behaviors".to_sym]
206
- field_map[name.to_sym] ||= {:values => [], :type => type, :behaviors => behaviors}
207
- field_map[name.to_sym][:values] << value.to_s
208
- end
209
- field_map
210
- end
211
62
 
212
63
  def to_solr(solr_doc = Hash.new) # :nodoc:
213
64
  fields.each do |field_key, field_info|
214
- values = field_info.fetch(:values, false)
65
+ values = get_values(rdf_subject, field_key)
66
+ directive = Solrizer::Directive.new(field_info[:type], field_info[:behaviors])
215
67
  if values
216
- field_info[:behaviors].each do |index_type|
217
- field_symbol = ActiveFedora::SolrService.solr_name(field_key, field_info[:type], index_type)
218
- values = [values] unless values.respond_to? :each
219
- values.each do |val|
220
- ::Solrizer::Extractor.insert_solr_field_value(solr_doc, field_symbol, val)
221
- end
68
+ Array(values).each do |val|
69
+ 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)
222
71
  end
223
72
  end
224
73
  end
225
74
  solr_doc
226
75
  end
227
76
 
228
- # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
229
- def find_predicate(predicate)
230
- predicate = self.class.prefix(predicate) unless predicate.kind_of? RDF::URI
231
- result = ActiveFedora::Predicates.find_predicate(predicate)
232
- RDF::URI(result.reverse.join)
233
- end
234
77
 
235
78
  # Populate a RDFDatastream object based on the "datastream" content
236
79
  # Assumes that the datastream contains RDF content
@@ -257,101 +100,10 @@ module ActiveFedora
257
100
  end
258
101
  end
259
102
 
260
- def query subject, predicate, &block
261
- predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
262
-
263
- q = RDF::Query.new do
264
- pattern [subject, predicate, :value]
265
- end
266
-
267
- q.execute(graph, &block)
268
- end
269
-
270
- # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
271
- def get_values(subject, predicate)
272
-
273
- predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
274
-
275
- return TermProxy.new(self, subject, predicate)
276
- end
277
-
278
- # if there are any existing statements with this predicate, replace them
279
- # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
280
-
281
- def set_value(subject, predicate, values)
282
-
283
- predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
284
-
285
- delete_predicate(subject, predicate)
286
-
287
- Array(values).each do |arg|
288
- arg = arg.to_s if arg.kind_of? RDF::Literal
289
- next if arg.empty?
290
-
291
- graph.insert([subject, predicate, arg])
292
- end
293
-
294
- return TermProxy.new(self, subject, predicate)
295
- end
296
-
297
- def delete_predicate(subject, predicate, values = nil)
298
- predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
299
-
300
- if values.nil?
301
- query = RDF::Query.new do
302
- pattern [subject, predicate, :value]
303
- end
304
-
305
- query.execute(graph).each do |solution|
306
- graph.delete [subject, predicate, solution.value]
307
- end
308
- else
309
- Array(values).each do |v|
310
- graph.delete [subject, predicate, v]
311
- end
312
- end
313
-
314
- end
315
-
316
- # append a value
317
- # @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
318
- def append(subject, predicate, args)
319
- graph.insert([subject, predicate, args])
320
-
321
-
322
- return TermProxy.new(self, subject, predicate)
323
- end
324
-
325
103
  def serialization_format
326
104
  raise "you must override the `serialization_format' method in a subclass"
327
105
  end
328
106
 
329
- def method_missing(name, *args)
330
- if (md = /^([^=]+)=$/.match(name.to_s)) && pred = find_predicate(md[1])
331
- set_value(rdf_subject, pred, *args)
332
- elsif pred = find_predicate(name)
333
- get_values(rdf_subject, name)
334
- else
335
- super
336
- end
337
- rescue ActiveFedora::UnregisteredPredicateError
338
- super
339
- end
340
-
341
- ##
342
- # Get the subject for this rdf/xml datastream
343
- def rdf_subject
344
- @subject ||= begin
345
- s = self.class.rdf_subject.call(self)
346
- s &&= RDF::URI.new(s) if s.is_a? String
347
- s
348
- end
349
- end
350
-
351
- def reset_rdf_subject!
352
- @subject = nil
353
- end
354
-
355
107
  # Creates a RDF datastream for insertion into a Fedora Object
356
108
  # Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
357
109
  def serialize
@@ -359,6 +111,9 @@ module ActiveFedora
359
111
  RDF::Writer.for(serialization_format).dump(graph)
360
112
  end
361
113
 
114
+
115
+ private
116
+
362
117
  def update_subjects_to_use_a_real_pid!
363
118
  return unless new?
364
119
 
@@ -377,6 +132,30 @@ module ActiveFedora
377
132
 
378
133
  @graph = new_repository
379
134
  end
135
+
136
+ # returns a Hash, e.g.: {field => {:values => [], :type => :something, :behaviors => []}, ...}
137
+ def fields
138
+ field_map = {}
139
+
140
+ rdf_subject = self.rdf_subject
141
+ query = RDF::Query.new do
142
+ pattern [rdf_subject, :predicate, :value]
143
+ end
144
+
145
+ query.execute(graph).each do |solution|
146
+ predicate = solution.predicate
147
+ value = solution.value
148
+
149
+ name, config = self.class.config_for_predicate(predicate)
150
+ next unless config
151
+ type = config[:type]
152
+ behaviors = config[:behaviors]
153
+ next unless type and behaviors
154
+ field_map[name] ||= {:values => [], :type => type, :behaviors => behaviors}
155
+ field_map[name][:values] << value.to_s
156
+ end
157
+ field_map
158
+ end
380
159
  end
381
160
  end
382
161