/
resource.rb
134 lines (112 loc) · 3.18 KB
/
resource.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
module Ldp
class Resource
require 'ldp/resource/binary_source'
require 'ldp/resource/rdf_source'
attr_reader :client, :subject
attr_accessor :content
def self.for(client, subject, response = nil)
case
when response.container?
Ldp::Container.for client, subject, response
when response.rdf_source?
Resource::RdfSource.new client, subject, response
else
Resource::BinarySource.new client, subject, response
end
end
def initialize client, subject, response = nil, base_path = ''
@client = client
@subject = subject
@get = response if response.is_a? Faraday::Response and current? response
@base_path = base_path
end
##
# Get the graph subject as a URI
def subject_uri
@subject_uri ||= RDF::URI.new subject
end
##
# Reload the LDP resource
def reload
self.class.new client, subject, @get
end
##
# Is the resource new, or does it exist in the LDP server?
def new?
subject.nil? || head == None
end
##
# Have we retrieved the content already?
def retrieved_content?
@get
end
##
# Get the resource
def get
@get ||= client.get(subject)
end
def head
@head ||= begin
@get || client.head(subject)
rescue Ldp::NotFound
None
end
end
##
# Delete the resource
def delete
client.delete subject do |req|
req.headers['If-Unmodified-Since'] = get.last_modified if retrieved_content?
end
end
def save
new? ? create : update
end
##
# Create a new resource at the URI
# @return [RdfSource] the new representation
def create &block
raise Ldp::Error, "Can't call create on an existing resource" unless new?
verb = subject.nil? ? :post : :put
resp = client.send(verb, (subject || @base_path), content) do |req|
req.headers["Link"] = "<#{interaction_model}>;rel=\"type\"" if interaction_model
yield req if block_given?
end
@subject = resp.headers['Location']
@subject_uri = nil
reload
end
##
# Update the stored graph
def update new_content = nil
new_content ||= content
resp = client.put subject, new_content do |req|
req.headers['If-Unmodified-Since'] = get.last_modified if retrieved_content?
yield req if block_given?
end
update_cached_get(resp) if retrieved_content?
resp
end
def current? response = nil
response ||= @get
return true if new? and subject.nil?
new_response = client.head(subject)
response.headers['ETag'] &&
response.headers['Last-Modified'] &&
new_response.headers['ETag'] == response.headers['ETag'] &&
new_response.headers['Last-Modified'] == response.headers['Last-Modified']
end
def update_cached_get(response)
response = Response.new(response)
if response.etag.nil? || response.last_modified.nil?
response = client.head(subject)
end
@get.etag = response.etag
@get.last_modified = response.last_modified
end
protected
def interaction_model
nil
end
end
end