diff sparql-7785ad38967f/sparql/executor.rb @ 0:46996d3b1cfb default tip

Uploaded
author greg
date Tue, 13 Mar 2012 16:29:09 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sparql-7785ad38967f/sparql/executor.rb	Tue Mar 13 16:29:09 2012 -0400
@@ -0,0 +1,130 @@
+#!/usr/bin/env ruby
+$: << File.expand_path('../rubylib/lib', File.dirname(__FILE__))
+$: << File.expand_path('sparql/lib', File.dirname(__FILE__))
+require "galaxy_tool"
+require 'rubygems'
+require 'sparql'
+require 'rubyrdf'
+
+class SPARQLExecutor < GalaxyTool::Base
+
+  option :endpoint,
+    :short => "-e",
+    :long => "--endpoint <URL>",
+    :class => String,
+    :description => "use <URL> as SPARQL endpoint.",
+    :proc => proc {|arg| arg.strip },
+    :required => true
+
+  option :query,
+    :long => "--query-file <filepath>",
+    :class => String,
+    :description => "read query expression from <filepath>.",
+    :proc => proc {|arg| File.read(arg).chomp },
+    :required => true
+
+  option :query,
+    :short => "-q",
+    :long => "--query <expression>",
+    :class => String,
+    :description => "use <expression> as query expression.",
+    :proc => proc {|arg| arg.chomp },
+    :required => true
+
+  option_output :short => "-o",
+    :long => "--output <filepath>",
+    :description => "use <filepath> as output file path."
+
+  option_info :long => "--info <filepath>",
+    :description => "use <filepath> as info file path. default is standard out (/dev/stdout)."
+
+  option_error_handler do |optparse, exception|
+    $stderr.puts "Error: " + exception.message
+    $stderr.puts optparse.help
+    raise exception
+  end
+
+  def info(info_out)
+    info_out.puts "Execute SPARQL query. The endpoint is #{options[:endpoint]}.\n"
+  end
+
+  def create_customized_client(endpoint)
+    client = SPARQL::Client.new(endpoint)
+
+    def client.parsed_xml(content)
+      REXML::Document.new(content).root
+    end
+
+    def client.parse_xml(content)
+      table = []
+      xml = parsed_xml(content)
+      
+      head = xml.elements['head']
+      variables = head.elements.map do |variable|
+        variable.attributes['name']
+      end
+      table << variables.map {|v| "?" + v }
+      
+      case
+      when boolean = xml.elements['boolean']
+        boolean.text == 'true'
+      when results = xml.elements['results']
+        table += results.elements.map do |result|
+          row = []
+          result.elements.each do |binding|
+            name = binding.attributes['name']
+            value_node = binding.children.find {|n| !n.is_a?(REXML::Text) }
+            value = parse_xml_value(value_node)
+            row[variables.index(name)] = value
+          end
+          row
+        end
+      else
+        raise NotImplementedError # TODO
+      end  
+      
+      table
+    end
+
+    def client.graph
+      @graph ||= RDF::Graph::Memory.new
+    end
+
+    def client.parse_xml_value(element)
+      case element
+      when REXML::Text
+        element.value
+      when REXML::Node
+        case element.name.to_sym
+        when :uri
+          RDF::UriNode.new(element.text)
+        when :literal
+          RDF::PlainLiteralNode.new(element.text)
+        when :bnode
+          RDF::BlankNode.new(element.text, graph)
+        else
+          raise NotImplementedError # TODO
+        end
+      else
+        raise NotImplementedError # TODO
+      end
+    end
+    
+    client
+  end
+
+  def search(client, query)
+    client.query(query)
+  end
+
+  def main(output)
+    client = create_customized_client(options[:endpoint])
+    search(client, options[:query]).each do |row|
+      output.puts row.join("\t")
+    end
+  end
+end
+
+if $0 == __FILE__
+  SPARQLExecutor.new.run(ARGV)
+end