activerdf 1.2 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -30,7 +30,7 @@ desc 'test and package gem'
30
30
  task :default => :install
31
31
 
32
32
  # get ActiveRdfVersion from commandline
33
- ActiveRdfVersion = '1.2'
33
+ ActiveRdfVersion = '1.2.1'
34
34
  NAME="activerdf"
35
35
  GEMNAME="#{NAME}-#{ActiveRdfVersion}.gem"
36
36
 
@@ -23,6 +23,7 @@ module RDFS
23
23
  def initialize uri
24
24
  raise ActiveRdfError, "creating resource <#{uri}>" unless uri.is_a?(String)
25
25
  @uri = uri
26
+ @predicates = Hash.new
26
27
  end
27
28
 
28
29
  # setting our own class uri to rdfs:resource
@@ -144,6 +145,10 @@ module RDFS
144
145
  # 4. eyal.age is a custom-written method in class Person
145
146
  # evidence: eyal type ?c, ?c.methods includes age
146
147
  # action: inject age into eyal and invoke
148
+ #
149
+ # 5. eyal.age is registered abbreviation
150
+ # evidence: age in @predicates
151
+ # action: return object from triple (eyal, @predicates[age], ?o)
147
152
 
148
153
  # maybe change order in which to check these, checking (4) is probably
149
154
  # cheaper than (1)-(2) but (1) and (2) are probably more probable (getting
@@ -151,8 +156,8 @@ module RDFS
151
156
 
152
157
  $activerdflog.debug "RDFS::Resource: method_missing on instance: called with method name #{method}"
153
158
 
154
- # are we doing an update or not?
155
- # checking if method ends with '='
159
+ # are we doing an update or not?
160
+ # checking if method ends with '='
156
161
 
157
162
  if method.to_s[-1..-1] == '='
158
163
  methodname = method.to_s[0..-2]
@@ -162,161 +167,175 @@ module RDFS
162
167
  update = false
163
168
  end
164
169
 
170
+ # check possibility (5)
171
+ if @predicates.include?(methodname)
172
+ return predicate_invocation(@predicates[methodname], args, update)
173
+ end
174
+
165
175
  candidates = if update
166
176
  (class_level_predicates + direct_predicates).compact.uniq
167
177
  else
168
178
  direct_predicates
169
179
  end
170
-
171
- # checking possibility (1) and (3)
172
- candidates.each do |pred|
173
- if Namespace.localname(pred) == methodname
174
- # found a property invocation of eyal: option 1) or 2)
175
- # query execution will return either the value for the predicate (1)
176
- # or nil (2)
177
- if update
178
- # TODO: delete old value if overwriting
179
- # FederiationManager.delete(self, pred, nil)
180
-
181
- # handling eyal.friends = [armin, andreas] --> expand array values
182
- args.each do |value|
183
- FederationManager.add(self, pred, value)
184
- end
185
- return args
186
- else
187
- # look into args, if it contains a hash with {:array => true} then
188
- # we should not flatten the query results
189
- return get_property_value(pred, args)
190
- end
191
- end
192
- end
193
-
194
- raise ActiveRdfError, "could not set #{methodname} to #{args}: no suitable
195
- predicate found. Maybe you are missing some schema information?" if update
196
-
197
- # get/set attribute value did not succeed, so checking option (2) and (4)
198
-
199
- # checking possibility (2), it is not handled correctly above since we use
200
- # direct_predicates instead of class_level_predicates. If we didn't find
201
- # anything with direct_predicates, we need to try the
202
- # class_level_predicates. Only if we don't find either, we
203
- # throw "method_missing"
204
- candidates = class_level_predicates
205
-
206
- # if any of the class_level candidates fits the sought method, then we
207
- # found situation (2), so we return nil or [] depending on the {:array =>
208
- # true} value
209
- if candidates.any?{|c| Namespace.localname(c) == methodname}
210
- return_ary = args[0][:array] if args[0].is_a? Hash
211
- if return_ary
212
- return []
213
- else
214
- return nil
215
180
 
216
- end
217
- end
181
+ # checking possibility (1) and (3)
182
+ candidates.each do |pred|
183
+ if Namespace.localname(pred) == methodname
184
+ return predicate_invocation(pred, args, update)
185
+ end
186
+ end
187
+
188
+ raise ActiveRdfError, "could not set #{methodname} to #{args}: no suitable
189
+ predicate found. Maybe you are missing some schema information?" if update
190
+
191
+ # get/set attribute value did not succeed, so checking option (2) and (4)
192
+
193
+ # checking possibility (2), it is not handled correctly above since we use
194
+ # direct_predicates instead of class_level_predicates. If we didn't find
195
+ # anything with direct_predicates, we need to try the
196
+ # class_level_predicates. Only if we don't find either, we
197
+ # throw "method_missing"
198
+ candidates = class_level_predicates
199
+
200
+ # if any of the class_level candidates fits the sought method, then we
201
+ # found situation (2), so we return nil or [] depending on the {:array =>
202
+ # true} value
203
+ if candidates.any?{|c| Namespace.localname(c) == methodname}
204
+ return_ary = args[0][:array] if args[0].is_a? Hash
205
+ if return_ary
206
+ return []
207
+ else
208
+ return nil
209
+ end
210
+ end
211
+
212
+ # checking possibility (4)
213
+ # TODO: implement search strategy to select in which class to invoke
214
+ # e.g. if to_s defined in Resource and in Person we should use Person
215
+ $activerdflog.debug "RDFS::Resource: method_missing option 4: custom class method"
216
+ self.type.each do |klass|
217
+ if klass.instance_methods.include?(method.to_s)
218
+ _dup = klass.new(uri)
219
+ return _dup.send(method,*args)
220
+ end
221
+ end
222
+
223
+ # if none of the three possibilities work out, we don't know this method
224
+ # invocation, but we don't want to throw NoMethodError, instead we return
225
+ # nil, so that eyal.age does not raise error, but returns nil. (in RDFS,
226
+ # we are never sure that eyal cannot have an age, we just dont know the
227
+ # age right now)
228
+ nil
229
+ end
218
230
 
219
- # checking possibility (4)
220
- # TODO: implement search strategy to select in which class to invoke
221
- # e.g. if to_s defined in Resource and in Person we should use Person
222
- $activerdflog.debug "RDFS::Resource: method_missing option 4: custom class method"
223
- self.type.each do |klass|
224
- if klass.instance_methods.include?(method.to_s)
225
- _dup = klass.new(uri)
226
- return _dup.send(method,*args)
227
- end
228
- end
231
+ # saves instance into datastore
232
+ def save
233
+ db = ConnectionPool.write_adapter
234
+ rdftype = Namespace.lookup(:rdf, :type)
235
+ types.each do |t|
236
+ db.add(self, rdftype, t)
237
+ end
238
+
239
+ Query.new.distinct(:p,:o).where(self, :p, :o).execute do |p, o|
240
+ db.add(self, p, o)
241
+ end
242
+ end
229
243
 
230
- # if none of the three possibilities work out, we don't know this method
231
- # invocation, but we don't want to throw NoMethodError, instead we return
232
- # nil, so that eyal.age does not raise error, but returns nil. (in RDFS,
233
- # we are never sure that eyal cannot have an age, we just dont know the
234
- # age right now)
235
- nil
236
- end
237
-
238
- # saves instance into datastore
239
- def save
240
- db = ConnectionPool.write_adapter
241
- rdftype = Namespace.lookup(:rdf, :type)
242
- types.each do |t|
243
- db.add(self, rdftype, t)
244
+ def type
245
+ types.collect do |type|
246
+ ObjectManager.construct_class(type)
247
+ end
244
248
  end
245
249
 
246
- Query.new.distinct(:p,:o).where(self, :p, :o).execute do |p, o|
247
- db.add(self, p, o)
250
+ def add_predicate localname, fulluri
251
+ localname = localname.to_s
252
+ fulluri = RDFS::Resource.new(fulluri) if fulluri.is_a? String
253
+
254
+ # predicates is a hash from abbreviation string to full uri resource
255
+ @predicates[localname] = fulluri
248
256
  end
249
- end
250
257
 
251
- def type
252
- types.collect do |type|
253
- ObjectManager.construct_class(type)
254
- end
255
- end
256
-
257
- # overrides built-in instance_of? to use rdf:type definitions
258
- def instance_of?(klass)
259
- self.type.include?(klass)
260
- end
261
-
262
- # returns all predicates that fall into the domain of the rdf:type of this
263
- # resource
264
- def class_level_predicates
265
- type = Namespace.lookup(:rdf, 'type')
266
- domain = Namespace.lookup(:rdfs, 'domain')
267
- Query.new.distinct(:p).where(self,type,:t).where(:p, domain, :t).execute || []
268
- end
269
-
270
- # returns all predicates that are directly defined for this resource
271
- def direct_predicates(distinct = true)
272
- if distinct
273
- q = Query.new.distinct(:p)
274
- else
275
- q = Query.new.select(:p)
276
- end
277
- q.where(self,:p, :o).execute
278
- end
279
-
280
- def property_accessors
281
- direct_predicates.collect {|pred| Namespace.localname(pred) }
282
- end
283
-
284
- # alias include? to ==, so that you can do paper.creator.include?(eyal)
285
- # without worrying whether paper.creator is single- or multi-valued
286
- alias include? ==
287
-
288
- # returns uri of resource, can be overridden in subclasses
289
- def to_s
290
- "<#{uri}>"
291
- end
292
-
293
- # # label of resource (rdfs:label if available, uri otherwise)
294
- # def label
295
- # get_property_value(Namespace.lookup(:rdfs,:label)) || uri
296
- # end
297
-
298
- private
299
- def get_property_value(predicate, args=[])
300
- return_ary = args[0][:array] if args[0].is_a?(Hash)
301
- flatten_results = !return_ary
302
- query = Query.new.distinct(:o).where(self, predicate, :o)
303
- query.execute(:flatten => flatten_results)
304
- end
305
-
306
- # returns all rdf:types of this resource
307
- def types
308
- type = Namespace.lookup(:rdf, :type)
309
-
310
- # we lookup the type in the database
311
- types = Query.new.distinct(:t).where(self,type,:t).execute
312
-
313
- # we are also always of type rdfs:resource and of our own class (e.g. foaf:Person)
314
- defaults = []
315
- defaults << Namespace.lookup(:rdfs,:Resource)
316
- defaults << self.class.class_uri
317
-
318
- (types + defaults).uniq
319
- end
320
258
 
321
- end
259
+ # overrides built-in instance_of? to use rdf:type definitions
260
+ def instance_of?(klass)
261
+ self.type.include?(klass)
262
+ end
263
+
264
+ # returns all predicates that fall into the domain of the rdf:type of this
265
+ # resource
266
+ def class_level_predicates
267
+ type = Namespace.lookup(:rdf, 'type')
268
+ domain = Namespace.lookup(:rdfs, 'domain')
269
+ Query.new.distinct(:p).where(self,type,:t).where(:p, domain, :t).execute || []
270
+ end
271
+
272
+ # returns all predicates that are directly defined for this resource
273
+ def direct_predicates(distinct = true)
274
+ if distinct
275
+ q = Query.new.distinct(:p)
276
+ else
277
+ q = Query.new.select(:p)
278
+ end
279
+ direct = q.where(self,:p, :o).execute
280
+ return (direct + direct.collect {|d| ancestors(d)}).flatten.uniq
281
+ end
282
+
283
+ def property_accessors
284
+ direct_predicates.collect {|pred| Namespace.localname(pred) }
285
+ end
286
+
287
+ # alias include? to ==, so that you can do paper.creator.include?(eyal)
288
+ # without worrying whether paper.creator is single- or multi-valued
289
+ alias include? ==
290
+
291
+ # returns uri of resource, can be overridden in subclasses
292
+ def to_s
293
+ "<#{uri}>"
294
+ end
295
+
296
+ # # label of resource (rdfs:label if available, uri otherwise)
297
+ # def label
298
+ # get_property_value(Namespace.lookup(:rdfs,:label)) || uri
299
+ # end
300
+
301
+ private
302
+
303
+ def ancestors(predicate)
304
+ subproperty = Namespace.lookup(:rdfs,:subPropertyOf)
305
+ Query.new.distinct(:p).where(predicate, subproperty, :p).execute
306
+ end
307
+
308
+ def predicate_invocation(predicate, args, update)
309
+ if update
310
+ args.each do |value|
311
+ FederationManager.add(self, predicate, value)
312
+ end
313
+ args
314
+ else
315
+ get_property_value(predicate, args)
316
+ end
317
+ end
318
+
319
+ def get_property_value(predicate, args=[])
320
+ return_ary = args[0][:array] if args[0].is_a?(Hash)
321
+ flatten_results = !return_ary
322
+ query = Query.new.distinct(:o).where(self, predicate, :o)
323
+ query.execute(:flatten => flatten_results)
324
+ end
325
+
326
+ # returns all rdf:types of this resource
327
+ def types
328
+ type = Namespace.lookup(:rdf, :type)
329
+
330
+ # we lookup the type in the database
331
+ types = Query.new.distinct(:t).where(self,type,:t).execute
332
+
333
+ # we are also always of type rdfs:resource and of our own class (e.g. foaf:Person)
334
+ defaults = []
335
+ defaults << Namespace.lookup(:rdfs,:Resource)
336
+ defaults << self.class.class_uri
337
+
338
+ (types + defaults).uniq
339
+ end
340
+ end
322
341
  end
data/lib/active_rdf.rb CHANGED
@@ -27,20 +27,20 @@ def load_adapter s
27
27
  end
28
28
 
29
29
  require 'rubygems'
30
- #determine if we are installed as a gem right now:
31
- if Gem::cache().search("activerdf").empty?
32
- #we are not running as a gem
33
- $activerdflog.info 'ActiveRDF is NOT installed as a Gem'
34
- load_adapter this_dir + '/../activerdf-rdflite/lib/activerdf_rdflite/rdflite'
35
- load_adapter this_dir + '/../activerdf-rdflite/lib/activerdf_rdflite/fetching'
36
- load_adapter this_dir + '/../activerdf-rdflite/lib/activerdf_rdflite/suggesting'
37
- load_adapter this_dir + '/../activerdf-redland/lib/activerdf_redland/redland'
38
- load_adapter this_dir + '/../activerdf-sparql/lib/activerdf_sparql/sparql'
39
- load_adapter this_dir + '/../activerdf-yars/lib/activerdf_yars/jars2'
30
+ # determine whether activerdf is installed as a gem:
31
+ if Gem::cache.search(/^activerdf$/).empty?
32
+ # we are not running as a gem
33
+ $activerdflog.info 'ActiveRDF is NOT installed as a Gem'
34
+ load_adapter this_dir + '/../activerdf-rdflite/lib/activerdf_rdflite/rdflite'
35
+ load_adapter this_dir + '/../activerdf-rdflite/lib/activerdf_rdflite/fetching'
36
+ load_adapter this_dir + '/../activerdf-rdflite/lib/activerdf_rdflite/suggesting'
37
+ load_adapter this_dir + '/../activerdf-redland/lib/activerdf_redland/redland'
38
+ load_adapter this_dir + '/../activerdf-sparql/lib/activerdf_sparql/sparql'
39
+ load_adapter this_dir + '/../activerdf-yars/lib/activerdf_yars/jars2'
40
40
  else
41
- #we are indeed running as a gem
42
- require 'gem_plugin'
43
- $activerdflog.info 'ActiveRDF is installed as a Gem'
44
- GemPlugin::Manager.instance.load "activerdf" => GemPlugin::INCLUDE
41
+ # we are running as a gem
42
+ require 'gem_plugin'
43
+ $activerdflog.info 'ActiveRDF is installed as a Gem'
44
+ GemPlugin::Manager.instance.load "activerdf" => GemPlugin::INCLUDE
45
45
  end
46
46
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: activerdf
5
5
  version: !ruby/object:Gem::Version
6
- version: "1.2"
7
- date: 2006-12-21 00:00:00 +01:00
6
+ version: 1.2.1
7
+ date: 2007-01-30 00:00:00 +00:00
8
8
  summary: Offers object-oriented access to RDF (with adapters to several datastores).
9
9
  require_paths:
10
10
  - lib