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,28 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Fedora
3
+ ##
4
+ # Lazily iterates over a doubly linked list, fixing up nodes if necessary.
5
+ class OrderedReader
6
+ include Enumerable
7
+ attr_reader :root
8
+ def initialize(root)
9
+ @root = root
10
+ end
11
+
12
+ def each
13
+ proxy = first_head
14
+ while proxy
15
+ yield proxy unless proxy.nil?
16
+ next_proxy = proxy.next
17
+ next_proxy.try(:prev=, proxy) if next_proxy && next_proxy.prev != proxy
18
+ proxy = next_proxy
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def first_head
25
+ root.head
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Fedora
3
+ class Persister
4
+ require 'valkyrie/persistence/fedora/persister/resource_factory'
5
+ attr_reader :adapter
6
+ delegate :connection, :base_path, :resource_factory, to: :adapter
7
+ def initialize(adapter:)
8
+ @adapter = adapter
9
+ end
10
+
11
+ def save(resource:)
12
+ initialize_repository
13
+ resource.created_at ||= Time.current
14
+ resource.updated_at ||= Time.current
15
+ orm = resource_factory.from_resource(resource: resource)
16
+ if !orm.new? || resource.id
17
+ orm.update do |req|
18
+ req.headers["Prefer"] = "handling=lenient; received=\"minimal\""
19
+ end
20
+ else
21
+ orm.create
22
+ end
23
+ resource_factory.to_resource(object: orm)
24
+ end
25
+
26
+ def save_all(resources:)
27
+ resources.map do |resource|
28
+ save(resource: resource)
29
+ end
30
+ end
31
+
32
+ def delete(resource:)
33
+ orm = resource_factory.from_resource(resource: resource)
34
+ orm.delete
35
+ resource
36
+ end
37
+
38
+ def initialize_repository
39
+ @initialized ||=
40
+ begin
41
+ resource = ::Ldp::Container::Basic.new(connection, base_path, nil, base_path)
42
+ resource.save if resource.new?
43
+ true
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Fedora
3
+ class Persister
4
+ class ModelConverter
5
+ attr_reader :resource, :adapter, :subject_uri
6
+ delegate :connection, :connection_prefix, :base_path, to: :adapter
7
+ def initialize(resource:, adapter:, subject_uri: RDF::URI(""))
8
+ @resource = resource
9
+ @adapter = adapter
10
+ @subject_uri = subject_uri
11
+ end
12
+
13
+ def convert
14
+ graph_resource.graph.delete([nil, nil, nil])
15
+ resource.attributes.each do |key, values|
16
+ output = property_converter.for(Property.new(subject_uri, key, values, adapter)).result
17
+ graph_resource.graph << output.to_graph
18
+ end
19
+ graph_resource
20
+ end
21
+
22
+ def graph_resource
23
+ @graph_resource ||= ::Ldp::Container::Basic.new(connection, subject, nil, base_path)
24
+ end
25
+
26
+ def subject
27
+ adapter.id_to_uri(resource.id) if resource.try(:id)
28
+ end
29
+
30
+ def property_converter
31
+ FedoraValue
32
+ end
33
+
34
+ class Property
35
+ attr_reader :key, :value, :subject, :adapter
36
+
37
+ def self.to_uri(key)
38
+ RDF::URI.new("http://example.com/predicate/#{key}")
39
+ end
40
+
41
+ def initialize(subject, key, value, adapter)
42
+ @subject = subject
43
+ @key = key
44
+ @value = value
45
+ @adapter = adapter
46
+ end
47
+
48
+ def to_graph(graph = RDF::Graph.new)
49
+ Array(value).each do |val|
50
+ graph << RDF::Statement.new(subject, self.class.to_uri(key), val)
51
+ end
52
+ graph
53
+ end
54
+ end
55
+
56
+ class CompositeProperty
57
+ attr_reader :properties
58
+ def initialize(properties)
59
+ @properties = properties
60
+ end
61
+
62
+ def to_graph(graph = RDF::Graph.new)
63
+ properties.each do |property|
64
+ property.to_graph(graph)
65
+ end
66
+ graph
67
+ end
68
+ end
69
+
70
+ class GraphProperty
71
+ attr_reader :key, :graph, :subject, :adapter
72
+ def initialize(subject, key, graph, adapter)
73
+ @subject = subject
74
+ @key = key
75
+ @graph = graph
76
+ @adapter = adapter
77
+ end
78
+
79
+ def to_graph(passed_graph = RDF::Graph.new)
80
+ passed_graph << graph
81
+ end
82
+ end
83
+
84
+ class FedoraValue < ::Valkyrie::ValueMapper
85
+ end
86
+
87
+ class OrderedMembers < ::Valkyrie::ValueMapper
88
+ FedoraValue.register(self)
89
+ def self.handles?(value)
90
+ value.is_a?(Property) && value.key == :member_ids && Array(value.value).present?
91
+ end
92
+
93
+ def result
94
+ initialize_list
95
+ apply_first_and_last
96
+ GraphProperty.new(value.subject, value.key, graph, value.adapter)
97
+ end
98
+
99
+ def graph
100
+ @graph ||= ordered_list.to_graph
101
+ end
102
+
103
+ def apply_first_and_last
104
+ return if ordered_list.to_a.empty?
105
+ graph << RDF::Statement.new(value.subject, ::RDF::Vocab::IANA.first, ordered_list.head.next.rdf_subject)
106
+ graph << RDF::Statement.new(value.subject, ::RDF::Vocab::IANA.last, ordered_list.tail.prev.rdf_subject)
107
+ end
108
+
109
+ def initialize_list
110
+ Array(value.value).each_with_index do |val, index|
111
+ ordered_list.insert_proxy_for_at(index, calling_mapper.for(Property.new(value.subject, :member_id, val, value.adapter)).result.value)
112
+ end
113
+ end
114
+
115
+ def ordered_list
116
+ @ordered_list ||= OrderedList.new(RDF::Graph.new, nil, nil, value.adapter)
117
+ end
118
+ end
119
+
120
+ class NestedProperty < ::Valkyrie::ValueMapper
121
+ FedoraValue.register(self)
122
+ def self.handles?(value)
123
+ value.is_a?(Property) && value.value.is_a?(Hash) && value.value[:internal_resource]
124
+ end
125
+
126
+ def result
127
+ nested_graph << RDF::Statement.new(value.subject, Property.to_uri(value.key), subject_uri)
128
+ GraphProperty.new(value.subject, value.key, nested_graph, value.adapter)
129
+ end
130
+
131
+ def nested_graph
132
+ @nested_graph ||= ModelConverter.new(resource: Valkyrie::Types::Anything[value.value], adapter: value.adapter, subject_uri: subject_uri).convert.graph
133
+ end
134
+
135
+ def subject_uri
136
+ @subject_uri ||= ::RDF::URI(RDF::Node.new.to_s.gsub("_:", "#"))
137
+ end
138
+ end
139
+
140
+ class NestedInternalValkyrieID < ::Valkyrie::ValueMapper
141
+ FedoraValue.register(self)
142
+ def self.handles?(value)
143
+ value.is_a?(Property) && value.value.is_a?(Valkyrie::ID) && value.subject.to_s.include?("#")
144
+ end
145
+
146
+ def result
147
+ calling_mapper.for(Property.new(value.subject, value.key, RDF::Literal.new(value.value, datatype: RDF::URI("http://example.com/predicate/valkyrie_id")), value.adapter)).result
148
+ end
149
+ end
150
+
151
+ class InternalValkyrieID < ::Valkyrie::ValueMapper
152
+ FedoraValue.register(self)
153
+ def self.handles?(value)
154
+ value.is_a?(Property) && value.value.is_a?(Valkyrie::ID) && !value.value.to_s.include?("://")
155
+ end
156
+
157
+ def result
158
+ calling_mapper.for(Property.new(value.subject, value.key, value.adapter.id_to_uri(value.value), value.adapter)).result
159
+ end
160
+ end
161
+
162
+ class TimeValue < ::Valkyrie::ValueMapper
163
+ FedoraValue.register(self)
164
+ def self.handles?(value)
165
+ value.is_a?(Property) && value.value.is_a?(Time)
166
+ end
167
+
168
+ def result
169
+ calling_mapper.for(Property.new(value.subject, value.key, value.value.to_datetime, value.adapter)).result
170
+ end
171
+ end
172
+
173
+ class IdentifiableValue < ::Valkyrie::ValueMapper
174
+ FedoraValue.register(self)
175
+ def self.handles?(value)
176
+ value.is_a?(Property) && value.value.is_a?(Valkyrie::ID)
177
+ end
178
+
179
+ def result
180
+ calling_mapper.for(Property.new(value.subject, value.key, RDF::Literal.new(value.value, datatype: RDF::URI("http://example.com/predicate/valkyrie_id")), value.adapter)).result
181
+ end
182
+ end
183
+
184
+ class EnumerableValue < ::Valkyrie::ValueMapper
185
+ FedoraValue.register(self)
186
+ def self.handles?(value)
187
+ value.is_a?(Property) && value.value.is_a?(Array)
188
+ end
189
+
190
+ def result
191
+ new_values = value.value.map do |val|
192
+ calling_mapper.for(Property.new(value.subject, value.key, val, value.adapter)).result
193
+ end
194
+ CompositeProperty.new(new_values)
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,338 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Fedora
3
+ class Persister
4
+ class OrmConverter
5
+ attr_reader :object, :adapter
6
+ delegate :graph, to: :object
7
+ def initialize(object:, adapter:)
8
+ @object = object
9
+ @adapter = adapter
10
+ end
11
+
12
+ def convert
13
+ Valkyrie::Types::Anything[attributes]
14
+ end
15
+
16
+ def attributes
17
+ GraphToAttributes.new(graph: graph, adapter: adapter).convert.merge(id:
18
+ id)
19
+ end
20
+
21
+ def id
22
+ id_property.present? ? Valkyrie::ID.new(id_property) : adapter.uri_to_id(object.subject_uri)
23
+ end
24
+
25
+ def id_property
26
+ return unless object.subject_uri.to_s.include?("#")
27
+ object.graph.query([RDF::URI(""), RDF::URI("http://example.com/predicate/id"), nil]).to_a.first.try(:object).to_s
28
+ end
29
+
30
+ class GraphToAttributes
31
+ attr_reader :graph, :adapter
32
+ def initialize(graph:, adapter:)
33
+ @graph = graph
34
+ @adapter = adapter
35
+ end
36
+
37
+ def convert
38
+ graph.each do |statement|
39
+ FedoraValue.for(Property.new(statement: statement, scope: graph, adapter: adapter)).result.apply_to(attributes)
40
+ end
41
+ attributes
42
+ end
43
+
44
+ def attributes
45
+ @attributes ||= {}
46
+ end
47
+
48
+ class FedoraValue < ::Valkyrie::ValueMapper
49
+ def result
50
+ Applicator.new(value)
51
+ end
52
+ end
53
+
54
+ class BlacklistedValue < ::Valkyrie::ValueMapper
55
+ FedoraValue.register(self)
56
+ def self.handles?(value)
57
+ value.statement.object.to_s.start_with?("http://www.w3.org/ns/ldp", "http://fedora.info")
58
+ end
59
+
60
+ def result
61
+ NullApplicator
62
+ end
63
+ end
64
+
65
+ class DifferentSubject < ::Valkyrie::ValueMapper
66
+ FedoraValue.register(self)
67
+ def self.handles?(value)
68
+ value.statement.subject.to_s.include?("#")
69
+ end
70
+
71
+ def result
72
+ NullApplicator
73
+ end
74
+ end
75
+
76
+ class CompositeApplicator
77
+ attr_reader :applicators
78
+ def initialize(applicators)
79
+ @applicators = applicators
80
+ end
81
+
82
+ def apply_to(hsh)
83
+ applicators.each do |applicator|
84
+ applicator.apply_to(hsh)
85
+ end
86
+ hsh
87
+ end
88
+ end
89
+
90
+ class MemberID < ::Valkyrie::ValueMapper
91
+ delegate :scope, :adapter, to: :value
92
+ FedoraValue.register(self)
93
+ def self.handles?(value)
94
+ value.statement.predicate == ::RDF::Vocab::IANA.first
95
+ end
96
+
97
+ def result
98
+ value.statement.predicate = ::RDF::URI("http://example.com/predicate/member_ids")
99
+ values = OrderedList.new(scope, head, tail, adapter).to_a.map(&:proxy_for)
100
+ values = values.map do |val|
101
+ calling_mapper.for(Property.new(statement: RDF::Statement.new(value.statement.subject, value.statement.predicate, val), scope: value.scope, adapter: value.adapter)).result
102
+ end
103
+ CompositeApplicator.new(values)
104
+ end
105
+
106
+ def head
107
+ scope.query([value.statement.subject, RDF::Vocab::IANA.first]).to_a.first.object
108
+ end
109
+
110
+ def tail
111
+ scope.query([value.statement.subject, RDF::Vocab::IANA.last]).to_a.first.object
112
+ end
113
+ end
114
+
115
+ class NestedValue < ::Valkyrie::ValueMapper
116
+ FedoraValue.register(self)
117
+ def self.handles?(value)
118
+ value.statement.object.is_a?(RDF::URI) && value.statement.object.to_s.include?("#") &&
119
+ (value.statement.object.to_s.start_with?("#") ||
120
+ value.statement.object.to_s.start_with?(value.adapter.connection_prefix))
121
+ end
122
+
123
+ def result
124
+ value.scope.each do |statement|
125
+ next unless statement.subject.to_s.include?("#")
126
+ subject = new_subject(statement)
127
+ graph << RDF::Statement.new(subject, statement.predicate, statement.object)
128
+ end
129
+ value.statement.object = resource
130
+ Applicator.new(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter))
131
+ end
132
+
133
+ def container
134
+ GraphContainer.new(graph, value.statement.object)
135
+ end
136
+
137
+ def resource
138
+ OrmConverter.new(object: container, adapter: value.adapter).convert
139
+ end
140
+
141
+ def new_subject(statement)
142
+ if statement.subject == value.statement.object
143
+ RDF::URI("")
144
+ else
145
+ statement.subject
146
+ end
147
+ end
148
+
149
+ def graph
150
+ @graph ||= RDF::Graph.new
151
+ end
152
+
153
+ class GraphContainer
154
+ attr_reader :graph, :subject_uri
155
+ def initialize(graph, subject_uri)
156
+ @graph = graph
157
+ @subject_uri = subject_uri
158
+ end
159
+ end
160
+ end
161
+
162
+ class IntegerValue < ::Valkyrie::ValueMapper
163
+ FedoraValue.register(self)
164
+ def self.handles?(value)
165
+ value.statement.object.is_a?(RDF::Literal) && value.statement.object.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#integer")
166
+ end
167
+
168
+ def result
169
+ value.statement.object = value.statement.object.to_i
170
+ calling_mapper.for(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter)).result
171
+ end
172
+ end
173
+
174
+ class DateTimeValue < ::Valkyrie::ValueMapper
175
+ FedoraValue.register(self)
176
+ def self.handles?(value)
177
+ value.statement.object.is_a?(RDF::Literal::DateTime)
178
+ end
179
+
180
+ def result
181
+ value.statement.object = ::DateTime.iso8601(value.statement.object.to_s).utc
182
+ calling_mapper.for(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter)).result
183
+ end
184
+ end
185
+
186
+ class LiteralValue < ::Valkyrie::ValueMapper
187
+ FedoraValue.register(self)
188
+ def self.handles?(value)
189
+ value.statement.object.is_a?(RDF::Literal) && value.statement.object.language.blank? && value.statement.object.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string")
190
+ end
191
+
192
+ def result
193
+ value.statement.object = value.statement.object.to_s
194
+ calling_mapper.for(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter)).result
195
+ end
196
+ end
197
+
198
+ class ValkyrieIDValue < ::Valkyrie::ValueMapper
199
+ FedoraValue.register(self)
200
+ def self.handles?(value)
201
+ value.statement.object.is_a?(RDF::Literal) && value.statement.object.datatype == RDF::URI("http://example.com/predicate/valkyrie_id")
202
+ end
203
+
204
+ def result
205
+ value.statement.object = Valkyrie::ID.new(value.statement.object.to_s)
206
+ calling_mapper.for(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter)).result
207
+ end
208
+ end
209
+
210
+ class InternalURI < ::Valkyrie::ValueMapper
211
+ FedoraValue.register(self)
212
+ def self.handles?(value)
213
+ value.statement.object.is_a?(RDF::URI) && value.statement.object.to_s.start_with?(value.adapter.connection_prefix)
214
+ end
215
+
216
+ def result
217
+ value.statement.object = value.adapter.uri_to_id(value.statement.object)
218
+ calling_mapper.for(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter)).result
219
+ end
220
+ end
221
+
222
+ class InternalModelValue < ::Valkyrie::ValueMapper
223
+ FedoraValue.register(self)
224
+ def self.handles?(value)
225
+ value.statement.predicate.to_s == "http://example.com/predicate/internal_resource"
226
+ end
227
+
228
+ def result
229
+ SingleApplicator.new(value)
230
+ end
231
+ end
232
+
233
+ class CreatedAtValue < ::Valkyrie::ValueMapper
234
+ FedoraValue.register(self)
235
+ def self.handles?(value)
236
+ value.statement.predicate.to_s == "http://example.com/predicate/created_at"
237
+ end
238
+
239
+ def result
240
+ NonStringSingleApplicator.new(value)
241
+ end
242
+ end
243
+
244
+ class UpdatedAtValue < ::Valkyrie::ValueMapper
245
+ FedoraValue.register(self)
246
+ def self.handles?(value)
247
+ value.statement.predicate.to_s == "http://example.com/predicate/updated_at"
248
+ end
249
+
250
+ def result
251
+ NonStringSingleApplicator.new(value)
252
+ end
253
+ end
254
+
255
+ class NullApplicator
256
+ def self.apply_to(_hsh); end
257
+ end
258
+
259
+ class Applicator
260
+ attr_reader :property
261
+ delegate :statement, to: :property
262
+ def initialize(property)
263
+ @property = property
264
+ end
265
+
266
+ def apply_to(hsh)
267
+ return if blacklist?(key)
268
+ hsh[key.to_sym] ||= []
269
+ hsh[key.to_sym] += cast_array(values)
270
+ end
271
+
272
+ def key
273
+ key = statement.predicate.to_s
274
+ namespaces.each do |namespace|
275
+ key = key.gsub(/^#{namespace}/, '')
276
+ end
277
+ key
278
+ end
279
+
280
+ def blacklist?(key)
281
+ blacklist.each do |blacklist_item|
282
+ return true if key.start_with?(blacklist_item)
283
+ end
284
+ false
285
+ end
286
+
287
+ def cast_array(values)
288
+ if values.is_a?(Time)
289
+ [values]
290
+ else
291
+ Array(values)
292
+ end
293
+ end
294
+
295
+ def blacklist
296
+ [
297
+ "http://fedora.info/definitions",
298
+ "http://www.iana.org/assignments/relation/last"
299
+ ]
300
+ end
301
+
302
+ def namespaces
303
+ [
304
+ "http://www.fedora.info/definitions/v4/",
305
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
306
+ "http://example.com/predicate/"
307
+ ]
308
+ end
309
+
310
+ def values
311
+ statement.object
312
+ end
313
+ end
314
+
315
+ class SingleApplicator < Applicator
316
+ def apply_to(hsh)
317
+ hsh[key.to_sym] = values.to_s
318
+ end
319
+ end
320
+
321
+ class NonStringSingleApplicator < Applicator
322
+ def apply_to(hsh)
323
+ hsh[key.to_sym] = values
324
+ end
325
+ end
326
+
327
+ class Property
328
+ attr_reader :statement, :scope, :adapter
329
+ def initialize(statement:, scope:, adapter:)
330
+ @statement = statement
331
+ @scope = scope
332
+ @adapter = adapter
333
+ end
334
+ end
335
+ end
336
+ end
337
+ end
338
+ end