active-triples 0.7.6 → 0.8.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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -3
- data/AUTHORS +1 -1
- data/CHANGES.md +12 -17
- data/Gemfile +2 -0
- data/README.md +2 -2
- data/active-triples.gemspec +6 -5
- data/lib/active_triples.rb +56 -5
- data/lib/active_triples/configurable.rb +13 -17
- data/lib/active_triples/list.rb +22 -21
- data/lib/active_triples/persistable.rb +100 -0
- data/lib/active_triples/persistence_strategies/parent_strategy.rb +89 -0
- data/lib/active_triples/persistence_strategies/persistence_strategy.rb +77 -0
- data/lib/active_triples/persistence_strategies/repository_strategy.rb +78 -0
- data/lib/active_triples/properties.rb +2 -1
- data/lib/active_triples/rdf_source.rb +94 -159
- data/lib/active_triples/relation.rb +17 -45
- data/lib/active_triples/repositories.rb +23 -9
- data/lib/active_triples/version.rb +1 -1
- data/spec/active_triples/configurable_spec.rb +5 -9
- data/spec/active_triples/identifiable_spec.rb +1 -18
- data/spec/active_triples/list_spec.rb +0 -4
- data/spec/active_triples/persistable_spec.rb +93 -0
- data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +93 -0
- data/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb +24 -0
- data/spec/active_triples/persistence_strategies/repository_strategy_spec.rb +120 -0
- data/spec/active_triples/rdf_source_spec.rb +217 -9
- data/spec/active_triples/relation_spec.rb +51 -4
- data/spec/active_triples/repositories_spec.rb +17 -7
- data/spec/active_triples/resource_spec.rb +6 -53
- data/spec/active_triples_spec.rb +50 -1
- data/spec/spec_helper.rb +5 -1
- data/spec/support/active_model_lint.rb +6 -3
- data/spec/support/dummies/basic_persistable.rb +13 -0
- data/spec/support/shared_examples/persistence_strategy.rb +36 -0
- metadata +32 -9
- data/spec/active_triples/validations_spec.rb +0 -33
@@ -0,0 +1,89 @@
|
|
1
|
+
module ActiveTriples
|
2
|
+
##
|
3
|
+
# Persistence strategy for projecting `RDFSource`s onto the graph of an owning
|
4
|
+
# parent source. This allows individual resources to be treated as within the
|
5
|
+
# scope of another `RDFSource`.
|
6
|
+
class ParentStrategy
|
7
|
+
include PersistenceStrategy
|
8
|
+
|
9
|
+
# @!attribute [r] obj
|
10
|
+
# the source to persist with this strategy
|
11
|
+
# @!attribute [r] parent
|
12
|
+
# the target parent source for persistence
|
13
|
+
attr_reader :obj, :parent
|
14
|
+
|
15
|
+
##
|
16
|
+
# @param obj [RDFSource, RDF::Enumerable] the `RDFSource` (or other
|
17
|
+
# `RDF::Enumerable` to persist with the strategy.
|
18
|
+
def initialize(obj)
|
19
|
+
@obj = obj
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
super { parent.destroy_child(obj) }
|
24
|
+
end
|
25
|
+
|
26
|
+
# Clear out any old assertions in the repository about this node or statement
|
27
|
+
# thus preparing to receive the updated assertions.
|
28
|
+
def erase_old_resource
|
29
|
+
if obj.rdf_subject.node?
|
30
|
+
final_parent.statements.each do |statement|
|
31
|
+
final_parent.send(:delete_statement, statement) if
|
32
|
+
statement.subject == obj.rdf_subject
|
33
|
+
end
|
34
|
+
else
|
35
|
+
final_parent.delete [obj.rdf_subject, nil, nil]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# @return [#persist!] the last parent in a chain from `parent` (e.g.
|
41
|
+
# the parent's parent's parent). This is the RDF::Mutable that the
|
42
|
+
# object will project itself on when persisting.
|
43
|
+
def final_parent
|
44
|
+
raise NilParentError if parent.nil?
|
45
|
+
@final_parent ||= begin
|
46
|
+
current = self.parent
|
47
|
+
while current && current.respond_to?(:parent) && current.parent
|
48
|
+
break if current.parent == current
|
49
|
+
current = current.parent
|
50
|
+
end
|
51
|
+
current
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Sets the target "parent" source for persistence operations.
|
57
|
+
#
|
58
|
+
# @param parent [RDFSource] source with a persistence strategy,
|
59
|
+
# must be mutable.
|
60
|
+
def parent=(parent)
|
61
|
+
raise UnmutableParentError unless parent.is_a? RDF::Mutable
|
62
|
+
raise UnmutableParentError unless parent.mutable?
|
63
|
+
@parent = parent
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Persists the object to the final parent.
|
68
|
+
#
|
69
|
+
# @return [true] true if the save did not error
|
70
|
+
def persist!
|
71
|
+
erase_old_resource
|
72
|
+
final_parent << obj
|
73
|
+
@persisted = true
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Repopulates the graph from parent.
|
78
|
+
#
|
79
|
+
# @return [Boolean]
|
80
|
+
def reload
|
81
|
+
obj << final_parent.query(subject: obj.rdf_subject)
|
82
|
+
@persisted = true unless obj.empty?
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
class NilParentError < RuntimeError; end
|
87
|
+
class UnmutableParentError < ArgumentError; end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module ActiveTriples
|
2
|
+
##
|
3
|
+
# @abstract defines the basic interface for persistence of {RDFSource}'s.
|
4
|
+
#
|
5
|
+
# A `PersistenceStrategy` has an underlying object (`obj`) which should
|
6
|
+
# be an `RDFSource` or equivalent. Strategies can be injected into `RDFSource`
|
7
|
+
# instances at runtime to change the target datastore, repository, or object
|
8
|
+
# the instance syncs its graph with on save and reload operations.
|
9
|
+
#
|
10
|
+
# @example Changing a PersistenceStrategy at runtime
|
11
|
+
# source = ActiveTriples::Resource.new
|
12
|
+
# source.persistence_strategy # => #<ActiveTriples::RepositoryStrategy:...>
|
13
|
+
#
|
14
|
+
# source.set_persistence_strategy(MyStrategy)
|
15
|
+
# source.persistence_strategy # => #<ActiveTriples::MyStrategy:...>
|
16
|
+
#
|
17
|
+
module PersistenceStrategy
|
18
|
+
##
|
19
|
+
# Deletes the resource from the repository.
|
20
|
+
#
|
21
|
+
# @yield prior to persisting, yields to allow a block that performs
|
22
|
+
# deletions in the persisted graph(s).
|
23
|
+
# @return [Boolean] true if the resource was sucessfully destroyed
|
24
|
+
def destroy(&block)
|
25
|
+
obj.clear
|
26
|
+
yield if block_given?
|
27
|
+
persist!
|
28
|
+
@destroyed = true
|
29
|
+
end
|
30
|
+
alias_method :destroy!, :destroy
|
31
|
+
|
32
|
+
##
|
33
|
+
# Indicates if the Resource has been destroyed.
|
34
|
+
#
|
35
|
+
# @return [true, false]
|
36
|
+
def destroyed?
|
37
|
+
@destroyed ||= false
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Indicates if the resource is persisted to the repository
|
42
|
+
#
|
43
|
+
# @return [Boolean] true if persisted; else false.
|
44
|
+
def persisted?
|
45
|
+
@persisted ||= false
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# @abstract save the object according to the strategy and set the
|
50
|
+
# @persisted flag to `true`
|
51
|
+
#
|
52
|
+
# @see #persisted?
|
53
|
+
#
|
54
|
+
# @return [true] true if the save did not error
|
55
|
+
def persist!
|
56
|
+
raise NotImplementedError, 'Abstract method #persist! is unimplemented'
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# @abstract Clear out any old assertions in the repository about this node
|
61
|
+
# or statement thus preparing to receive the updated assertions.
|
62
|
+
#
|
63
|
+
# @return [Boolean]
|
64
|
+
def erase_old_resource
|
65
|
+
raise NotImplementedError,
|
66
|
+
'Abstract method #erase_old_resource is unimplemented'
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# @abstract Repopulate the in-memory graph from the persisted graph
|
71
|
+
#
|
72
|
+
# @return [Boolean]
|
73
|
+
def reload
|
74
|
+
raise NotImplementedError, 'Abstract method #reload is unimplemented'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ActiveTriples
|
2
|
+
##
|
3
|
+
# Persistence strategy for projecting `RDFSource` to `RDF::Repositories`.
|
4
|
+
class RepositoryStrategy
|
5
|
+
include PersistenceStrategy
|
6
|
+
|
7
|
+
# @!attribute [r] obj
|
8
|
+
# the source to persist with this strategy
|
9
|
+
attr_reader :obj
|
10
|
+
|
11
|
+
##
|
12
|
+
# @param obj [RDFSource, RDF::Enumerable] the `RDFSource` (or other
|
13
|
+
# `RDF::Enumerable` to persist with the strategy.
|
14
|
+
def initialize(obj)
|
15
|
+
@obj = obj
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Clear out any old assertions in the repository about this node or statement
|
20
|
+
# thus preparing to receive the updated assertions.
|
21
|
+
def erase_old_resource
|
22
|
+
if obj.node?
|
23
|
+
repository.statements.each do |statement|
|
24
|
+
repository.send(:delete_statement, statement) if
|
25
|
+
statement.subject == obj
|
26
|
+
end
|
27
|
+
else
|
28
|
+
repository.delete [obj.to_term, nil, nil]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Persists the object to the repository
|
34
|
+
#
|
35
|
+
# @return [true] returns true if the save did not error
|
36
|
+
def persist!
|
37
|
+
erase_old_resource
|
38
|
+
repository << obj
|
39
|
+
@persisted = true
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Repopulates the graph from the repository.
|
44
|
+
#
|
45
|
+
# @return [Boolean]
|
46
|
+
def reload
|
47
|
+
obj << repository.query(subject: obj)
|
48
|
+
@persisted = true unless obj.empty?
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# @return [RDF::Repository] The RDF::Repository that the object will project
|
54
|
+
# itself on when persisting.
|
55
|
+
def repository
|
56
|
+
@repository ||= set_repository
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
##
|
62
|
+
# Finds an appropriate repository from the calling object's configuration.
|
63
|
+
# If no repository is configured, builds an ephemeral in-memory
|
64
|
+
# repository and 'persists' there.
|
65
|
+
#
|
66
|
+
# @todo find a way to move this logic out (PersistenceStrategyBuilder?).
|
67
|
+
# so the dependency on Repositories is externalized.
|
68
|
+
def set_repository
|
69
|
+
repo_sym = obj.class.repository || obj.singleton_class.repository
|
70
|
+
if repo_sym.nil?
|
71
|
+
RDF::Repository.new
|
72
|
+
else
|
73
|
+
repo = Repositories.repositories[repo_sym]
|
74
|
+
repo || raise(RepositoryNotFoundError, "The class #{obj.class} expects a repository called #{repo_sym}, but none was declared")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -60,7 +60,8 @@ module ActiveTriples
|
|
60
60
|
#
|
61
61
|
# @return [ActiveTriples::NodeConfig]
|
62
62
|
def config_for_term_or_uri(term)
|
63
|
-
return properties[term.to_s] unless
|
63
|
+
return properties[term.to_s] unless
|
64
|
+
term.is_a?(RDF::Resource) && !term.is_a?(RDFSource)
|
64
65
|
properties.each_value { |v| return v if v.predicate == term.to_uri }
|
65
66
|
end
|
66
67
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'deprecation'
|
2
1
|
require 'active_model'
|
3
2
|
require 'active_support/core_ext/hash'
|
4
3
|
|
@@ -32,6 +31,11 @@ module ActiveTriples
|
|
32
31
|
# @see http://www.w3.org/TR/ldp/#dfn-linked-data-platform-rdf-source an
|
33
32
|
# example of the RDF source concept as defined in the LDP specification
|
34
33
|
#
|
34
|
+
# An `RDFSource` is an {RDF::Term}---it can be used as a subject, predicate,
|
35
|
+
# object, or context in an {RDF::Statement}.
|
36
|
+
#
|
37
|
+
# @todo complete RDF::Value/RDF::Term/RDF::Resource interfaces
|
38
|
+
#
|
35
39
|
# @see ActiveModel
|
36
40
|
# @see RDF::Resource
|
37
41
|
# @see RDF::Queryable
|
@@ -39,20 +43,15 @@ module ActiveTriples
|
|
39
43
|
extend ActiveSupport::Concern
|
40
44
|
|
41
45
|
include NestedAttributes
|
46
|
+
include Persistable
|
42
47
|
include Properties
|
43
48
|
include Reflection
|
44
49
|
include RDF::Value
|
45
|
-
include RDF::Countable
|
46
|
-
include RDF::Durable
|
47
|
-
include RDF::Enumerable
|
48
50
|
include RDF::Queryable
|
49
|
-
include
|
51
|
+
include ActiveModel::Validations
|
50
52
|
include ActiveModel::Conversion
|
51
53
|
include ActiveModel::Serialization
|
52
54
|
include ActiveModel::Serializers::JSON
|
53
|
-
include ActiveModel::Validations
|
54
|
-
|
55
|
-
attr_accessor :parent
|
56
55
|
|
57
56
|
def type_registry
|
58
57
|
@@type_registry ||= {}
|
@@ -61,7 +60,6 @@ module ActiveTriples
|
|
61
60
|
|
62
61
|
included do
|
63
62
|
extend Configurable
|
64
|
-
extend Deprecation
|
65
63
|
extend ActiveModel::Naming
|
66
64
|
extend ActiveModel::Translation
|
67
65
|
extend ActiveModel::Callbacks
|
@@ -73,28 +71,11 @@ module ActiveTriples
|
|
73
71
|
graph.valid?
|
74
72
|
end
|
75
73
|
|
76
|
-
delegate :query, :each, :load!, :count, :has_statement?, :to => :@graph
|
77
|
-
|
78
74
|
define_model_callbacks :persist
|
79
|
-
|
80
|
-
protected
|
81
|
-
|
82
|
-
def insert_statement(*args)
|
83
|
-
@graph.send(:insert_statement, *args)
|
84
|
-
end
|
85
|
-
|
86
|
-
def delete_statement(*args)
|
87
|
-
@graph.send(:delete_statement, *args)
|
88
|
-
end
|
89
75
|
end
|
90
76
|
|
91
|
-
|
92
|
-
|
93
|
-
#
|
94
|
-
# @return [true, false]
|
95
|
-
def writable?
|
96
|
-
!frozen?
|
97
|
-
end
|
77
|
+
delegate :each, :load!, :count, :has_statement?, :to => :graph
|
78
|
+
delegate :to_base, :term?, :escape, :to => :to_term
|
98
79
|
|
99
80
|
##
|
100
81
|
# Initialize an instance of this resource class. Defaults to a
|
@@ -109,11 +90,17 @@ module ActiveTriples
|
|
109
90
|
# @todo move this logic out to a Builder?
|
110
91
|
def initialize(*args, &block)
|
111
92
|
resource_uri = args.shift unless args.first.is_a?(Hash)
|
112
|
-
|
93
|
+
unless args.first.is_a?(Hash) || args.empty?
|
94
|
+
set_persistence_strategy(ParentStrategy)
|
95
|
+
persistence_strategy.parent = args.shift
|
96
|
+
else
|
97
|
+
set_persistence_strategy(RepositoryStrategy)
|
98
|
+
end
|
113
99
|
@graph = RDF::Graph.new(*args, &block)
|
114
100
|
set_subject!(resource_uri) if resource_uri
|
115
101
|
|
116
102
|
reload
|
103
|
+
|
117
104
|
# Append type to graph if necessary.
|
118
105
|
Array(self.class.type).each do |type|
|
119
106
|
unless self.get_values(:type).include?(type)
|
@@ -122,14 +109,34 @@ module ActiveTriples
|
|
122
109
|
end
|
123
110
|
end
|
124
111
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
112
|
+
##
|
113
|
+
# Compares self to other for {RDF::Term} equality.
|
114
|
+
#
|
115
|
+
# Delegates the check to `other#==` passing it the term version of `self`.
|
116
|
+
#
|
117
|
+
# @param other [Object]
|
118
|
+
#
|
119
|
+
# @see RDF::Term#==
|
120
|
+
# @see RDF::Node#==
|
121
|
+
# @see RDF::URI#==
|
122
|
+
def ==(other)
|
123
|
+
other == to_term
|
124
|
+
end
|
125
|
+
|
126
|
+
##
|
127
|
+
# Delegate parent to the persistence strategy if possible
|
128
|
+
#
|
129
|
+
# @todo establish a better pattern for this. `#parent` has been a public method
|
130
|
+
# in the past, but it's probably time to deprecate it.
|
131
|
+
def parent
|
132
|
+
persistence_strategy.respond_to?(:parent) ? persistence_strategy.parent : nil
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# @todo deprecate/remove
|
137
|
+
# @see #parent
|
138
|
+
def parent=(parent)
|
139
|
+
persistence_strategy.respond_to?(:parent=) ? (persistence_strategy.parent = parent) : nil
|
133
140
|
end
|
134
141
|
|
135
142
|
def attributes
|
@@ -147,6 +154,8 @@ module ActiveTriples
|
|
147
154
|
hash
|
148
155
|
end
|
149
156
|
|
157
|
+
##
|
158
|
+
# @return [Class] gives `self#class`
|
150
159
|
def reflections
|
151
160
|
self.class
|
152
161
|
end
|
@@ -186,26 +195,54 @@ module ActiveTriples
|
|
186
195
|
end
|
187
196
|
|
188
197
|
##
|
189
|
-
#
|
190
|
-
#
|
198
|
+
# Gives the representation of this
|
199
|
+
#
|
200
|
+
# @return [RDF::URI, RDF::Node] the URI that identifies this `RDFSource`;
|
201
|
+
# or a bnode identifier
|
202
|
+
#
|
203
|
+
# @see RDF::Term#to_term
|
191
204
|
def rdf_subject
|
192
205
|
@rdf_subject ||= RDF::Node.new
|
193
206
|
end
|
194
207
|
alias_method :to_term, :rdf_subject
|
195
208
|
|
196
209
|
##
|
197
|
-
# A string identifier for the resource
|
210
|
+
# @return [String] A string identifier for the resource; '' if the
|
211
|
+
# resource is a node
|
212
|
+
def humanize
|
213
|
+
node? ? '' : rdf_subject.to_s
|
214
|
+
end
|
215
|
+
|
216
|
+
##
|
217
|
+
# @return [RDF::URI] the uri
|
218
|
+
def to_uri
|
219
|
+
uri? ? rdf_subject : NullURI.new
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# @return [String]
|
224
|
+
#
|
225
|
+
# @see RDF::Node#id
|
198
226
|
def id
|
199
|
-
node? ?
|
227
|
+
node? ? rdf_subject.id : rdf_subject.to_s
|
200
228
|
end
|
201
229
|
|
202
230
|
##
|
203
|
-
# @return [Boolean]
|
231
|
+
# @return [Boolean] true if the Term is a node
|
232
|
+
#
|
204
233
|
# @see RDF::Term#node?
|
205
234
|
def node?
|
206
235
|
rdf_subject.node?
|
207
236
|
end
|
208
237
|
|
238
|
+
##
|
239
|
+
# @return [Boolean] true if the Term is a uri
|
240
|
+
#
|
241
|
+
# @see RDF::Term#uri?
|
242
|
+
def uri?
|
243
|
+
rdf_subject.uri?
|
244
|
+
end
|
245
|
+
|
209
246
|
##
|
210
247
|
# @return [String, nil] the base URI the resource will use when
|
211
248
|
# setting its subject. `nil` if none is used.
|
@@ -235,14 +272,6 @@ module ActiveTriples
|
|
235
272
|
node? ? [] : [rdf_subject.to_s]
|
236
273
|
end
|
237
274
|
|
238
|
-
##
|
239
|
-
# Lists fields registered as properties on the object.
|
240
|
-
#
|
241
|
-
# @return [Array<Symbol>] the list of registered properties.
|
242
|
-
def fields
|
243
|
-
properties.keys.map(&:to_sym).reject{|x| x == :type}
|
244
|
-
end
|
245
|
-
|
246
275
|
##
|
247
276
|
# Load data from the #rdf_subject URI. Retrieved data will be
|
248
277
|
# parsed into the Resource's graph from available RDF::Readers
|
@@ -255,50 +284,11 @@ module ActiveTriples
|
|
255
284
|
# # => "Oregon State University"
|
256
285
|
#
|
257
286
|
# @return [ActiveTriples::Entity] self
|
258
|
-
def fetch
|
259
|
-
load(rdf_subject
|
287
|
+
def fetch
|
288
|
+
load(rdf_subject)
|
260
289
|
self
|
261
290
|
end
|
262
291
|
|
263
|
-
def persist!(opts={})
|
264
|
-
return if @persisting
|
265
|
-
return false if opts[:validate] && !valid?
|
266
|
-
@persisting = true
|
267
|
-
run_callbacks :persist do
|
268
|
-
raise "failed when trying to persist to non-existant repository or parent resource" unless repository
|
269
|
-
erase_old_resource
|
270
|
-
repository << self
|
271
|
-
@persisted = true
|
272
|
-
end
|
273
|
-
@persisting = false
|
274
|
-
true
|
275
|
-
end
|
276
|
-
|
277
|
-
##
|
278
|
-
# Indicates if the resource is persisted.
|
279
|
-
#
|
280
|
-
# @see #persist
|
281
|
-
# @return [true, false]
|
282
|
-
def persisted?
|
283
|
-
@persisted ||= false
|
284
|
-
return (@persisted and parent.persisted?) if parent
|
285
|
-
@persisted
|
286
|
-
end
|
287
|
-
|
288
|
-
##
|
289
|
-
# Repopulates the graph from the repository or parent resource.
|
290
|
-
#
|
291
|
-
# @return [true, false]
|
292
|
-
def reload
|
293
|
-
@relation_cache ||= {}
|
294
|
-
return false if (node? && self.class.repository != :parent) || !repository
|
295
|
-
self << repository.query(subject: rdf_subject)
|
296
|
-
unless empty?
|
297
|
-
@persisted = true
|
298
|
-
end
|
299
|
-
true
|
300
|
-
end
|
301
|
-
|
302
292
|
##
|
303
293
|
# Adds or updates a property with supplied values.
|
304
294
|
#
|
@@ -350,7 +340,6 @@ module ActiveTriples
|
|
350
340
|
get_relation([uri_or_term_property])
|
351
341
|
end
|
352
342
|
|
353
|
-
|
354
343
|
def get_relation(args)
|
355
344
|
@relation_cache ||= {}
|
356
345
|
rel = Relation.new(self, args)
|
@@ -389,22 +378,6 @@ module ActiveTriples
|
|
389
378
|
end
|
390
379
|
end
|
391
380
|
|
392
|
-
def destroy
|
393
|
-
clear
|
394
|
-
persist! if repository
|
395
|
-
parent.destroy_child(self) if parent
|
396
|
-
@destroyed = true
|
397
|
-
end
|
398
|
-
alias_method :destroy!, :destroy
|
399
|
-
|
400
|
-
##
|
401
|
-
# Indicates if the Resource has been destroyed.
|
402
|
-
#
|
403
|
-
# @return [true, false]
|
404
|
-
def destroyed?
|
405
|
-
@destroyed ||= false
|
406
|
-
end
|
407
|
-
|
408
381
|
def destroy_child(child)
|
409
382
|
statements.each do |statement|
|
410
383
|
delete_statement(statement) if statement.subject == child.rdf_subject || statement.object == child.rdf_subject
|
@@ -414,7 +387,7 @@ module ActiveTriples
|
|
414
387
|
##
|
415
388
|
# Indicates if the record is 'new' (has not yet been persisted).
|
416
389
|
#
|
417
|
-
# @return [
|
390
|
+
# @return [Boolean]
|
418
391
|
def new_record?
|
419
392
|
not persisted?
|
420
393
|
end
|
@@ -427,26 +400,20 @@ module ActiveTriples
|
|
427
400
|
@marked_for_destruction
|
428
401
|
end
|
429
402
|
|
430
|
-
protected
|
431
|
-
|
432
|
-
#Clear out any old assertions in the repository about this node or statement
|
433
|
-
# thus preparing to receive the updated assertions.
|
434
|
-
def erase_old_resource
|
435
|
-
if node?
|
436
|
-
repository.statements.each do |statement|
|
437
|
-
repository.send(:delete_statement, statement) if statement.subject == rdf_subject
|
438
|
-
end
|
439
|
-
else
|
440
|
-
repository.delete [rdf_subject, nil, nil]
|
441
|
-
end
|
442
|
-
end
|
443
|
-
|
444
403
|
private
|
445
404
|
|
446
405
|
def graph
|
447
406
|
@graph
|
448
407
|
end
|
449
408
|
|
409
|
+
##
|
410
|
+
# Lists fields registered as properties on the object.
|
411
|
+
#
|
412
|
+
# @return [Array<Symbol>] the list of registered properties.
|
413
|
+
def fields
|
414
|
+
properties.keys.map(&:to_sym).reject{ |x| x == :type }
|
415
|
+
end
|
416
|
+
|
450
417
|
##
|
451
418
|
# Returns the properties registered and their configurations.
|
452
419
|
#
|
@@ -474,21 +441,6 @@ module ActiveTriples
|
|
474
441
|
predicates.select { |p| !preds.include? p }
|
475
442
|
end
|
476
443
|
|
477
|
-
##
|
478
|
-
# Given a predicate which has been registered to a property,
|
479
|
-
# returns the name of the matching property.
|
480
|
-
#
|
481
|
-
# @param predicate [RDF::URI]
|
482
|
-
#
|
483
|
-
# @return [String, nil] the name of the property mapped to the
|
484
|
-
# predicate provided
|
485
|
-
def property_for_predicate(predicate)
|
486
|
-
properties.each do |property, values|
|
487
|
-
return property if values[:predicate] == predicate
|
488
|
-
end
|
489
|
-
return nil
|
490
|
-
end
|
491
|
-
|
492
444
|
def default_labels
|
493
445
|
[RDF::SKOS.prefLabel,
|
494
446
|
RDF::DC.title,
|
@@ -497,23 +449,6 @@ module ActiveTriples
|
|
497
449
|
RDF::SKOS.hiddenLabel]
|
498
450
|
end
|
499
451
|
|
500
|
-
##
|
501
|
-
# Return the repository (or parent) that this resource should
|
502
|
-
# write to when persisting.
|
503
|
-
#
|
504
|
-
# @return [RDF::Repository, ActiveTriples::Entity] the target
|
505
|
-
# repository
|
506
|
-
def repository
|
507
|
-
@repository ||=
|
508
|
-
if self.class.repository == :parent
|
509
|
-
final_parent
|
510
|
-
else
|
511
|
-
repo = Repositories.repositories[self.class.repository]
|
512
|
-
raise RepositoryNotFoundError, "The class #{self.class} expects a repository called #{self.class.repository}, but none was declared" unless repo
|
513
|
-
repo
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|
517
452
|
##
|
518
453
|
# Takes a URI or String and aggressively tries to convert it into
|
519
454
|
# an RDF term. If a String is given, first tries to interpret it
|
@@ -532,7 +467,7 @@ module ActiveTriples
|
|
532
467
|
# @return [RDF::Resource] A term
|
533
468
|
# @raise [RuntimeError] no valid RDF term could be built
|
534
469
|
def get_uri(uri_or_str)
|
535
|
-
return uri_or_str.
|
470
|
+
return uri_or_str.to_term if uri_or_str.respond_to? :to_term
|
536
471
|
return uri_or_str if uri_or_str.is_a? RDF::Node
|
537
472
|
uri_or_node = RDF::Resource.new(uri_or_str)
|
538
473
|
return uri_or_node if uri_or_node.valid?
|
@@ -550,11 +485,11 @@ module ActiveTriples
|
|
550
485
|
# which can become a Resource.
|
551
486
|
#
|
552
487
|
# @param uri [#to_uri, String]
|
553
|
-
# @param
|
488
|
+
# @param args values to pass as arguments to ::new
|
554
489
|
#
|
555
490
|
# @return [ActiveTriples::Entity] a Resource with the given uri
|
556
|
-
def from_uri(uri,
|
557
|
-
new(uri,
|
491
|
+
def from_uri(uri, *args)
|
492
|
+
new(uri, *args)
|
558
493
|
end
|
559
494
|
|
560
495
|
##
|