active-triples 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/AUTHORS +2 -2
- data/Guardfile +9 -0
- data/README.md +129 -15
- data/WAIVER +5 -0
- data/active-triples.gemspec +2 -0
- data/lib/active_triples/configurable.rb +18 -3
- data/lib/active_triples/list.rb +7 -0
- data/lib/active_triples/node_config.rb +1 -0
- data/lib/active_triples/properties.rb +20 -32
- data/lib/active_triples/resource.rb +138 -26
- data/lib/active_triples/term.rb +20 -17
- data/lib/active_triples/version.rb +1 -1
- data/spec/active_triples/configurable_spec.rb +37 -0
- data/spec/{rdf_list_spec.rb → active_triples/list_spec.rb} +47 -35
- data/spec/{rdf_nested_attributes_spec.rb → active_triples/nested_attributes_spec.rb} +9 -9
- data/spec/{rdf_properties_spec.rb → active_triples/properties_spec.rb} +0 -23
- data/spec/{rdf_repositories_spec.rb → active_triples/repositories_spec.rb} +0 -0
- data/spec/{rdf_resource_spec.rb → active_triples/resource_spec.rb} +18 -9
- data/spec/pragmatic_context_spec.rb +53 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/active_model_lint.rb +4 -4
- metadata +40 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8f2271397f8aecc1c96f8bd3cf63744e87e0989
|
4
|
+
data.tar.gz: 25d4b23e7404fafd3c437e4cf0ff4de54f9c7c54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4645aa5fc8dd320fe19fe46268b500533fad11836093dcd8ad594b7b9052f5f531e61332b625a4284ebae92b8de2651ca29e8aa0c9833b5a5a0a9e635a3a75a
|
7
|
+
data.tar.gz: fed0f9f047b36fd5f84bb231e83f021da0aa27991239697b58c173df75685b4a30a4a5715095cf538d709fd4c4336debf93b1814df0b73d0be0a3fc11a01becf
|
data/AUTHORS
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
Tom Johnson (thomas.johnson@oregonstate.edu)
|
2
|
-
Trey Terrell
|
1
|
+
* Tom Johnson (thomas.johnson@oregonstate.edu)
|
2
|
+
* Trey Terrell
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -1,38 +1,152 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Description
|
2
|
+
-----------
|
3
3
|
|
4
4
|
[![Build Status](https://travis-ci.org/no-reply/ActiveTriples.png?branch=master)](https://travis-ci.org/no-reply/ActiveTriples)
|
5
5
|
|
6
|
-
|
6
|
+
An ActiveModel-like interface for RDF data. Models graphs as Resources with property/attribute configuration, accessors, and other methods to support Linked Data in a Ruby/Rails enviornment.
|
7
|
+
|
8
|
+
This library was extracted from work on [ActiveFedora](https://github.com/projecthydra/active_fedora). It is closely related to (and borrows some syntax from) [Spira](https://github.com/ruby-rdf/spira), but does some important things differently.
|
9
|
+
|
10
|
+
Installation
|
11
|
+
------------
|
12
|
+
|
13
|
+
Add `gem "active-triples"` to your Gemfile and run `bundle`.
|
14
|
+
|
15
|
+
Or install manually with `gem install active-triples`.
|
16
|
+
|
17
|
+
Defining Resource Models
|
18
|
+
------------------------
|
19
|
+
|
20
|
+
The core class of ActiveTriples is ActiveTriples::Resource. You can subclass this to create ActiveModel-like classes that represent a node in an RDF graph, and its surrounding statements. Resources implement all the functionality of an RDF::Graph. You can manipulate them by adding or deleting statements, query, serialize, and load arbitrary RDF.
|
7
21
|
|
8
|
-
How to Use
|
9
|
-
-----------
|
10
22
|
|
11
23
|
```ruby
|
12
24
|
class Thing < ActiveTriples::Resource
|
13
25
|
configure :type => RDF::OWL.Thing, :base_uri => 'http://example.org/things#'
|
14
26
|
property :title, :predicate => RDF::DC.title
|
15
27
|
property :description, :predicate => RDF::DC.description
|
16
|
-
property :creator, :predicate => RDF::DC.creator, :class_name => 'Person'
|
17
28
|
end
|
18
29
|
|
19
30
|
obj = Thing.new('123')
|
20
31
|
obj.title = 'Resource'
|
21
|
-
obj.description = 'A resource
|
32
|
+
obj.description = 'A resource.'
|
33
|
+
obj.dump :ntriples # => "<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"
|
34
|
+
```
|
35
|
+
URI and bnode values are built out as Resources when accessed, and a model class can be configured on individual properties.
|
22
36
|
|
23
|
-
|
24
|
-
|
37
|
+
```ruby
|
38
|
+
Thing.property :creator, :predicate => RDF::DC.creator, :class_name => 'Person'
|
25
39
|
|
26
40
|
class Person < ActiveTriples::Resource
|
27
41
|
configure :type => RDF::FOAF.Person, :base_uri => 'http://example.org/people#'
|
28
42
|
property :name, :predicate => RDF::FOAF.name
|
29
43
|
end
|
30
44
|
|
31
|
-
|
32
|
-
|
45
|
+
obj_2 = Thing.new('2')
|
46
|
+
obj_2.creator = Person.new
|
47
|
+
obj_2.creator
|
33
48
|
# => [#<Person:0x3fbe84ac9234(default)>]
|
34
49
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
50
|
+
obj_2.creator.first.name = 'Herman Melville'
|
51
|
+
obj_2.dump :ntriples # => "<http://example.org/things#2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Thing> .\n<http://example.org/things#2> <http://purl.org/dc/terms/creator> _:g70263220218800 .\n_:g70263220218800 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .\n_:g70263220218800 <http://xmlns.com/foaf/0.1/name> \"Herman Melville\" .\n"
|
52
|
+
```
|
53
|
+
|
54
|
+
Open Model
|
55
|
+
-----------
|
56
|
+
|
57
|
+
A Resource lets you handle data as a graph, independent of whether it is defined in the model. This is important for working in a Linked Data context, where you will want access to data you may not have known about when your models were written.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
related = Thing.new
|
61
|
+
|
62
|
+
related << RDF::Statement(related, RDF::DC.relation, obj)
|
63
|
+
related << RDF::Statement(related, RDF::DC.subject, 'ActiveTriples')
|
64
|
+
|
65
|
+
related.query(:subject => related, :predicate => RDF::DC.relation).each_statement {|s,p,o| puts o}
|
66
|
+
# => http://example.org/things#123
|
67
|
+
related.query(:subject => subject, :predicate => RDF::DC.relation).each_statement {|s,p,o| puts o}
|
68
|
+
# => http://example.org/things#123
|
69
|
+
```
|
70
|
+
|
71
|
+
Any operation you can run against an RDF::Graph works with Resources, too. Or you can use generic setters and getters with URI predicates:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
related.set_value(RDF::DC.relation, obj)
|
75
|
+
related.set_value(RDF::DC.subject, 'ActiveTriples')
|
76
|
+
|
77
|
+
related.get_values(RDF::DC.relation) # => [#<Thing:0x3f949c6a2294(default)>]
|
78
|
+
related.get_values(RDF::DC.subject) # => ["ActiveTriples"]
|
79
|
+
```
|
80
|
+
|
81
|
+
Some convienience methods provide support for handling data from web sources:
|
82
|
+
* `fetch` loads data from the Resource's #rdf_subject URI
|
83
|
+
* `rdf_label` queries across common (& configured) label fields and returning the best match
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
require 'linkeddata' # to support various serializations
|
87
|
+
|
88
|
+
osu = ActiveTriples::Resource.new 'http://dbpedia.org/resource/Oregon_State_University'
|
89
|
+
osu.fetch
|
90
|
+
|
91
|
+
osu.rdf_label => => ["Oregon State University", "Oregon State University", "Université d'État de l'Oregon", "Oregon State University", "Oregon State University", "オレゴン州立大学", "Universidad Estatal de Oregón", "Oregon State University", "俄勒岡州立大學", "Universidade do Estado do Oregon"]
|
92
|
+
```
|
93
|
+
|
94
|
+
Typed Data
|
95
|
+
-----------
|
96
|
+
|
97
|
+
Typed literals are handled natively through Ruby types and [RDF::Literal](https://github.com/ruby-rdf/rdf/tree/develop/lib/rdf/model/literal). There is no need to register a specific type for a property, simply pass the setter the appropriate typed data. See the examples in the RDF::Literal documentation for futher information about supported datatypes.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
Thing.property :date, :predicate => RDF::DC.date
|
101
|
+
|
102
|
+
my_thing = Thing.new
|
103
|
+
my_thing.date = Date.today
|
104
|
+
|
105
|
+
puts my_thing.dump :ntriples
|
106
|
+
# _:g70072864570340 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Thing> .
|
107
|
+
# _:g70072864570340 <http://purl.org/dc/terms/date> "2014-06-19Z"^^<http://www.w3.org/2001/XMLSchema#date> .
|
108
|
+
```
|
109
|
+
|
110
|
+
Data is cast back to the appropriate class when it is accessed.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
my_thing.date
|
114
|
+
# => [Thu, 19 Jun 2014]
|
115
|
+
```
|
116
|
+
|
117
|
+
Note that you can mix types on a single property.
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
my_thing.date << DateTime.now
|
121
|
+
my_thing.date << "circa 2014"
|
122
|
+
my_thing.date
|
123
|
+
# => [Thu, 19 Jun 2014, Thu, 19 Jun 2014 11:39:21 -0700, "circa 2014"]
|
124
|
+
|
125
|
+
puts my_thing.dump :ntriples
|
126
|
+
# _:g70072864570340 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Thing> .
|
127
|
+
# _:g70072864570340 <http://purl.org/dc/terms/date> "2014-06-19Z"^^<http://www.w3.org/2001/XMLSchema#date> .
|
128
|
+
# _:g70072864570340 <http://purl.org/dc/terms/date> "2014-06-19T11:39:21-07:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
|
129
|
+
# _:g70072864570340 <http://purl.org/dc/terms/date> "circa 2014" .
|
130
|
+
```
|
131
|
+
|
132
|
+
Repositories and Persistence
|
133
|
+
-----------------------------
|
134
|
+
|
135
|
+
Contributing
|
136
|
+
-------------
|
137
|
+
|
138
|
+
Please observe the following guidelines:
|
139
|
+
|
140
|
+
- Do your work in a feature branch based on ```master``` and rebase before submitting a pull request.
|
141
|
+
- Write tests for your contributions.
|
142
|
+
- Document every method you add using YARD annotations. (_Note: Annotations are sparse in the existing codebase, help us fix that!_)
|
143
|
+
- Organize your commits into logical units.
|
144
|
+
- Don't leave trailing whitespace (i.e. run ```git diff --check``` before committing).
|
145
|
+
- Use [well formed](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) commit messages.
|
146
|
+
|
147
|
+
By contributing to ActiveTriples, you agree to dedicate all copyright interest over submitted work to the public domain (see the included ```WAIVER``` and ```LICENSE``` files). For substantial contributions, you may be asked to submit a formal disclaimer of your (and/or your employer's) copyright interest in the software.
|
148
|
+
|
149
|
+
License
|
150
|
+
--------
|
151
|
+
|
152
|
+
This is free and unencumbered public domain software. For more information, see http://unlicense.org/ or the accompanying ```LICENSE``` file.
|
data/WAIVER
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
I dedicate any and all copyright interest in this software to the
|
2
|
+
public domain. I make this dedication for the benefit of the public at
|
3
|
+
large and to the detriment of my heirs and successors. I intend this
|
4
|
+
dedication to be an overt act of relinquishment in perpetuity of all
|
5
|
+
present and future rights to this software under copyright law.
|
data/active-triples.gemspec
CHANGED
@@ -22,8 +22,10 @@ Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
s.add_development_dependency('rdoc')
|
24
24
|
s.add_development_dependency('rspec')
|
25
|
+
s.add_development_dependency('guard-rspec')
|
25
26
|
s.add_development_dependency('webmock')
|
26
27
|
s.add_development_dependency('nokogiri')
|
28
|
+
s.add_development_dependency('pragmatic_context', '~> 0.1.2')
|
27
29
|
|
28
30
|
s.files = `git ls-files`.split("\n")
|
29
31
|
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
@@ -8,7 +8,7 @@ module ActiveTriples
|
|
8
8
|
#
|
9
9
|
# Define properties at the class level with:
|
10
10
|
#
|
11
|
-
# configure base_uri: "http://oregondigital.org/resource/", repository: :
|
11
|
+
# configure base_uri: "http://oregondigital.org/resource/", repository: :default
|
12
12
|
# Available properties are base_uri, rdf_label, type, and repository
|
13
13
|
module Configurable
|
14
14
|
extend Deprecation
|
@@ -25,6 +25,8 @@ module ActiveTriples
|
|
25
25
|
nil
|
26
26
|
end
|
27
27
|
|
28
|
+
##
|
29
|
+
# @deprecated use `configure type:` instead.
|
28
30
|
def rdf_type(value)
|
29
31
|
Deprecation.warn Configurable, "rdf_type is deprecated and will be removed in active-fedora 8.0.0. Use configure type: instead.", caller
|
30
32
|
configure type: value
|
@@ -34,8 +36,21 @@ module ActiveTriples
|
|
34
36
|
:parent
|
35
37
|
end
|
36
38
|
|
37
|
-
|
38
|
-
#
|
39
|
+
##
|
40
|
+
# API for configuring class properties on a Resource. This is an
|
41
|
+
# alternative to overriding the methods in this module.
|
42
|
+
#
|
43
|
+
# Can configure the following values:
|
44
|
+
# - base_uri (allows passing slugs to the Resource initializer
|
45
|
+
# in place of fully qualified URIs)
|
46
|
+
# - rdf_label (overrides default label predicates)
|
47
|
+
# - type (a default rdf:type to include when initializing a
|
48
|
+
# new Resource)
|
49
|
+
# - repository (the target persist location to for the Resource)
|
50
|
+
#
|
51
|
+
# configure base_uri: "http://oregondigital.org/resource/", repository: :default
|
52
|
+
#
|
53
|
+
# @param options [Hash]
|
39
54
|
def configure(options = {})
|
40
55
|
{
|
41
56
|
base_uri: options[:base_uri],
|
data/lib/active_triples/list.rb
CHANGED
@@ -110,6 +110,13 @@ module ActiveTriples
|
|
110
110
|
super
|
111
111
|
end
|
112
112
|
|
113
|
+
protected
|
114
|
+
# Clear out any old assertions in the repository about this node or statement
|
115
|
+
# thus preparing to receive the updated assertions.
|
116
|
+
def erase_old_resource
|
117
|
+
RDF::List.new(rdf_subject, repository).clear
|
118
|
+
end
|
119
|
+
|
113
120
|
private
|
114
121
|
def attributes_to_list(value, klass)
|
115
122
|
value.each do |entry|
|
@@ -16,6 +16,7 @@ module ActiveTriples
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def class_name
|
19
|
+
raise "class_name for #{term} is a #{@class_name.class}; must be a class" unless @class_name.kind_of? Class or @class_name.kind_of? String
|
19
20
|
if @class_name.kind_of?(String)
|
20
21
|
begin
|
21
22
|
new_class = @class_name.constantize
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'deprecation'
|
2
1
|
require 'active_support/core_ext/hash'
|
3
2
|
|
4
3
|
module ActiveTriples
|
@@ -11,15 +10,7 @@ module ActiveTriples
|
|
11
10
|
#
|
12
11
|
# property :title, predicate: RDF::DC.title, class_name: ResourceClass
|
13
12
|
#
|
14
|
-
# or with the 'old' style:
|
15
|
-
#
|
16
|
-
# map_predicates do |map|
|
17
|
-
# map.title(in: RDF::DC)
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# You can pass a block to either to set index behavior.
|
21
13
|
module Properties
|
22
|
-
extend Deprecation
|
23
14
|
attr_accessor :config
|
24
15
|
|
25
16
|
##
|
@@ -35,6 +26,11 @@ module ActiveTriples
|
|
35
26
|
register_property(name)
|
36
27
|
end
|
37
28
|
|
29
|
+
##
|
30
|
+
# Returns the properties registered to the class and their
|
31
|
+
# configurations.
|
32
|
+
#
|
33
|
+
# @return [ActiveSupport::HashWithIndifferentAccess{String => ActiveTriples::NodeConfig}]
|
38
34
|
def config
|
39
35
|
@config ||= if superclass.respond_to? :config
|
40
36
|
superclass.config.dup
|
@@ -46,11 +42,23 @@ module ActiveTriples
|
|
46
42
|
alias_method :properties, :config
|
47
43
|
alias_method :properties=, :config=
|
48
44
|
|
45
|
+
##
|
46
|
+
# Given a property name or a predicate, return the configuration
|
47
|
+
# for the matching property.
|
48
|
+
#
|
49
|
+
# @param term [#to_sym, RDF::Resource] a property name to predicate
|
50
|
+
#
|
51
|
+
# @return [ActiveTriples::NodeConfig]
|
49
52
|
def config_for_term_or_uri(term)
|
50
53
|
return config[term.to_sym] unless term.kind_of? RDF::Resource
|
51
54
|
config.each { |k, v| return v if v.predicate == term.to_uri }
|
52
55
|
end
|
53
56
|
|
57
|
+
##
|
58
|
+
# List the property names registered to the class.
|
59
|
+
#
|
60
|
+
# @return [Array<Symbol>] list of the symbolized names of registered
|
61
|
+
# properties
|
54
62
|
def fields
|
55
63
|
properties.keys.map(&:to_sym)
|
56
64
|
end
|
@@ -59,7 +67,9 @@ module ActiveTriples
|
|
59
67
|
|
60
68
|
##
|
61
69
|
# Private method for creating accessors for a given property.
|
62
|
-
#
|
70
|
+
#
|
71
|
+
# @param [#to_s] name Name of the accessor to be created,
|
72
|
+
# get/set_value is called on the resource using this.
|
63
73
|
def register_property(name)
|
64
74
|
parent = Proc.new{self}
|
65
75
|
# parent = Proc.new{resource} if self < ActiveFedora::Datastream
|
@@ -70,27 +80,5 @@ module ActiveTriples
|
|
70
80
|
instance_eval(&parent).get_values(name.to_sym)
|
71
81
|
end
|
72
82
|
end
|
73
|
-
|
74
|
-
public
|
75
|
-
# Mapper is for backwards compatibility with ActiveFedora::RDFDatastream
|
76
|
-
class Mapper
|
77
|
-
attr_accessor :parent
|
78
|
-
def initialize(parent)
|
79
|
-
@parent = parent
|
80
|
-
end
|
81
|
-
def method_missing(name, *args, &block)
|
82
|
-
properties = args.first || {}
|
83
|
-
vocab = properties.delete(:in)
|
84
|
-
to = properties.delete(:to) || name
|
85
|
-
predicate = vocab.send(to)
|
86
|
-
parent.property(name, properties.merge(predicate: predicate), &block)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
def map_predicates
|
90
|
-
Deprecation.warn Properties, "map_predicates is deprecated and will be removed in active-fedora 8.0.0. Use property :name, predicate: predicate instead.", caller
|
91
|
-
mapper = Mapper.new(self)
|
92
|
-
yield(mapper)
|
93
|
-
end
|
94
|
-
|
95
83
|
end
|
96
84
|
end
|
@@ -24,8 +24,7 @@ module ActiveTriples
|
|
24
24
|
extend Configurable
|
25
25
|
extend Properties
|
26
26
|
extend Deprecation
|
27
|
-
|
28
|
-
include ActiveModel::Conversion
|
27
|
+
include ActiveModel::Model
|
29
28
|
include ActiveModel::Serialization
|
30
29
|
include ActiveModel::Serializers::JSON
|
31
30
|
include NestedAttributes
|
@@ -37,13 +36,23 @@ module ActiveTriples
|
|
37
36
|
end
|
38
37
|
|
39
38
|
##
|
40
|
-
# Adapter for a consistent interface for creating a new
|
41
|
-
# Similar functionality should exist in all objects
|
39
|
+
# Adapter for a consistent interface for creating a new Resource
|
40
|
+
# from a URI. Similar functionality should exist in all objects
|
41
|
+
# which can become a Resource.
|
42
|
+
#
|
43
|
+
# @param uri [#to_uri, String]
|
44
|
+
# @param vals values to pass as arguments to ::new
|
45
|
+
#
|
46
|
+
# @return [ActiveTriples::Resource] a Resource with
|
42
47
|
def from_uri(uri,vals=nil)
|
43
48
|
new(uri, vals)
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
52
|
+
##
|
53
|
+
# Specifies whether the object is currently writable.
|
54
|
+
#
|
55
|
+
# @return [true, false]
|
47
56
|
def writable?
|
48
57
|
!frozen?
|
49
58
|
end
|
@@ -68,8 +77,14 @@ module ActiveTriples
|
|
68
77
|
self.get_values(:type) << self.class.type if self.class.type.kind_of?(RDF::URI) && type.empty?
|
69
78
|
end
|
70
79
|
|
80
|
+
##
|
81
|
+
# Returns the current object.
|
82
|
+
#
|
83
|
+
# @deprecated redundant, simply returns self.
|
84
|
+
#
|
85
|
+
# @return [self]
|
71
86
|
def graph
|
72
|
-
Deprecation.warn Resource, "graph is redundant & deprecated. It will be removed in
|
87
|
+
Deprecation.warn Resource, "graph is redundant & deprecated. It will be removed in ActiveTriples 0.2.0.", caller
|
73
88
|
self
|
74
89
|
end
|
75
90
|
|
@@ -112,28 +127,51 @@ module ActiveTriples
|
|
112
127
|
end
|
113
128
|
end
|
114
129
|
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Returns a serialized string representation of self.
|
133
|
+
# Extends the base implementation builds a JSON-LD context if the
|
134
|
+
# specified format is :jsonld and a context is provided by
|
135
|
+
# #jsonld_context
|
136
|
+
#
|
137
|
+
# @see RDF::Enumerable#dump
|
138
|
+
#
|
139
|
+
# @param args [Array<Object>]
|
140
|
+
# @return [String]
|
141
|
+
def dump(*args)
|
142
|
+
if args.first == :jsonld and respond_to?(:jsonld_context)
|
143
|
+
args << {} unless args.last.is_a?(Hash)
|
144
|
+
args.last[:context] ||= jsonld_context
|
145
|
+
end
|
146
|
+
super
|
147
|
+
end
|
115
148
|
|
149
|
+
##
|
150
|
+
# @return [RDF::URI, RDF::Node] a URI or Node which the resource's
|
151
|
+
# properties are about.
|
116
152
|
def rdf_subject
|
117
153
|
@rdf_subject ||= RDF::Node.new
|
118
154
|
end
|
119
|
-
|
155
|
+
alias_method :to_term, :rdf_subject
|
156
|
+
|
157
|
+
##
|
158
|
+
# A string identifier for the resource
|
120
159
|
def id
|
121
160
|
node? ? nil : rdf_subject.to_s
|
122
161
|
end
|
123
|
-
|
162
|
+
|
124
163
|
def node?
|
125
164
|
return true if rdf_subject.kind_of? RDF::Node
|
126
165
|
false
|
127
166
|
end
|
128
167
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
168
|
+
##
|
169
|
+
# @return [String, nil] the base URI the resource will use when
|
170
|
+
# setting its subject. `nil` if none is used.
|
133
171
|
def base_uri
|
134
172
|
self.class.base_uri
|
135
173
|
end
|
136
|
-
|
174
|
+
|
137
175
|
def type
|
138
176
|
self.get_values(:type).to_a.map{|x| x.rdf_subject}
|
139
177
|
end
|
@@ -144,8 +182,8 @@ module ActiveTriples
|
|
144
182
|
end
|
145
183
|
|
146
184
|
##
|
147
|
-
#
|
148
|
-
# configured label fields
|
185
|
+
# Looks for labels in various default fields, prioritizing
|
186
|
+
# configured label fields.
|
149
187
|
def rdf_label
|
150
188
|
labels = Array(self.class.rdf_label)
|
151
189
|
labels += default_labels
|
@@ -156,12 +194,26 @@ module ActiveTriples
|
|
156
194
|
node? ? [] : [rdf_subject.to_s]
|
157
195
|
end
|
158
196
|
|
197
|
+
##
|
198
|
+
# Lists fields registered as properties on the object.
|
199
|
+
#
|
200
|
+
# @return [Array<Symbol>] the list of registered properties.
|
159
201
|
def fields
|
160
202
|
properties.keys.map(&:to_sym).reject{|x| x == :type}
|
161
203
|
end
|
162
204
|
|
163
205
|
##
|
164
|
-
# Load data from URI
|
206
|
+
# Load data from the #rdf_subject URI. Retrieved data will be
|
207
|
+
# parsed into the Resource's graph from available RDF::Readers
|
208
|
+
# and available from property accessors if if predicates are
|
209
|
+
# registered.
|
210
|
+
#
|
211
|
+
# osu = ActiveTriples::Resource.new('http://dbpedia.org/resource/Oregon_State_University')
|
212
|
+
# osu.fetch
|
213
|
+
# osu.rdf_label.first
|
214
|
+
# # => "Oregon State University"
|
215
|
+
#
|
216
|
+
# @return [ActiveTriples::Resource] self
|
165
217
|
def fetch
|
166
218
|
load(rdf_subject)
|
167
219
|
self
|
@@ -169,16 +221,16 @@ module ActiveTriples
|
|
169
221
|
|
170
222
|
def persist!
|
171
223
|
raise "failed when trying to persist to non-existant repository or parent resource" unless repository
|
172
|
-
|
173
|
-
if node?
|
174
|
-
repository.statements.each do |statement|
|
175
|
-
repository.send(:delete_statement, statement) if statement.subject == rdf_subject
|
176
|
-
end
|
177
|
-
end
|
224
|
+
erase_old_resource
|
178
225
|
repository << self
|
179
226
|
@persisted = true
|
180
227
|
end
|
181
228
|
|
229
|
+
##
|
230
|
+
# Indicates if the resource is persisted.
|
231
|
+
#
|
232
|
+
# @see #persist
|
233
|
+
# @return [true, false]
|
182
234
|
def persisted?
|
183
235
|
@persisted ||= false
|
184
236
|
return (@persisted and parent.persisted?) if parent
|
@@ -187,6 +239,8 @@ module ActiveTriples
|
|
187
239
|
|
188
240
|
##
|
189
241
|
# Repopulates the graph from the repository or parent resource.
|
242
|
+
#
|
243
|
+
# @return [true, false]
|
190
244
|
def reload
|
191
245
|
@term_cache ||= {}
|
192
246
|
if self.class.repository == :parent
|
@@ -280,6 +334,10 @@ module ActiveTriples
|
|
280
334
|
end
|
281
335
|
alias_method :destroy!, :destroy
|
282
336
|
|
337
|
+
##
|
338
|
+
# Indicates if the Resource has been destroyed.
|
339
|
+
#
|
340
|
+
# @return [true, false]
|
283
341
|
def destroyed?
|
284
342
|
@destroyed ||= false
|
285
343
|
end
|
@@ -290,12 +348,16 @@ module ActiveTriples
|
|
290
348
|
end
|
291
349
|
end
|
292
350
|
|
351
|
+
##
|
352
|
+
# Indicates if the record is 'new' (has not yet been persisted).
|
353
|
+
#
|
354
|
+
# @return [true, false]
|
293
355
|
def new_record?
|
294
356
|
not persisted?
|
295
357
|
end
|
296
358
|
|
297
359
|
##
|
298
|
-
# @return [String] the string
|
360
|
+
# @return [String] the string representation of the resource
|
299
361
|
def solrize
|
300
362
|
node? ? rdf_label : rdf_subject.to_s
|
301
363
|
end
|
@@ -308,22 +370,57 @@ module ActiveTriples
|
|
308
370
|
@marked_for_destruction
|
309
371
|
end
|
310
372
|
|
311
|
-
|
373
|
+
protected
|
374
|
+
|
375
|
+
#Clear out any old assertions in the repository about this node or statement
|
376
|
+
# thus preparing to receive the updated assertions.
|
377
|
+
def erase_old_resource
|
378
|
+
if node?
|
379
|
+
repository.statements.each do |statement|
|
380
|
+
repository.send(:delete_statement, statement) if statement.subject == rdf_subject
|
381
|
+
end
|
382
|
+
else
|
383
|
+
repository.delete [rdf_subject, nil, nil]
|
384
|
+
end
|
385
|
+
end
|
312
386
|
|
387
|
+
private
|
388
|
+
|
389
|
+
##
|
390
|
+
# Returns the properties registered and their configurations.
|
391
|
+
#
|
392
|
+
# @return [ActiveSupport::HashWithIndifferentAccess{String => ActiveTriples::NodeConfig}]
|
313
393
|
def properties
|
314
394
|
self.singleton_class.properties
|
315
395
|
end
|
316
396
|
|
397
|
+
##
|
398
|
+
# List of RDF predicates registered as properties on the object.
|
399
|
+
#
|
400
|
+
# @return [Array<RDF::URI>]
|
317
401
|
def registered_predicates
|
318
402
|
properties.values.map { |config| config.predicate }
|
319
403
|
end
|
320
404
|
|
405
|
+
##
|
406
|
+
# List of RDF predicates used in the Resource's triples, but not
|
407
|
+
# mapped to any property or accessor methods.
|
408
|
+
#
|
409
|
+
# @return [Array<RDF::URI>]
|
321
410
|
def unregistered_predicates
|
322
411
|
preds = registered_predicates
|
323
412
|
preds << RDF.type
|
324
413
|
predicates.select { |p| !preds.include? p }
|
325
414
|
end
|
326
415
|
|
416
|
+
##
|
417
|
+
# Given a predicate which has been registered to a property,
|
418
|
+
# returns the name of the matching property.
|
419
|
+
#
|
420
|
+
# @param predicate [RDF::URI]
|
421
|
+
#
|
422
|
+
# @return [String, nil] the name of the property mapped to the
|
423
|
+
# predicate provided
|
327
424
|
def property_for_predicate(predicate)
|
328
425
|
properties.each do |property, values|
|
329
426
|
return property if values[:predicate] == predicate
|
@@ -342,6 +439,9 @@ module ActiveTriples
|
|
342
439
|
##
|
343
440
|
# Return the repository (or parent) that this resource should
|
344
441
|
# write to when persisting.
|
442
|
+
#
|
443
|
+
# @return [RDF::Repository, ActiveTriples::Resource] the target
|
444
|
+
# repository
|
345
445
|
def repository
|
346
446
|
@repository ||=
|
347
447
|
if self.class.repository == :parent
|
@@ -352,10 +452,22 @@ module ActiveTriples
|
|
352
452
|
end
|
353
453
|
|
354
454
|
##
|
355
|
-
# Takes a URI or String and aggressively tries to
|
356
|
-
#
|
455
|
+
# Takes a URI or String and aggressively tries to convert it into
|
456
|
+
# an RDF term. If a String is given, first tries to interpret it
|
457
|
+
# as a valid URI, then tries to append it to base_uri. Finally,
|
458
|
+
# raises an error if no valid term can be built.
|
459
|
+
#
|
460
|
+
# The argument must be an RDF::Node, an object that responds to
|
461
|
+
# #to_uri, a String that represents a valid URI, or a String that
|
462
|
+
# appends to the Resource's base_uri to create a valid URI.
|
463
|
+
#
|
464
|
+
# @TODO: URI.scheme_list is naive and incomplete. Find a better
|
465
|
+
# way to check for an existing scheme.
|
357
466
|
#
|
358
|
-
# @
|
467
|
+
# @param uri_or_str [RDF::Resource, String]
|
468
|
+
#
|
469
|
+
# @return [RDF::Resource] A term
|
470
|
+
# @raise [RuntimeError] no valid RDF term could be built
|
359
471
|
def get_uri(uri_or_str)
|
360
472
|
return uri_or_str.to_uri if uri_or_str.respond_to? :to_uri
|
361
473
|
return uri_or_str if uri_or_str.kind_of? RDF::Node
|