valkyrie 2.1.0 → 3.0.0.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +71 -36
  3. data/.lando.yml +58 -0
  4. data/.rubocop.yml +11 -1
  5. data/.tool-versions +1 -1
  6. data/CHANGELOG.md +94 -13
  7. data/CONTRIBUTING.md +30 -8
  8. data/README.md +24 -48
  9. data/Rakefile +26 -20
  10. data/db/config.yml +3 -10
  11. data/lib/generators/valkyrie/resource_generator.rb +3 -3
  12. data/lib/valkyrie/change_set.rb +3 -3
  13. data/lib/valkyrie/id.rb +12 -19
  14. data/lib/valkyrie/indexers/access_controls_indexer.rb +17 -17
  15. data/lib/valkyrie/persistence/buffered_persister.rb +2 -2
  16. data/lib/valkyrie/persistence/composite_persister.rb +3 -3
  17. data/lib/valkyrie/persistence/custom_query_container.rb +8 -16
  18. data/lib/valkyrie/persistence/fedora/list_node.rb +43 -43
  19. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +5 -1
  20. data/lib/valkyrie/persistence/fedora/ordered_list.rb +90 -90
  21. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +5 -5
  22. data/lib/valkyrie/persistence/fedora/permissive_schema.rb +1 -1
  23. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +15 -16
  24. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +14 -19
  25. data/lib/valkyrie/persistence/fedora/persister.rb +83 -83
  26. data/lib/valkyrie/persistence/fedora/query_service.rb +39 -41
  27. data/lib/valkyrie/persistence/memory/persister.rb +51 -35
  28. data/lib/valkyrie/persistence/memory/query_service.rb +26 -30
  29. data/lib/valkyrie/persistence/postgres/orm_converter.rb +52 -52
  30. data/lib/valkyrie/persistence/postgres/persister.rb +4 -1
  31. data/lib/valkyrie/persistence/postgres/query_service.rb +34 -34
  32. data/lib/valkyrie/persistence/shared/json_value_mapper.rb +1 -1
  33. data/lib/valkyrie/persistence/solr/metadata_adapter.rb +15 -3
  34. data/lib/valkyrie/persistence/solr/model_converter.rb +323 -340
  35. data/lib/valkyrie/persistence/solr/orm_converter.rb +4 -4
  36. data/lib/valkyrie/persistence/solr/persister.rb +16 -4
  37. data/lib/valkyrie/persistence/solr/queries/find_by_alternate_identifier_query.rb +1 -1
  38. data/lib/valkyrie/persistence/solr/queries/find_by_id_query.rb +1 -1
  39. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +1 -1
  40. data/lib/valkyrie/persistence/solr/query_service.rb +12 -12
  41. data/lib/valkyrie/persistence/solr/repository.rb +17 -7
  42. data/lib/valkyrie/resource/access_controls.rb +1 -1
  43. data/lib/valkyrie/resource.rb +0 -1
  44. data/lib/valkyrie/specs/shared_specs/change_set.rb +1 -1
  45. data/lib/valkyrie/specs/shared_specs/file.rb +1 -0
  46. data/lib/valkyrie/specs/shared_specs/persister.rb +22 -4
  47. data/lib/valkyrie/specs/shared_specs/queries.rb +7 -0
  48. data/lib/valkyrie/specs/shared_specs/resource.rb +1 -1
  49. data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +19 -0
  50. data/lib/valkyrie/specs/shared_specs/write_only/metadata_adapter.rb +62 -0
  51. data/lib/valkyrie/specs/shared_specs.rb +2 -0
  52. data/lib/valkyrie/storage/disk.rb +24 -1
  53. data/lib/valkyrie/storage/fedora.rb +17 -17
  54. data/lib/valkyrie/storage_adapter.rb +12 -12
  55. data/lib/valkyrie/types.rb +1 -1
  56. data/lib/valkyrie/version.rb +1 -1
  57. data/lib/valkyrie/vocab/pcdm_use.rb +12 -0
  58. data/lib/valkyrie.rb +13 -27
  59. data/tasks/dev.rake +14 -51
  60. data/valkyrie.gemspec +3 -6
  61. metadata +25 -63
  62. data/.docker-stack/valkyrie-development/docker-compose.yml +0 -53
  63. data/.docker-stack/valkyrie-test/docker-compose.yml +0 -53
  64. data/tasks/docker.rake +0 -31
@@ -65,412 +65,395 @@ module Valkyrie::Persistence::Solr
65
65
 
66
66
  private
67
67
 
68
- # Maps Solr Document fields to attributes with single values
69
- # Filters for fields which store the Valkyrie resource type
70
- # @param [Hash] attribute_hash
71
- # @return [Hash]
72
- def add_single_values(attribute_hash)
73
- attribute_hash.select do |k, v|
74
- field = k.to_s.split("_").last
75
- property = k.to_s.gsub("_#{field}", "")
76
- next true if multivalued?(field)
77
- next false if property == "internal_resource"
78
- next false if v.length > 1
79
- true
80
- end
68
+ # Maps Solr Document fields to attributes with single values
69
+ # Filters for fields which store the Valkyrie resource type
70
+ # @param [Hash] attribute_hash
71
+ # @return [Hash]
72
+ def add_single_values(attribute_hash)
73
+ attribute_hash.select do |k, v|
74
+ field = k.to_s.split("_").last
75
+ property = k.to_s.gsub("_#{field}", "")
76
+ next true if multivalued?(field)
77
+ next false if property == "internal_resource"
78
+ next false if v.length > 1
79
+ true
81
80
  end
81
+ end
82
82
 
83
- # Determines whether or not a field is multivalued
84
- # @note this is tied to conventions in the Solr Schema
85
- # @see https://github.com/samvera-labs/valkyrie/blob/master/solr/config/schema.xml
86
- # @see https://lucene.apache.org/solr/guide/defining-fields.html#defining-fields
87
- # @param [String] field
88
- # @return [Boolean]
89
- def multivalued?(field)
90
- field.end_with?('m', 'mv')
91
- end
83
+ # Determines whether or not a field is multivalued
84
+ # @note this is tied to conventions in the Solr Schema
85
+ # @see https://github.com/samvera-labs/valkyrie/blob/main/solr/config/schema.xml
86
+ # @see https://lucene.apache.org/solr/guide/defining-fields.html#defining-fields
87
+ # @param [String] field
88
+ # @return [Boolean]
89
+ def multivalued?(field)
90
+ field.end_with?('m', 'mv')
91
+ end
92
92
 
93
- # If optimistic locking is enabled for this Valkyrie Resource, generates a Hash containing the locking token
94
- # @return [Hash]
95
- def lock_hash
96
- return {} unless resource.optimistic_locking_enabled? && lock_token.present?
97
- { _version_: lock_token }
98
- end
93
+ # If optimistic locking is enabled for this Valkyrie Resource, generates a Hash containing the locking token
94
+ # @return [Hash]
95
+ def lock_hash
96
+ return {} unless resource.optimistic_locking_enabled? && lock_token.present?
97
+ { _version_: lock_token }
98
+ end
99
99
 
100
- # Retrieves the lock token from the resource attributes
101
- # @return [String]
102
- def lock_token
103
- @lock_token ||= begin
104
- found_token = resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK]
105
- .find { |token| token.adapter_id == resource_factory.adapter_id }
106
- return if found_token.nil?
107
- found_token.token
108
- end
100
+ # Retrieves the lock token from the resource attributes
101
+ # @return [String]
102
+ def lock_token
103
+ @lock_token ||= begin
104
+ found_token = resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK]
105
+ .find { |token| token.adapter_id == resource_factory.adapter_id }
106
+ return if found_token.nil?
107
+ found_token.token
109
108
  end
109
+ end
110
110
 
111
- # Generates the Valkyrie Resource attribute Hash
112
- # @return [Hash]
113
- def attribute_hash
114
- properties.each_with_object({}) do |property, hsh|
115
- next if property == Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK
116
- attr = resource_attributes[property]
117
- mapper_val = SolrMapperValue.for(Property.new(property, attr)).result
118
- unless mapper_val.respond_to?(:apply_to)
119
- raise "Unable to cast #{resource_attributes[:internal_resource]}#" \
120
- "#{property} which has been set to an instance of '#{attr.class}'"
121
- end
122
- mapper_val.apply_to(hsh)
123
- end
111
+ # Generates the Valkyrie Resource attribute Hash
112
+ # @return [Hash]
113
+ def attribute_hash
114
+ properties.each_with_object({}) do |property, hsh|
115
+ next if property == Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK
116
+ attr = resource_attributes[property]
117
+ next if attr.nil?
118
+ mapper_val = SolrMapperValue.for(Property.new(property, attr)).result
119
+ unless mapper_val.respond_to?(:apply_to)
120
+ raise "Unable to cast #{resource_attributes[:internal_resource]}#" \
121
+ "#{property} which has been set to an instance of '#{attr.class}'"
122
+ end
123
+ mapper_val.apply_to(hsh)
124
124
  end
125
+ end
125
126
 
126
- # Accesses the keys for the attributes on the Valkyrie Resource
127
- # @return [Array<Symbol>]
128
- def properties
129
- resource_attributes.keys - [:id, :created_at, :updated_at, :new_record]
130
- end
131
-
132
- # Access the attributes for the Valkyrie resources
133
- # @return [Hash]
134
- def resource_attributes
135
- @resource_attributes ||= resource.attributes
136
- end
137
-
138
- ##
139
- # A container resource for holding a `key`, `value, and `scope` of a value
140
- # in a resource together for casting.
141
- class Property
142
- attr_reader :key, :value, :scope
143
- # @param key [Symbol] Property identifier.
144
- # @param value [Object] Value or list of values which are underneath the
145
- # key.
146
- # @param scope [Object] The resource or point where the key and values
147
- # came from.
148
- def initialize(key, value, scope = [])
149
- @key = key
150
- @value = value
151
- @scope = scope
152
- end
153
- end
127
+ # Accesses the keys for the attributes on the Valkyrie Resource
128
+ # @return [Array<Symbol>]
129
+ def properties
130
+ resource_attributes.keys - [:id, :created_at, :updated_at, :new_record]
131
+ end
154
132
 
155
- ##
156
- # Represents a key/value combination in the solr document, used for isolating logic around
157
- # how to apply a value to a hash.
158
- class SolrRow
159
- attr_reader :key, :fields, :values
160
- # @param key [Symbol] Solr key.
161
- # @param fields [Array<Symbol>] Field suffixes to index into.
162
- # @param values [Array] Values to index into the given fields.
163
- def initialize(key:, fields:, values:)
164
- @key = key
165
- @fields = Array.wrap(fields)
166
- @values = Array.wrap(values)
167
- end
133
+ # Access the attributes for the Valkyrie resources
134
+ # @return [Hash]
135
+ def resource_attributes
136
+ @resource_attributes ||= resource.attributes
137
+ end
168
138
 
169
- # @param hsh [Hash] The solr hash to apply to.
170
- # @return [Hash] The updated solr hash.
171
- def apply_to(hsh)
172
- return hsh if values.blank?
173
- fields.each do |field|
174
- hsh["#{key}_#{field}".to_sym] ||= []
175
- hsh["#{key}_#{field}".to_sym] += values
176
- end
177
- hsh
178
- end
139
+ ##
140
+ # A container resource for holding a `key`, `value, and `scope` of a value
141
+ # in a resource together for casting.
142
+ class Property
143
+ attr_reader :key, :value, :scope
144
+ # @param key [Symbol] Property identifier.
145
+ # @param value [Object] Value or list of values which are underneath the
146
+ # key.
147
+ # @param scope [Object] The resource or point where the key and values
148
+ # came from.
149
+ def initialize(key, value, scope = [])
150
+ @key = key
151
+ @value = value
152
+ @scope = scope
179
153
  end
154
+ end
180
155
 
181
- ##
182
- # Wraps up multiple SolrRows to apply them all at once, while looking like
183
- # just one.
184
- class CompositeSolrRow
185
- attr_reader :solr_rows
186
-
187
- # @param [Array<Valkyrie::Persistence::Solr::Mapper::SolrRow>] solr_rows
188
- def initialize(solr_rows)
189
- @solr_rows = solr_rows
190
- end
191
-
192
- # Merge a Hash of attribute values into a logical row of Solr fields
193
- # @param [Hash] hsh
194
- # @see Valkyrie::Persistence::Solr::Mapper::SolrRow#apply_to
195
- def apply_to(hsh)
196
- solr_rows.each do |solr_row|
197
- solr_row.apply_to(hsh)
198
- end
199
- hsh
200
- end
156
+ ##
157
+ # Represents a key/value combination in the solr document, used for isolating logic around
158
+ # how to apply a value to a hash.
159
+ class SolrRow
160
+ attr_reader :key, :fields, :values
161
+ # @param key [Symbol] Solr key.
162
+ # @param fields [Array<Symbol>] Field suffixes to index into.
163
+ # @param values [Array] Values to index into the given fields.
164
+ def initialize(key:, fields:, values:)
165
+ @key = key
166
+ @fields = fields
167
+ @values = values
201
168
  end
202
169
 
203
- # Container for casting mappers.
204
- class SolrMapperValue < ::Valkyrie::ValueMapper
170
+ # @param hsh [Hash] The solr hash to apply to.
171
+ # @return [Hash] The updated solr hash.
172
+ def apply_to(hsh)
173
+ return hsh if values.blank?
174
+ fields.each do |field|
175
+ hsh["#{key}_#{field}".to_sym] ||= []
176
+ hsh["#{key}_#{field}".to_sym] += values
177
+ end
178
+ hsh
205
179
  end
180
+ end
206
181
 
207
- # Casts {Boolean} values into a recognizable string in Solr.
208
- class BooleanPropertyValue < ::Valkyrie::ValueMapper
209
- SolrMapperValue.register(self)
182
+ ##
183
+ # Wraps up multiple SolrRows to apply them all at once, while looking like
184
+ # just one.
185
+ class CompositeSolrRow
186
+ attr_reader :solr_rows
210
187
 
211
- # Determines whether or not a Property value behaves like a boolean value
212
- # @param [Object] value
213
- # @return [Boolean]
214
- def self.handles?(value)
215
- value.is_a?(Property) && ([true, false].include? value.value)
216
- end
188
+ # @param [Array<Valkyrie::Persistence::Solr::Mapper::SolrRow>] solr_rows
189
+ def initialize(solr_rows)
190
+ @solr_rows = solr_rows
191
+ end
217
192
 
218
- # Constructs a SolrRow object for a Property with a Boolean value
219
- # @note this prepends the string "boolean-" to the value indexed in Solr
220
- # @return [SolrRow]
221
- def result
222
- calling_mapper.for(Property.new(value.key, "boolean-#{value.value}")).result
193
+ # Merge a Hash of attribute values into a logical row of Solr fields
194
+ # @param [Hash] hsh
195
+ # @see Valkyrie::Persistence::Solr::Mapper::SolrRow#apply_to
196
+ def apply_to(hsh)
197
+ solr_rows.each do |solr_row|
198
+ solr_row.apply_to(hsh)
223
199
  end
200
+ hsh
224
201
  end
202
+ end
225
203
 
226
- # Casts nested resources into a JSON string in solr.
227
- class NestedObjectValue < ::Valkyrie::ValueMapper
228
- SolrMapperValue.register(self)
204
+ # Container for casting mappers.
205
+ class SolrMapperValue < ::Valkyrie::ValueMapper
206
+ end
229
207
 
230
- # Determines whether or not a Property value is a Hash
231
- # @param [Object] value
232
- # @return [Boolean]
233
- def self.handles?(value)
234
- value.value.is_a?(Hash) || value.value.is_a?(Valkyrie::Resource)
235
- end
208
+ # Casts {Boolean} values into a recognizable string in Solr.
209
+ class BooleanPropertyValue < ::Valkyrie::ValueMapper
210
+ SolrMapperValue.register(self)
236
211
 
237
- # Constructs a SolrRow object for a Property with a Hash value
238
- # @note this prepends the string "serialized-" to the value indexed in Solr
239
- # This is indexed as a stored multivalued text
240
- # @see https://lucene.apache.org/solr/guide/defining-fields.html#defining-fields
241
- # @see https://github.com/samvera-labs/valkyrie/blob/master/solr/config/schema.xml
242
- # @return [SolrRow]
243
- def result
244
- SolrRow.new(key: value.key, fields: ["tsim"], values: "serialized-#{value.value.to_json}")
245
- end
212
+ # Determines whether or not a Property value behaves like a boolean value
213
+ # @param [Object] value
214
+ # @return [Boolean]
215
+ def self.handles?(value)
216
+ value.is_a?(Property) && ([true, false].include? value.value)
246
217
  end
247
218
 
248
- # Casts enumerable values one by one.
249
- class EnumerableValue < ::Valkyrie::ValueMapper
250
- SolrMapperValue.register(self)
219
+ # Constructs a SolrRow object for a Property with a Boolean value
220
+ # @note this prepends the string "boolean-" to the value indexed in Solr
221
+ # @return [SolrRow]
222
+ def result
223
+ calling_mapper.for(Property.new(value.key, "boolean-#{value.value}")).result
224
+ end
225
+ end
251
226
 
252
- # Determines whether or not a Property value is an Array
253
- # @param [Object] value
254
- # @return [Boolean]
255
- def self.handles?(value)
256
- value.is_a?(Property) && value.value.is_a?(Array)
257
- end
227
+ # Casts nested resources into a JSON string in solr.
228
+ class NestedObjectValue < ::Valkyrie::ValueMapper
229
+ SolrMapperValue.register(self)
258
230
 
259
- # Constructs a CompositeSolrRow object for a set of Property values
260
- # @return [CompositeSolrRow]
261
- def result
262
- CompositeSolrRow.new(
263
- value.value.map do |val|
264
- calling_mapper.for(Property.new(value.key, val, value.value)).result
265
- end
266
- )
267
- end
231
+ # Determines whether or not a Property value is a Hash
232
+ # @param [Object] value
233
+ # @return [Boolean]
234
+ def self.handles?(value)
235
+ value.value.is_a?(Hash) || value.value.is_a?(Valkyrie::Resource)
268
236
  end
269
237
 
270
- # Skips nil values.
271
- class NilPropertyValue < ::Valkyrie::ValueMapper
272
- SolrMapperValue.register(self)
238
+ # Constructs a SolrRow object for a Property with a Hash value
239
+ # @note this prepends the string "serialized-" to the value indexed in Solr
240
+ # This is indexed as a stored multivalued text
241
+ # @see https://lucene.apache.org/solr/guide/defining-fields.html#defining-fields
242
+ # @see https://github.com/samvera-labs/valkyrie/blob/main/solr/config/schema.xml
243
+ # @return [SolrRow]
244
+ def result
245
+ SolrRow.new(key: value.key, fields: ["tsim"], values: ["serialized-#{value.value.to_json}"])
246
+ end
247
+ end
273
248
 
274
- # Determines whether or not a Property value responds as nil
275
- # @param [Object] value
276
- # @return [Boolean]
277
- def self.handles?(value)
278
- value.is_a?(Property) && value.value.nil?
279
- end
249
+ # Casts enumerable values one by one.
250
+ class EnumerableValue < ::Valkyrie::ValueMapper
251
+ SolrMapperValue.register(self)
280
252
 
281
- # Constructs a SolrRow object for a Property with a nil value
282
- # @return [SolrRow]
283
- def result
284
- SolrRow.new(key: value.key, fields: [], values: nil)
285
- end
253
+ # Determines whether or not a Property value is an Array
254
+ # @param [Object] value
255
+ # @return [Boolean]
256
+ def self.handles?(value)
257
+ value.is_a?(Property) && value.value.is_a?(Array)
258
+ end
259
+
260
+ # Constructs a CompositeSolrRow object for a set of Property values
261
+ # @return [CompositeSolrRow]
262
+ def result
263
+ CompositeSolrRow.new(
264
+ value.value.map do |val|
265
+ calling_mapper.for(Property.new(value.key, val, value.value)).result
266
+ end
267
+ )
286
268
  end
269
+ end
287
270
 
288
- # Casts {Valkyrie::ID} values into a recognizable string in solr.
289
- class IDPropertyValue < ::Valkyrie::ValueMapper
290
- SolrMapperValue.register(self)
271
+ # Casts {Valkyrie::ID} values into a recognizable string in solr.
272
+ class IDPropertyValue < ::Valkyrie::ValueMapper
273
+ SolrMapperValue.register(self)
291
274
 
292
- # Determines whether or not a Property value is a Valkyrie ID
293
- # @param [Object] value
294
- # @return [Boolean]
295
- def self.handles?(value)
296
- value.is_a?(Property) && value.value.is_a?(::Valkyrie::ID)
297
- end
275
+ # Determines whether or not a Property value is a Valkyrie ID
276
+ # @param [Object] value
277
+ # @return [Boolean]
278
+ def self.handles?(value)
279
+ value.is_a?(Property) && value.value.is_a?(::Valkyrie::ID)
280
+ end
298
281
 
299
- # Constructs a SolrRow object for the Property Valkyrie ID value
300
- # @note this prepends the string "id-" to the value indexed in Solr
301
- # @return [SolrRow]
302
- def result
303
- calling_mapper.for(Property.new(value.key, "id-#{value.value.id}")).result
304
- end
282
+ # Constructs a SolrRow object for the Property Valkyrie ID value
283
+ # @note this prepends the string "id-" to the value indexed in Solr
284
+ # @return [SolrRow]
285
+ def result
286
+ calling_mapper.for(Property.new(value.key, "id-#{value.value.id}")).result
305
287
  end
288
+ end
306
289
 
307
- # Casts {RDF::URI} values into a recognizable string in solr.
308
- class URIPropertyValue < ::Valkyrie::ValueMapper
309
- SolrMapperValue.register(self)
290
+ # Casts {RDF::URI} values into a recognizable string in solr.
291
+ class URIPropertyValue < ::Valkyrie::ValueMapper
292
+ SolrMapperValue.register(self)
310
293
 
311
- # Determines whether or not a Property value is a URI
312
- # @param [Object] value
313
- # @return [Boolean]
314
- def self.handles?(value)
315
- value.is_a?(Property) && value.value.is_a?(::RDF::URI)
316
- end
294
+ # Determines whether or not a Property value is a URI
295
+ # @param [Object] value
296
+ # @return [Boolean]
297
+ def self.handles?(value)
298
+ value.is_a?(Property) && value.value.is_a?(::RDF::URI)
299
+ end
317
300
 
318
- # Constructs a SolrRow object for the Property URI value
319
- # @note this prepends the string "uri-" to the value indexed in Solr
320
- # @return [SolrRow]
321
- def result
322
- calling_mapper.for(Property.new(value.key, "uri-#{value.value}")).result
323
- end
301
+ # Constructs a SolrRow object for the Property URI value
302
+ # @note this prepends the string "uri-" to the value indexed in Solr
303
+ # @return [SolrRow]
304
+ def result
305
+ calling_mapper.for(Property.new(value.key, "uri-#{value.value}")).result
324
306
  end
307
+ end
325
308
 
326
- # Casts {Integer} values into a recognizable string in Solr.
327
- class IntegerPropertyValue < ::Valkyrie::ValueMapper
328
- SolrMapperValue.register(self)
309
+ # Casts {Integer} values into a recognizable string in Solr.
310
+ class IntegerPropertyValue < ::Valkyrie::ValueMapper
311
+ SolrMapperValue.register(self)
329
312
 
330
- # Determines whether or not a Property value is an Integer
331
- # @param [Object] value
332
- # @return [Boolean]
333
- def self.handles?(value)
334
- value.is_a?(Property) && value.value.is_a?(Integer)
335
- end
313
+ # Determines whether or not a Property value is an Integer
314
+ # @param [Object] value
315
+ # @return [Boolean]
316
+ def self.handles?(value)
317
+ value.is_a?(Property) && value.value.is_a?(Integer)
318
+ end
336
319
 
337
- # Constructs a SolrRow object for the Property Integer value
338
- # @note this prepends the string "integer-" to the value indexed in Solr
339
- # @return [SolrRow]
340
- def result
341
- calling_mapper.for(Property.new(value.key, "integer-#{value.value}")).result
342
- end
320
+ # Constructs a SolrRow object for the Property Integer value
321
+ # @note this prepends the string "integer-" to the value indexed in Solr
322
+ # @return [SolrRow]
323
+ def result
324
+ calling_mapper.for(Property.new(value.key, "integer-#{value.value}")).result
343
325
  end
326
+ end
344
327
 
345
- # Casts {Float} values into a recognizable string in Solr.
346
- class FloatPropertyValue < ::Valkyrie::ValueMapper
347
- SolrMapperValue.register(self)
348
- def self.handles?(value)
349
- value.is_a?(Property) && value.value.is_a?(Float)
350
- end
328
+ # Casts {Float} values into a recognizable string in Solr.
329
+ class FloatPropertyValue < ::Valkyrie::ValueMapper
330
+ SolrMapperValue.register(self)
331
+ def self.handles?(value)
332
+ value.is_a?(Property) && value.value.is_a?(Float)
333
+ end
351
334
 
352
- def result
353
- calling_mapper.for(Property.new(value.key, "float-#{value.value}")).result
354
- end
335
+ def result
336
+ calling_mapper.for(Property.new(value.key, "float-#{value.value}")).result
355
337
  end
338
+ end
356
339
 
357
- # Casts {DateTime} values into a recognizable string in Solr.
358
- class DateTimePropertyValue < ::Valkyrie::ValueMapper
359
- SolrMapperValue.register(self)
340
+ # Casts {DateTime} values into a recognizable string in Solr.
341
+ class DateTimePropertyValue < ::Valkyrie::ValueMapper
342
+ SolrMapperValue.register(self)
360
343
 
361
- # Determines whether or not a Property value is a DateTime or Time
362
- # @param [Object] value
363
- # @return [Boolean]
364
- def self.handles?(value)
365
- value.is_a?(Property) && (value.value.is_a?(Time) || value.value.is_a?(DateTime))
366
- end
344
+ # Determines whether or not a Property value is a DateTime or Time
345
+ # @param [Object] value
346
+ # @return [Boolean]
347
+ def self.handles?(value)
348
+ value.is_a?(Property) && (value.value.is_a?(Time) || value.value.is_a?(DateTime))
349
+ end
367
350
 
368
- # Constructs a SolrRow object for a datestamp derived from the value
369
- # @note this prepends the string "datetime-" to the value indexed in Solr
370
- # @return [SolrRow]
371
- def result
372
- calling_mapper.for(Property.new(value.key, "datetime-#{JSON.parse(to_datetime(value.value).to_json)}")).result
373
- end
351
+ # Constructs a SolrRow object for a datestamp derived from the value
352
+ # @note this prepends the string "datetime-" to the value indexed in Solr
353
+ # @return [SolrRow]
354
+ def result
355
+ calling_mapper.for(Property.new(value.key, "datetime-#{JSON.parse(to_datetime(value.value).to_json)}")).result
356
+ end
374
357
 
375
- private
358
+ private
376
359
 
377
- # Converts a value to a UTC timestamp if it is a DateTime or behaves like a Time value
378
- # @param [Object] value
379
- # @return [Time]
380
- def to_datetime(value)
381
- return value.utc if value.is_a?(DateTime)
382
- return value.to_datetime.utc if value.respond_to?(:to_datetime)
383
- end
360
+ # Converts a value to a UTC timestamp if it is a DateTime or behaves like a Time value
361
+ # @param [Object] value
362
+ # @return [Time]
363
+ def to_datetime(value)
364
+ return value.new_offset(0) if value.is_a?(DateTime)
365
+ return value.to_datetime.new_offset(0) if value.respond_to?(:to_datetime)
384
366
  end
367
+ end
385
368
 
386
- # Handles casting language-tagged strings when there are both
387
- # language-tagged and non-language-tagged strings in Solr. Assumes English
388
- # for non-language-tagged strings.
389
- class SharedStringPropertyValue < ::Valkyrie::ValueMapper
390
- SolrMapperValue.register(self)
369
+ # Handles casting language-tagged strings when there are both
370
+ # language-tagged and non-language-tagged strings in Solr. Assumes English
371
+ # for non-language-tagged strings.
372
+ class SharedStringPropertyValue < ::Valkyrie::ValueMapper
373
+ SolrMapperValue.register(self)
391
374
 
392
- # Determines whether or not a Property value is a String whether or not the Property has an RDF literal specifying the language tag
393
- # @param [Object] value
394
- # @return [Boolean]
395
- def self.handles?(value)
396
- value.is_a?(Property) && value.value.is_a?(String) && value.scope.find { |x| x.is_a?(::RDF::Literal) }.present?
397
- end
375
+ # Determines whether or not a Property value is a String whether or not the Property has an RDF literal specifying the language tag
376
+ # @param [Object] value
377
+ # @return [Boolean]
378
+ def self.handles?(value)
379
+ value.is_a?(Property) && value.value.is_a?(String) && value.scope.find { |x| x.is_a?(::RDF::Literal) }.present?
380
+ end
398
381
 
399
- # Constructs a CompositeSolrRow object with the language-tagged literal value
400
- # @return [CompositeSolrRow]
401
- def result
402
- CompositeSolrRow.new(
403
- [
404
- calling_mapper.for(Property.new(value.key, value.value)).result,
405
- calling_mapper.for(Property.new("#{value.key}_lang", "eng")).result,
406
- calling_mapper.for(Property.new("#{value.key}_type", "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString")).result
407
- ]
408
- )
409
- end
382
+ # Constructs a CompositeSolrRow object with the language-tagged literal value
383
+ # @return [CompositeSolrRow]
384
+ def result
385
+ CompositeSolrRow.new(
386
+ [
387
+ calling_mapper.for(Property.new(value.key, value.value)).result,
388
+ calling_mapper.for(Property.new("#{value.key}_lang", "eng")).result,
389
+ calling_mapper.for(Property.new("#{value.key}_type", "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString")).result
390
+ ]
391
+ )
410
392
  end
393
+ end
411
394
 
412
- # Handles casting strings.
413
- class StringPropertyValue < ::Valkyrie::ValueMapper
414
- SolrMapperValue.register(self)
395
+ # Handles casting strings.
396
+ class StringPropertyValue < ::Valkyrie::ValueMapper
397
+ SolrMapperValue.register(self)
415
398
 
416
- # Determines whether or not a Property value is a String
417
- # @param [Object] value
418
- # @return [Boolean]
419
- def self.handles?(value)
420
- value.is_a?(Property) && value.value.is_a?(String)
421
- end
399
+ # Determines whether or not a Property value is a String
400
+ # @param [Object] value
401
+ # @return [Boolean]
402
+ def self.handles?(value)
403
+ value.is_a?(Property) && value.value.is_a?(String)
404
+ end
422
405
 
423
- # Constructs a SolrRow object with the String values and Solr field settings
424
- # @return [SolrRow]
425
- def result
426
- SolrRow.new(key: value.key, fields: fields, values: value.value)
427
- end
406
+ # Constructs a SolrRow object with the String values and Solr field settings
407
+ # @return [SolrRow]
408
+ def result
409
+ SolrRow.new(key: value.key, fields: fields, values: [value.value])
410
+ end
428
411
 
429
- # Generates the Solr fields used during the indexing
430
- # String are normally indexed using the following:
431
- # - stored text
432
- # - stored english text
433
- # - stored single string
434
- # - multivalued string
435
- # - stored multivalued text
436
- # - stored multivalued english text
437
- # If the string is greater than 1000 characters in length, it is only indexed as a stored multivalued text
438
- # @see https://lucene.apache.org/solr/guide/defining-fields.html#defining-fields
439
- # @see https://github.com/samvera-labs/valkyrie/blob/master/solr/config/schema.xml
440
- # @return [Array<Symbol>]
441
- def fields
442
- if value.value.length > 1000
443
- [:tsim]
444
- else
445
- [:tsim, :ssim, :tesim, :tsi, :ssi, :tesi]
446
- end
412
+ # Generates the Solr fields used during the indexing
413
+ # String are normally indexed using the following:
414
+ # - stored text
415
+ # - stored english text
416
+ # - stored single string
417
+ # - multivalued string
418
+ # - stored multivalued text
419
+ # - stored multivalued english text
420
+ # If the string is greater than 1000 characters in length, it is only indexed as a stored multivalued text
421
+ # @see https://lucene.apache.org/solr/guide/defining-fields.html#defining-fields
422
+ # @see https://github.com/samvera-labs/valkyrie/blob/main/solr/config/schema.xml
423
+ # @return [Array<Symbol>]
424
+ def fields
425
+ if value.value.length > 1000
426
+ [:tsim]
427
+ else
428
+ [:tsim, :ssim, :tesim, :tsi, :ssi, :tesi]
447
429
  end
448
430
  end
431
+ end
449
432
 
450
- # Handles casting language-typed {RDF::Literal}s
451
- class LiteralPropertyValue < ::Valkyrie::ValueMapper
452
- SolrMapperValue.register(self)
433
+ # Handles casting language-typed {RDF::Literal}s
434
+ class LiteralPropertyValue < ::Valkyrie::ValueMapper
435
+ SolrMapperValue.register(self)
453
436
 
454
- # Determines whether or not a Property value is an RDF literal
455
- # @param [Object] value
456
- # @return [Boolean]
457
- def self.handles?(value)
458
- value.is_a?(Property) && value.value.is_a?(::RDF::Literal)
459
- end
437
+ # Determines whether or not a Property value is an RDF literal
438
+ # @param [Object] value
439
+ # @return [Boolean]
440
+ def self.handles?(value)
441
+ value.is_a?(Property) && value.value.is_a?(::RDF::Literal)
442
+ end
460
443
 
461
- # Constructs a CompositeSolrRow object with the language-tagged literal value
462
- # @return [CompositeSolrRow]
463
- def result
464
- key = value.key
465
- val = value.value
466
- CompositeSolrRow.new(
467
- [
468
- calling_mapper.for(Property.new(key, val.to_s)).result,
469
- calling_mapper.for(Property.new("#{key}_lang", val.language.to_s)).result,
470
- calling_mapper.for(Property.new("#{key}_type", val.datatype.to_s)).result
471
- ]
472
- )
473
- end
444
+ # Constructs a CompositeSolrRow object with the language-tagged literal value
445
+ # @return [CompositeSolrRow]
446
+ def result
447
+ key = value.key
448
+ val = value.value
449
+ CompositeSolrRow.new(
450
+ [
451
+ calling_mapper.for(Property.new(key, val.to_s)).result,
452
+ calling_mapper.for(Property.new("#{key}_lang", val.language.to_s)).result,
453
+ calling_mapper.for(Property.new("#{key}_type", val.datatype.to_s)).result
454
+ ]
455
+ )
474
456
  end
457
+ end
475
458
  end
476
459
  end