active-fedora 9.10.4 → 9.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/History.txt +0 -13
- data/lib/active_fedora.rb +7 -0
- data/lib/active_fedora/aggregation.rb +11 -0
- data/lib/active_fedora/aggregation/base_extension.rb +17 -0
- data/lib/active_fedora/aggregation/list_source.rb +103 -0
- data/lib/active_fedora/aggregation/ordered_reader.rb +27 -0
- data/lib/active_fedora/aggregation/proxy.rb +18 -0
- data/lib/active_fedora/associations.rb +40 -0
- data/lib/active_fedora/associations/builder/aggregation.rb +51 -0
- data/lib/active_fedora/associations/builder/filter.rb +18 -0
- data/lib/active_fedora/associations/builder/orders.rb +63 -0
- data/lib/active_fedora/associations/filter_association.rb +71 -0
- data/lib/active_fedora/associations/orders_association.rb +149 -0
- data/lib/active_fedora/attached_files.rb +2 -1
- data/lib/active_fedora/attribute_methods.rb +4 -4
- data/lib/active_fedora/autosave_association.rb +14 -0
- data/lib/active_fedora/base.rb +1 -0
- data/lib/active_fedora/cleaner.rb +1 -1
- data/lib/active_fedora/errors.rb +3 -0
- data/lib/active_fedora/fedora.rb +17 -7
- data/lib/active_fedora/file/streaming.rb +13 -4
- data/lib/active_fedora/orders.rb +12 -0
- data/lib/active_fedora/orders/collection_proxy.rb +8 -0
- data/lib/active_fedora/orders/list_node.rb +161 -0
- data/lib/active_fedora/orders/ordered_list.rb +264 -0
- data/lib/active_fedora/orders/target_proxy.rb +60 -0
- data/lib/active_fedora/reflection.rb +215 -42
- data/lib/active_fedora/validations.rb +1 -1
- data/lib/active_fedora/version.rb +1 -1
- data/lib/generators/active_fedora/config/solr/templates/solr/config/schema.xml +1 -1
- data/solr/config/schema.xml +1 -1
- data/spec/integration/attributes_spec.rb +8 -0
- data/spec/integration/file_spec.rb +22 -0
- data/spec/integration/has_many_associations_spec.rb +23 -0
- data/spec/integration/versionable_spec.rb +6 -6
- data/spec/unit/active_fedora_spec.rb +1 -1
- data/spec/unit/aggregation/list_source_spec.rb +134 -0
- data/spec/unit/aggregation/ordered_reader_spec.rb +43 -0
- data/spec/unit/fedora_spec.rb +1 -1
- data/spec/unit/filter_spec.rb +133 -0
- data/spec/unit/ordered_spec.rb +369 -0
- data/spec/unit/orders/list_node_spec.rb +151 -0
- data/spec/unit/orders/ordered_list_spec.rb +335 -0
- data/spec/unit/orders/reflection_spec.rb +22 -0
- data/spec/unit/reflection_spec.rb +2 -4
- metadata +25 -3
@@ -0,0 +1,71 @@
|
|
1
|
+
module ActiveFedora::Associations
|
2
|
+
class FilterAssociation < ::ActiveFedora::Associations::CollectionAssociation
|
3
|
+
# @param [Array] records a list of records to replace the current association with
|
4
|
+
# @raise [ArgumentError] if one of the records doesn't match the prescribed condition
|
5
|
+
def writer(records)
|
6
|
+
records.each { |r| validate_assertion!(r) }
|
7
|
+
existing_matching_records.each do |r|
|
8
|
+
extending_from.delete(r)
|
9
|
+
end
|
10
|
+
extending_from.concat(records)
|
11
|
+
end
|
12
|
+
|
13
|
+
delegate :delete, to: :extending_from
|
14
|
+
|
15
|
+
# @param [Array] records a list of records to append to the current association
|
16
|
+
# @raise [ArgumentError] if one of the records doesn't match the prescribed condition
|
17
|
+
def concat(records)
|
18
|
+
records.flatten.each { |r| validate_assertion!(r) }
|
19
|
+
extending_from.concat(records)
|
20
|
+
end
|
21
|
+
|
22
|
+
def ids_reader
|
23
|
+
load_target
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def count_records
|
28
|
+
ids_reader.length
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# target should never be cached as part of this objects state, because
|
34
|
+
# extending_from.target could change and we want to reflect those changes
|
35
|
+
def target
|
36
|
+
find_target
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_target?
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_target
|
44
|
+
existing_matching_records
|
45
|
+
end
|
46
|
+
|
47
|
+
# We can't create an association scope on here until we can figure a way to
|
48
|
+
# index/query the condition in Solr
|
49
|
+
def association_scope
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def existing_matching_records
|
54
|
+
extending_from.reader.to_a.select do |r|
|
55
|
+
validate_assertion(r)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def extending_from
|
60
|
+
owner.association(options.fetch(:extending_from))
|
61
|
+
end
|
62
|
+
|
63
|
+
def validate_assertion(record)
|
64
|
+
record.send(options.fetch(:condition))
|
65
|
+
end
|
66
|
+
|
67
|
+
def validate_assertion!(record)
|
68
|
+
raise ArgumentError, "#{record.class} with ID: #{record.id} was expected to #{options.fetch(:condition)}, but it was false" unless validate_assertion(record)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module ActiveFedora::Associations
|
2
|
+
class OrdersAssociation < ::ActiveFedora::Associations::CollectionAssociation
|
3
|
+
def initialize(*args)
|
4
|
+
super
|
5
|
+
@target = find_target
|
6
|
+
end
|
7
|
+
|
8
|
+
def inspect
|
9
|
+
"#<ActiveFedora::Associations::OrdersAssociation:#{object_id}>"
|
10
|
+
end
|
11
|
+
|
12
|
+
def reader(*args)
|
13
|
+
@proxy ||= ActiveFedora::Orders::CollectionProxy.new(self)
|
14
|
+
@null_proxy ||= ActiveFedora::Orders::CollectionProxy.new(self)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
# Meant to override all nodes with the given nodes.
|
19
|
+
# @param [Array<ActiveFedora::Base>] nodes Nodes to set as ordered members
|
20
|
+
def target_writer(nodes)
|
21
|
+
target_reader.clear
|
22
|
+
target_reader.concat(nodes)
|
23
|
+
target_reader
|
24
|
+
end
|
25
|
+
|
26
|
+
def target_reader
|
27
|
+
@target_proxy ||= ActiveFedora::Orders::TargetProxy.new(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_reflection
|
31
|
+
reflection
|
32
|
+
end
|
33
|
+
|
34
|
+
def replace(new_ordered_list)
|
35
|
+
raise unless new_ordered_list.is_a? ActiveFedora::Orders::OrderedList
|
36
|
+
list_container.ordered_self = new_ordered_list
|
37
|
+
@target = find_target
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_target
|
41
|
+
ordered_proxies
|
42
|
+
end
|
43
|
+
|
44
|
+
def load_target
|
45
|
+
@target = find_target
|
46
|
+
end
|
47
|
+
|
48
|
+
# Append a target node to the end of the order.
|
49
|
+
# @param [ActiveFedora::Base] record Record to append
|
50
|
+
def append_target(record, _skip_callbacks = false)
|
51
|
+
unless unordered_association.target.include?(record)
|
52
|
+
unordered_association.concat(record)
|
53
|
+
end
|
54
|
+
target.append_target(record, proxy_in: owner)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Insert a target node in a specific position
|
58
|
+
# @param [Integer] loc Position to insert record.
|
59
|
+
# @param [ActiveFedora::Base] record Record to insert
|
60
|
+
def insert_target_at(loc, record)
|
61
|
+
unless unordered_association.target.include?(record)
|
62
|
+
unordered_association.concat(record)
|
63
|
+
end
|
64
|
+
target.insert_at(loc, record, proxy_in: owner)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Insert a target ID in a specific position
|
68
|
+
# @param [Integer] loc Position to insert record ID
|
69
|
+
# @param [String] id ID of record to insert.
|
70
|
+
def insert_target_id_at(loc, id)
|
71
|
+
raise ArgumentError, "ID can not be nil" if id.nil?
|
72
|
+
unless unordered_association.ids_reader.include?(id)
|
73
|
+
raise ArgumentError, "#{id} is not a part of #{unordered_association.reflection.name}"
|
74
|
+
end
|
75
|
+
target.insert_proxy_for_at(loc, ActiveFedora::Base.id_to_uri(id), proxy_in: owner)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Delete whatever node is at a specific position
|
79
|
+
# @param [Integer] loc Position to delete
|
80
|
+
delegate :delete_at, to: :target
|
81
|
+
|
82
|
+
# Delete all occurences of the specified target
|
83
|
+
# @param obj object to delete
|
84
|
+
delegate :delete_target, to: :target
|
85
|
+
|
86
|
+
# Delete multiple list nodes.
|
87
|
+
# @param [Array<ActiveFedora::Orders::ListNode>] records
|
88
|
+
def delete_records(records, _method = nil)
|
89
|
+
records.each do |record|
|
90
|
+
delete_record(record)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Delete a list node
|
95
|
+
# @param [ActiveFedora::Orders::ListNode] record Node to delete.
|
96
|
+
def delete_record(record)
|
97
|
+
target.delete_node(record)
|
98
|
+
end
|
99
|
+
|
100
|
+
def insert_record(record, _force = true, _validate = true)
|
101
|
+
record.save_target
|
102
|
+
list_container.save
|
103
|
+
# NOTE: This turns out to be pretty cheap, but should we be doing it
|
104
|
+
# elsewhere?
|
105
|
+
unless list_container.changed?
|
106
|
+
owner.head = [list_container.head_id.first]
|
107
|
+
owner.tail = [list_container.tail_id.first]
|
108
|
+
owner.save
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def scope(*_args)
|
113
|
+
@scope ||= ActiveFedora::Relation.new(klass)
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def ordered_proxies
|
119
|
+
list_container.ordered_self
|
120
|
+
end
|
121
|
+
|
122
|
+
def create_list_node(record)
|
123
|
+
node = ListNode.new(RDF::URI.new("#{list_container.uri}##{::RDF::Node.new.id}"), list_container.resource)
|
124
|
+
node.proxyIn = owner
|
125
|
+
node.proxyFor = record
|
126
|
+
node
|
127
|
+
end
|
128
|
+
|
129
|
+
def association_scope
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
|
133
|
+
def list_container
|
134
|
+
list_container_association.reader
|
135
|
+
end
|
136
|
+
|
137
|
+
def list_container_association
|
138
|
+
owner.association(options[:through])
|
139
|
+
end
|
140
|
+
|
141
|
+
def unordered_association
|
142
|
+
owner.association(unordered_reflection_name)
|
143
|
+
end
|
144
|
+
|
145
|
+
def unordered_reflection_name
|
146
|
+
reflection.unordered_reflection.name
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -131,7 +131,8 @@ module ActiveFedora
|
|
131
131
|
|
132
132
|
def create_singleton_association(file_path)
|
133
133
|
undeclared_files << file_path.to_sym
|
134
|
-
|
134
|
+
|
135
|
+
association = Associations::BasicContainsAssociation.new(self, Reflection::ContainsReflection.new(file_path, nil, { class_name: 'ActiveFedora::File' }, self.class))
|
135
136
|
@association_cache[file_path.to_sym] = association
|
136
137
|
|
137
138
|
singleton_class.send :define_method, accessor_name(file_path) do
|
@@ -31,23 +31,23 @@ module ActiveFedora
|
|
31
31
|
super
|
32
32
|
end
|
33
33
|
|
34
|
-
# Raises an
|
34
|
+
# Raises an ActiveFedora::DangerousAttributeError exception when an
|
35
35
|
# \Active \Record method is defined in the model, otherwise +false+.
|
36
36
|
#
|
37
37
|
# class Person < ActiveRecord::Base
|
38
38
|
# def save
|
39
|
-
# 'already defined by Active
|
39
|
+
# 'already defined by Active Fedora'
|
40
40
|
# end
|
41
41
|
# end
|
42
42
|
#
|
43
43
|
# Person.instance_method_already_implemented?(:save)
|
44
|
-
# # =>
|
44
|
+
# # => ActiveFedora::DangerousAttributeError: save is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
|
45
45
|
#
|
46
46
|
# Person.instance_method_already_implemented?(:name)
|
47
47
|
# # => false
|
48
48
|
def instance_method_already_implemented?(method_name)
|
49
49
|
if dangerous_attribute_method?(method_name)
|
50
|
-
raise DangerousAttributeError, "#{method_name} is defined by Active
|
50
|
+
raise DangerousAttributeError, "#{method_name} is defined by Active Fedora. Check to make sure that you don't have an attribute or method with the same name."
|
51
51
|
end
|
52
52
|
|
53
53
|
if superclass == Base
|
@@ -153,6 +153,7 @@ module ActiveFedora
|
|
153
153
|
# Reloads the attributes of the object as usual and clears <tt>marked_for_destruction</tt> flag.
|
154
154
|
def reload
|
155
155
|
@marked_for_destruction = false
|
156
|
+
@destroyed_by_association = nil
|
156
157
|
super
|
157
158
|
end
|
158
159
|
|
@@ -172,6 +173,19 @@ module ActiveFedora
|
|
172
173
|
@marked_for_destruction
|
173
174
|
end
|
174
175
|
|
176
|
+
# Records the association that is being destroyed and destroying this
|
177
|
+
# record in the process.
|
178
|
+
def destroyed_by_association=(reflection)
|
179
|
+
@destroyed_by_association = reflection
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the association for the parent being destroyed.
|
183
|
+
#
|
184
|
+
# Used to avoid updating the counter cache unnecessarily.
|
185
|
+
def destroyed_by_association
|
186
|
+
@destroyed_by_association
|
187
|
+
end
|
188
|
+
|
175
189
|
# Returns whether or not this record has been changed in any way (including whether
|
176
190
|
# any of its nested autosave associations are likewise changed)
|
177
191
|
def changed_for_autosave?
|
data/lib/active_fedora/base.rb
CHANGED
data/lib/active_fedora/errors.rb
CHANGED
data/lib/active_fedora/fedora.rb
CHANGED
@@ -2,7 +2,6 @@ module ActiveFedora
|
|
2
2
|
class Fedora
|
3
3
|
def initialize(config)
|
4
4
|
@config = config
|
5
|
-
init_base_path
|
6
5
|
end
|
7
6
|
|
8
7
|
def host
|
@@ -26,11 +25,10 @@ module ActiveFedora
|
|
26
25
|
end
|
27
26
|
|
28
27
|
def connection
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@connection ||= CachingConnection.new(authorized_connection, omit_ldpr_interaction_model: true)
|
28
|
+
@connection ||= begin
|
29
|
+
init_base_path
|
30
|
+
build_connection
|
31
|
+
end
|
34
32
|
end
|
35
33
|
|
36
34
|
def clean_connection
|
@@ -46,14 +44,18 @@ module ActiveFedora
|
|
46
44
|
|
47
45
|
# Call this to create a Container Resource to act as the base path for this connection
|
48
46
|
def init_base_path
|
47
|
+
return if @initialized
|
48
|
+
connection = build_connection
|
49
|
+
|
49
50
|
connection.head(root_resource_path)
|
50
51
|
ActiveFedora::Base.logger.info "Attempted to init base path `#{root_resource_path}`, but it already exists" if ActiveFedora::Base.logger
|
52
|
+
@initialized = true
|
51
53
|
false
|
52
54
|
rescue Ldp::NotFound
|
53
55
|
unless host.downcase.end_with?("/rest")
|
54
56
|
ActiveFedora::Base.logger.warn "Fedora URL (#{host}) does not end with /rest. This could be a problem. Check your fedora.yml config"
|
55
57
|
end
|
56
|
-
connection.put(root_resource_path, BLANK).success?
|
58
|
+
@initialized = connection.put(root_resource_path, BLANK).success?
|
57
59
|
end
|
58
60
|
|
59
61
|
# Remove a leading slash from the base_path
|
@@ -61,6 +63,14 @@ module ActiveFedora
|
|
61
63
|
@root_resource_path ||= base_path.sub(SLASH, BLANK)
|
62
64
|
end
|
63
65
|
|
66
|
+
def build_connection
|
67
|
+
# The InboundRelationConnection does provide more data, useful for
|
68
|
+
# things like ldp:IndirectContainers, but it's imposes a significant
|
69
|
+
# performance penalty on every request
|
70
|
+
# @connection ||= InboundRelationConnection.new(CachingConnection.new(authorized_connection))
|
71
|
+
CachingConnection.new(authorized_connection, omit_ldpr_interaction_model: true)
|
72
|
+
end
|
73
|
+
|
64
74
|
def authorized_connection
|
65
75
|
options = {}
|
66
76
|
options[:ssl] = ssl_options if ssl_options
|
@@ -22,13 +22,22 @@ module ActiveFedora::File::Streaming
|
|
22
22
|
@headers = headers
|
23
23
|
end
|
24
24
|
|
25
|
-
def each
|
25
|
+
def each(no_of_requests_limit = 3, &block)
|
26
|
+
raise ArgumentError, 'HTTP redirect too deep' if no_of_requests_limit == 0
|
26
27
|
Net::HTTP.start(uri.host, uri.port) do |http|
|
27
28
|
request = Net::HTTP::Get.new uri, headers
|
28
29
|
http.request request do |response|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
case response
|
31
|
+
when Net::HTTPSuccess
|
32
|
+
response.read_body do |chunk|
|
33
|
+
yield chunk
|
34
|
+
end
|
35
|
+
when Net::HTTPRedirection
|
36
|
+
no_of_requests_limit -= 1
|
37
|
+
@uri = URI(response["location"])
|
38
|
+
each(no_of_requests_limit, &block)
|
39
|
+
else
|
40
|
+
raise "Couldn't get data from Fedora (#{uri}). Response: #{response.code}"
|
32
41
|
end
|
33
42
|
end
|
34
43
|
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module ActiveFedora::Orders
|
2
|
+
class ListNode
|
3
|
+
attr_reader :rdf_subject
|
4
|
+
attr_accessor :prev, :next, :target
|
5
|
+
attr_writer :next_uri, :prev_uri
|
6
|
+
attr_accessor :proxy_in, :proxy_for
|
7
|
+
def initialize(node_cache, rdf_subject, graph = RDF::Graph.new)
|
8
|
+
@rdf_subject = rdf_subject
|
9
|
+
@graph = graph
|
10
|
+
@node_cache = node_cache
|
11
|
+
Builder.new(rdf_subject, graph).populate(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the next proxy or a tail sentinel.
|
15
|
+
# @return [ActiveFedora::Orders::ListNode]
|
16
|
+
def next
|
17
|
+
@next ||=
|
18
|
+
if next_uri
|
19
|
+
node_cache.fetch(next_uri) do
|
20
|
+
node = self.class.new(node_cache, next_uri, graph)
|
21
|
+
node.prev = self
|
22
|
+
node
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the previous proxy or a head sentinel.
|
28
|
+
# @return [ActiveFedora::Orders::ListNode]
|
29
|
+
def prev
|
30
|
+
@prev ||=
|
31
|
+
if prev_uri
|
32
|
+
node_cache.fetch(prev_uri) do
|
33
|
+
node = self.class.new(node_cache, prev_uri, graph)
|
34
|
+
node.next = self
|
35
|
+
node
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Graph representation of node.
|
41
|
+
# @return [ActiveFedora::Orders::ListNode::Resource]
|
42
|
+
def to_graph
|
43
|
+
g = Resource.new(rdf_subject)
|
44
|
+
g.proxy_for = target_uri
|
45
|
+
g.proxy_in = proxy_in.try(:uri)
|
46
|
+
g.next = self.next.try(:rdf_subject)
|
47
|
+
g.prev = prev.try(:rdf_subject)
|
48
|
+
g
|
49
|
+
end
|
50
|
+
|
51
|
+
# Object representation of proxyFor
|
52
|
+
# @return [ActiveFedora::Base]
|
53
|
+
def target
|
54
|
+
@target ||=
|
55
|
+
if proxy_for.present?
|
56
|
+
node_cache.fetch(proxy_for) do
|
57
|
+
ActiveFedora::Base.from_uri(proxy_for, nil)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def target_uri
|
63
|
+
RDF::URI(ActiveFedora::Base.id_to_uri(target_id)) if target_id
|
64
|
+
end
|
65
|
+
|
66
|
+
def target_id
|
67
|
+
MaybeID.new(@target.try(:id) || proxy_for).value
|
68
|
+
end
|
69
|
+
|
70
|
+
# Persists target if it's been accessed or set.
|
71
|
+
def save_target
|
72
|
+
if @target
|
73
|
+
@target.save
|
74
|
+
else
|
75
|
+
true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def proxy_in_id
|
80
|
+
MaybeID.new(@proxy_in.try(:id) || proxy_in).value
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns an ID whether or not the given value is a URI.
|
84
|
+
class MaybeID
|
85
|
+
attr_reader :uri_or_id
|
86
|
+
def initialize(uri_or_id)
|
87
|
+
@uri_or_id = uri_or_id
|
88
|
+
end
|
89
|
+
|
90
|
+
def value
|
91
|
+
id_composite.new([uri_or_id], translator).to_a.first
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def id_composite
|
97
|
+
ActiveFedora::Associations::IDComposite
|
98
|
+
end
|
99
|
+
|
100
|
+
def translator
|
101
|
+
ActiveFedora::Base.translate_uri_to_id
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Methods necessary for association functionality
|
106
|
+
def destroyed?
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
def marked_for_destruction?
|
111
|
+
false
|
112
|
+
end
|
113
|
+
|
114
|
+
def valid?
|
115
|
+
true
|
116
|
+
end
|
117
|
+
|
118
|
+
def changed_for_autosave?
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
122
|
+
def new_record?
|
123
|
+
@target && @target.new_record?
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
attr_reader :next_uri, :prev_uri, :graph, :node_cache
|
129
|
+
|
130
|
+
class Builder
|
131
|
+
attr_reader :uri, :graph
|
132
|
+
def initialize(uri, graph)
|
133
|
+
@uri = uri
|
134
|
+
@graph = graph
|
135
|
+
end
|
136
|
+
|
137
|
+
def populate(instance)
|
138
|
+
instance.proxy_for = resource.proxy_for.first
|
139
|
+
instance.proxy_in = resource.proxy_in.first
|
140
|
+
instance.next_uri = resource.next.first
|
141
|
+
instance.prev_uri = resource.prev.first
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def resource
|
147
|
+
@resource ||= Resource.new(uri, graph)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class Resource < ActiveTriples::Resource
|
152
|
+
property :proxy_for, predicate: ::RDF::Vocab::ORE.proxyFor, cast: false
|
153
|
+
property :proxy_in, predicate: ::RDF::Vocab::ORE.proxyIn, cast: false
|
154
|
+
property :next, predicate: ::RDF::Vocab::IANA.next, cast: false
|
155
|
+
property :prev, predicate: ::RDF::Vocab::IANA.prev, cast: false
|
156
|
+
def final_parent
|
157
|
+
parent
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|