summaryrefslogtreecommitdiff
path: root/lib/opentox.rb
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2012-03-08 15:23:43 +0000
committerChristoph Helma <helma@in-silico.ch>2012-03-08 15:23:43 +0000
commit63fcd8f8feed58af4b1e1ff0e5fdaa09791c9596 (patch)
tree97103c785013abd8fe2b3798f73ebec4bcb9e885 /lib/opentox.rb
parent2f6d5c75fc1fece5fc10cc7c45ad59cf6b820d64 (diff)
improved integration of error reports, call stack added as errorDetails
Diffstat (limited to 'lib/opentox.rb')
-rw-r--r--lib/opentox.rb118
1 files changed, 78 insertions, 40 deletions
diff --git a/lib/opentox.rb b/lib/opentox.rb
index 9ba64bd..342b04e 100644
--- a/lib/opentox.rb
+++ b/lib/opentox.rb
@@ -1,52 +1,73 @@
-#TODO: switch services to 1.2
-RDF::OT = RDF::Vocabulary.new 'http://www.opentox.org/api/1.2#'
-RDF::OT1 = RDF::Vocabulary.new 'http://www.opentox.org/api/1.1#'
-RDF::OTA = RDF::Vocabulary.new 'http://www.opentox.org/algorithmTypes.owl#'
-
-SERVICES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "Investigation"]
-
-# Regular expressions for parsing classification data
-TRUE_REGEXP = /^(true|active|1|1.0|tox|activating|carcinogen|mutagenic)$/i
-FALSE_REGEXP = /^(false|inactive|0|0.0|low tox|deactivating|non-carcinogen|non-mutagenic)$/i
-
# defaults to stderr, may be changed to file output (e.g in opentox-service)
$logger = OTLogger.new(STDERR)
$logger.level = Logger::DEBUG
module OpenTox
- attr_accessor :subjectid, :uri, :response
- attr_writer :metadata
+ attr_accessor :uri, :subjectid, :rdf, :response
+ # Ruby interface
+
+ # Create a new OpenTox object (does not load data from service)
+ # @param [optional,String] URI
+ # @param [optional,String] subjectid
+ # @return [OpenTox] OpenTox object
def initialize uri=nil, subjectid=nil
- @uri = uri.chomp
+ @uri = uri.to_s.chomp
@subjectid = subjectid
+ @rdf = RDF::Graph.new
end
- # Ruby interface
+ # Load metadata from service
+ def pull
+ kind_of?(OpenTox::Dataset) ? uri = File.join(@uri,"metadata") : uri = @uri
+ # TODO generic method for all formats
+ parse_rdfxml RestClientWrapper.get(uri,{},{:accept => $default_rdf, :subjectid => @subjectid})
+ end
- def metadata reload=true
- if reload or @metadata.empty?
- @metadata = {}
- kind_of?(OpenTox::Dataset) ? uri = File.join(@uri,"metadata") : uri = @uri
- RDF::Reader.for(:rdfxml).new( RestClientWrapper.get(uri) ) do |reader|
- reader.each_statement do |statement|
- @metadata[statement.predicate] = statement.object if statement.subject == @uri
- end
- end
+ # Get object metadata
+ # @return [Hash] Metadata
+ def metadata
+ pull if @rdf.empty?
+ metadata = {}
+ @rdf.query([RDF::URI.new(@uri),nil,nil]).collect do |statement|
+ metadata[statement.predicate] ||= []
+ metadata[statement.predicate] << statement.object
end
- @metadata
+ metadata
+ end
+
+ # Get metadata values
+ # @param [RDF] Key from RDF Vocabularies
+ # @return [Array] Values for supplied key
+ def [](key)
+ pull if @rdf.empty?
+ @rdf.query([RDF::URI.new(@uri),key,nil]).collect{|statement| statement.object}
end
+ # Save object at service
def save
- post self.to_rdfxml, { :content_type => 'application/rdf+xml'}
+ #TODO: dynamic assignment
+ post self.to_rdfxml, { :content_type => $default_rdf}
end
- def to_rdfxml
- rdf = RDF::Writer.for(:rdfxml).buffer do |writer|
- @metadata.each { |p,o| writer << RDF::Statement.new(RDF::URI.new(@uri), p, o) }
+ RDF_FORMATS.each do |format|
+
+ # rdf parse methods for all formats e.g. parse_rdfxml
+ send :define_method, "parse_#{format}".to_sym do |rdf|
+ @rdf = RDF::Graph.new
+ RDF::Reader.for(format).new(rdf) do |reader|
+ reader.each_statement{ |statement| @rdf << statement }
+ end
+ end
+
+ # rdf serialization methods for all formats e.g. to_rdfxml
+ send :define_method, "to_#{format}".to_sym do
+ rdf = RDF::Writer.for(format).buffer do |writer|
+ @rdf.each{|statement| writer << statement}
+ end
+ rdf
end
- rdf
end
# REST API
@@ -70,32 +91,49 @@ module OpenTox
def delete headers={}
headers[:subjectid] ||= @subjectid
- @response = RestClientWrapper.delete(@uri.to_s,nil,nil,headers)
+ @response = RestClientWrapper.delete(@uri.to_s,nil,headers)
end
# class methods
module ClassMethods
+ def all service_uri, subjectid=nil
+ uris = RestClientWrapper.get(service_uri, {}, :accept => 'text/uri-list').split("\n").compact
+ uris.collect{|uri| URI.task?(service_uri) ? from_uri(uri, subjectid, false) : from_uri(uri, subjectid)}
+ end
+
def create service_uri, subjectid=nil
- uri = RestClientWrapper.post(service_uri, {}, :subjectid => subjectid).chomp
- subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")
+ uri = RestClientWrapper.post(service_uri, {}, {:accept => 'text/uri-list', :subjectid => subjectid})
+ URI.task?(service_uri) ? from_uri(uri, subjectid, false) : from_uri(uri, subjectid)
end
def from_file service_uri, filename, subjectid=nil
file = File.new filename
- uri = RestClientWrapper.post(service_uri, {:file => file}, {:subjectid => subjectid, :content_type => file.mime_type, :accept => "text/uri-list"})
- puts uri
+ from_uri RestClientWrapper.post(service_uri, {:file => file}, {:subjectid => subjectid, :content_type => file.mime_type, :accept => "text/uri-list"}), subjectid
end
- def all service_uri, subjectid=nil
- uris = RestClientWrapper.get(service_uri, {}, :accept => 'text/uri-list').split("\n").compact
- uris.collect{|uri| subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")}
- end
+ private
+ def from_uri uri, subjectid=nil, wait=true
+
+ uri.chomp!
+ # TODO add waiting task
+ if URI.task? uri and wait
+ t = OpenTox::Task.new(uri)
+ t.wait
+ uri = t.resultURI
+ end
+ # guess class from uri, this is potentially unsafe, but polling metadata from large uri lists is way too slow (and not all service provide RDF.type in their metadata)
+ result = CLASSES.collect{|s| s if uri =~ /#{s.downcase}/}.compact
+ internal_server_error "Cannot determine class from URI: '#{uri}.\nCandidate classes are #{result.inspect}" unless result.size == 1
+ klass = result.first
+ # initialize with/without subjectid
+ subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")
+ end
end
# create default OpenTox classes
- SERVICES.each do |klass|
+ CLASSES.each do |klass|
c = Class.new do
include OpenTox
extend OpenTox::ClassMethods