1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
#TODO: switch services to 1.2
#TODO: error handling
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"]
# not working
RestClient.add_before_execution_proc do |req, params|
params[:subjectid] = @subjectid
end
class String
def to_object
# TODO: fix, this is unsafe
self =~ /dataset/ ? uri = File.join(self.chomp,"metadata") : uri = self.chomp
raise "#{uri} is not a valid URI." unless RDF::URI.new(uri).uri?
RDF::Reader.open(uri) do |reader|
reader.each_statement do |statement|
if statement.predicate == RDF.type and statement.subject == uri
klass = "OpenTox::#{statement.object.to_s.split("#").last}"
object = eval "#{klass}.new \"#{uri}\""
end
end
end
# fallback: guess class from uri
# TODO: fix services and remove
unless object
case uri
when /compound/
object = OpenTox::Compound.new uri
when /feature/
object = OpenTox::Feature.new uri
when /dataset/
object = OpenTox::Dataset.new uri.sub(/\/metadata/,'')
when /algorithm/
object = OpenTox::Algorithm.new uri
when /model/
object = OpenTox::Model.new uri
when /validation/
object = OpenTox::Validation.new uri
when /task/
object = OpenTox::Task.new uri
else
raise "Class for #{uri} not found."
end
end
if object.class == Task # wait for tasks
object.wait_for_completion
object = object.result_uri.to_s.to_object
end
object
end
=begin
def object_from_uri
# TODO: fix, this is unsafe
self =~ /dataset/ ? uri = File.join(self.chomp,"metadata") : uri = self.chomp
RDF::Reader.open(uri) do |reader|
reader.each_statement do |statement|
if statement.predicate == RDF.type and statement.subject == uri
klass = "OpenTox::#{statement.object.to_s.split("#").last}"
return eval "#{klass}.new \"#{uri}\""
end
end
end
# guess class from uri
# TODO: fix services and remove
case uri
when /compound/
return OpenTox::Compound.new uri
when /feature/
return OpenTox::Feature.new uri
when /dataset/
return OpenTox::Dataset.new uri.sub(/\/metadata/,'')
when /algorithm/
return OpenTox::Algorithm.new uri
when /model/
return OpenTox::Model.new uri
when /validation/
return OpenTox::Validation.new uri
when /task/
return OpenTox::Task.new uri
else
raise "Class for #{uri} not found."
end
end
=end
end
module OpenTox
attr_accessor :subjectid, :uri, :response
attr_writer :metadata
def initialize uri=nil, subjectid=nil
@uri = uri.chomp
@subjectid = subjectid
end
# Ruby interface
def metadata reload=true
if reload
@metadata = {}
RDF::Reader.open(@uri) do |reader|
reader.each_statement do |statement|
@metadata[statement.predicate] = statement.object if statement.subject == @uri
end
end
end
@metadata
end
def save
rdf = RDF::Writer.for(:rdfxml).buffer do |writer|
@metadata.each { |p,o| writer << RDF::Statement.new(RDF::URI.new(@uri), p, o) }
end
post rdf, { :content_type => 'application/rdf+xml'}
end
# REST API
def get params={}
params[:subjectid] ||= @subjectid
params[:accept] ||= 'application/rdf+xml'
@response = RestClient.get @uri, params
end
def post payload={}, params={}
params[:subjectid] ||= @subjectid
params[:accept] ||= 'application/rdf+xml'
@response = RestClient.post(@uri.to_s, payload, params)
begin
@response.to_s.to_object
rescue
@response
end
end
def put payload={}, params={}
params[:subjectid] ||= @subjectid
params[:accept] ||= 'application/rdf+xml'
@response = RestClient.put(@uri.to_s, payload, params)
end
def delete params={}
params[:subjectid] ||= @subjectid
params[:accept] ||= 'application/rdf+xml'
@response = RestClient.delete(@uri.to_s,:subjectid => @subjectid)
end
# class methods
module ClassMethods
def create service_uri, subjectid=nil
uri = RestClient.post(service_uri, {}, :subjectid => subjectid).chomp
eval("#{self}.new(\"#{uri}\", #{subjectid})")
end
def from_file service_uri, file, subjectid=nil
RestClient.post(service_uri, :file => File.new(file), :subjectid => subjectid).chomp.to_object
end
def all service_uri, subjectid=nil
uris = RestClient.get(service_uri, {:accept => 'text/uri-list'}).split("\n").compact
uris.collect{|uri| eval "#{self}.new(\"#{uri}\", #{subjectid})"}
end
end
class FromUri
end
# create default classes
SERVICES.each do |s|
eval "class #{s}
include OpenTox
extend OpenTox::ClassMethods
end"
end
private
end
|