active-triples 0.7.6 → 0.8.0

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