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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -3
  3. data/AUTHORS +1 -1
  4. data/CHANGES.md +12 -17
  5. data/Gemfile +2 -0
  6. data/README.md +2 -2
  7. data/active-triples.gemspec +6 -5
  8. data/lib/active_triples.rb +56 -5
  9. data/lib/active_triples/configurable.rb +13 -17
  10. data/lib/active_triples/list.rb +22 -21
  11. data/lib/active_triples/persistable.rb +100 -0
  12. data/lib/active_triples/persistence_strategies/parent_strategy.rb +89 -0
  13. data/lib/active_triples/persistence_strategies/persistence_strategy.rb +77 -0
  14. data/lib/active_triples/persistence_strategies/repository_strategy.rb +78 -0
  15. data/lib/active_triples/properties.rb +2 -1
  16. data/lib/active_triples/rdf_source.rb +94 -159
  17. data/lib/active_triples/relation.rb +17 -45
  18. data/lib/active_triples/repositories.rb +23 -9
  19. data/lib/active_triples/version.rb +1 -1
  20. data/spec/active_triples/configurable_spec.rb +5 -9
  21. data/spec/active_triples/identifiable_spec.rb +1 -18
  22. data/spec/active_triples/list_spec.rb +0 -4
  23. data/spec/active_triples/persistable_spec.rb +93 -0
  24. data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +93 -0
  25. data/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb +24 -0
  26. data/spec/active_triples/persistence_strategies/repository_strategy_spec.rb +120 -0
  27. data/spec/active_triples/rdf_source_spec.rb +217 -9
  28. data/spec/active_triples/relation_spec.rb +51 -4
  29. data/spec/active_triples/repositories_spec.rb +17 -7
  30. data/spec/active_triples/resource_spec.rb +6 -53
  31. data/spec/active_triples_spec.rb +50 -1
  32. data/spec/spec_helper.rb +5 -1
  33. data/spec/support/active_model_lint.rb +6 -3
  34. data/spec/support/dummies/basic_persistable.rb +13 -0
  35. data/spec/support/shared_examples/persistence_strategy.rb +36 -0
  36. metadata +32 -9
  37. data/spec/active_triples/validations_spec.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90cd49de8c91815ff02733feaf843e01618037c8
4
- data.tar.gz: c6b95f28bc6b814a6464adefc46858bba2709f71
3
+ metadata.gz: 134e560560581d9eb910f02fb4acfe1796a49e8c
4
+ data.tar.gz: 06111e25af63727d289515c461f5d648bdfbf9ff
5
5
  SHA512:
6
- metadata.gz: 69f978b7d1aa618f3942acf21c99ca4c5b211d0d573a260bfe7487a3e3fa92509eb459bfaa2e915195b3249af7f0e75a5c0d571cf0b9b18f9d76ba640fcd9072
7
- data.tar.gz: b13615881670aed59931f21f6d7f1b043e23dee5ee0230131b0758d1d179c7c508c4cbde35980a771bf8f989112c62091ee38ec21f57f96063ea35e51e4eeeeb
6
+ metadata.gz: 12bcd4d12842619f883cc042052f53e1a89bca2b6bf78f926318ebe7a6072ee3d9116ebfc56c52deceb7401694a2d3fdaaadbea7753f5348aa5e5c44e8e469c5
7
+ data.tar.gz: 61a6ee297b43bd909bf89f5a91ea815fdcef3dced6a8863a4f2af7b7f989ad77bc187e5140a4ea6001876d943ea8a011a126febdfa1ae97fe499746ba94c2fc1
@@ -4,12 +4,14 @@ script: "bundle exec rspec spec"
4
4
  sudo: false
5
5
  cache: bundler
6
6
  rvm:
7
- - 2.1.10
8
- - 2.2.5
9
- - 2.3.1
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 (thomas.johnson@oregonstate.edu)
1
+ * Tom Johnson (tom@dp.la)
2
2
  * Trey Terrell
data/CHANGES.md CHANGED
@@ -1,21 +1,16 @@
1
- 0.7.3
2
- ----
3
-
4
- - Optimize querying by using Graph#query instead of Queryable#query
5
- - Improved error handling
6
-
7
- 0.7.2
8
- ----
9
-
10
- - Allows interoperability between `ActiveModel::Validations` and
11
- `RDF::Graph#valid?`. This fixes a bug with validation callbacks. See:
12
- [#167](https://github.com/ActiveTriples/ActiveTriples/pull/167).
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
@@ -3,3 +3,5 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem 'pry-byebug' unless ENV["CI"]
6
+
7
+ gem 'rdf-spec', :github => 'ruby-rdf/rdf-spec', :branch => 'develop'
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  Description
2
2
  -----------
3
3
 
4
- [![Build Status](https://travis-ci.org/ActiveTriples/ActiveTriples.png?branch=master)](https://travis-ci.org/ActiveTriples/ActiveTriples)
5
- [![Coverage Status](https://coveralls.io/repos/ActiveTriples/ActiveTriples/badge.png?branch=master)](https://coveralls.io/r/ActiveTriples/ActiveTriples?branch=master)
4
+ [![Build Status](https://travis-ci.org/ActiveTriples/ActiveTriples.png?branch=develop)](https://travis-ci.org/ActiveTriples/ActiveTriples)
5
+ [![Coverage Status](https://coveralls.io/repos/ActiveTriples/ActiveTriples/badge.svg?branch=develop)](https://coveralls.io/r/ActiveTriples/ActiveTriples?branch=develop)
6
6
  [![Gem Version](https://badge.fury.io/rb/active-triples.svg)](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.
@@ -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 = 'thomas.johnson@oregonstate.edu'
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.0')
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') unless ENV['CI']
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')
@@ -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
- # deprecated class
26
- autoload :Term, 'active_triples/relation'
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('::')).flatten.inject(Kernel) do |mod, class_name|
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
- # Resource and RDFDatastream. It does its work at the class level,
7
- # and is meant to be extended.
6
+ # RDFSources.
8
7
  #
9
8
  # Define properties at the class level with:
10
9
  #
11
- # configure base_uri: "http://oregondigital.org/resource/", repository: :default
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] || :parent
34
+ configuration[:repository]
40
35
  end
41
36
 
42
37
  ##
43
- # API for configuring class properties on a Resource. This is an
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 Resource initializer
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 Resource)
52
- # - repository (the target persist location to for the Resource)
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
- Resource.type_registry[uri] = self
66
+ RDFSource.type_registry[uri] = self
71
67
  end
72
68
  end
73
69
  end
@@ -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
- parent = graph.parent if graph.respond_to? :parent
31
- @graph = ListResource.new(subject) << graph unless graph.kind_of? RDFSource
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
- # Find an AF::Rdf::Resource from the value returned by RDF::List
79
+ # find an AF::Rdf::Resource from the value returned by RDF::List
87
80
  def node_from_value(value)
88
- if value.kind_of? RDF::Resource
89
- type_uri = resource.query([value, RDF.type, nil]).to_a.first.try(:object)
90
- klass = ActiveTriples::Resource.type_registry[type_uri]
91
- klass ||= Resource
92
- return klass.from_uri(value,resource)
93
- end
94
- value
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, repository).clear
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
- resource << value if value.kind_of? RDFSource
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