module Ldp class Resource require 'ldp/resource/binary_source' require 'ldp/resource/rdf_source' attr_reader :client, :subject attr_accessor :content 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-Match'] = get.etag 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 "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| 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-Match'] = get.etag 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.wrap(client, response) if response.etag.nil? || response.last_modified.nil? response = Response.wrap(client, client.head(subject)) end @get.etag = response.etag @get.last_modified = response.last_modified end end end