lib/rdf/json/reader.rb in rdf-json-0.2.0 vs lib/rdf/json/reader.rb in rdf-json-0.3.0.pre

- old
+ new

@@ -1,9 +1,12 @@ module RDF::JSON ## # RDF/JSON parser. # + # @example Loading RDF/JSON parsing support + # require 'rdf/json' + # # @example Obtaining an RDF/JSON reader class # RDF::Reader.for(:json) #=> RDF::JSON::Reader # RDF::Reader.for("etc/doap.json") # RDF::Reader.for(:file_name => "etc/doap.json") # RDF::Reader.for(:file_extension => "json") @@ -27,10 +30,12 @@ # @see http://n2.talis.com/wiki/RDF_JSON_Specification class Reader < RDF::Reader format RDF::JSON::Format ## + # The graph constructed when parsing. + # # @return [RDF::Graph] attr_reader :graph ## # Initializes the RDF/JSON reader instance. @@ -41,11 +46,11 @@ # @yieldparam [Reader] reader def initialize(input = $stdin, options = {}, &block) super do @graph = RDF::Graph.new - JSON.parse(@input.read).each do |subject, predicates| + ::JSON.parse(@input.read).each do |subject, predicates| subject = parse_subject(subject) predicates.each do |predicate, objects| predicate = parse_predicate(predicate) objects.each do |object| object = parse_object(object) @@ -63,67 +68,103 @@ # # @param [String] subject # @return [RDF::Resource] def parse_subject(subject) case subject - when /^_:/ then RDF::Node.new(subject[2..-1]) - else RDF::URI.new(subject) + when /^_:/ then parse_node(subject) + else parse_uri(subject) end end ## # Parses an RDF/JSON predicate string into a URI reference. # # @param [String] predicate # @return [RDF::URI] def parse_predicate(predicate) - # TODO: optional support for CURIE predicates (issue #1 on GitHub). - RDF::URI.intern(predicate) + # TODO: optional support for CURIE predicates? (issue #1 on GitHub). + parse_uri(predicate, :intern => true) end ## # Parses an RDF/JSON object string into an RDF value. # # @param [Hash{String => Object}] object # @return [RDF::Value] def parse_object(object) - raise RDF::ReaderError.new, "missing 'type' key in #{object.inspect}" unless object.has_key?('type') - raise RDF::ReaderError.new, "missing 'value' key in #{object.inspect}" unless object.has_key?('value') + raise RDF::ReaderError, "missing 'type' key in #{object.inspect}" unless object.has_key?('type') + raise RDF::ReaderError, "missing 'value' key in #{object.inspect}" unless object.has_key?('value') case type = object['type'] when 'bnode' - RDF::Node.new(object['value'][2..-1]) + parse_node(object['value']) when 'uri' - RDF::URI.new(object['value']) + parse_uri(object['value']) when 'literal' - RDF::Literal.new(object['value'], { + literal = RDF::Literal.new(object['value'], { :language => object['lang'], :datatype => object['datatype'], }) + literal.validate! if validate? + literal.canonicalize! if canonicalize? + literal else raise RDF::ReaderError, "expected 'type' to be 'bnode', 'uri', or 'literal', but got #{type.inspect}" end end ## + # Parses an RDF/JSON blank node string into an `RDF::Node` instance. + # + # @param [String] string + # @return [RDF::Node] + def parse_node(string) + RDF::Node.new(string[2..-1]) # strips off the initial '_:' + end + alias_method :parse_bnode, :parse_node + + ## + # Parses an RDF/JSON URI string into an `RDF::URI` instance. + # + # @param [String] string + # @param [Hash{Symbol => Object}] options + # @option options [Boolean] :intern (false) + # @return [RDF::URI] + def parse_uri(string, options = {}) + uri = RDF::URI.send(intern = intern? && options[:intern] ? :intern : :new, string) + uri.validate! if validate? + uri.canonicalize! if canonicalize? && !intern + uri + end + + ## # @private # @see RDF::Reader#each_graph # @since 0.2.0 def each_graph(&block) - block_given? ? @block.call(@graph) : enum_for(:each_graph).extend(RDF::Countable) + if block_given? + block.call(@graph) + end + enum_graph end ## # @private # @see RDF::Reader#each_statement def each_statement(&block) - block_given? ? @graph.each_statement(&block) : enum_for(:each_statement).extend(RDF::Countable) + if block_given? + @graph.each_statement(&block) + end + enum_statement end ## # @private - # @see RDF::Reader#each_statement + # @see RDF::Reader#each_triple def each_triple(&block) - block_given? ? @graph.each_triple(&block) : enum_for(:each_triple).extend(RDF::Countable) + if block_given? + @graph.each_triple(&block) + end + enum_triple end - end # class Reader -end # module RDF::JSON + end # Reader +end # RDF::JSON