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
|
module OpenTox
module Backend
class FourStore
@@accept_formats = [ "application/rdf+xml", "text/turtle", "text/plain", "text/uri-list", "text/html", 'application/sparql-results+xml' ]
@@content_type_formats = [ "application/rdf+xml", "text/turtle", "text/plain", "application/x-turtle" ]
def self.list mime_type
bad_request_error "'#{mime_type}' is not a supported mime type. Please specify one of #{@@accept_formats.join(", ")} in the Accept Header." unless @@accept_formats.include? mime_type
if mime_type =~ /(uri-list|html|sparql-results)/
sparql = "SELECT DISTINCT ?uri WHERE {GRAPH ?uri {?uri <#{RDF.type}> <#{klass}>.} }"
else
sparql = "CONSTRUCT {?uri <#{RDF.type}> <#{klass}>.} WHERE { GRAPH ?uri {?uri <#{RDF.type}> <#{klass}>.} }"
end
query sparql, mime_type
end
def self.head uri
sparql = "SELECT DISTINCT ?g WHERE {GRAPH ?g {<#{uri}> ?p ?o.} }"
rdf = query sparql, 'application/sparql-results+xml'
#resource_not_found_error "#{uri} not found." unless rdf.match("#{uri}")
return nil unless rdf.match("#{uri}")
rdf
end
def self.get uri, mime_type
bad_request_error "'#{mime_type}' is not a supported mime type. Please specify one of #{@@accept_formats.join(", ")} in the Accept Header." unless @@accept_formats.include? mime_type
sparql = "CONSTRUCT {?s ?p ?o.} FROM <#{uri}> WHERE { ?s ?p ?o. }"
rdf = query sparql, mime_type
resource_not_found_error "#{uri} not found." if rdf.empty?
rdf
end
def self.post uri, rdf, mime_type
bad_request_error "'#{mime_type}' is not a supported content type. Please use one of #{@@content_type_formats.join(", ")}." unless @@content_type_formats.include? mime_type or mime_type == "multipart/form-data"
bad_request_error "Request body empty." unless rdf
mime_type = "application/x-turtle" if mime_type == "text/plain" # ntriples is turtle in 4store
RestClientWrapper.post File.join(four_store_uri,"data")+"/", :data => rdf.gsub(/\\C|\\\\C/,'C'), :graph => uri, "mime-type" => mime_type # remove backslashes in SMILES (4store interprets them as UTF-8 \C even within single quoates)
update "INSERT DATA { GRAPH <#{uri}> { <#{uri}> <#{RDF::DC.modified}> \"#{DateTime.now}\" } }"
end
def self.put uri, rdf, mime_type
bad_request_error "'#{mime_type}' is not a supported content type. Please use one of #{@@content_type_formats.join(", ")}." unless @@content_type_formats.include? mime_type
bad_request_error "Reqest body empty." unless rdf
mime_type = "application/x-turtle" if mime_type == "text/plain"
RestClientWrapper.put File.join(four_store_uri,"data",uri), rdf.gsub(/\\C|\\\\C/,'C'), :content_type => mime_type # remove backslashes in SMILES (4store interprets them as UTF-8 \C even within single quoates)
update "INSERT DATA { GRAPH <#{uri}> { <#{uri}> <#{RDF::DC.modified}> \"#{DateTime.now}\" } }"
end
def self.delete uri
RestClientWrapper.delete data_uri(uri)
end
def self.update sparql
RestClientWrapper.post update_uri, {:update => sparql}
end
def self.query sparql, mime_type
if sparql =~ /SELECT/i
# return list unless mime_type
case mime_type
when 'application/sparql-results+xml'
RestClientWrapper.get(sparql_uri+"?query=#{CGI.escape(sparql)}",{}, { :accept => mime_type })
when 'application/json'
RestClientWrapper.get(sparql_uri+"?query=#{CGI.escape(sparql)}",{}, { :accept => mime_type })
when /(uri-list|html)/
uri_list = RestClientWrapper.get(sparql_uri+"?query=#{CGI.escape(sparql)}",{}, { :accept => "text/plain" })
uri_list = uri_list.gsub(/"|<|>/,"").split("\n").drop(1).join("\n")
uri_list = uri_list.to_html if mime_type=~/html/
return uri_list
else
bad_request_error "#{mime_type} is not a supported mime type for SELECT statements."
end
elsif sparql =~ /CONSTRUCT/i
case mime_type
when "text/plain", "application/rdf+xml"
RestClientWrapper.get(sparql_uri+"?query=#{CGI.escape(sparql)}",{}, { :accept => mime_type})
when /turtle/
nt = RestClientWrapper.get(sparql_uri+"?query=#{CGI.escape(sparql)}",{},{ :accept => "text/tab-separated-values"})
if !nt.empty?
rdf = RDF::Graph.new
RDF::Reader.for(:ntriples).new(nt) do |reader|
reader.each_statement { |statement| rdf << statement }
end
prefixes = {:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}
['OT', 'DC', 'XSD', 'OLO'].each{|p| prefixes[p.downcase.to_sym] = eval("RDF::#{p}.to_s") }
# TODO: fails for large datasets?? multi_cell_call
turtle = RDF::Turtle::Writer.for(:turtle).buffer(:prefixes => prefixes) do |writer|
writer << rdf
end
else
nt
end
when /html/
# modified ntriples output, delivers large datasets
#TODO optimize representation
nt = RestClientWrapper.get(sparql_uri+"?query=#{CGI.escape(sparql)}",{}, {:accept => "text/plain" })
if !nt.empty?
regex = Regexp.new '(https?:\/\/[\S]+)([>"])'
bnode = Regexp.new '_:[a-z0-9]*'
html = "<html><body>" + nt.gsub(regex, '<a href="\1">\1</a>\2').gsub(/\n/,'<br/>').gsub(bnode, '<>') + "</body></html>"
html
else
nt
end
end
else
# TODO: check if this prevents SPARQL injections
bad_request_error "Only SELECT and CONSTRUCT are accepted SPARQL statements."
end
rescue
bad_request_error $!.message, sparql_uri, $!.backtrace
end
def self.klass
RDF::OT[SERVICE.capitalize]
end
def self.four_store_uri
# credentials are removed from uri in error.rb
$four_store[:uri].sub(%r{//},"//#{$four_store[:user]}:#{$four_store[:password]}@")
end
def self.sparql_uri
File.join(four_store_uri, "sparql") + '/'
end
def self.update_uri
File.join(four_store_uri, "update") + '/'
end
def self.data_uri uri
File.join(four_store_uri, "data","?graph=#{uri}")
end
end
end
end
|