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
|
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 service_uri, mime_type
mime_type = "text/html" if mime_type.match(%r{\*/\*})
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/
sparql = "SELECT DISTINCT ?g WHERE {GRAPH ?g {?s <#{RDF.type}> <#{klass}>; ?p ?o. } }"
else
sparql = "CONSTRUCT {?s ?p ?o.} FROM WHERE {?s <#{RDF.type}> <#{klass}>; ?p ?o. }"
end
query sparql, mime_type
end
def self.get uri, mime_type
mime_type = "text/html" if mime_type.match(%r{\*/\*})
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
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
rescue
rest_call_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
RestClient.put File.join(four_store_uri,"data",uri), rdf, :content_type => mime_type
rescue
rest_call_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 "text/uri-list"
RestClient.get(sparql_uri, :params => { :query => sparql }, :accept => "text/plain").body.gsub(/"|<|>/,'').split("\n").drop(1).join("\n")
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
turtle = "<html><body>" + turtle.gsub(%r{<(.*)>},'<<a href="\1">\1</a>>').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
rest_call_error $!.message, sparql_uri
end
def self.klass
RDF::OT[SERVICE.capitalize]
end
=begin
def self.available? uri
sparql = "SELECT DISTINCT ?s WHERE {GRAPH <#{uri}> {?s <#{RDF.type}> <#{klass}>} }"
r = query(sparql, nil)
r.size == 1 and r.first == uri
end
def self.convert rdf_string, input_format, output_format, rewrite_uri=nil
rewrite_uri ? serialize(parse_and_rewrite_uri(rdf_string,input_format, rewrite_uri), output_format) : serialize(parse(rdf_string,input_format), output_format)
end
def self.parse_and_rewrite_uri string, format, rewrite_uri
rdf = RDF::Graph.new
subject = nil
statements = [] # use array instead of graph for performance reasons
RDF::Reader.for(format).new(string) do |reader|
reader.each_statement do |statement|
subject = statement.subject if statement.predicate == RDF.type and statement.object == klass
statements << statement
end
end
bad_request_error "No class specified with <#{RDF.type}> statement." unless subject
statements.each do |statement|
if rewrite_uri
statement.subject = RDF::URI.new rewrite_uri if statement.subject.to_s == subject
statement.object = RDF::URI.new rewrite_uri if statement.predicate == RDF::XSD.anyURI
end
rdf << statement
end
rdf
end
=end
def self.four_store_uri
# TODO remove credentials from URI 9security risk in tasks)
$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
|