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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 134e560560581d9eb910f02fb4acfe1796a49e8c
|
4
|
+
data.tar.gz: 06111e25af63727d289515c461f5d648bdfbf9ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12bcd4d12842619f883cc042052f53e1a89bca2b6bf78f926318ebe7a6072ee3d9116ebfc56c52deceb7401694a2d3fdaaadbea7753f5348aa5e5c44e8e469c5
|
7
|
+
data.tar.gz: 61a6ee297b43bd909bf89f5a91ea815fdcef3dced6a8863a4f2af7b7f989ad77bc187e5140a4ea6001876d943ea8a011a126febdfa1ae97fe499746ba94c2fc1
|
data/.travis.yml
CHANGED
@@ -4,12 +4,14 @@ script: "bundle exec rspec spec"
|
|
4
4
|
sudo: false
|
5
5
|
cache: bundler
|
6
6
|
rvm:
|
7
|
-
- 2.
|
8
|
-
- 2.
|
9
|
-
- 2.
|
7
|
+
- 2.0.0
|
8
|
+
- 2.1.0
|
9
|
+
- 2.1.1
|
10
|
+
- 2.2.1
|
10
11
|
- ruby-head
|
11
12
|
- jruby
|
12
13
|
- rbx-2
|
13
14
|
matrix:
|
14
15
|
allow_failures:
|
15
16
|
- rvm: jruby
|
17
|
+
- rvm: ruby-head
|
data/AUTHORS
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
* Tom Johnson (
|
1
|
+
* Tom Johnson (tom@dp.la)
|
2
2
|
* Trey Terrell
|
data/CHANGES.md
CHANGED
@@ -1,21 +1,16 @@
|
|
1
|
-
0.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
0.7.1
|
15
|
-
----
|
1
|
+
0.8.0
|
2
|
+
-----
|
3
|
+
- Adds RDF.rb interfaces to `RDFSource`, improving interoperability
|
4
|
+
with other `ruby-rdf` packages.
|
5
|
+
- Introduces a defined `Persistable` interface and
|
6
|
+
`PersistenceStrategies`.
|
7
|
+
- Changes `Relation`'s delete methods to remove all values, instead of
|
8
|
+
trying to maintain a predicate -> class pair on the property
|
9
|
+
definitions in some cases. The previous functionality was unclear and
|
10
|
+
unreliable.
|
11
|
+
- Adds a `Schema` concept, for defining property definitions that are
|
12
|
+
portable across `RDFSource` types.
|
16
13
|
|
17
|
-
- Adds a Schema concept, for defining property definitions that are portable
|
18
|
-
across RDFSource types.
|
19
14
|
|
20
15
|
0.7.0
|
21
16
|
-----
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Description
|
2
2
|
-----------
|
3
3
|
|
4
|
-
[](https://travis-ci.org/ActiveTriples/ActiveTriples)
|
5
|
+
[](https://coveralls.io/r/ActiveTriples/ActiveTriples?branch=develop)
|
6
6
|
[](http://badge.fury.io/rb/active-triples)
|
7
7
|
|
8
8
|
An ActiveModel-like interface for RDF data. Models graphs as RDFSources with property/attribute configuration, accessors, and other methods to support Linked Data in a Ruby/Rails enviornment. See [RDF Concepts and Abstract Syntax](http://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/#change-over-time) for an informal definition of an RDF Source.
|
data/active-triples.gemspec
CHANGED
@@ -8,22 +8,23 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Tom Johnson", "Trey Terrell"]
|
10
10
|
s.homepage = 'https://github.com/no-reply/ActiveTriples'
|
11
|
-
s.email = '
|
11
|
+
s.email = 'tom@dp.la'
|
12
12
|
s.summary = %q{RDF graphs in ActiveModel wrappers.}
|
13
13
|
s.description = %q{ActiveTriples provides tools for modeling RDF as discrete resources.}
|
14
14
|
s.license = "APACHE2"
|
15
15
|
s.required_ruby_version = '>= 1.9.3'
|
16
|
-
|
17
|
-
s.add_dependency('rdf', '~> 1.1')
|
16
|
+
|
17
|
+
s.add_dependency('rdf', '~> 1.1.13')
|
18
18
|
s.add_dependency('linkeddata', '~> 1.1')
|
19
19
|
s.add_dependency('activemodel', '>= 3.0.0')
|
20
|
-
s.add_dependency('deprecation', '~> 1
|
20
|
+
s.add_dependency('deprecation', '~> 0.1')
|
21
21
|
s.add_dependency('activesupport', '>= 3.0.0')
|
22
22
|
|
23
23
|
s.add_development_dependency('rdoc')
|
24
24
|
s.add_development_dependency('rspec')
|
25
|
+
s.add_development_dependency('rdf-spec')
|
25
26
|
s.add_development_dependency('coveralls')
|
26
|
-
s.add_development_dependency('guard-rspec')
|
27
|
+
s.add_development_dependency('guard-rspec')
|
27
28
|
s.add_development_dependency('webmock')
|
28
29
|
s.add_development_dependency('nokogiri')
|
29
30
|
s.add_development_dependency('pragmatic_context', '~> 0.1.2')
|
data/lib/active_triples.rb
CHANGED
@@ -2,6 +2,29 @@ require 'rdf'
|
|
2
2
|
require 'active_triples/version'
|
3
3
|
require 'active_support'
|
4
4
|
|
5
|
+
##
|
6
|
+
# An ActiveModel compliant ObjectGraphMapper for RDF data.
|
7
|
+
#
|
8
|
+
# Models graphs as `RDFSources` with property/attribute configuration,
|
9
|
+
# accessors, and other methods to support Linked Data in a Ruby enviornment.
|
10
|
+
#
|
11
|
+
# @example modeling a simple resource
|
12
|
+
# class Thing
|
13
|
+
# include ActiveTriples::RDFSource
|
14
|
+
# configure :type => RDF::OWL.Thing, :base_uri => 'http://example.org/things#'
|
15
|
+
# property :title, :predicate => RDF::DC.title
|
16
|
+
# property :description, :predicate => RDF::DC.description
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# obj = Thing.new('123')
|
20
|
+
# obj.title = 'Resource'
|
21
|
+
# obj.description = 'A resource.'
|
22
|
+
# obj.dump :ntriples
|
23
|
+
# # => "<http://example.org/things#123> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Thing> .\n<http://example.org/things#123> <http://purl.org/dc/terms/title> \"Resource\" .\n<http://example.org/things#123> <http://purl.org/dc/terms/description> \"A resource.\" .\n"
|
24
|
+
#
|
25
|
+
# @see http://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/#change-over-time
|
26
|
+
# RDF Concepts and Abstract Syntax for an informal definition of an RDF
|
27
|
+
# Source.
|
5
28
|
module ActiveTriples
|
6
29
|
extend ActiveSupport::Autoload
|
7
30
|
eager_autoload do
|
@@ -10,6 +33,7 @@ module ActiveTriples
|
|
10
33
|
autoload :List
|
11
34
|
autoload :Relation
|
12
35
|
autoload :Configurable
|
36
|
+
autoload :Persistable
|
13
37
|
autoload :Properties
|
14
38
|
autoload :PropertyBuilder
|
15
39
|
autoload :Reflection
|
@@ -22,18 +46,44 @@ module ActiveTriples
|
|
22
46
|
autoload :Property
|
23
47
|
autoload :ExtensionStrategy
|
24
48
|
|
25
|
-
#
|
26
|
-
autoload :
|
49
|
+
# persistence strategies
|
50
|
+
autoload :PersistenceStrategy,
|
51
|
+
'active_triples/persistence_strategies/persistence_strategy'
|
52
|
+
autoload :ParentStrategy,
|
53
|
+
'active_triples/persistence_strategies/parent_strategy'
|
54
|
+
autoload :RepositoryStrategy,
|
55
|
+
'active_triples/persistence_strategies/repository_strategy'
|
27
56
|
end
|
28
|
-
|
57
|
+
|
58
|
+
##
|
29
59
|
# Raised when a declared repository doesn't have a definition
|
30
60
|
class RepositoryNotFoundError < StandardError
|
31
61
|
end
|
32
62
|
|
63
|
+
##
|
64
|
+
# Converts a string for a class or module into a a constant. This will find
|
65
|
+
# classes in or above a given container class.
|
66
|
+
#
|
67
|
+
# @example finding a class in Kernal
|
68
|
+
# ActiveTriples.class_from_string('MyClass') # => MyClass
|
69
|
+
#
|
70
|
+
# @example finding a class in a module
|
71
|
+
# ActiveTriples.class_from_string('MyClass', MyModule)
|
72
|
+
# # => MyModule::MyClass
|
73
|
+
#
|
74
|
+
# @example when a class exists above the module, but not in it
|
75
|
+
# ActiveTriples.class_from_string('Object', MyModule)
|
76
|
+
# # => Object
|
77
|
+
#
|
78
|
+
# @param class_name [String]
|
79
|
+
# @param container_class
|
80
|
+
#
|
81
|
+
# @return [Class]
|
33
82
|
def self.class_from_string(class_name, container_class=Kernel)
|
34
83
|
container_class = container_class.name if container_class.is_a? Module
|
35
84
|
container_parts = container_class.split('::')
|
36
|
-
(container_parts + class_name.split('::'))
|
85
|
+
(container_parts + class_name.split('::'))
|
86
|
+
.flatten.inject(Kernel) do |mod, class_name|
|
37
87
|
if mod == Kernel
|
38
88
|
Object.const_get(class_name)
|
39
89
|
elsif mod.const_defined? class_name.to_sym
|
@@ -45,6 +95,8 @@ module ActiveTriples
|
|
45
95
|
end
|
46
96
|
end
|
47
97
|
|
98
|
+
##
|
99
|
+
# A simplified, Belgian version of this software
|
48
100
|
def self.ActiveTripels
|
49
101
|
puts <<-eos
|
50
102
|
|
@@ -61,5 +113,4 @@ module ActiveTriples
|
|
61
113
|
eos
|
62
114
|
"Yum"
|
63
115
|
end
|
64
|
-
|
65
116
|
end
|
@@ -3,12 +3,14 @@ require 'deprecation'
|
|
3
3
|
module ActiveTriples
|
4
4
|
##
|
5
5
|
# Module to include configurable class-wide properties common to
|
6
|
-
#
|
7
|
-
# and is meant to be extended.
|
6
|
+
# RDFSources.
|
8
7
|
#
|
9
8
|
# Define properties at the class level with:
|
10
9
|
#
|
11
|
-
#
|
10
|
+
# @example
|
11
|
+
# configure base_uri: "http://oregondigital.org/resource/",
|
12
|
+
# repository: :default
|
13
|
+
#
|
12
14
|
# Available properties are base_uri, rdf_label, type, and repository
|
13
15
|
module Configurable
|
14
16
|
extend Deprecation
|
@@ -28,29 +30,23 @@ module ActiveTriples
|
|
28
30
|
@configuration ||= Configuration.new
|
29
31
|
end
|
30
32
|
|
31
|
-
##
|
32
|
-
# @deprecated use `configure type:` instead.
|
33
|
-
def rdf_type(value)
|
34
|
-
Deprecation.warn Configurable, "rdf_type is deprecated and will be removed in active-fedora 8.0.0. Use configure type: instead.", caller
|
35
|
-
configure type: value
|
36
|
-
end
|
37
|
-
|
38
33
|
def repository
|
39
|
-
configuration[:repository]
|
34
|
+
configuration[:repository]
|
40
35
|
end
|
41
36
|
|
42
37
|
##
|
43
|
-
# API for configuring class properties on a
|
38
|
+
# API for configuring class properties on a RDFSource. This is an
|
44
39
|
# alternative to overriding the methods in this module.
|
45
40
|
#
|
46
41
|
# Can configure the following values:
|
47
|
-
# - base_uri (allows passing slugs to the
|
42
|
+
# - base_uri (allows passing slugs to the RDFSource initializer
|
48
43
|
# in place of fully qualified URIs)
|
49
44
|
# - rdf_label (overrides default label predicates)
|
50
45
|
# - type (a default rdf:type to include when initializing a
|
51
|
-
# new
|
52
|
-
# - repository (the target persist location to for the
|
53
|
-
#
|
46
|
+
# new RDFSource)
|
47
|
+
# - repository (the target persist location to for the RDFSource)
|
48
|
+
#
|
49
|
+
# @example
|
54
50
|
# configure base_uri: "http://oregondigital.org/resource/", repository: :default
|
55
51
|
#
|
56
52
|
# @param options [Hash]
|
@@ -67,7 +63,7 @@ module ActiveTriples
|
|
67
63
|
def transform_type(values)
|
68
64
|
Array(values).map do |value|
|
69
65
|
RDF::URI.new(value).tap do |uri|
|
70
|
-
|
66
|
+
RDFSource.type_registry[uri] = self
|
71
67
|
end
|
72
68
|
end
|
73
69
|
end
|
data/lib/active_triples/list.rb
CHANGED
@@ -11,7 +11,7 @@ module ActiveTriples
|
|
11
11
|
include Properties
|
12
12
|
include Reflection
|
13
13
|
|
14
|
-
delegate :rdf_subject, :mark_for_destruction, :marked_for_destruction?, :set_value, :get_values, :parent, :type, :dump, :attributes=, to: :resource
|
14
|
+
delegate :rdf_subject, :mark_for_destruction, :marked_for_destruction?, :set_value, :get_values, :parent, :persist, :persist!, :type, :dump, :attributes=, to: :resource
|
15
15
|
alias_method :to_ary, :to_a
|
16
16
|
|
17
17
|
class << self
|
@@ -27,8 +27,8 @@ module ActiveTriples
|
|
27
27
|
|
28
28
|
def initialize(*args)
|
29
29
|
super
|
30
|
-
|
31
|
-
|
30
|
+
@graph = ListResource.new(subject) unless
|
31
|
+
graph.kind_of? RDFSource
|
32
32
|
graph << parent if parent
|
33
33
|
graph.list = self
|
34
34
|
graph.reload
|
@@ -36,13 +36,10 @@ module ActiveTriples
|
|
36
36
|
|
37
37
|
def clear
|
38
38
|
graph.send :erase_old_resource
|
39
|
-
parent = graph.parent
|
40
39
|
old_subject = subject
|
41
40
|
super
|
42
41
|
@subject = old_subject
|
43
42
|
@graph = ListResource.new(subject)
|
44
|
-
graph << parent if parent
|
45
|
-
graph.parent = parent
|
46
43
|
graph.list = self
|
47
44
|
end
|
48
45
|
|
@@ -78,20 +75,17 @@ module ActiveTriples
|
|
78
75
|
node_from_value(super)
|
79
76
|
end
|
80
77
|
|
81
|
-
def shift
|
82
|
-
node_from_value(super)
|
83
|
-
end
|
84
|
-
|
85
78
|
##
|
86
|
-
#
|
79
|
+
# find an AF::Rdf::Resource from the value returned by RDF::List
|
87
80
|
def node_from_value(value)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
81
|
+
return value unless value.is_a? RDF::Resource
|
82
|
+
return value if value.is_a? RDFSource
|
83
|
+
|
84
|
+
type_uri = resource.query([value, RDF.type, nil]).to_a.first.try(:object)
|
85
|
+
klass = RDFSource.type_registry[type_uri]
|
86
|
+
klass ||= Resource
|
87
|
+
|
88
|
+
klass.from_uri(value, resource)
|
95
89
|
end
|
96
90
|
|
97
91
|
##
|
@@ -125,13 +119,15 @@ module ActiveTriples
|
|
125
119
|
end
|
126
120
|
|
127
121
|
protected
|
122
|
+
|
128
123
|
# Clear out any old assertions in the repository about this node or statement
|
129
124
|
# thus preparing to receive the updated assertions.
|
130
125
|
def erase_old_resource
|
131
|
-
RDF::List.new(rdf_subject,
|
126
|
+
RDF::List.new(rdf_subject, self).clear
|
132
127
|
end
|
133
128
|
|
134
129
|
private
|
130
|
+
|
135
131
|
def attributes_to_list(value, klass)
|
136
132
|
value.each do |entry|
|
137
133
|
item = klass.new()
|
@@ -172,12 +168,17 @@ module ActiveTriples
|
|
172
168
|
if empty?
|
173
169
|
@graph.type = RDF.List
|
174
170
|
resource.set_value(RDF.first, value)
|
175
|
-
resource.insert([subject, RDF.rest, RDF.nil])
|
171
|
+
resource.insert([subject.to_term, RDF.rest, RDF.nil])
|
176
172
|
resource << value if value.kind_of? RDFSource
|
177
173
|
return self
|
178
174
|
end
|
179
175
|
super
|
180
|
-
|
176
|
+
if value.kind_of? RDFSource
|
177
|
+
resource << value
|
178
|
+
value.set_persistence_strategy(ParentStrategy)
|
179
|
+
value.persistence_strategy.parent = resource
|
180
|
+
value.persist!
|
181
|
+
end
|
181
182
|
end
|
182
183
|
end
|
183
184
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module ActiveTriples
|
2
|
+
##
|
3
|
+
# Bundles the core interfaces used by ActiveTriples persistence strategies
|
4
|
+
# to treat a graph as persistable. Specificially:
|
5
|
+
#
|
6
|
+
# - RDF::Enumerable
|
7
|
+
# - RDF::Mutable
|
8
|
+
#
|
9
|
+
# @abstract implement {#graph} as a reference to an `RDF::Graph` or similar.
|
10
|
+
module Persistable
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
include RDF::Enumerable
|
14
|
+
include RDF::Mutable
|
15
|
+
|
16
|
+
##
|
17
|
+
# @see RDF::Enumerable.each
|
18
|
+
def each(*args)
|
19
|
+
graph.each(*args)
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# @see RDF::Writable.insert_statement
|
24
|
+
def insert_statement(*args)
|
25
|
+
graph.send(:insert_statement, *args)
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# @see RDF::Writable.delete_statement
|
30
|
+
def delete_statement(*args)
|
31
|
+
graph.send(:delete_statement, *args)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Returns the persistence strategy object that handles this object's
|
36
|
+
# persistence
|
37
|
+
def persistence_strategy
|
38
|
+
@persistence_strategy || set_persistence_strategy(RepositoryStrategy)
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Sets a persistence strategy
|
43
|
+
#
|
44
|
+
# @param klass [Class] A class implementing the persistence strategy
|
45
|
+
# interface
|
46
|
+
def set_persistence_strategy(klass)
|
47
|
+
@persistence_strategy = klass.new(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Removes the statements in this RDFSource's graph from the persisted graph
|
52
|
+
#
|
53
|
+
# @return [Boolean]
|
54
|
+
def destroy
|
55
|
+
persistence_strategy.destroy
|
56
|
+
end
|
57
|
+
alias_method :destroy!, :destroy
|
58
|
+
|
59
|
+
##
|
60
|
+
# @return [Boolean] true if this item is destroyed
|
61
|
+
def destroyed?
|
62
|
+
persistence_strategy.destroyed?
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Sends a persistence message to the persistence_startegy, saving the
|
67
|
+
# RDFSource.
|
68
|
+
#
|
69
|
+
# @return [Boolean]
|
70
|
+
def persist!(opts={})
|
71
|
+
return if @persisting
|
72
|
+
result = false
|
73
|
+
return result if opts[:validate] && !valid?
|
74
|
+
@persisting = true
|
75
|
+
run_callbacks :persist do
|
76
|
+
result = persistence_strategy.persist!
|
77
|
+
end
|
78
|
+
@persisting = false
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Indicates if the resource is persisted.
|
84
|
+
#
|
85
|
+
# @see #persist
|
86
|
+
# @return [Boolean]
|
87
|
+
def persisted?
|
88
|
+
persistence_strategy.persisted?
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Repopulates the graph according to the persistence strategy
|
93
|
+
#
|
94
|
+
# @return [Boolean]
|
95
|
+
def reload
|
96
|
+
@term_cache ||= {}
|
97
|
+
persistence_strategy.reload
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|