module Ldp class Resource attr_reader :client, :subject ## # Create a new LDP resource with a blank RDF graph def self.create client, subject self.new client, subject, RDF::Graph.new end def initialize client, subject, graph_or_response = nil @client = client @subject = subject @graph = graph_or_response if graph_or_response.is_a? RDF::Graph @get = graph_or_response if graph_or_response.is_a? Ldp::Response end ## # Get the graph subject as a URI def subject_uri @subject_uri ||= RDF::URI.new subject end ## # Reload the LDP resource def reload Ldp::Resource.new client, subject end ## # Is the resource new, or does it exist in the LDP server? def new? get end ## # Have we retrieved the content already? def retrieved_content? @get end ## # Get the resource def get @get ||= client.get(subject).tap do |result| raise NotFound if result.status == 404 end end ## # Delete the resource def delete client.delete subject do |req| req.headers['If-Match'] = get.etag if retrieved_content? end end ## # Create a new resource at the URI def create raise "" if new? resp = client.post '', graph.dump(:ttl) do |req| req.headers['Slug'] = subject end @subject = resp.headers['Location'] @subject_uri = nil end ## # Update the stored graph def update new_graph = nil new_graph ||= graph client.put subject, new_graph.dump(:ttl) do |req| req.headers['If-Match'] = get.etag if retrieved_content? end end def graph @graph ||= begin original_graph = get.graph inlinedResources = get.graph.query(:predicate => Ldp.inlinedResource).map { |x| x.object } unless inlinedResources.empty? new_graph = RDF::Graph.new original_graph.each_statement do |s| unless inlinedResources.include? s.subject new_graph << s end end new_graph else original_graph end end end def self.check_for_differences_and_reload_resource old_object new_object = old_object.reload bijection = new_object.graph.bijection_to(old_object.graph) diff = RDF::Graph.new old_object.graph.each do |statement| if statement.has_blank_nodes? subject = bijection.fetch(statement.subject, false) if statement.subject.node? object = bijection.fetch(statement.object, false) if statement.object.node? bijection_statement = RDF::Statement.new :subject => subject || statemnet.subject, :predicate => statement.predicate, :object => object || statement.object diff << statement if subject === false or object === false or new_object.graph.has_statement?(bijection_statement) elsif !new_object.graph.has_statement? statement diff << statement end end diff end ## # Reload this resource as an LDP container def as_container Ldp::Container.new client, subject, @graph || @get end end end