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
|
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" ]
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 = "SELECT DISTINCT ?g WHERE {GRAPH ?g {?s <#{RDF.type}> <#{klass}>; <#{RDF::DC.modified}> ?o.} } ORDER BY ?o"
else
sparql = "CONSTRUCT {?s ?p ?o.} WHERE {?s <#{RDF.type}> <#{klass}>; ?p ?o. }"
end
query sparql, mime_type
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 "Reqest body empty." unless rdf
mime_type = "application/x-turtle" if mime_type == "text/plain" # ntriples is turtle in 4store
begin
RestClient.post File.join(four_store_uri,"data")+"/", :data => rdf, :graph => uri, "mime-type" => mime_type
update "INSERT DATA { GRAPH <#{uri}> { <#{uri}> <#{RDF::DC.modified}> \"#{DateTime.now}\" } }"
rescue
bad_request_error $!.message, File.join(four_store_uri,"data")+"/"
end
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"
begin
RestClientWrapper.put File.join(four_store_uri,"data",uri), rdf, :content_type => mime_type
update "INSERT DATA { GRAPH <#{uri}> { <#{uri}> <#{RDF::DC.modified}> \"#{DateTime.now}\" } }"
rescue
bad_request_error $!.message, File.join(four_store_uri,"data",uri)
end
end
def self.delete uri
RestClientWrapper.delete data_uri(uri)
end
def self.update sparql
RestClient.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'
RestClient.get(sparql_uri, :params => { :query => sparql }, :accept => mime_type).body
when 'application/json'
RestClient.get(sparql_uri, :params => { :query => sparql }, :accept => mime_type).body
when /(uri-list|html)/
uri_list = RestClient.get(sparql_uri, :params => { :query => sparql }, :accept => "text/plain").body.gsub(/"|<|>/,'').split("\n").drop(1).join("\n")
uri_list = OpenTox.text_to_html(uri_list) 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"
RestClient.get(sparql_uri, :params => { :query => sparql }, :accept => mime_type).body
when /html|turtle/
# TODO: fix and improve
nt = RestClient.get(sparql_uri, :params => { :query => sparql }, :accept => "text/plain").body # 4store returns ntriples for turtle
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::N3::Writer.for(:turtle).buffer(:prefixes => prefixes) do |writer|
rdf.each{|statement| writer << statement}
end
regex = Regexp.new '(https?:\/\/[\S]+)([>"])'
turtle = "<html><body>" + turtle.gsub( regex, '<a href="\1">\1</a>\2' ).gsub(/\n/,'<br/>') + "</body></html>" if mime_type =~ /html/ and !turtle.empty?
turtle
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
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
|