activerdf_net7 1.6.16 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +63 -0
- data/activerdf-jena/lib/activerdf_jena/jena.rb +4 -4
- data/activerdf-jena/lib/activerdf_jena/jena_adapter.rb +55 -55
- data/activerdf-jena/lib/activerdf_jena/lucene.rb +1 -1
- data/activerdf-jena/lib/activerdf_jena/ng4j.rb +7 -7
- data/activerdf-jena/lib/activerdf_jena/ng4j_adapter.rb +47 -47
- data/activerdf-jena/lib/activerdf_jena/pellet.rb +1 -1
- data/activerdf-jena/test/test_jena_adapter.rb +121 -120
- data/activerdf-jena/test/test_ng4j_adapter.rb +111 -110
- data/activerdf-rdflite/lib/activerdf_rdflite/fetching.rb +23 -19
- data/activerdf-rdflite/lib/activerdf_rdflite/rdflite.rb +153 -277
- data/activerdf-rdflite/lib/activerdf_rdflite/suggesting.rb +2 -2
- data/activerdf-rdflite/test/test_fetching.rb +7 -22
- data/activerdf-rdflite/test/test_rdflite.rb +44 -257
- data/activerdf-redland/lib/activerdf_redland/redland.rb +246 -282
- data/activerdf-redland/test/test_redland_adapter.rb +62 -224
- data/activerdf-sesame/ext/wrapper-sesame2.jar +0 -0
- data/activerdf-sesame/java/build.number +2 -2
- data/activerdf-sesame/java/build.xml +0 -0
- data/activerdf-sesame/java/lib/junit-3.8.2.jar +0 -0
- data/activerdf-sesame/java/settings.xml +0 -0
- data/activerdf-sesame/java/src/org/activerdf/wrapper/sesame2/WrapperForSesame2.java +0 -0
- data/activerdf-sesame/java/temp/build/org/activerdf/wrapper/sesame2/WrapperForSesame2.class +0 -0
- data/activerdf-sesame/java/temp/manifest/MANIFEST.MF +2 -2
- data/activerdf-sesame/java/test-src/org/activerdf/wrapper/sesame2/TestWrapperForSesame2.java +0 -0
- data/activerdf-sesame/lib/activerdf_sesame/sesame.rb +360 -364
- data/activerdf-sesame/test/test_sesame_adapter.rb +85 -83
- data/activerdf-sparql/lib/activerdf_sparql/sparql.rb +147 -148
- data/activerdf-sparql/lib/activerdf_sparql/sparql_result_parser.rb +5 -5
- data/activerdf-sparql/test/test_sparql_adapter.rb +2 -0
- data/activerdf-yars/lib/activerdf_yars/jars2.rb +85 -83
- data/lib/active_rdf/federation/active_rdf_adapter.rb +26 -39
- data/lib/active_rdf/federation/connection_pool.rb +119 -110
- data/lib/active_rdf/federation/federation_manager.rb +51 -51
- data/lib/active_rdf/objectmanager/bnode.rb +8 -2
- data/lib/active_rdf/objectmanager/literal.rb +81 -50
- data/lib/active_rdf/objectmanager/namespace.rb +117 -84
- data/lib/active_rdf/objectmanager/object_manager.rb +101 -96
- data/lib/active_rdf/objectmanager/ordered_set.rb +1 -1
- data/lib/active_rdf/objectmanager/property.rb +345 -0
- data/lib/active_rdf/objectmanager/property_list.rb +4 -4
- data/lib/active_rdf/objectmanager/property_lookup.rb +57 -0
- data/lib/active_rdf/objectmanager/resource.rb +293 -501
- data/lib/active_rdf/objectmanager/resource_like.rb +2 -2
- data/lib/active_rdf/objectmanager/resource_query.rb +85 -0
- data/lib/active_rdf/queryengine/ntriples_parser.rb +75 -68
- data/lib/active_rdf/queryengine/query.rb +237 -183
- data/lib/active_rdf/queryengine/query2jars2.rb +17 -15
- data/lib/active_rdf/queryengine/query2sparql.rb +107 -101
- data/lib/active_rdf.rb +28 -17
- data/lib/active_rdf_helpers.rb +37 -5
- data/lib/active_rdf_log.rb +11 -11
- data/test/adapters/test_activerdf_adapter.rb +138 -0
- data/test/{test_adapters.rb → adapters/test_adapters.rb} +6 -24
- data/test/adapters/test_bnode_capable_adapter.rb +31 -0
- data/test/adapters/test_context_aware_adapter.rb +31 -0
- data/test/adapters/test_network_aware_adapter.rb +29 -0
- data/test/adapters/test_persistent_adapter.rb +21 -0
- data/test/adapters/test_read_only_adapter.rb +15 -0
- data/test/adapters/test_reasoning_adapter.rb +11 -0
- data/test/adapters/test_writable_adapter.rb +163 -0
- data/test/common.rb +78 -96
- data/test/federation/test_connection_pool.rb +25 -44
- data/test/federation/test_federation_manager.rb +45 -45
- data/test/objectmanager/test_literal.rb +47 -26
- data/test/objectmanager/test_namespace.rb +3 -1
- data/test/objectmanager/test_object_manager.rb +35 -45
- data/test/objectmanager/test_ordered_set.rb +1 -1
- data/test/objectmanager/test_property.rb +261 -0
- data/test/objectmanager/test_resource_reading.rb +196 -104
- data/test/objectmanager/test_resource_reasoning.rb +26 -0
- data/test/objectmanager/test_resource_writing.rb +34 -25
- data/test/queryengine/my_external_resource.rb +5 -1
- data/test/queryengine/test_external_resource_class.rb +1 -8
- data/test/queryengine/test_ntriples_parser.rb +5 -3
- data/test/queryengine/test_query.rb +3 -3
- data/test/queryengine/test_query2jars2.rb +2 -2
- data/test/queryengine/test_query2sparql.rb +2 -2
- data/test/queryengine/test_query_engine.rb +46 -28
- metadata +16 -8
- data/activerdf-rdflite/test/test_bnode_data.nt +0 -5
- data/activerdf-rdflite/test/test_data.nt +0 -32
- data/activerdf-rdflite/test/test_escaped_data.nt +0 -2
- data/activerdf-redland/test/test_person_data.nt +0 -42
- data/test/objectmanager/test_talia_syntax.rb +0 -68
@@ -1,7 +1,7 @@
|
|
1
|
-
|
1
|
+
require 'active_rdf'
|
2
2
|
require 'objectmanager/object_manager'
|
3
3
|
require 'objectmanager/namespace'
|
4
|
-
require '
|
4
|
+
require 'queryengine/query'
|
5
5
|
require 'instance_exec'
|
6
6
|
|
7
7
|
module RDFS
|
@@ -9,601 +9,393 @@ module RDFS
|
|
9
9
|
# including data lookup (e.g. eyal.age), data updates (e.g. eyal.age=20),
|
10
10
|
# class-level lookup (Person.find_by_name 'eyal'), and class-membership
|
11
11
|
# (eyal.class ...Person).
|
12
|
+
class RDFS::Resource
|
13
|
+
##### #####
|
14
|
+
##### class level methods #####
|
15
|
+
##### #####
|
12
16
|
|
13
|
-
class Resource
|
14
|
-
|
15
|
-
include ResourceLike
|
16
|
-
|
17
|
-
# adding accessor to the class uri:
|
18
|
-
# the uri of the rdf resource being represented by this class
|
19
17
|
class << self
|
20
18
|
attr_accessor :class_uri
|
21
19
|
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# creates new resource representing an RDF resource
|
27
|
-
def initialize uri
|
28
|
-
@uri = case uri
|
29
|
-
# allow Resource.new(other_resource)
|
30
|
-
when RDFS::Resource
|
31
|
-
uri.uri
|
32
|
-
# allow Resource.new('<uri>') by stripping out <>
|
33
|
-
when /^<([^>]*)>$/
|
34
|
-
$1
|
35
|
-
# allow Resource.new('uri')
|
36
|
-
when String
|
37
|
-
uri
|
38
|
-
else
|
39
|
-
raise ActiveRdfError, "cannot create resource <#{uri}>"
|
40
|
-
end
|
41
|
-
@predicates = Hash.new
|
21
|
+
def Resource.uri
|
22
|
+
class_uri.uri
|
42
23
|
end
|
43
24
|
|
44
|
-
|
45
|
-
# (has to be done after defining our RDFS::Resource.new
|
46
|
-
# because it cannot be found in Namespace.lookup otherwise)
|
47
|
-
self.class_uri = Namespace.lookup(:rdfs, :Resource)
|
48
|
-
|
49
|
-
def self.uri; class_uri.uri; end
|
50
|
-
def self.==(other)
|
25
|
+
def Resource.==(other)
|
51
26
|
other.respond_to?(:uri) ? other.uri == self.uri : false
|
52
27
|
end
|
53
|
-
def self.localname; Namespace.localname(self); end
|
54
|
-
|
55
|
-
##### ######
|
56
|
-
##### start of instance-level code
|
57
|
-
##### ######
|
58
28
|
|
59
|
-
def
|
60
|
-
|
61
|
-
def ==(other);
|
62
|
-
other.respond_to?(:uri) ? other.uri == self.uri : false
|
29
|
+
def Resource.eql?(other)
|
30
|
+
self == other
|
63
31
|
end
|
64
|
-
alias_method 'eql?','=='
|
65
32
|
|
66
|
-
|
67
|
-
|
68
|
-
def hash; uri.hash; end
|
69
|
-
|
70
|
-
def self.to_ntriple; "<#{class_uri.uri}>"; end
|
71
|
-
|
72
|
-
def to_xml
|
73
|
-
base = Namespace.expand(Namespace.prefix(self),'').chop
|
74
|
-
|
75
|
-
xml = "<?xml version=\"1.0\"?>\n"
|
76
|
-
xml += "<rdf:RDF xmlns=\"#{base}\#\"\n"
|
77
|
-
Namespace.abbreviations.each { |p| uri = Namespace.expand(p,''); xml += " xmlns:#{p.to_s}=\"#{uri}\"\n" if uri != base + '#' }
|
78
|
-
xml += " xml:base=\"#{base}\">\n"
|
79
|
-
|
80
|
-
xml += "<rdf:Description rdf:about=\"\##{localname}\">\n"
|
81
|
-
direct_predicates.each do |p|
|
82
|
-
objects = Query.new.distinct(:o).where(self, p, :o).execute
|
83
|
-
objects.each do |obj|
|
84
|
-
prefix, localname = Namespace.prefix(p), Namespace.localname(p)
|
85
|
-
pred_xml = if prefix
|
86
|
-
"%s:%s" % [prefix, localname]
|
87
|
-
else
|
88
|
-
p.uri
|
89
|
-
end
|
90
|
-
|
91
|
-
case obj
|
92
|
-
when RDFS::Resource
|
93
|
-
xml += " <#{pred_xml} rdf:resource=\"#{obj.uri}\"/>\n"
|
94
|
-
when LocalizedString
|
95
|
-
xml += " <#{pred_xml} xml:lang=\"#{obj.lang}\">#{obj}</#{pred_xml}>\n"
|
96
|
-
else
|
97
|
-
xml += " <#{pred_xml} rdf:datatype=\"#{obj.xsd_type.uri}\">#{obj}</#{pred_xml}>\n"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
xml += "</rdf:Description>\n"
|
102
|
-
xml += "</rdf:RDF>"
|
33
|
+
def Resource.localname
|
34
|
+
ActiveRDF::Namespace.localname(self)
|
103
35
|
end
|
104
36
|
|
105
|
-
##### #####
|
106
|
-
##### class level methods #####
|
107
|
-
##### #####
|
108
|
-
|
109
37
|
# returns the predicates that have this resource as their domain (applicable
|
110
38
|
# predicates for this resource)
|
111
39
|
def Resource.predicates
|
112
|
-
|
113
|
-
Query.new.distinct(:p).where(:p, domain, class_uri).execute || []
|
40
|
+
class_uri.instance_predicates
|
114
41
|
end
|
115
42
|
|
116
|
-
|
117
|
-
|
118
|
-
def [](property)
|
119
|
-
if !property.instance_of?(RDFS::Resource)
|
120
|
-
property = RDFS::Resource.new(property)
|
121
|
-
end
|
122
|
-
|
123
|
-
plv = Query.new.distinct(:o).where(self, property, :o).execute
|
124
|
-
|
125
|
-
# make and return new propertis collection
|
126
|
-
PropertyList.new(property, plv, self)
|
43
|
+
def Resource.properties
|
44
|
+
predicates.collect{|prop| RDF::Property.new(prop)}
|
127
45
|
end
|
128
46
|
|
129
|
-
#
|
130
|
-
|
131
|
-
|
132
|
-
if /find_by_(.+)/.match(method.to_s)
|
133
|
-
ActiveRdfLogger::log_debug "Constructing dynamic finder for #{method}", self
|
134
|
-
|
135
|
-
# construct proxy to handle delayed lookups
|
136
|
-
# (find_by_foaf::name_and_foaf::age)
|
137
|
-
proxy = DynamicFinderProxy.new($1, nil, *args)
|
138
|
-
|
139
|
-
# if proxy already found a value (find_by_name) we will not get a more
|
140
|
-
# complex query, so return the value. Otherwise, return the proxy so that
|
141
|
-
# subsequent lookups are handled
|
142
|
-
return proxy.value || proxy
|
143
|
-
end
|
47
|
+
# Find all resources of this type
|
48
|
+
def Resource.find_all(options = {}, &blk)
|
49
|
+
ActiveRDF::ResourceQuery.new(self,options.delete(:context)).execute(options,&blk)
|
144
50
|
end
|
145
51
|
|
146
|
-
#
|
147
|
-
#
|
148
|
-
def Resource.
|
149
|
-
|
52
|
+
# Find resources of this type, restricted by optional property args
|
53
|
+
# see ActiveRDF::ResourceQuery usage
|
54
|
+
def Resource.find_by(context = nil)
|
55
|
+
ActiveRDF::ResourceQuery.new(self,context)
|
150
56
|
end
|
151
57
|
|
152
|
-
|
153
|
-
|
58
|
+
# Find an existing resource with the given uri, otherwise returns nil
|
59
|
+
def Resource.find(uri)
|
60
|
+
res = Resource.new(uri)
|
61
|
+
res unless res.new_record?
|
154
62
|
end
|
155
63
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
# extract sort options from args
|
161
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
162
|
-
|
163
|
-
query = Query.new.distinct(:s)
|
164
|
-
query.where(:s, Namespace.lookup(:rdf,:type), self)
|
64
|
+
# Pass all other methods to class_uri
|
65
|
+
def Resource.method_missing(method,*args)
|
66
|
+
class_uri.send(method,*args)
|
67
|
+
end
|
165
68
|
|
166
|
-
|
167
|
-
|
168
|
-
query.sort(:sort_value)
|
169
|
-
query.where(:s, sort_predicate, :sort_value)
|
170
|
-
end
|
69
|
+
# uri of the resource (for instances of this class: rdf resources)
|
70
|
+
attr_reader :uri
|
171
71
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
72
|
+
# creates new resource representing an RDF resource
|
73
|
+
def initialize(uri_or_resource)
|
74
|
+
@uri = case uri_or_resource
|
75
|
+
# allow Resource.new(other_resource)
|
76
|
+
when RDFS::Resource
|
77
|
+
uri_or_resource.uri
|
78
|
+
# allow Resource.new('<uri>') by stripping out <>
|
79
|
+
when /^<([^>]*)>$/
|
80
|
+
$1
|
81
|
+
# allow Resource.new('uri')
|
82
|
+
when String
|
83
|
+
uri_or_resource
|
84
|
+
else
|
85
|
+
raise ActiveRdfError, "cannot create resource <#{uri_or_resource}>"
|
86
|
+
end
|
87
|
+
end
|
177
88
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
query.where(:s, p, o, options[:context])
|
183
|
-
else
|
184
|
-
query.where(:s, p, o)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
else
|
188
|
-
if options[:context]
|
189
|
-
query.where(:s, :p, :o, options[:context])
|
190
|
-
end
|
191
|
-
end
|
89
|
+
# setting our own class uri to rdfs:resource
|
90
|
+
# (has to be done after defining our RDFS::Resource.new
|
91
|
+
# because it cannot be found in ActiveRDF::Namespace.lookup otherwise)
|
92
|
+
self.class_uri = ActiveRDF::Namespace.lookup(:rdfs, :Resource)
|
192
93
|
|
193
|
-
|
194
|
-
|
94
|
+
##### #####
|
95
|
+
##### instance level methods #####
|
96
|
+
##### #####
|
195
97
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
end
|
200
|
-
else
|
201
|
-
query.execute(:flatten => false)
|
202
|
-
end
|
98
|
+
# a resource is same as another if they both represent the same uri
|
99
|
+
def ==(other);
|
100
|
+
other.respond_to?(:uri) ? other.uri == self.uri : false
|
203
101
|
end
|
102
|
+
alias_method 'eql?','=='
|
204
103
|
|
205
|
-
|
206
|
-
|
104
|
+
# overriding hash to use uri.hash
|
105
|
+
# needed for array.uniq
|
106
|
+
def hash
|
107
|
+
uri.hash
|
207
108
|
end
|
208
109
|
|
209
|
-
#
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
def inverse
|
214
|
-
inverseobj = Object.new
|
215
|
-
inverseobj.instance_variable_set(:@obj_uri, self)
|
216
|
-
|
217
|
-
class <<inverseobj
|
218
|
-
|
219
|
-
def [](property_uri)
|
220
|
-
property = RDFS::Resource.new(property_uri)
|
221
|
-
Query.new.distinct(:s).where(:s, property, @obj_uri).execute
|
222
|
-
end
|
223
|
-
private(:type)
|
224
|
-
end
|
225
|
-
|
226
|
-
return inverseobj
|
227
|
-
end
|
228
|
-
|
229
|
-
# manages invocations such as eyal.age
|
230
|
-
def method_missing(method, *args,&block)
|
231
|
-
# possibilities:
|
232
|
-
# 1. eyal.age is a property of eyal (triple exists <eyal> <age> "30")
|
233
|
-
# evidence: eyal age ?a, ?a is not nil (only if value exists)
|
234
|
-
# action: return ?a
|
235
|
-
#
|
236
|
-
# 2. eyal's class is in domain of age, but does not have value for eyal
|
237
|
-
# explain: eyal is a person and some other person (not eyal) has an age
|
238
|
-
# evidence: eyal type ?c, age domain ?c
|
239
|
-
# action: return nil
|
240
|
-
#
|
241
|
-
# 3. eyal.age = 30 (setting a value for a property)
|
242
|
-
# explain: eyal has (or could have) a value for age, and we update that value
|
243
|
-
# complication: we need to find the full URI for age (by looking at
|
244
|
-
# possible predicates to use
|
245
|
-
# evidence: eyal age ?o (eyal has a value for age now, we're updating it)
|
246
|
-
# evidence: eyal type ?c, age domain ?c (eyal could have a value for age, we're setting it)
|
247
|
-
# action: add triple (eyal, age, 30), return 30
|
248
|
-
#
|
249
|
-
# 4. eyal.age is a custom-written method in class Person
|
250
|
-
# evidence: eyal type ?c, ?c.methods includes age
|
251
|
-
# action: inject age into eyal and invoke
|
252
|
-
#
|
253
|
-
# 5. eyal.age is registered abbreviation
|
254
|
-
# evidence: age in @predicates
|
255
|
-
# action: return object from triple (eyal, @predicates[age], ?o)
|
256
|
-
#
|
257
|
-
# 6. eyal.foaf::name, where foaf is a registered abbreviation
|
258
|
-
# evidence: foaf in Namespace.
|
259
|
-
# action: return namespace proxy that handles 'name' invocation, by
|
260
|
-
# rewriting into predicate lookup (similar to case (5)
|
261
|
-
|
262
|
-
ActiveRdfLogger.log_debug(self) { "Method_missing: #{method}" }
|
263
|
-
|
264
|
-
# are we doing an update or not?
|
265
|
-
# checking if method ends with '='
|
266
|
-
|
267
|
-
update = method.to_s[-1..-1] == '='
|
268
|
-
methodname = if update
|
269
|
-
method.to_s[0..-2]
|
270
|
-
else
|
271
|
-
method.to_s
|
272
|
-
end
|
273
|
-
|
274
|
-
# extract single values from array unless user asked for eyal.all_age
|
275
|
-
flatten = true
|
276
|
-
if method.to_s[0..3] == 'all_'
|
277
|
-
flatten = false
|
278
|
-
methodname = methodname[4..-1]
|
279
|
-
end
|
280
|
-
|
281
|
-
# check possibility (5)
|
282
|
-
if @predicates.include?(methodname)
|
283
|
-
if update
|
284
|
-
return set_predicate(@predicates[methodname], args)
|
285
|
-
else
|
286
|
-
return get_predicate(@predicates[methodname], false, &block)
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
# check possibility (6)
|
291
|
-
if Namespace.abbreviations.include?(methodname.to_sym)
|
292
|
-
namespace = Object.new
|
293
|
-
namespace.instance_variable_set(:@uri, methodname)
|
294
|
-
namespace.instance_variable_set(:@subject, self)
|
295
|
-
namespace.instance_variable_set(:@flatten, flatten)
|
296
|
-
|
297
|
-
# catch the invocation on the namespace
|
298
|
-
class <<namespace
|
299
|
-
def method_missing(localname, *values, &block)
|
300
|
-
update = localname.to_s[-1..-1] == '='
|
301
|
-
predicate = if update
|
302
|
-
Namespace.lookup(@uri, localname.to_s[0..-2])
|
303
|
-
else
|
304
|
-
Namespace.lookup(@uri, localname)
|
305
|
-
end
|
110
|
+
# overriding sort based on uri
|
111
|
+
def <=>(other)
|
112
|
+
uri <=> other.uri
|
113
|
+
end
|
306
114
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
end
|
312
|
-
end
|
313
|
-
private(:type)
|
314
|
-
end
|
315
|
-
return namespace
|
316
|
-
end
|
115
|
+
def is_a?(klass)
|
116
|
+
klass = ActiveRDF::ObjectManager.construct_class(klass)
|
117
|
+
super || types.any?{|t| klass == t}
|
118
|
+
end
|
317
119
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
end
|
120
|
+
def instance_of?(klass)
|
121
|
+
klass = ActiveRDF::ObjectManager.construct_class(klass)
|
122
|
+
super || direct_types.any?{|t| klass == t}
|
123
|
+
end
|
323
124
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
if update
|
328
|
-
return set_predicate(pred, args)
|
329
|
-
else
|
330
|
-
return get_predicate(pred, flatten, &block)
|
331
|
-
end
|
332
|
-
end
|
333
|
-
end
|
125
|
+
def new_record?
|
126
|
+
ActiveRDF::Query.new.count(:p).where(self,:p,:o).execute == 0
|
127
|
+
end
|
334
128
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
# direct_predicates instead of class_level_predicates. If we didn't find
|
341
|
-
# anything with direct_predicates, we need to try the
|
342
|
-
# class_level_predicates. Only if we don't find either, we
|
343
|
-
# throw "method_missing"
|
344
|
-
candidates = class_level_predicates
|
345
|
-
|
346
|
-
# if any of the class_level candidates fits the sought method, then we
|
347
|
-
# found situation (2), so we return nil or [] depending on the {:array =>
|
348
|
-
# true} value
|
349
|
-
if candidates.any?{ |c| Namespace.localname(c) == methodname }
|
350
|
-
return_ary = args[0][:array] if args[0].is_a? Hash
|
351
|
-
if return_ary
|
352
|
-
return []
|
353
|
-
else
|
354
|
-
return nil
|
355
|
-
end
|
356
|
-
end
|
129
|
+
# saves instance into datastore
|
130
|
+
def save
|
131
|
+
ActiveRDF::ConnectionPool.write_adapter.add(self,RDF::type,self.class)
|
132
|
+
self
|
133
|
+
end
|
357
134
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
ActiveRdfLogger::log_debug(self){ "RDFS::Resource: method_missing option 4: custom class method" }
|
362
|
-
self.type.each do |klass|
|
363
|
-
if klass.instance_methods.include?(method.to_s)
|
364
|
-
_dup = klass.new(uri)
|
365
|
-
return _dup.send(method,*args)
|
366
|
-
end
|
367
|
-
end
|
135
|
+
def abbreviation
|
136
|
+
[ActiveRDF::Namespace.prefix(uri).to_s, localname]
|
137
|
+
end
|
368
138
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
# age right now)
|
374
|
-
nil
|
139
|
+
# get an abbreviation from to_s
|
140
|
+
# returns a copy of uri if no abbreviation found
|
141
|
+
def abbr
|
142
|
+
(abbr = ActiveRDF::Namespace.abbreviate(uri)) ? abbr : uri
|
375
143
|
end
|
376
144
|
|
377
|
-
#
|
378
|
-
def
|
379
|
-
|
380
|
-
|
381
|
-
types.each do |t|
|
382
|
-
db.add(self, rdftype, t)
|
383
|
-
end
|
145
|
+
# checks if an abbrivation exists for this resource
|
146
|
+
def abbr?
|
147
|
+
ActiveRDF::Namespace.prefix(self) ? true : false
|
148
|
+
end
|
384
149
|
|
385
|
-
|
386
|
-
|
387
|
-
end
|
150
|
+
def localname
|
151
|
+
ActiveRDF::Namespace.localname(self)
|
388
152
|
end
|
389
153
|
|
390
|
-
# returns
|
391
|
-
# FOAF::Person]
|
154
|
+
# returns an RDF::Property for RDF::type's of this resource, e.g. [RDFS::Resource, FOAF::Person]
|
392
155
|
#
|
393
|
-
# Note: this method performs a database lookup for { self rdf:type ?o }.
|
394
|
-
# simple type-checking (to know if you are handling an ActiveRDF object,
|
395
|
-
# self.class, which does not do a database query, but simply returns
|
156
|
+
# Note: this method performs a database lookup for { self rdf:type ?o }.
|
157
|
+
# For simple type-checking (to know if you are handling an ActiveRDF object,
|
158
|
+
# use self.class, which does not do a database query, but simply returns
|
396
159
|
# RDFS::Resource.
|
397
160
|
def type
|
398
|
-
|
399
|
-
ObjectManager.construct_class(type)
|
400
|
-
end
|
161
|
+
RDF::Property.new(RDF::type, self)
|
401
162
|
end
|
402
163
|
|
164
|
+
def type=(type)
|
165
|
+
RDF::Property.new(RDF::type, self).replace(type)
|
166
|
+
end
|
167
|
+
|
168
|
+
def types
|
169
|
+
type.to_a | [RDFS::Resource.class_uri] # all resources are subtype of RDFS::Resource
|
170
|
+
end
|
171
|
+
alias :direct_types :types
|
172
|
+
|
173
|
+
# returns array of Classes for all types
|
174
|
+
def classes
|
175
|
+
types.collect{|type_res| ActiveRDF::ObjectManager.construct_class(type_res)}
|
176
|
+
end
|
177
|
+
|
178
|
+
# TODO: remove
|
403
179
|
# define a localname for a predicate URI
|
404
180
|
#
|
405
|
-
# localname should be a Symbol or String, fulluri a Resource or String, e.g.
|
406
|
-
#
|
407
|
-
def
|
181
|
+
# localname should be a Symbol or String, fulluri a Resource or String, e.g.
|
182
|
+
# register_predicate(:name, FOAF::lastName)
|
183
|
+
def register_predicate(localname, fulluri)
|
184
|
+
warn "Registered predicates is deprecated. Please use registered namespaces instead."
|
408
185
|
localname = localname.to_s
|
409
186
|
fulluri = RDFS::Resource.new(fulluri) if fulluri.is_a? String
|
410
187
|
|
411
188
|
# predicates is a hash from abbreviation string to full uri resource
|
412
|
-
@predicates[localname] = fulluri
|
189
|
+
(@predicates ||= {})[localname] = fulluri
|
413
190
|
end
|
414
191
|
|
192
|
+
# returns array of RDFS::Resources for properties that belong to this resource
|
193
|
+
def class_predicates
|
194
|
+
ActiveRDF::Query.new.distinct(:p).where(:p,RDFS::domain,:t).where(self,RDF::type,:t).execute |
|
195
|
+
ActiveRDF::Query.new.distinct(:p).where(:p,RDFS::domain,RDFS::Resource).execute # all resources share RDFS::Resource properties
|
196
|
+
end
|
197
|
+
alias class_level_predicates class_predicates
|
415
198
|
|
416
|
-
#
|
417
|
-
def
|
418
|
-
|
199
|
+
# returns array of RDF::Propertys for properties that belong to this resource
|
200
|
+
def class_properties
|
201
|
+
class_predicates.collect{|prop| RDF::Property.new(prop,self)}
|
419
202
|
end
|
420
203
|
|
421
|
-
# returns
|
422
|
-
|
423
|
-
|
424
|
-
type = Namespace.lookup(:rdf, 'type')
|
425
|
-
domain = Namespace.lookup(:rdfs, 'domain')
|
426
|
-
Query.new.distinct(:p).where(self,type,:t).where(:p, domain, :t).execute || []
|
204
|
+
# returns array of RDFS::Resources for properties that are directly defined for this resource
|
205
|
+
def direct_predicates
|
206
|
+
ActiveRDF::Query.new.distinct(:p).where(self,:p,:o).execute
|
427
207
|
end
|
428
208
|
|
429
|
-
# returns
|
430
|
-
def
|
431
|
-
|
432
|
-
Query.new.distinct(:p).where(self, :p, :o).execute
|
433
|
-
else
|
434
|
-
Query.new.select(:p).where(self, :p, :o).execute
|
435
|
-
end
|
209
|
+
# returns array of RDF::Propertys that are directly defined for this resource
|
210
|
+
def direct_properties
|
211
|
+
direct_predicates.collect{|prop| RDF::Property.new(prop,self)}
|
436
212
|
end
|
437
213
|
|
438
|
-
|
439
|
-
|
214
|
+
# returns array of RDFS::Resources for all known properties of this resource
|
215
|
+
def predicates
|
216
|
+
direct_predicates | class_predicates
|
440
217
|
end
|
441
218
|
|
442
|
-
#
|
443
|
-
|
444
|
-
|
219
|
+
# returns array of RDF::Propertys for all known properties of this resource
|
220
|
+
def properties
|
221
|
+
predicates.collect{|prop| RDF::Property.new(prop,self)}
|
222
|
+
end
|
445
223
|
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
values
|
224
|
+
# returns array RDFS::Resources for known properties that do not have a value
|
225
|
+
def empty_predicates
|
226
|
+
empty_properties.collect{|prop| RDFS::Resource.new(prop)}
|
450
227
|
end
|
451
228
|
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
end
|
457
|
-
values = query.execute(:flatten => flatten)
|
458
|
-
|
459
|
-
# TODO: fix '<<' for Fixnum values etc (we cannot use values.instance_eval
|
460
|
-
# because Fixnum cannot do instace_eval, they're not normal classes)
|
461
|
-
if values.is_a?(RDFS::Resource) and !values.nil?
|
462
|
-
# prepare returned values for accepting << later, eg. in
|
463
|
-
# eyal.foaf::knows << knud
|
464
|
-
#
|
465
|
-
# store @subject, @predicate in returned values
|
466
|
-
values.instance_exec(self, predicate) do |s,p|
|
467
|
-
@subj = s
|
468
|
-
@pred = p
|
469
|
-
end
|
229
|
+
# returns array RDF::Propertys for known properties that do not have a value
|
230
|
+
def empty_properties
|
231
|
+
properties.reject{|prop| prop.size > 0}
|
232
|
+
end
|
470
233
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
234
|
+
# for resources of type RDFS::Class, returns array of RDFS::Resources for the known properties of their objects
|
235
|
+
def instance_predicates
|
236
|
+
ip = ActiveRDF::Query.new.distinct(:p).where(:p,RDFS::domain,self).execute
|
237
|
+
if ip.size > 0
|
238
|
+
ip |= ActiveRDF::Query.new.distinct(:p).where(:p,RDFS::domain,RDFS::Resource).execute # all resources share RDFS::Resource properties
|
239
|
+
else []
|
477
240
|
end
|
241
|
+
end
|
478
242
|
|
479
|
-
|
243
|
+
# for resources of type RDFS::Class, returns array of RDF::Propertys for the known properties of their objects
|
244
|
+
def instance_properties
|
245
|
+
instance_predicates.collect{|prop| RDF::Property.new(prop,self)}
|
480
246
|
end
|
481
247
|
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
# Query.new.distinct(:p).where(predicate, subproperty, :p).execute
|
486
|
-
# end
|
248
|
+
def contexts
|
249
|
+
ActiveRDF::Query.new.distinct(:c).where(self,nil,nil,:c).execute
|
250
|
+
end
|
487
251
|
|
252
|
+
if $activerdf_internal_reasoning
|
253
|
+
# Add support for some limited RDFS reasoning
|
488
254
|
|
489
|
-
|
490
|
-
# Ruby classes (it returns an array of RDFS::Resources)
|
491
|
-
def types
|
492
|
-
type = Namespace.lookup(:rdf, :type)
|
255
|
+
### Overidden methods
|
493
256
|
|
494
|
-
#
|
495
|
-
types
|
257
|
+
# returns array of RDFS::Resources for all types, including supertypes
|
258
|
+
def types
|
259
|
+
types = self.type.to_a
|
260
|
+
types |= types.collect{|type| type.super_types}.flatten
|
261
|
+
types |= [RDFS::Resource.class_uri] # all resources are subtype of RDFS::Resource
|
262
|
+
types
|
263
|
+
end
|
496
264
|
|
497
|
-
#
|
498
|
-
|
499
|
-
|
500
|
-
|
265
|
+
# returns array of RDFS::Resources for the class properties of this resource, including those of its supertypes
|
266
|
+
def class_predicates
|
267
|
+
types.inject([]){|class_preds,type| class_preds |= type.instance_predicates}
|
268
|
+
end
|
501
269
|
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
#
|
508
|
-
|
509
|
-
|
510
|
-
@where = nil
|
511
|
-
@value = nil
|
512
|
-
attr_reader :value
|
513
|
-
private(:type)
|
514
|
-
|
515
|
-
# construct proxy from find_by text
|
516
|
-
# foaf::name
|
517
|
-
def initialize(find_string, where, *args)
|
518
|
-
@where = where || []
|
519
|
-
parse_attributes(find_string, *args)
|
520
|
-
end
|
270
|
+
# for resources of type RDFS::Class, returns array of RDFS::Resources for the known properties of their objects, including those of its supertypes
|
271
|
+
def instance_predicates
|
272
|
+
preds = ActiveRDF::Query.new.distinct(:p).where(:p,RDFS::domain,self).execute
|
273
|
+
preds |= preds.collect{|p| p.super_predicates}.flatten
|
274
|
+
preds |= super_types.collect{|type| type.instance_predicates}.flatten
|
275
|
+
preds |= ActiveRDF::Query.new.distinct(:p).where(:p,RDFS::domain,RDFS::Resource).execute # all resources share RDFS::Resource properties
|
276
|
+
preds
|
277
|
+
end
|
521
278
|
|
522
|
-
|
523
|
-
# we store the ns:name for later (we need to wait until we have the
|
524
|
-
# arguments before actually constructing the where clause): now we just
|
525
|
-
# store that a where clause should appear about foaf:name
|
279
|
+
### New methods
|
526
280
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
@where << Namespace.lookup(@ns, method.to_s)
|
533
|
-
query(*args)
|
534
|
-
end
|
535
|
-
end
|
281
|
+
# for resources of type RDFS::Class, returns array of RDFS::Resources for all super types defined by RDF::subClassOf
|
282
|
+
def super_types
|
283
|
+
sups = ActiveRDF::Query.new.distinct(:super_class).where(self,RDFS::subClassOf,:super_class).execute
|
284
|
+
sups |= sups.inject([]){|supsups, sup| supsups |= sup.super_types}
|
285
|
+
end
|
536
286
|
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
attributes.each do |atr|
|
542
|
-
# attribute can be:
|
543
|
-
# - a namespace prefix (foaf): store prefix in @ns to prepare for method_missing
|
544
|
-
# - name (attribute name): store in where to prepare for method_missing
|
545
|
-
if Namespace.abbreviations.include?(atr.to_sym)
|
546
|
-
@ns = atr.to_s.downcase.to_sym
|
547
|
-
else
|
548
|
-
# found simple attribute label, e.g. 'name'
|
549
|
-
# find out candidate (full) predicate for this localname: investigate
|
550
|
-
# all possible predicates and select first one with matching localname
|
551
|
-
candidates = Query.new.distinct(:p).where(:s,:p,:o).execute
|
552
|
-
@where << candidates.select {|cand| Namespace.localname(cand) == atr}.first
|
287
|
+
# for resources of type RDFS::Class, returns array of classes for all super types defined by RDF::subClassOf
|
288
|
+
# otherwise returns empty array
|
289
|
+
def super_classes
|
290
|
+
super_types.collect{|type_res| ActiveRDF::ObjectManager.construct_class(type_res)}
|
553
291
|
end
|
292
|
+
|
293
|
+
# for resources of type RDF::Property, returns array of RDFS::Resources for all super properties defined by RDFS::subPropertyOf
|
294
|
+
def super_predicates
|
295
|
+
sups = ActiveRDF::Query.new.distinct(:super_property).where(self, RDFS::subPropertyOf, :super_property).execute
|
296
|
+
sups |= sups.inject([]){|supsups, sup| supsups |= sup.super_predicates}
|
297
|
+
end
|
298
|
+
|
299
|
+
# for resources of type RDF::Property, returns array of RDF::Propertys for all super properties defined by RDFS::subPropertyOf
|
300
|
+
def super_properties
|
301
|
+
super_predicates.collect{|prop| RDF::Property.new(prop,self)}
|
302
|
+
end
|
303
|
+
|
304
|
+
# for resources of type RDF::Property, returns array of RDFS::Resources for all sub properties defined by RDFS::subPropertyOf
|
305
|
+
def sub_predicates
|
306
|
+
subs = ActiveRDF::Query.new.distinct(:sub_property).where(:sub_property, RDFS::subPropertyOf, self).execute
|
307
|
+
subs |= subs.inject([]){|subsubs, sub| subsubs |= sub.sub_predicates}
|
308
|
+
end
|
309
|
+
|
310
|
+
# for resources of type RDF::Property, returns array of RDF::Propertys for all sub properties defined by RDFS::subPropertyOf
|
311
|
+
def sub_properties
|
312
|
+
sub_predicates.collect{|prop| RDF::Property.new(prop,self)}
|
313
|
+
end
|
314
|
+
|
315
|
+
# end $activerdf_internal_reasoning
|
554
316
|
end
|
555
317
|
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
if Namespace.abbreviations.include?(attributes.last.to_sym)
|
561
|
-
return self
|
562
|
-
else
|
563
|
-
return query(*args)
|
318
|
+
alias :to_s :uri
|
319
|
+
def to_literal_s
|
320
|
+
raise ActiveRDF::ActiveRdfError, "emtpy RDFS::Resources not allowed" if self.uri.size == 0
|
321
|
+
"<#{uri}>"
|
564
322
|
end
|
565
|
-
end
|
566
323
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
324
|
+
def inspect
|
325
|
+
if ActiveRDF::ConnectionPool.adapters.size > 0
|
326
|
+
type =
|
327
|
+
if (t = self.type) and t.size > 0
|
328
|
+
t = t.collect{|res| res.abbr }
|
329
|
+
t.size > 1 ? t.inspect : t.first
|
330
|
+
else
|
331
|
+
self.class
|
332
|
+
end
|
333
|
+
label =
|
334
|
+
if abbr?
|
335
|
+
abbr
|
336
|
+
elsif (l = self.label) and l.size > 0
|
337
|
+
if l.size == 1 then l.only
|
338
|
+
else l.inspect
|
339
|
+
end
|
340
|
+
else
|
341
|
+
uri
|
342
|
+
end
|
578
343
|
else
|
579
|
-
|
344
|
+
type = self.class
|
345
|
+
label = self.uri
|
580
346
|
end
|
347
|
+
"#<#{type} #{label}>"
|
581
348
|
end
|
582
349
|
|
583
|
-
|
584
|
-
|
585
|
-
sort_predicate = options[:order]
|
586
|
-
query.sort(:sort_value)
|
587
|
-
# add sort predicate where clause unless we have it already
|
588
|
-
query.where(:s, sort_predicate, :sort_value) unless @where.include? sort_predicate
|
589
|
-
end
|
350
|
+
def to_xml
|
351
|
+
base = ActiveRDF::Namespace.expand(ActiveRDF::Namespace.prefix(self),'').chop
|
590
352
|
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
end
|
353
|
+
xml = "<?xml version=\"1.0\"?>\n"
|
354
|
+
xml += "<rdf:RDF xmlns=\"#{base}\#\"\n"
|
355
|
+
ActiveRDF::Namespace.abbreviations.each { |p| uri = ActiveRDF::Namespace.expand(p,''); xml += " xmlns:#{p.to_s}=\"#{uri}\"\n" if uri != base + '#' }
|
356
|
+
xml += " xml:base=\"#{base}\">\n"
|
596
357
|
|
597
|
-
|
598
|
-
|
358
|
+
xml += "<rdf:Description rdf:about=\"\##{localname}\">\n"
|
359
|
+
direct_predicates.each do |p|
|
360
|
+
objects = ActiveRDF::Query.new.distinct(:o).where(self, p, :o).execute
|
361
|
+
objects.each do |obj|
|
362
|
+
prefix, localname = ActiveRDF::Namespace.prefix(p), ActiveRDF::Namespace.localname(p)
|
363
|
+
pred_xml = if prefix
|
364
|
+
"%s:%s" % [prefix, localname]
|
365
|
+
else
|
366
|
+
p.uri
|
367
|
+
end
|
599
368
|
|
600
|
-
|
369
|
+
case obj
|
370
|
+
when RDFS::Resource
|
371
|
+
xml += " <#{pred_xml} rdf:resource=\"#{obj.uri}\"/>\n"
|
372
|
+
when LocalizedString
|
373
|
+
xml += " <#{pred_xml} xml:lang=\"#{obj.lang}\">#{obj}</#{pred_xml}>\n"
|
374
|
+
else
|
375
|
+
xml += " <#{pred_xml} rdf:datatype=\"#{obj.xsd_type.uri}\">#{obj}</#{pred_xml}>\n"
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
xml += "</rdf:Description>\n"
|
380
|
+
xml += "</rdf:RDF>"
|
381
|
+
end
|
382
|
+
|
383
|
+
# Searches for property belonging to this resource. Returns RDF::Property.
|
384
|
+
# Replaces any existing values if method is an assignment: resource.prop = new_value
|
385
|
+
def method_missing(method, *args)
|
386
|
+
# check for custom written method
|
387
|
+
# eyal.age is a custom-written method in class Person
|
388
|
+
# evidence: eyal type ?c, ?c.methods includes age
|
389
|
+
# action: return results from calling custom method
|
390
|
+
classes.each do |klass|
|
391
|
+
if klass.instance_methods.include?(method.to_s)
|
392
|
+
_dup = klass.new(uri)
|
393
|
+
return _dup.send(method,*args)
|
394
|
+
end
|
395
|
+
end
|
601
396
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
# itself is returned)
|
606
|
-
@value = query.execute
|
607
|
-
return @value
|
397
|
+
# otherwise pass search on to PropertyQuery
|
398
|
+
ActiveRDF::PropertyLookup.new(self).method_missing(method, *args)
|
399
|
+
end
|
608
400
|
end
|
609
|
-
end
|
401
|
+
end
|