lib/sparql/results.rb in sparql-0.0.2 vs lib/sparql/results.rb in sparql-0.1.0
- old
+ new
@@ -116,26 +116,43 @@
# Serialize solutions using the determined format
#
# @param [RDF::Query::Solutions, RDF::Queryable, Boolean] solutions
# Solutions as either a solution set, a Queryable object (such as a graph) or a Boolean value
# @param [Hash{Symbol => Object}] options
- # @option options [:format]
+ # @option options [#to_sym] :format
# Format of results, one of :html, :json or :xml.
# May also be an RDF::Writer format to serialize DESCRIBE or CONSTRUCT results
- # @option options [:content_type]
+ # @option options [String] :content_type
# Format of results, one of 'application/sparql-results+json' or 'application/sparql-results+xml'
# May also be an RDF::Writer content_type to serialize DESCRIBE or CONSTRUCT results
+ # @option options [Array<String>] :content_types
+ # Similar to :content_type, but takes an ordered array of appropriate content types,
+ # and serializes using the first appropriate type, including wild-cards.
# @return [String]
# String with serialized results and #content_type
+ # @raise [RDF::WriterError] when inappropriate formatting options are used
def serialize_results(solutions, options = {})
- format = options[:format]
- content_type = options[:content_type]
+ format = options[:format].to_sym if options[:format]
+ content_type = options[:content_type].to_s.split(';').first
+ content_types = options[:content_types] || ['*/*']
format ||= RDF::Query::Solutions::MIME_TYPES.invert[content_type] if content_type
+ if !format && !content_type
+ case solutions
+ when RDF::Queryable
+ content_type = first_content_type(content_types, RDF::Format.content_types.keys) || 'text/plain'
+ format = RDF::Writer.for(:content_type => content_type).to_sym
+ else
+ content_type = first_content_type(content_types, RDF::Query::Solutions::MIME_TYPES.values) || 'application/sparql-results+xml'
+ format = RDF::Query::Solutions::MIME_TYPES.invert[content_type]
+ end
+ end
+
serialization = case solutions
- when TrueClass, FalseClass
- case format ||= :xml
+ when TrueClass, FalseClass, RDF::Literal::TRUE, RDF::Literal::FALSE
+ solutions = solutions.object if solutions.is_a?(RDF::Literal)
+ case format
when :json
require 'json' unless defined?(::JSON)
{:boolean => solutions}.to_json
when :xml
require 'builder' unless defined?(::Builder)
@@ -147,22 +164,33 @@
when :html
require 'builder' unless defined?(::Builder)
content_type = "text/html"
xml = ::Builder::XmlMarkup.new(:indent => 2)
xml.div(solutions.to_s, :class => "sparql")
+ else
+ raise RDF::WriterError, "Unknown format #{(format || content_type).inspect} for #{solutions.class}"
end
when RDF::Queryable
+ begin
+ require 'linkeddata'
+ rescue LoadError => e
+ require 'rdf/ntriples'
+ end
fmt = RDF::Format.for(format ? format.to_sym : {:content_type => content_type})
fmt ||= RDF::NTriples::Format
format ||= fmt.to_sym
- content_type ||= fmt.content_types.first
- fmt.writer.buffer << solutions
+ content_type ||= fmt.content_type.first
+ results = solutions.dump(format, options)
+ raise RDF::WriterError, "Unknown format #{fmt.inspect} for #{solutions.class}" unless results
+ results
when RDF::Query::Solutions
- case format ||= :xml
+ case format
when :json then solutions.to_json
when :xml then solutions.to_xml
when :html then solutions.to_html
+ else
+ raise RDF::WriterError, "Unknown format #{(format || content_type).inspect} for #{solutions.class}"
end
end
content_type ||= RDF::Query::Solutions::MIME_TYPES[format] if format
@@ -182,9 +210,29 @@
<p>%s: %s</p>
</body>
</html>
).freeze
+ ##
+ # Find a content_type from a list using an ordered list of acceptable content types
+ # using wildcard matching
+ #
+ # @param [Array<String>] acceptable
+ # @param [Array<String>] available
+ # @return [String]
+ #
+ # @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
+ def first_content_type(acceptable, available)
+ return acceptable.first if available.empty?
+ available.flatten!
+ acceptable.each do |pattern|
+ type = available.detect { |t| File.fnmatch(pattern, t) }
+ return type if type
+ end
+ nil
+ end
+ module_function :first_content_type
+
##
# Serialize error results
#
# Returns appropriate content based upon an execution exception
# @param [Exception] exception