valkyrie 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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