valkyrie 0.0.0 → 0.1.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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -3
  3. data/.rubocop.yml +28 -0
  4. data/Gemfile +6 -1
  5. data/README.md +145 -10
  6. data/Rakefile +59 -1
  7. data/bin/console +1 -1
  8. data/config/valkyrie.yml +8 -0
  9. data/db/config.yml +17 -0
  10. data/db/migrate/20160111215816_enable_uuid_extension.rb +6 -0
  11. data/db/migrate/20161007101725_create_orm_resources.rb +10 -0
  12. data/db/migrate/20170124135846_add_model_type_to_orm_resources.rb +6 -0
  13. data/db/migrate/20170531004548_change_model_type_to_internal_model.rb +6 -0
  14. data/db/schema.rb +65 -0
  15. data/db/seeds.rb +8 -0
  16. data/lib/config/database_connection.rb +15 -0
  17. data/lib/generators/valkyrie/resource_generator.rb +27 -0
  18. data/lib/generators/valkyrie/templates/resource.rb.erb +9 -0
  19. data/lib/generators/valkyrie/templates/resource_spec.rb.erb +13 -0
  20. data/lib/valkyrie.rb +76 -1
  21. data/lib/valkyrie/adapter_container.rb +12 -0
  22. data/lib/valkyrie/change_set.rb +84 -0
  23. data/lib/valkyrie/decorators/decorator_list.rb +15 -0
  24. data/lib/valkyrie/decorators/decorator_with_arguments.rb +14 -0
  25. data/lib/valkyrie/derivative_service.rb +42 -0
  26. data/lib/valkyrie/engine.rb +10 -0
  27. data/lib/valkyrie/file_characterization_service.rb +42 -0
  28. data/lib/valkyrie/id.rb +32 -0
  29. data/lib/valkyrie/indexers/access_controls_indexer.rb +19 -0
  30. data/lib/valkyrie/local_file_service.rb +11 -0
  31. data/lib/valkyrie/metadata_adapter.rb +22 -0
  32. data/lib/valkyrie/persist_derivatives.rb +29 -0
  33. data/lib/valkyrie/persistence.rb +14 -0
  34. data/lib/valkyrie/persistence/buffered_persister.rb +28 -0
  35. data/lib/valkyrie/persistence/composite_persister.rb +29 -0
  36. data/lib/valkyrie/persistence/delete_tracking_buffer.rb +21 -0
  37. data/lib/valkyrie/persistence/fedora.rb +11 -0
  38. data/lib/valkyrie/persistence/fedora/list_node.rb +88 -0
  39. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +45 -0
  40. data/lib/valkyrie/persistence/fedora/ordered_list.rb +146 -0
  41. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +28 -0
  42. data/lib/valkyrie/persistence/fedora/persister.rb +47 -0
  43. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +199 -0
  44. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +338 -0
  45. data/lib/valkyrie/persistence/fedora/persister/resource_factory.rb +21 -0
  46. data/lib/valkyrie/persistence/fedora/query_service.rb +80 -0
  47. data/lib/valkyrie/persistence/memory.rb +8 -0
  48. data/lib/valkyrie/persistence/memory/metadata_adapter.rb +22 -0
  49. data/lib/valkyrie/persistence/memory/persister.rb +58 -0
  50. data/lib/valkyrie/persistence/memory/query_service.rb +86 -0
  51. data/lib/valkyrie/persistence/postgres.rb +6 -0
  52. data/lib/valkyrie/persistence/postgres/metadata_adapter.rb +20 -0
  53. data/lib/valkyrie/persistence/postgres/orm.rb +9 -0
  54. data/lib/valkyrie/persistence/postgres/orm/resource.rb +7 -0
  55. data/lib/valkyrie/persistence/postgres/orm_converter.rb +118 -0
  56. data/lib/valkyrie/persistence/postgres/persister.rb +33 -0
  57. data/lib/valkyrie/persistence/postgres/queries.rb +8 -0
  58. data/lib/valkyrie/persistence/postgres/queries/find_inverse_references_query.rb +31 -0
  59. data/lib/valkyrie/persistence/postgres/queries/find_members_query.rb +33 -0
  60. data/lib/valkyrie/persistence/postgres/queries/find_references_query.rb +33 -0
  61. data/lib/valkyrie/persistence/postgres/query_service.rb +53 -0
  62. data/lib/valkyrie/persistence/postgres/resource_converter.rb +18 -0
  63. data/lib/valkyrie/persistence/postgres/resource_factory.rb +30 -0
  64. data/lib/valkyrie/persistence/solr.rb +6 -0
  65. data/lib/valkyrie/persistence/solr/metadata_adapter.rb +42 -0
  66. data/lib/valkyrie/persistence/solr/model_converter.rb +270 -0
  67. data/lib/valkyrie/persistence/solr/orm_converter.rb +252 -0
  68. data/lib/valkyrie/persistence/solr/persister.rb +32 -0
  69. data/lib/valkyrie/persistence/solr/queries.rb +11 -0
  70. data/lib/valkyrie/persistence/solr/queries/default_paginator.rb +16 -0
  71. data/lib/valkyrie/persistence/solr/queries/find_all_query.rb +33 -0
  72. data/lib/valkyrie/persistence/solr/queries/find_by_id_query.rb +24 -0
  73. data/lib/valkyrie/persistence/solr/queries/find_inverse_references_query.rb +30 -0
  74. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +43 -0
  75. data/lib/valkyrie/persistence/solr/queries/find_references_query.rb +34 -0
  76. data/lib/valkyrie/persistence/solr/query_service.rb +48 -0
  77. data/lib/valkyrie/persistence/solr/repository.rb +36 -0
  78. data/lib/valkyrie/persistence/solr/resource_factory.rb +24 -0
  79. data/lib/valkyrie/rdf_patches.rb +17 -0
  80. data/lib/valkyrie/resource.rb +106 -0
  81. data/lib/valkyrie/resource/access_controls.rb +13 -0
  82. data/lib/valkyrie/specs/shared_specs.rb +10 -0
  83. data/lib/valkyrie/specs/shared_specs/change_set_persister.rb +60 -0
  84. data/lib/valkyrie/specs/shared_specs/derivative_service.rb +30 -0
  85. data/lib/valkyrie/specs/shared_specs/file.rb +12 -0
  86. data/lib/valkyrie/specs/shared_specs/file_characterization_service.rb +33 -0
  87. data/lib/valkyrie/specs/shared_specs/metadata_adapter.rb +10 -0
  88. data/lib/valkyrie/specs/shared_specs/persister.rb +154 -0
  89. data/lib/valkyrie/specs/shared_specs/queries.rb +128 -0
  90. data/lib/valkyrie/specs/shared_specs/resource.rb +71 -0
  91. data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +44 -0
  92. data/lib/valkyrie/storage.rb +8 -0
  93. data/lib/valkyrie/storage/disk.rb +55 -0
  94. data/lib/valkyrie/storage/fedora.rb +71 -0
  95. data/lib/valkyrie/storage/memory.rb +31 -0
  96. data/lib/valkyrie/storage_adapter.rb +100 -0
  97. data/lib/valkyrie/types.rb +34 -0
  98. data/lib/valkyrie/value_mapper.rb +67 -0
  99. data/lib/valkyrie/version.rb +2 -1
  100. data/lib/valkyrie/vocab/pcdm_use.rb +73 -0
  101. data/valkyrie.gemspec +33 -7
  102. metadata +462 -7
  103. data/.travis.yml +0 -5
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ require 'valkyrie/persistence/postgres/orm'
3
+ require 'valkyrie/persistence/postgres/resource_factory'
4
+ module Valkyrie::Persistence::Postgres
5
+ class Persister
6
+ attr_reader :adapter
7
+ delegate :resource_factory, to: :adapter
8
+ def initialize(adapter:)
9
+ @adapter = adapter
10
+ end
11
+
12
+ # (see Valkyrie::Persistence::Memory::Persister#save)
13
+ def save(resource:)
14
+ orm_object = resource_factory.from_resource(resource: resource)
15
+ orm_object.save!
16
+ resource_factory.to_resource(object: orm_object)
17
+ end
18
+
19
+ # (see Valkyrie::Persistence::Memory::Persister#save_all)
20
+ def save_all(resources:)
21
+ resources.map do |resource|
22
+ save(resource: resource)
23
+ end
24
+ end
25
+
26
+ # (see Valkyrie::Persistence::Memory::Persister#delete)
27
+ def delete(resource:)
28
+ orm_object = resource_factory.from_resource(resource: resource)
29
+ orm_object.delete
30
+ resource
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'valkyrie/persistence/postgres/queries/find_inverse_references_query'
3
+ require 'valkyrie/persistence/postgres/queries/find_members_query'
4
+ require 'valkyrie/persistence/postgres/queries/find_references_query'
5
+ module Valkyrie::Persistence::Postgres
6
+ module Queries
7
+ end
8
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Postgres::Queries
3
+ class FindInverseReferencesQuery
4
+ delegate :orm_class, to: :resource_factory
5
+ attr_reader :obj, :property, :resource_factory
6
+ def initialize(obj, property, resource_factory:)
7
+ @obj = obj
8
+ @property = property
9
+ @resource_factory = resource_factory
10
+ end
11
+
12
+ def run
13
+ relation.lazy.map do |orm_object|
14
+ resource_factory.to_resource(object: orm_object)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def relation
21
+ orm_class.find_by_sql([query, property, "[{\"id\": \"#{obj.id}\"}]"])
22
+ end
23
+
24
+ def query
25
+ <<-SQL
26
+ SELECT * FROM orm_resources WHERE
27
+ metadata->? @> ?
28
+ SQL
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Postgres::Queries
3
+ class FindMembersQuery
4
+ attr_reader :obj, :resource_factory
5
+ delegate :orm_class, to: :resource_factory
6
+ def initialize(obj, resource_factory:)
7
+ @obj = obj
8
+ @resource_factory = resource_factory
9
+ end
10
+
11
+ def run
12
+ return [] if obj.id.blank?
13
+ relation.lazy.map do |orm_object|
14
+ resource_factory.to_resource(object: orm_object)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def relation
21
+ orm_class.find_by_sql([query, obj.id.to_s])
22
+ end
23
+
24
+ def query
25
+ <<-SQL
26
+ SELECT member.* FROM orm_resources a,
27
+ jsonb_array_elements(a.metadata->'member_ids') WITH ORDINALITY AS b(member, member_pos)
28
+ JOIN orm_resources member ON (b.member->>'id')::uuid = member.id WHERE a.id = ?
29
+ ORDER BY b.member_pos
30
+ SQL
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Postgres::Queries
3
+ class FindReferencesQuery
4
+ delegate :orm_class, to: :resource_factory
5
+ attr_reader :obj, :property, :resource_factory
6
+ def initialize(obj, property, resource_factory:)
7
+ @obj = obj
8
+ @property = property
9
+ @resource_factory = resource_factory
10
+ end
11
+
12
+ def run
13
+ return [] if obj.id.blank? || obj[property].blank?
14
+ relation.lazy.map do |orm_object|
15
+ resource_factory.to_resource(object: orm_object)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def relation
22
+ orm_class.find_by_sql([query, property, obj.id.to_s])
23
+ end
24
+
25
+ def query
26
+ <<-SQL
27
+ SELECT member.* FROM orm_resources a,
28
+ jsonb_array_elements(a.metadata->?) AS b(member)
29
+ JOIN orm_resources member ON (b.member->>'id')::uuid = member.id WHERE a.id = ?
30
+ SQL
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ require 'valkyrie/persistence/postgres/queries'
3
+ module Valkyrie::Persistence::Postgres
4
+ class QueryService
5
+ attr_reader :adapter
6
+ delegate :resource_factory, to: :adapter
7
+ delegate :orm_class, to: :resource_factory
8
+ def initialize(adapter:)
9
+ @adapter = adapter
10
+ end
11
+
12
+ # (see Valkyrie::Persistence::Memory::QueryService#find_all)
13
+ def find_all
14
+ orm_class.all.lazy.map do |orm_object|
15
+ resource_factory.to_resource(object: orm_object)
16
+ end
17
+ end
18
+
19
+ # (see Valkyrie::Persistence::Memory::QueryService#find_all_of_model)
20
+ def find_all_of_model(model:)
21
+ orm_class.where(internal_resource: model.to_s).lazy.map do |orm_object|
22
+ resource_factory.to_resource(object: orm_object)
23
+ end
24
+ end
25
+
26
+ # (see Valkyrie::Persistence::Memory::QueryService#find_by)
27
+ def find_by(id:)
28
+ resource_factory.to_resource(object: orm_class.find(id))
29
+ rescue ActiveRecord::RecordNotFound
30
+ raise Valkyrie::Persistence::ObjectNotFoundError
31
+ end
32
+
33
+ # (see Valkyrie::Persistence::Memory::QueryService#find_members)
34
+ def find_members(resource:)
35
+ Valkyrie::Persistence::Postgres::Queries::FindMembersQuery.new(resource, resource_factory: resource_factory).run
36
+ end
37
+
38
+ # (see Valkyrie::Persistence::Memory::QueryService#find_parents)
39
+ def find_parents(resource:)
40
+ find_inverse_references_by(resource: resource, property: :member_ids)
41
+ end
42
+
43
+ # (see Valkyrie::Persistence::Memory::QueryService#find_references_by)
44
+ def find_references_by(resource:, property:)
45
+ Valkyrie::Persistence::Postgres::Queries::FindReferencesQuery.new(resource, property, resource_factory: resource_factory).run
46
+ end
47
+
48
+ # (see Valkyrie::Persistence::Memory::QueryService#find_inverse_references_by)
49
+ def find_inverse_references_by(resource:, property:)
50
+ Valkyrie::Persistence::Postgres::Queries::FindInverseReferencesQuery.new(resource, property, resource_factory: resource_factory).run
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Postgres
3
+ class ResourceConverter
4
+ delegate :orm_class, to: :resource_factory
5
+ attr_reader :resource, :resource_factory
6
+ def initialize(resource, resource_factory:)
7
+ @resource = resource
8
+ @resource_factory = resource_factory
9
+ end
10
+
11
+ def convert!
12
+ orm_class.find_or_initialize_by(id: resource.id.to_s).tap do |orm_object|
13
+ orm_object.internal_resource = resource.internal_resource
14
+ orm_object.metadata.merge!(resource.attributes.except(:id, :internal_resource, :created_at, :updated_at))
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ require 'valkyrie/persistence/postgres/orm_converter'
3
+ require 'valkyrie/persistence/postgres/resource_converter'
4
+ module Valkyrie::Persistence::Postgres
5
+ class ResourceFactory
6
+ class << self
7
+ # @param orm_object [Valkyrie::Persistence::Postgres::ORM::Resource] AR
8
+ # record to be converted.
9
+ # @return [Valkyrie::Resource] Model representation of the AR record.
10
+ def to_resource(object:)
11
+ ::Valkyrie::Persistence::Postgres::ORMConverter.new(object).convert!
12
+ end
13
+
14
+ # @param resource [Valkyrie::Resource] Model to be converted to ActiveRecord.
15
+ # @return [Valkyrie::Persistence::Postgres::ORM::Resource] ActiveRecord
16
+ # resource for the Valkyrie resource.
17
+ def from_resource(resource:)
18
+ ::Valkyrie::Persistence::Postgres::ResourceConverter.new(resource, resource_factory: self).convert!
19
+ # ::Valkyrie::Persistence::Postgres::ORM::Resource.find_or_initialize_by(id: resource.id.to_s).tap do |orm_object|
20
+ # orm_object.internal_resource = resource.internal_resource
21
+ # orm_object.metadata.merge!(resource.attributes.except(:id, :internal_resource, :created_at, :updated_at))
22
+ # end
23
+ end
24
+
25
+ def orm_class
26
+ ::Valkyrie::Persistence::Postgres::ORM::Resource
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence
3
+ module Solr
4
+ require 'valkyrie/persistence/solr/metadata_adapter'
5
+ end
6
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+ require 'rsolr'
3
+ module Valkyrie::Persistence::Solr
4
+ require 'valkyrie/persistence/solr/persister'
5
+ require 'valkyrie/persistence/solr/query_service'
6
+ require 'valkyrie/persistence/solr/resource_factory'
7
+ class MetadataAdapter
8
+ attr_reader :connection, :resource_indexer
9
+ # @param connection [RSolr::Client] The RSolr connection to index to.
10
+ # @param resource_indexer [Class, #to_solr] An indexer which is able to
11
+ # receive a `resource` argument and then has an instance method `#to_solr`
12
+ def initialize(connection:, resource_indexer: NullIndexer)
13
+ @connection = connection
14
+ @resource_indexer = resource_indexer
15
+ end
16
+
17
+ # @return [Valkyrie::Persistence::Solr::Persister] The solr persister.
18
+ def persister
19
+ Valkyrie::Persistence::Solr::Persister.new(adapter: self)
20
+ end
21
+
22
+ # @return [Valkyrie::Persistence::Solr::QueryService] The solr query
23
+ # service.
24
+ def query_service
25
+ Valkyrie::Persistence::Solr::QueryService.new(connection: connection, resource_factory: resource_factory)
26
+ end
27
+
28
+ # @return [Valkyrie::Persistence::Solr::ResourceFactory] A resource factory
29
+ # to convert a resource to a solr document and back.
30
+ def resource_factory
31
+ Valkyrie::Persistence::Solr::ResourceFactory.new(resource_indexer: resource_indexer)
32
+ end
33
+
34
+ class NullIndexer
35
+ def initialize(_); end
36
+
37
+ def to_solr
38
+ {}
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,270 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr
3
+ class ModelConverter
4
+ attr_reader :resource, :resource_factory
5
+ delegate :resource_indexer, to: :resource_factory
6
+ def initialize(resource, resource_factory:)
7
+ @resource = resource
8
+ @resource_factory = resource_factory
9
+ end
10
+
11
+ def convert!
12
+ to_h.merge(internal_resource_ssim: [resource.internal_resource]).merge(indexer_solr(resource))
13
+ end
14
+
15
+ def indexer_solr(resource)
16
+ resource_indexer.new(resource: resource).to_solr
17
+ end
18
+
19
+ # @return [String] The solr document ID
20
+ def id
21
+ "id-#{resource.id}"
22
+ end
23
+
24
+ # @return [String] ISO-8601 timestamp in UTC of the created_at for this solr
25
+ # document.
26
+ def created_at
27
+ resource_attributes[:created_at] || Time.current.utc.iso8601
28
+ end
29
+
30
+ # @return [Hash] Solr document to index.
31
+ def to_h
32
+ {
33
+ "id": id,
34
+ "created_at_dtsi": created_at
35
+ }.merge(attribute_hash)
36
+ end
37
+
38
+ private
39
+
40
+ def attribute_hash
41
+ properties.each_with_object({}) do |property, hsh|
42
+ SolrMapperValue.for(Property.new(property, resource_attributes[property])).result.apply_to(hsh)
43
+ end
44
+ end
45
+
46
+ def properties
47
+ resource_attributes.keys - [:id, :created_at, :updated_at]
48
+ end
49
+
50
+ def resource_attributes
51
+ @resource_attributes ||= resource.attributes
52
+ end
53
+
54
+ ##
55
+ # A container resource for holding a `key`, `value, and `scope` of a value
56
+ # in a resource together for casting.
57
+ class Property
58
+ attr_reader :key, :value, :scope
59
+ # @param key [Symbol] Property identifier.
60
+ # @param value [Object] Value or list of values which are underneath the
61
+ # key.
62
+ # @param scope [Object] The resource or point where the key and values
63
+ # came from.
64
+ def initialize(key, value, scope = [])
65
+ @key = key
66
+ @value = value
67
+ @scope = scope
68
+ end
69
+ end
70
+
71
+ ##
72
+ # Represents a key/value combination in the solr document, used for isolating logic around
73
+ # how to apply a value to a hash.
74
+ class SolrRow
75
+ attr_reader :key, :fields, :values
76
+ # @param key [Symbol] Solr key.
77
+ # @param fields [Array<Symbol>] Field suffixes to index into.
78
+ # @param values [Array] Values to index into the given fields.
79
+ def initialize(key:, fields:, values:)
80
+ @key = key
81
+ @fields = Array.wrap(fields)
82
+ @values = Array.wrap(values)
83
+ end
84
+
85
+ # @param hsh [Hash] The solr hash to apply to.
86
+ # @return [Hash] The updated solr hash.
87
+ def apply_to(hsh)
88
+ return hsh if values.blank?
89
+ fields.each do |field|
90
+ hsh["#{key}_#{field}".to_sym] ||= []
91
+ hsh["#{key}_#{field}".to_sym] += values
92
+ end
93
+ hsh
94
+ end
95
+ end
96
+
97
+ ##
98
+ # Wraps up multiple SolrRows to apply them all at once, while looking like
99
+ # just one.
100
+ class CompositeSolrRow
101
+ attr_reader :solr_rows
102
+ def initialize(solr_rows)
103
+ @solr_rows = solr_rows
104
+ end
105
+
106
+ # @see Valkyrie::Persistence::Solr::Mapper::SolrRow#apply_to
107
+ def apply_to(hsh)
108
+ solr_rows.each do |solr_row|
109
+ solr_row.apply_to(hsh)
110
+ end
111
+ hsh
112
+ end
113
+ end
114
+
115
+ # Container for casting mappers.
116
+ class SolrMapperValue < ::Valkyrie::ValueMapper
117
+ end
118
+
119
+ # Casts nested resources into a JSON string in solr.
120
+ class NestedObjectValue < ::Valkyrie::ValueMapper
121
+ SolrMapperValue.register(self)
122
+ def self.handles?(value)
123
+ value.value.is_a?(Hash)
124
+ end
125
+
126
+ def result
127
+ SolrRow.new(key: value.key, fields: ["tsim"], values: "serialized-#{value.value.to_json}")
128
+ end
129
+ end
130
+
131
+ # Casts enumerable values one by one.
132
+ class EnumerableValue < ::Valkyrie::ValueMapper
133
+ SolrMapperValue.register(self)
134
+ def self.handles?(value)
135
+ value.is_a?(Property) && value.value.is_a?(Array)
136
+ end
137
+
138
+ def result
139
+ CompositeSolrRow.new(
140
+ value.value.map do |val|
141
+ calling_mapper.for(Property.new(value.key, val, value.value)).result
142
+ end
143
+ )
144
+ end
145
+ end
146
+
147
+ # Skips nil values.
148
+ class NilPropertyValue < ::Valkyrie::ValueMapper
149
+ SolrMapperValue.register(self)
150
+ def self.handles?(value)
151
+ value.is_a?(Property) && value.value.nil?
152
+ end
153
+
154
+ def result
155
+ SolrRow.new(key: value.key, fields: [], values: nil)
156
+ end
157
+ end
158
+
159
+ # Casts {Valkyrie::ID} values into a recognizable string in solr.
160
+ class IDPropertyValue < ::Valkyrie::ValueMapper
161
+ SolrMapperValue.register(self)
162
+ def self.handles?(value)
163
+ value.is_a?(Property) && value.value.is_a?(::Valkyrie::ID)
164
+ end
165
+
166
+ def result
167
+ calling_mapper.for(Property.new(value.key, "id-#{value.value.id}")).result
168
+ end
169
+ end
170
+
171
+ # Casts {RDF::URI} values into a recognizable string in solr.
172
+ class URIPropertyValue < ::Valkyrie::ValueMapper
173
+ SolrMapperValue.register(self)
174
+ def self.handles?(value)
175
+ value.is_a?(Property) && value.value.is_a?(::RDF::URI)
176
+ end
177
+
178
+ def result
179
+ calling_mapper.for(Property.new(value.key, "uri-#{value.value}")).result
180
+ end
181
+ end
182
+
183
+ # Casts {Integer} values into a recognizable string in Solr.
184
+ class IntegerPropertyValue < ::Valkyrie::ValueMapper
185
+ SolrMapperValue.register(self)
186
+ def self.handles?(value)
187
+ value.is_a?(Property) && value.value.is_a?(Integer)
188
+ end
189
+
190
+ def result
191
+ calling_mapper.for(Property.new(value.key, "integer-#{value.value}")).result
192
+ end
193
+ end
194
+
195
+ # Casts {DateTime} values into a recognizable string in Solr.
196
+ class DateTimePropertyValue < ::Valkyrie::ValueMapper
197
+ SolrMapperValue.register(self)
198
+ def self.handles?(value)
199
+ value.is_a?(Property) && (value.value.is_a?(Time) || value.value.is_a?(DateTime))
200
+ end
201
+
202
+ def result
203
+ calling_mapper.for(Property.new(value.key, "datetime-#{JSON.parse(to_datetime(value.value).to_json)}")).result
204
+ end
205
+
206
+ private
207
+
208
+ def to_datetime(value)
209
+ return value.utc if value.is_a?(DateTime)
210
+ return value.to_datetime.utc if value.respond_to?(:to_datetime)
211
+ end
212
+ end
213
+
214
+ # Handles casting language-tagged strings when there are both
215
+ # language-tagged and non-language-tagged strings in Solr. Assumes English
216
+ # for non-language-tagged strings.
217
+ class SharedStringPropertyValue < ::Valkyrie::ValueMapper
218
+ SolrMapperValue.register(self)
219
+ def self.handles?(value)
220
+ value.is_a?(Property) && value.value.is_a?(String) && value.scope.find { |x| x.is_a?(::RDF::Literal) }.present?
221
+ end
222
+
223
+ def result
224
+ CompositeSolrRow.new(
225
+ [
226
+ calling_mapper.for(Property.new(value.key, value.value)).result,
227
+ calling_mapper.for(Property.new("#{value.key}_lang", "eng")).result
228
+ ]
229
+ )
230
+ end
231
+ end
232
+
233
+ # Handles casting strings.
234
+ class StringPropertyValue < ::Valkyrie::ValueMapper
235
+ SolrMapperValue.register(self)
236
+ def self.handles?(value)
237
+ value.is_a?(Property) && value.value.is_a?(String)
238
+ end
239
+
240
+ def result
241
+ SolrRow.new(key: value.key, fields: fields, values: value.value)
242
+ end
243
+
244
+ def fields
245
+ if value.value.length > 1000
246
+ [:tsim]
247
+ else
248
+ [:tsim, :ssim, :tesim]
249
+ end
250
+ end
251
+ end
252
+
253
+ # Handles casting language-typed {RDF::Literal}s
254
+ class LiteralPropertyValue < ::Valkyrie::ValueMapper
255
+ SolrMapperValue.register(self)
256
+ def self.handles?(value)
257
+ value.is_a?(Property) && value.value.is_a?(::RDF::Literal)
258
+ end
259
+
260
+ def result
261
+ CompositeSolrRow.new(
262
+ [
263
+ calling_mapper.for(Property.new(value.key, value.value.to_s)).result,
264
+ calling_mapper.for(Property.new("#{value.key}_lang", value.value.language.to_s)).result
265
+ ]
266
+ )
267
+ end
268
+ end
269
+ end
270
+ end