ldp 0.0.3 → 0.0.4
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/Gemfile +1 -1
- data/bin/ldp +127 -0
- data/ldp.gemspec +2 -0
- data/lib/ldp/client/methods.rb +89 -12
- data/lib/ldp/client.rb +18 -21
- data/lib/ldp/container/basic.rb +23 -0
- data/lib/ldp/container/direct.rb +16 -0
- data/lib/ldp/container/indirect.rb +11 -0
- data/lib/ldp/container.rb +23 -9
- data/lib/ldp/orm.rb +49 -20
- data/lib/ldp/resource/binary_source.rb +23 -0
- data/lib/ldp/resource/rdf_source.rb +77 -0
- data/lib/ldp/resource.rb +39 -70
- data/lib/ldp/response/paging.rb +57 -0
- data/lib/ldp/response.rb +59 -95
- data/lib/ldp/uri.rb +37 -5
- data/lib/ldp/version.rb +1 -1
- data/lib/ldp.rb +11 -1
- data/spec/lib/ldp/client_spec.rb +71 -30
- data/spec/lib/ldp/orm/orm_spec.rb +19 -9
- data/spec/lib/ldp/resource/rdf_source_spec.rb +52 -0
- data/spec/lib/ldp/resource_spec.rb +30 -0
- data/spec/lib/ldp/response_spec.rb +2 -8
- data/spec/spec_helper.rb +2 -1
- metadata +41 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b564742703ded9a1ea57b61c4d35095152470b0d
|
4
|
+
data.tar.gz: 92c8f28addad7872849b36acfdeac29bb2ebf280
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c47ff6ed7653614374db095e93defbfa21138b072862de841464c06b8c0494707ee5d39610d06bdb640d8b4214590aae81de5f264ccbb61349afe2ffffaeb594
|
7
|
+
data.tar.gz: 2ad220371ea1d981c8ab3d29aca7f615e0bf573d56da2c56de84ba0d15a23a1173638eba23e97ef38d09eab26a7cef398037113453b017a8ffe5b01c138b25aa
|
data/Gemfile
CHANGED
data/bin/ldp
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path('../../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'ldp'
|
7
|
+
require 'slop'
|
8
|
+
|
9
|
+
HttpLogger.logger = Logger.new(STDERR)
|
10
|
+
HttpLogger.log_headers = true
|
11
|
+
|
12
|
+
def with_error_handling
|
13
|
+
yield
|
14
|
+
rescue Ldp::NotFound
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
do_help = lambda do |x|
|
19
|
+
|
20
|
+
x.command 'help' do
|
21
|
+
run do |opts, args|
|
22
|
+
puts opts.help
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
Slop.parse do
|
29
|
+
banner "Usage: ldp [command] --host [HOST] [options]"
|
30
|
+
|
31
|
+
on '-v', 'Print the version' do
|
32
|
+
puts "ldp #{Ldp::VERSION}"
|
33
|
+
end
|
34
|
+
|
35
|
+
on :host=, "Host"
|
36
|
+
|
37
|
+
do_help.call(self)
|
38
|
+
|
39
|
+
command 'get' do
|
40
|
+
banner "Usage: ldp get --host [HOST] [PATH]"
|
41
|
+
|
42
|
+
on :host=, "Host"
|
43
|
+
|
44
|
+
do_help.call(self)
|
45
|
+
|
46
|
+
run do |opts, (path)|
|
47
|
+
with_error_handling do
|
48
|
+
host = opts[:host] || ENV['LDP_HOST']
|
49
|
+
puts Ldp::Client.new(url: host).find_or_initialize(path).get.body
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
command 'delete' do
|
55
|
+
banner "Usage: ldp delete --host [HOST] [PATH]"
|
56
|
+
|
57
|
+
on :host=, "Host"
|
58
|
+
do_help.call(self)
|
59
|
+
|
60
|
+
run do |opts, (path)|
|
61
|
+
with_error_handling do
|
62
|
+
host = opts[:host] || ENV['LDP_HOST']
|
63
|
+
Ldp::Client.new(url: host).delete path
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
command 'create' do
|
69
|
+
banner "Usage: ldp create --host [HOST] [PATH] [SOURCE]"
|
70
|
+
|
71
|
+
on :host=, "Host"
|
72
|
+
do_help.call(self)
|
73
|
+
|
74
|
+
run do |opts, (path, file)|
|
75
|
+
with_error_handling do
|
76
|
+
host = opts[:host] || ENV['LDP_HOST']
|
77
|
+
if file.nil?
|
78
|
+
Ldp::Client.new(url: host).post path
|
79
|
+
elsif file == "-"
|
80
|
+
Ldp::Client.new(url: host).post path, $stdin
|
81
|
+
else
|
82
|
+
Ldp::Client.new(url: host).post path, File.read(file)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
command 'replace' do
|
89
|
+
banner "Usage: ldp replace --host [HOST] [PATH] [SOURCE]"
|
90
|
+
|
91
|
+
on :host=, "Host"
|
92
|
+
do_help.call(self)
|
93
|
+
|
94
|
+
run do |opts, (path,file)|
|
95
|
+
with_error_handling do
|
96
|
+
host = opts[:host] || ENV['LDP_HOST']
|
97
|
+
if file.nil?
|
98
|
+
Ldp::Client.new(url: host).put path
|
99
|
+
elsif file == "-"
|
100
|
+
Ldp::Client.new(url: host).put path, $stdin
|
101
|
+
else
|
102
|
+
Ldp::Client.new(url: host).put path, File.read(file)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
command 'patch' do
|
109
|
+
banner "Usage: ldp patch --host [HOST] [PATH] [SOURCE]"
|
110
|
+
|
111
|
+
on :host=, "Host"
|
112
|
+
do_help.call(self)
|
113
|
+
|
114
|
+
run do |opts, (path,file)|
|
115
|
+
with_error_handling do
|
116
|
+
host = opts[:host] || ENV['LDP_HOST']
|
117
|
+
if file.nil?
|
118
|
+
Ldp::Client.new(url: host).patch path
|
119
|
+
elsif file == "-"
|
120
|
+
Ldp::Client.new(url: host).patch path, $stdin.read
|
121
|
+
else
|
122
|
+
Ldp::Client.new(url: host).patch path, File.read(file)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/ldp.gemspec
CHANGED
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "faraday"
|
22
22
|
spec.add_dependency "linkeddata", ">= 1.1"
|
23
|
+
spec.add_dependency "http_logger"
|
24
|
+
spec.add_dependency "slop"
|
23
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
26
|
spec.add_development_dependency "rake"
|
25
27
|
spec.add_development_dependency "rspec"
|
data/lib/ldp/client/methods.rb
CHANGED
@@ -1,12 +1,46 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
##
|
4
|
+
# HTTP client methods for making requests to an LDP resource and getting a response back.
|
1
5
|
module Ldp::Client::Methods
|
2
|
-
|
3
|
-
|
6
|
+
|
7
|
+
attr_reader :http
|
8
|
+
def initialize_http_client *http_client
|
9
|
+
if http_client.length == 1 and http_client.first.is_a? Faraday::Connection
|
10
|
+
@http = http_client.first
|
11
|
+
else
|
12
|
+
@http = Faraday.new *http_client
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def head url
|
17
|
+
logger.debug "LDP: HEAD [#{url}]"
|
18
|
+
resp = http.head do |req|
|
19
|
+
req.url munge_to_relative_url(url)
|
20
|
+
|
21
|
+
yield req if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
check_for_errors(resp)
|
4
25
|
end
|
5
26
|
|
6
27
|
# Get a LDP Resource by URI
|
7
|
-
def get url
|
28
|
+
def get url, options = {}
|
29
|
+
logger.debug "LDP: GET [#{url}]"
|
8
30
|
resp = http.get do |req|
|
9
|
-
req.url url
|
31
|
+
req.url munge_to_relative_url(url)
|
32
|
+
|
33
|
+
if options[:minimal]
|
34
|
+
req.headers["Prefer"] = "return=minimal"
|
35
|
+
else
|
36
|
+
includes = Array(options[:include]).map { |x| Ldp.send("prefer_#{x}") if Ldp.respond_to? "prefer_#{x}" }
|
37
|
+
omits = Array(options[:omit]).map { |x| Ldp.send("prefer_#{x}") if Ldp.respond_to? "prefer_#{x}" }
|
38
|
+
req.headers["Prefer"] = ["return=representation",
|
39
|
+
("include=\"#{includes.join(" ")}\"" unless includes.empty?),
|
40
|
+
("omit=\"#{omits.join(" ")}\"" unless omits.empty?)
|
41
|
+
].compact.join("; ")
|
42
|
+
end
|
43
|
+
|
10
44
|
yield req if block_given?
|
11
45
|
end
|
12
46
|
|
@@ -15,41 +49,84 @@ module Ldp::Client::Methods
|
|
15
49
|
else
|
16
50
|
resp
|
17
51
|
end
|
52
|
+
|
53
|
+
check_for_errors(resp)
|
18
54
|
end
|
19
55
|
|
20
56
|
# Delete a LDP Resource by URI
|
21
57
|
def delete url
|
22
|
-
|
23
|
-
|
58
|
+
logger.debug "LDP: DELETE [#{url}]"
|
59
|
+
resp = http.delete do |req|
|
60
|
+
req.url munge_to_relative_url(url)
|
24
61
|
yield req if block_given?
|
25
62
|
end
|
63
|
+
|
64
|
+
check_for_errors(resp)
|
26
65
|
end
|
27
66
|
|
28
67
|
# Post TTL to an LDP Resource
|
29
68
|
def post url, body = nil, headers = {}
|
30
|
-
logger.debug "POST [#{url}]
|
31
|
-
http.post do |req|
|
32
|
-
req.url url
|
69
|
+
logger.debug "LDP: POST [#{url}]"
|
70
|
+
resp = http.post do |req|
|
71
|
+
req.url munge_to_relative_url(url)
|
33
72
|
req.headers = default_headers.merge headers
|
34
73
|
req.body = body
|
35
74
|
yield req if block_given?
|
36
75
|
end
|
76
|
+
check_for_errors(resp)
|
37
77
|
end
|
38
78
|
|
39
79
|
# Update an LDP resource with TTL by URI
|
40
80
|
def put url, body, headers = {}
|
41
|
-
logger.debug "PUT [#{url}]
|
42
|
-
http.put do |req|
|
43
|
-
req.url url
|
81
|
+
logger.debug "LDP: PUT [#{url}]"
|
82
|
+
resp = http.put do |req|
|
83
|
+
req.url munge_to_relative_url(url)
|
44
84
|
req.headers = default_headers.merge headers
|
45
85
|
req.body = body
|
46
86
|
yield req if block_given?
|
47
87
|
end
|
88
|
+
check_for_errors(resp)
|
48
89
|
end
|
49
90
|
|
91
|
+
# Update an LDP resource with TTL by URI
|
92
|
+
def patch url, body, headers = {}
|
93
|
+
logger.debug "LDP: PATCH [#{url}]"
|
94
|
+
resp = http.patch do |req|
|
95
|
+
req.url munge_to_relative_url(url)
|
96
|
+
req.headers = default_patch_headers.merge headers
|
97
|
+
req.body = body
|
98
|
+
yield req if block_given?
|
99
|
+
end
|
100
|
+
check_for_errors(resp)
|
101
|
+
end
|
50
102
|
private
|
103
|
+
|
104
|
+
def check_for_errors resp
|
105
|
+
resp.tap do |resp|
|
106
|
+
unless resp.success?
|
107
|
+
raise Ldp::NotFound.new(resp.body) if resp.status == 404
|
108
|
+
raise Ldp::HttpError.new("STATUS: #{resp.status} #{resp.body[0, 1000]}...")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
51
112
|
|
52
113
|
def default_headers
|
53
114
|
{"Content-Type"=>"text/turtle"}
|
54
115
|
end
|
116
|
+
|
117
|
+
def default_patch_headers
|
118
|
+
{"Content-Type"=>"application/sparql-update"}
|
119
|
+
end
|
120
|
+
##
|
121
|
+
# Some valid query paths can be mistaken for absolute URIs
|
122
|
+
# with an alternative scheme. If the scheme isn't HTTP(S), assume
|
123
|
+
# they meant a relative URI instead.
|
124
|
+
def munge_to_relative_url url
|
125
|
+
purl = URI.parse(url)
|
126
|
+
if purl.absolute? and !((purl.scheme rescue nil) =~ /^http/)
|
127
|
+
"./" + url
|
128
|
+
else
|
129
|
+
url
|
130
|
+
end
|
131
|
+
end
|
55
132
|
end
|
data/lib/ldp/client.rb
CHANGED
@@ -1,36 +1,33 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
##
|
2
|
+
# LDP client for presenting an ORM on top of an LDP resource
|
3
3
|
module Ldp
|
4
4
|
class Client
|
5
5
|
|
6
6
|
require 'ldp/client/methods'
|
7
|
-
|
8
7
|
include Ldp::Client::Methods
|
9
|
-
|
10
|
-
attr_reader :http
|
11
8
|
|
12
9
|
def initialize *http_client
|
13
|
-
|
14
|
-
@http = http_client.first
|
15
|
-
else
|
16
|
-
@http = Faraday.new *http_client
|
17
|
-
end
|
10
|
+
initialize_http_client *http_client
|
18
11
|
end
|
19
12
|
|
20
13
|
# Find or initialize a new LDP resource by URI
|
21
|
-
def find_or_initialize subject
|
22
|
-
data = get(subject)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
14
|
+
def find_or_initialize subject, options = {}
|
15
|
+
data = get(subject, options = {})
|
16
|
+
|
17
|
+
case
|
18
|
+
when !data.is_a?(Ldp::Response)
|
19
|
+
Resource::BinarySource.new self, subject, data
|
20
|
+
when data.container?
|
21
|
+
Ldp::Container.new_from_response self, subject, data
|
22
|
+
when data.resource?
|
23
|
+
Resource::RdfSource.new self, subject, data
|
24
|
+
else
|
25
|
+
Resource::BinarySource.new self, subject, data
|
32
26
|
end
|
33
27
|
end
|
34
28
|
|
29
|
+
def logger
|
30
|
+
Ldp.logger
|
31
|
+
end
|
35
32
|
end
|
36
33
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ldp
|
2
|
+
class Container::Basic < Container
|
3
|
+
def members
|
4
|
+
return enum_for(:members) unless block_given?
|
5
|
+
contains.each { |k, x| yield x }
|
6
|
+
end
|
7
|
+
|
8
|
+
def contains
|
9
|
+
@contains ||= Hash[get.graph.query(predicate: Ldp.contains).map do |x|
|
10
|
+
[x.object, Ldp::Resource::RdfSource.new(client, x.object, contained_graph(x.object))]
|
11
|
+
end]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def contained_graph subject
|
16
|
+
g = RDF::Graph.new
|
17
|
+
get.graph.query(subject: subject) do |stmt|
|
18
|
+
g << stmt
|
19
|
+
end
|
20
|
+
g
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ldp
|
2
|
+
class Container::Direct < Container::Basic
|
3
|
+
def members
|
4
|
+
return enum_for(:members) unless block_given?
|
5
|
+
|
6
|
+
get.graph.query(subject: subject, predicate: member_relation).map do |x|
|
7
|
+
yield contains[x.object] || Ldp::Resource::RdfSource.new(client, x.object)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def member_relation
|
12
|
+
graph.first_object(predicate: Ldp.hasMemberRelation) || Ldp.member
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Ldp
|
2
|
+
class Container::Indirect < Container::Direct
|
3
|
+
def members
|
4
|
+
return enum_for(:members) unless block_given?
|
5
|
+
|
6
|
+
get.graph.query(predicate: member_relation, object: subject).map do |x|
|
7
|
+
yield contains[x.object] || Ldp::Resource::RdfSource.new(client, x.object)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/ldp/container.rb
CHANGED
@@ -1,7 +1,22 @@
|
|
1
1
|
module Ldp
|
2
|
-
class Container < Resource
|
2
|
+
class Container < Resource::RdfSource
|
3
|
+
require 'ldp/container/basic'
|
4
|
+
require 'ldp/container/direct'
|
5
|
+
require 'ldp/container/indirect'
|
6
|
+
|
7
|
+
def self.new_from_response client, subject, data
|
8
|
+
case
|
9
|
+
when data.types.include?(Ldp.indirect_container)
|
10
|
+
Ldp::Container::Indirect.new client, subject, data
|
11
|
+
when data.types.include?(Ldp.direct_container)
|
12
|
+
Ldp::Container::Direct.new client, subject, data
|
13
|
+
else
|
14
|
+
Ldp::Container::Basic.new client, subject, data
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
3
18
|
##
|
4
|
-
# Add a resource to the LDP container
|
19
|
+
# Add a new resource to the LDP container
|
5
20
|
def add *args
|
6
21
|
# slug, graph
|
7
22
|
# graph
|
@@ -11,21 +26,20 @@ module Ldp
|
|
11
26
|
when (args.length > 2 || args.length == 0)
|
12
27
|
|
13
28
|
when (args.length == 2)
|
14
|
-
slug,
|
29
|
+
slug, graph_or_content = args
|
15
30
|
when (args.first.is_a? RDF::Graph)
|
16
31
|
slug = nil
|
17
|
-
|
32
|
+
graph_or_content = args.first
|
18
33
|
else
|
19
34
|
slug = args.first
|
20
|
-
|
35
|
+
graph_or_content = RDF::Graph.new
|
21
36
|
end
|
22
37
|
|
23
|
-
resp = client.post subject,
|
38
|
+
resp = client.post subject, (graph_or_content.is_a?(RDF::Graph) ? graph_or_content.dump(:ttl) : graph_or_content) do |req|
|
24
39
|
req.headers['Slug'] = slug
|
25
40
|
end
|
26
41
|
|
27
|
-
|
28
|
-
return client.find_or_initialize subject
|
42
|
+
client.find_or_initialize resp.headers['Location']
|
29
43
|
end
|
30
44
|
end
|
31
|
-
end
|
45
|
+
end
|
data/lib/ldp/orm.rb
CHANGED
@@ -7,39 +7,67 @@ module Ldp
|
|
7
7
|
def initialize resource
|
8
8
|
@resource = resource
|
9
9
|
end
|
10
|
+
|
11
|
+
def subject_uri
|
12
|
+
resource.subject_uri
|
13
|
+
end
|
14
|
+
|
15
|
+
def new?
|
16
|
+
resource.new?
|
17
|
+
end
|
18
|
+
|
19
|
+
def persisted?
|
20
|
+
!new?
|
21
|
+
end
|
10
22
|
|
11
23
|
def graph
|
12
|
-
|
24
|
+
Ldp.instrument 'graph.orm.ldp', subject: subject_uri do
|
25
|
+
resource.graph
|
26
|
+
end
|
13
27
|
end
|
14
28
|
|
15
29
|
def value predicate
|
16
|
-
graph.query(:subject =>
|
30
|
+
graph.query(:subject => subject_uri, :predicate => predicate).map do |stmt|
|
17
31
|
stmt.object
|
18
32
|
end
|
19
33
|
end
|
20
34
|
|
21
35
|
def query *args, &block
|
22
|
-
|
36
|
+
Ldp.instrument 'query.orm.ldp', subject: subject_uri do
|
37
|
+
graph.query *args, &block
|
38
|
+
end
|
23
39
|
end
|
24
40
|
|
25
41
|
def reload
|
26
|
-
Ldp
|
42
|
+
Ldp.instrument 'reload.orm.ldp', subject: subject_uri do
|
43
|
+
Ldp::Orm.new resource.reload
|
44
|
+
end
|
27
45
|
end
|
28
46
|
|
29
47
|
def create
|
30
|
-
|
48
|
+
Ldp.instrument 'create.orm.ldp', subject: subject_uri do
|
49
|
+
# resource.create returns a reloaded resource which causes any default URIs (e.g. "<>")
|
50
|
+
# in the graph to be transformed to routable URIs
|
51
|
+
Ldp::Orm.new resource.create
|
52
|
+
end
|
31
53
|
end
|
32
54
|
|
33
55
|
def save
|
34
|
-
|
56
|
+
Ldp.instrument 'save.orm.ldp', subject: subject_uri do
|
57
|
+
@last_response = resource.save
|
35
58
|
|
36
|
-
|
59
|
+
diff = resource.check_for_differences_and_reload
|
37
60
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
61
|
+
if diff.any?
|
62
|
+
diff
|
63
|
+
else
|
64
|
+
@last_response.success?
|
65
|
+
end
|
42
66
|
end
|
67
|
+
rescue Ldp::HttpError => e
|
68
|
+
@last_response = e
|
69
|
+
logger.debug e
|
70
|
+
false
|
43
71
|
end
|
44
72
|
|
45
73
|
def save!
|
@@ -48,14 +76,16 @@ module Ldp
|
|
48
76
|
if result.is_a? RDF::Graph
|
49
77
|
raise GraphDifferenceException.new "", result
|
50
78
|
elsif !result
|
51
|
-
raise SaveException.new
|
79
|
+
raise SaveException.new @last_response
|
52
80
|
end
|
53
81
|
|
54
82
|
result
|
55
83
|
end
|
56
84
|
|
57
85
|
def delete
|
58
|
-
|
86
|
+
Ldp.instrument 'delete.orm.ldp', subject: subject_uri do
|
87
|
+
resource.delete
|
88
|
+
end
|
59
89
|
end
|
60
90
|
|
61
91
|
def method_missing meth, *args, &block
|
@@ -66,6 +96,11 @@ module Ldp
|
|
66
96
|
super
|
67
97
|
end
|
68
98
|
|
99
|
+
private
|
100
|
+
|
101
|
+
def logger
|
102
|
+
Ldp.logger
|
103
|
+
end
|
69
104
|
end
|
70
105
|
|
71
106
|
class GraphDifferenceException < Exception
|
@@ -76,12 +111,6 @@ module Ldp
|
|
76
111
|
end
|
77
112
|
end
|
78
113
|
|
79
|
-
class SaveException <
|
80
|
-
attr_reader :response
|
81
|
-
def initialize message, response
|
82
|
-
super(message)
|
83
|
-
@response = response
|
84
|
-
end
|
114
|
+
class SaveException < RuntimeError
|
85
115
|
end
|
86
116
|
end
|
87
|
-
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ldp
|
2
|
+
class Resource::BinarySource < Ldp::Resource
|
3
|
+
attr_accessor :content
|
4
|
+
|
5
|
+
def initialize client, subject, content_or_response = nil
|
6
|
+
super client, subject, content_or_response
|
7
|
+
|
8
|
+
case content_or_response
|
9
|
+
when Faraday::Response
|
10
|
+
else
|
11
|
+
@content = content_or_response
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def content
|
16
|
+
@content ||= get.body
|
17
|
+
end
|
18
|
+
|
19
|
+
def described_by
|
20
|
+
client.find_or_initialize Array(Ldp::Response.links(self)["describedby"]).first
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Ldp
|
2
|
+
class Resource::RdfSource < Ldp::Resource
|
3
|
+
|
4
|
+
def initialize client, subject, graph_or_response = nil
|
5
|
+
super client, subject, graph_or_response
|
6
|
+
|
7
|
+
case graph_or_response
|
8
|
+
when RDF::Graph
|
9
|
+
@graph = graph_or_response
|
10
|
+
when Ldp::Response
|
11
|
+
when NilClass
|
12
|
+
#nop
|
13
|
+
else
|
14
|
+
raise ArgumentError, "Third argument to #{self.class}.new should be a RDF::Graph or a Ldp::Response. You provided #{graph_or_response.class}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
super do |req|
|
20
|
+
req.headers = { "Content-Type" => "text/turtle" }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def content
|
25
|
+
graph.dump(:ttl) if graph
|
26
|
+
end
|
27
|
+
|
28
|
+
def graph
|
29
|
+
@graph ||= RDF::Graph.new if new?
|
30
|
+
@graph ||= begin
|
31
|
+
original_graph = get.graph
|
32
|
+
|
33
|
+
inlinedResources = get.graph.query(:predicate => Ldp.contains).map { |x| x.object }
|
34
|
+
|
35
|
+
# we want to scope this graph to just statements about this model, not contained relations
|
36
|
+
unless inlinedResources.empty?
|
37
|
+
new_graph = RDF::Graph.new
|
38
|
+
|
39
|
+
original_graph.each_statement do |s|
|
40
|
+
unless inlinedResources.include? s.subject
|
41
|
+
new_graph << s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
new_graph
|
46
|
+
else
|
47
|
+
original_graph
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_for_differences_and_reload
|
53
|
+
self.class.check_for_differences_and_reload_resource self
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.check_for_differences_and_reload_resource old_object
|
57
|
+
new_object = old_object.reload
|
58
|
+
|
59
|
+
bijection = new_object.graph.bijection_to(old_object.graph)
|
60
|
+
diff = RDF::Graph.new
|
61
|
+
|
62
|
+
old_object.graph.each do |statement|
|
63
|
+
if statement.has_blank_nodes?
|
64
|
+
subject = bijection.fetch(statement.subject, false) if statement.subject.node?
|
65
|
+
object = bijection.fetch(statement.object, false) if statement.object.node?
|
66
|
+
bijection_statement = RDF::Statement.new :subject => subject || statemnet.subject, :predicate => statement.predicate, :object => object || statement.object
|
67
|
+
|
68
|
+
diff << statement if subject === false or object === false or new_object.graph.has_statement?(bijection_statement)
|
69
|
+
elsif !new_object.graph.has_statement? statement
|
70
|
+
diff << statement
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
diff
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|