Class: SesameAdapter

Inherits:
ActiveRdfAdapter
  • Object
show all
Defined in:
lib/activerdf_sesame/sesame.rb

Overview

TODO: about this adapter

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ SesameAdapter

instantiates Sesame database available parameters:

  • :location => path to a file for persistent storing or :memory for in-memory (defaults to in-memory)

  • :inferencing => true or false, if sesame2 rdfs inferencing is uses (defaults to true)



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
# File 'lib/activerdf_sesame/sesame.rb', line 38

def initialize(params = {})
	$activerdflog.info "initializing Sesame Adapter with params #{params.to_s}"

	@reads = true
	@writes = true

	# if no directory path given, we use in-memory store
   if params[:location]
     if params[:location] == :memory
       sesameLocation = nil      
     else
       sesameLocation = JFile.new(params[:location])
     end
   else
     sesameLocation = nil
   end
   
   # if no inferencing is specified, we use the sesame2 rdfs inferencing
   sesameInferencing = params[:inferencing] || nil

# this will not work at the current state of jruby	
#    # fancy JRuby code so that the user does not have to set the java CLASSPATH
#    
#    this_dir = File.dirname(File.expand_path(__FILE__))
#    
#    jar1 = JFile.new(this_dir + "/../../ext/wrapper-sesame2.jar")
#    jar2 = JFile.new(this_dir + "/../../ext/openrdf-sesame-2.0-alpha4-onejar.jar")
#
#    # make an array of URL, which contains the URLs corresponding to the files
#    uris = JURL[].new(2)
#    uris[0] = jar1.toURL
#    uris[1] = jar2.toURL
#
#    # this is our custom class loader, yay!
#    @activerdfClassLoader = URLClassLoader.new(uris)
#    classWrapper = JClass.forName("org.activerdf.wrapper.sesame2.WrapperForSesame2", true, @activerdfClassLoader)    
#    @myWrapperInstance = classWrapper.new_instance 

   @myWrapperInstance = WrapperForSesame2.new

	if sesameLocation == nil
	  if sesameInferencing == nil
       @db = @myWrapperInstance.callConstructor
	  else
       @db = @myWrapperInstance.callConstructor(sesameInferencing)		  
	  end
	else
	  if sesameInferencing == nil
	    @db = @myWrapperInstance.callConstructor(sesameLocation)		  
	  else
	    @db = @myWrapperInstance.callConstructor(sesameLocation,sesameInferencing)		  
	  end
	end
	
   @valueFactory = @db.getRepository.getSail.getValueFactory

   # define the finalizer, which will call close on the sesame triple store
   # recipie for this, is from: http://wiki.rubygarden.org/Ruby/page/show/GCAndMemoryManagement
   ObjectSpace.define_finalizer(self, SesameAdapter.create_finalizer(@db))       
end

Class Method Details

.create_finalizer(db) ⇒ Object

TODO: this does not work, but it is also not caused by jruby.



100
101
102
103
# File 'lib/activerdf_sesame/sesame.rb', line 100

def SesameAdapter.create_finalizer(db)
  # we have to call close on the sesame triple store, because otherwise some of the iterators are not closed properly
  proc { puts "die";  db.close }
end

Instance Method Details

#add(s, p, o, c = nil) ⇒ Object

adds triple(s,p,o) to datastore s,p must be resources, o can be primitive data or resource



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
# File 'lib/activerdf_sesame/sesame.rb', line 155

def add(s,p,o,c=nil)

   if s.class == RDFS::Resource then
     sesameSubject = @valueFactory.createURI(s.uri)
   else
     raise ActiveRdfError, "the Sesame Adapter tried to add a subject which was not of type RDFS::Resource, but of type #{s.class}"
   end
   if p.class == RDFS::Resource then
     sesamePredicate = @valueFactory.createURI(p.uri)
   else
     raise ActiveRdfError, "the Sesame Adapter tried to add a predicate which was not of type RDFS::Resource, but of type #{p.class}"
   end
   if o.class == RDFS::Resource then
     sesameObject = @valueFactory.createURI(o.uri)
   else
     sesameObject = @valueFactory.createLiteral(o.to_s)
   end

   # TODO: handle context, especially if it is null

   @db.add(sesameSubject, sesamePredicate, sesameObject)
   # for contexts, just add 4th parameter

   # TODO: do we need to handle errors from the java side ? 

   return @db
end

#clearObject

deletes all triples from datastore



113
114
115
# File 'lib/activerdf_sesame/sesame.rb', line 113

def clear
	@db.clear
end

#closeObject

close the underlying sesame triple store. if not called there may be open iterators.



196
197
198
# File 'lib/activerdf_sesame/sesame.rb', line 196

def close
  @db.close
end

#delete(s, p, o, c = nil) ⇒ Object

deletes triple(s,p,o,c) from datastore symbol parameters match anything: delete(:s,:p,:o) will delete all triples you can specify a context to limit deletion to that context: delete(:s,:p,:o, ‘context’) will delete all triples with that context



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
# File 'lib/activerdf_sesame/sesame.rb', line 121

def delete(s, p, o, c=nil)
   if s.class == RDFS::Resource then
     sesameSubject = @valueFactory.createURI(s.uri)
   elsif s == :s
     sesameSubject = nil
   else
     raise ActiveRdfError, "the Sesame Adapter tried to delete a subject which was not of type RDFS::Resource, but of type #{s.class}"
   end
   if p.class == RDFS::Resource then
     sesamePredicate = @valueFactory.createURI(p.uri)
   elsif p == :p 
     sesamePredicate = nil
   else
     raise ActiveRdfError, "the Sesame Adapter tried to delete a predicate which was not of type RDFS::Resource, but of type #{p.class}"
   end
   if o.class == RDFS::Resource then
     sesameObject = @valueFactory.createURI(o.uri)
   elsif o == :o
     sesameObject = nil
   else
     sesameObject = @valueFactory.createLiteral(o.to_s)
   end	

   # TODO contexts
   candidateStatements = @db.getStatements(sesameSubject, sesamePredicate, sesameObject, false)
   
   @db.remove(candidateStatements)
   
   candidateStatements.close
   return @db
end

#dumpObject

returns all triples in the datastore



201
202
203
204
205
206
207
208
209
210
# File 'lib/activerdf_sesame/sesame.rb', line 201

def dump
   # the sesame connection has an export method, which writes all explicit statements to 
   # a to a RDFHandler, which we supply, by constructing a NTriplesWriter, which writes to StringWriter, 
   # and we kindly ask that StringWriter to make a string for us. Note, you have to use stringy.to_s, 
   # somehow stringy.toString does not work. yes yes, those wacky jruby guys ;) 
   stringy = StringWriter.new
   sesameWriter = NTriplesWriter.new(stringy)
   @db.export(sesameWriter)
   return stringy.to_s
end

#flushObject

flushing is done automatically, because we run sesame2 in autocommit mode



186
187
188
# File 'lib/activerdf_sesame/sesame.rb', line 186

def flush
	true
end

#load(file) ⇒ Object

loads triples from file in ntriples format



213
214
215
216
217
218
# File 'lib/activerdf_sesame/sesame.rb', line 213

def load(file)
   reader = FileReader.new(file)
   @db.add(reader, "", RDFFormat::NTRIPLES)
   
   return @db
end

#query(query) ⇒ Object

executes ActiveRDF query on the sesame triple store associated with this adapter



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/activerdf_sesame/sesame.rb', line 221

def query(query)

   # we want to put the results in here
   results = []
   
   # translate the query object into a SPARQL query string
   qs = Query2SPARQL.translate(query)
   
   # evaluate the query on the sesame triple store
   # TODO: if we want to get inferred statements back we have to say so, as third boolean parameter
   tuplequeryresult = @db.evaluateTupleQuery(QueryLanguage::SPARQL, qs)

   # what are the variables of the query ?
   variables = tuplequeryresult.getBindingNames
   sizeOfVariables = variables.size

   # a solution is a binding of a variable to all entities that matched this variable in the sparql query
   solutionIterator = tuplequeryresult.iterator
   
   # the following is plainly ugly. the reason is that JRuby currently does not support
   # using iterators in the ruby way: with "each". it is possible to define "each" for java.util.Iterator
   # using JavaUtilities.extend_proxy but that fails in strange ways. this is ugly but works. 
   
   # TODO: null handling, if a value is null...
   
   # if there only was one variable, then the results array should look like this: 
   # results = [ [first Value For The Variable], [second Value], ...]
   if sizeOfVariables == 1 then
     # the counter keeps track of the number of values, so we can insert them into the results at the right position
     counter = 0 
     while solutionIterator.hasNext
       solution = solutionIterator.next
       
       temparray = []
       # get the value associated with a variable in this specific solution
       temparray[0] = convertSesame2ActiveRDF(solution.getValue(variables[0]))
       results[counter] = temparray
       counter = counter + 1
     end    
   else
   # if there is more then one variable the results array looks like this: 
   # results = [ [Value From First Solution For First Variable, Value From First Solution For Second Variable, ...],
   #             [Value From Second Solution For First Variable, Value From Second Solution for Second Variable, ...], ...]
     counter = 0
     while solutionIterator.hasNext
       solution = solutionIterator.next
       
       temparray = []
       for n in 1..sizeOfVariables
         value = convertSesame2ActiveRDF(solution.getValue(variables[n-1]))
         temparray[n-1] = value
       end   
       results[counter] = temparray
       counter = counter + 1       
     end    
   end
   
   return results
end

#saveObject

saving is done automatically, because we run sesame2 in autocommit mode



190
191
192
# File 'lib/activerdf_sesame/sesame.rb', line 190

def save
  true
end

#sizeObject

returns the number of triples in the datastore (incl. possible duplicates)



108
109
110
# File 'lib/activerdf_sesame/sesame.rb', line 108

def size
	@db.size
end