module RDF ## # An RDF graph. class Graph < Resource include RDF::Enumerable include RDF::Mutable include RDF::Queryable ## # @return [Resource] attr_accessor :context ## # @return [Array<Statement>] attr_accessor :data ## # Creates a new `Graph` instance populated by the RDF data returned by # dereferencing the given context URL. # # @overload # @param [String, #to_s] url # @param [Hash{Symbol => Object}] options # @yield [graph] # @yieldparam [Graph] graph # @return [void] # # @overload # @param [String, #to_s] url # @param [Hash{Symbol => Object}] options # @return [Graph] # # @return [void] def self.load(url, options = {}, &block) self.new(url, options) do |graph| graph.load! unless graph.unnamed? if block_given? case block.arity when 1 then block.call(graph) else graph.instance_eval(&block) end end end end ## # @param [Resource] context # @param [Hash{Symbol => Object}] options # @yield [graph] # @yieldparam [Graph] def initialize(context = nil, options = {}, &block) @context = case context when nil then nil when RDF::Resource then context else RDF::URI.new(context) end @options = options.dup @data = @options.delete(:data) || [] if block_given? case block.arity when 1 then block.call(self) else instance_eval(&block) end end end ## # @return [void] def load!(*args) case when args.empty? load(context.to_s, context ? {:base_uri => context}.merge(@options) : @options) else super end end ## # Returns `true` to indicate that this is a graph. # # @return [Boolean] def graph? true end ## # Returns `true` if this is a named graph. # # @return [Boolean] def named? !unnamed? end ## # Returns `true` if this is a unnamed graph. # # @return [Boolean] def unnamed? context.nil? end ## # Returns all unique RDF contexts for this graph. # # @return [Array<Resource>] def contexts named? ? [context] : [] end ## # Returns the URI representation of this graph. # # @return [URI] def to_uri context end ## # Returns a string representation of this graph. # # @return [String] def to_s named? ? context.to_s : "<>" end ## # Returns `true` if this graph contains no RDF statements. # # @return [Boolean] # @see RDF::Enumerable#empty? def empty? @data.empty? end ## # Returns the number of RDF statements in this graph. # # @return [Integer] # @see RDF::Enumerable#count def count @data.size end ## # Returns `true` if this graph contains the given RDF statement. # # @param [Statement] statement # @return [Boolean] # @see RDF::Enumerable#has_statement? def has_statement?(statement) statement = statement.dup statement.context = context @data.include?(statement) end ## # Enumerates each RDF statement in this graph. # # @yield [statement] # @yieldparam [Statement] statement # @return [Enumerator] # @see RDF::Enumerable#each_statement def each(&block) @data.each(&block) end ## # Inserts the given RDF statement into the graph. # # @param [RDF::Statement] statement # @return [void] # @see RDF::Mutable#insert def insert_statement(statement) statement = statement.dup statement.context = context @data.push(statement.dup) unless @data.include?(statement) end ## # Deletes the given RDF statement from the graph. # # @param [RDF::Statement] statement # @return [void] # @see RDF::Mutable#delete def delete_statement(statement) statement = statement.dup statement.context = context @data.delete(statement) end ## # Deletes all RDF statements from this graph. # # @return [void] # @see RDF::Mutable#clear def clear_statements @data.clear end protected :insert_statement protected :delete_statement protected :clear_statements end end