ldpath 0.3.1 → 1.0.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -4
- data/.rubocop_todo.yml +2 -33
- data/.travis.yml +4 -1
- data/CHANGELOG.md +98 -0
- data/CODE_OF_CONDUCT.md +36 -0
- data/CONTRIBUTING.md +161 -0
- data/Gemfile +6 -2
- data/README.md +31 -7
- data/SUPPORT.md +6 -0
- data/bin/ldpath +20 -12
- data/ldpath.gemspec +9 -4
- data/lib/ldpath/field_mapping.rb +43 -1
- data/lib/ldpath/functions.rb +84 -72
- data/lib/ldpath/parser.rb +31 -36
- data/lib/ldpath/program.rb +7 -62
- data/lib/ldpath/result.rb +83 -0
- data/lib/ldpath/selectors.rb +105 -28
- data/lib/ldpath/tests.rb +11 -13
- data/lib/ldpath/transform.rb +28 -27
- data/lib/ldpath/version.rb +1 -1
- data/lib/ldpath.rb +3 -4
- data/spec/fixtures/bbc_b0081dq5.nt +4 -0
- data/spec/fixtures/loc_n79021164.nt +3 -0
- data/spec/ldpath_parser_spec.rb +19 -1
- data/spec/ldpath_program_spec.rb +87 -32
- data/spec/ldpath_transform_spec.rb +10 -0
- data/spec/lib/functions/list_spec.rb +1 -1
- data/spec/spec_helper.rb +31 -1
- metadata +73 -9
- data/.rubocop_hound.yml +0 -1063
data/lib/ldpath/functions.rb
CHANGED
@@ -1,83 +1,83 @@
|
|
1
1
|
# rubocop:disable Style/MethodName
|
2
2
|
module Ldpath
|
3
3
|
module Functions
|
4
|
-
def concat(
|
5
|
-
args.
|
4
|
+
def concat(_uri, _context, *args)
|
5
|
+
deep_flatten_compact(*args).to_a.join
|
6
6
|
end
|
7
7
|
|
8
|
-
def first(
|
9
|
-
args.
|
8
|
+
def first(_uri, _context, *args)
|
9
|
+
deep_flatten_compact(*args).first
|
10
10
|
end
|
11
11
|
|
12
|
-
def last(
|
13
|
-
args.
|
12
|
+
def last(_uri, _context, *args)
|
13
|
+
deep_flatten_compact(*args).to_a.last
|
14
14
|
end
|
15
15
|
|
16
|
-
def count(
|
17
|
-
args.
|
16
|
+
def count(_uri, _context, *args)
|
17
|
+
deep_flatten_compact(*args).count
|
18
18
|
end
|
19
19
|
|
20
|
-
def eq(
|
21
|
-
a, b, *rem = args.
|
22
|
-
unless rem.empty?
|
23
|
-
|
24
|
-
end
|
20
|
+
def eq(_uri, _context, *args)
|
21
|
+
a, b, *rem = deep_flatten_compact(*args).first(3)
|
22
|
+
raise "Too many arguments to fn:eq" unless rem.empty?
|
23
|
+
|
25
24
|
a == b
|
26
25
|
end
|
27
26
|
|
28
|
-
def ne(
|
29
|
-
a, b, *rem = args.
|
30
|
-
unless rem.empty?
|
31
|
-
|
32
|
-
end
|
27
|
+
def ne(_uri, _context, *args)
|
28
|
+
a, b, *rem = deep_flatten_compact(*args).first(3)
|
29
|
+
raise "Too many arguments to fn:ne" unless rem.empty?
|
30
|
+
|
33
31
|
a != b
|
34
32
|
end
|
35
33
|
|
36
|
-
def lt(
|
37
|
-
a, b, *rem = args.
|
38
|
-
unless rem.empty?
|
39
|
-
|
40
|
-
end
|
34
|
+
def lt(_uri, _context, *args)
|
35
|
+
a, b, *rem = deep_flatten_compact(*args).first(3)
|
36
|
+
raise "Too many arguments to fn:lt" unless rem.empty?
|
37
|
+
|
41
38
|
a < b
|
42
39
|
end
|
43
40
|
|
44
|
-
def le(
|
45
|
-
a, b, *rem = args.
|
46
|
-
unless rem.empty?
|
47
|
-
|
48
|
-
end
|
41
|
+
def le(_uri, _context, *args)
|
42
|
+
a, b, *rem = deep_flatten_compact(*args).first(3)
|
43
|
+
raise "Too many arguments to fn:le" unless rem.empty?
|
44
|
+
|
49
45
|
a <= b
|
50
46
|
end
|
51
47
|
|
52
|
-
def gt(
|
53
|
-
a, b, *rem = args.
|
54
|
-
unless rem.empty?
|
55
|
-
|
56
|
-
end
|
48
|
+
def gt(_uri, _context, *args)
|
49
|
+
a, b, *rem = deep_flatten_compact(*args).first(3)
|
50
|
+
raise "Too many arguments to fn:gt" unless rem.empty?
|
51
|
+
|
57
52
|
a > b
|
58
53
|
end
|
59
54
|
|
60
|
-
def ge(
|
61
|
-
a, b, *rem = args.
|
62
|
-
unless rem.empty?
|
63
|
-
|
64
|
-
end
|
55
|
+
def ge(_uri, _context, *args)
|
56
|
+
a, b, *rem = deep_flatten_compact(*args).first(3)
|
57
|
+
raise "Too many arguments to fn:ge" unless rem.empty?
|
58
|
+
|
65
59
|
a >= b
|
66
60
|
end
|
67
61
|
|
68
62
|
# collections
|
69
63
|
def flatten(uri, context, lists)
|
70
|
-
|
64
|
+
return to_enum(:flatten, uri, context, lists) unless block_given?
|
65
|
+
|
66
|
+
deep_flatten_compact(lists).each do |x|
|
67
|
+
RDF::List.new(subject: x, graph: context).to_a.each do |i|
|
68
|
+
yield i
|
69
|
+
end
|
70
|
+
end
|
71
71
|
end
|
72
72
|
|
73
73
|
def get(uri, context, list, idx)
|
74
74
|
idx = idx.respond_to?(:to_i) ? idx.to_i : idx.to_s.to_i
|
75
75
|
|
76
|
-
flatten(uri, context, list)[idx]
|
76
|
+
flatten(uri, context, list).to_a[idx]
|
77
77
|
end
|
78
78
|
|
79
79
|
def subList(uri, context, list, idx_start, idx_end = nil)
|
80
|
-
arr = flatten(uri, context, list)
|
80
|
+
arr = flatten(uri, context, list).to_a
|
81
81
|
|
82
82
|
idx_start = idx_start.respond_to?(:to_i) ? idx_start.to_i : idx_start.to_s.to_i
|
83
83
|
idx_end &&= idx_end.respond_to?(:to_i) ? idx_end.to_i : idx_end.to_s.to_i
|
@@ -91,102 +91,114 @@ module Ldpath
|
|
91
91
|
|
92
92
|
# dates
|
93
93
|
|
94
|
-
def earliest(
|
95
|
-
args.
|
94
|
+
def earliest(_uri, _context, *args)
|
95
|
+
deep_flatten_compact(*args).min
|
96
96
|
end
|
97
97
|
|
98
|
-
def latest(
|
99
|
-
args.
|
98
|
+
def latest(_uri, _context, *args)
|
99
|
+
deep_flatten_compact(*args).max
|
100
100
|
end
|
101
101
|
|
102
102
|
# math
|
103
103
|
|
104
|
-
def min(
|
105
|
-
args.
|
104
|
+
def min(_uri, _context, *args)
|
105
|
+
deep_flatten_compact(*args).min
|
106
106
|
end
|
107
107
|
|
108
|
-
def max(
|
109
|
-
args.
|
108
|
+
def max(_uri, _context, *args)
|
109
|
+
deep_flatten_compact(*args).max
|
110
110
|
end
|
111
111
|
|
112
|
-
def round(
|
113
|
-
args.map do |
|
114
|
-
|
115
|
-
i.respond_to? :round ? i.round : i
|
116
|
-
end
|
112
|
+
def round(_uri, _context, *args)
|
113
|
+
deep_flatten_compact(*args).map do |i|
|
114
|
+
i.respond_to?(:round) ? i.round : i
|
117
115
|
end
|
118
116
|
end
|
119
117
|
|
120
|
-
def sum(
|
121
|
-
args.inject(0) { |
|
118
|
+
def sum(_uri, _context, *args)
|
119
|
+
args.inject(0) { |acc, elem| acc + elem }
|
122
120
|
end
|
123
121
|
|
124
122
|
# text
|
125
123
|
|
126
|
-
def replace(
|
124
|
+
def replace(_uri, _context, str, pattern, replacement)
|
127
125
|
regex = Regexp.parse(pattern)
|
128
126
|
Array(str).map do |x|
|
129
127
|
x.gsub(regex, replacement)
|
130
128
|
end
|
131
129
|
end
|
132
130
|
|
133
|
-
def strlen(
|
131
|
+
def strlen(_uri, _context, str)
|
134
132
|
Array(str).map(&:length)
|
135
133
|
end
|
136
134
|
|
137
|
-
def wc(
|
135
|
+
def wc(_uri, _context, str)
|
138
136
|
Array(str).map { |x| x.split.length }
|
139
137
|
end
|
140
138
|
|
141
|
-
def strLeft(
|
139
|
+
def strLeft(_uri, _context, str, left)
|
142
140
|
Array(str).map { |x| x[0..left.to_i] }
|
143
141
|
end
|
144
142
|
|
145
|
-
def strRight(
|
143
|
+
def strRight(_uri, _context, str, right)
|
146
144
|
Array(str).map { |x| x[right.to_i..x.length] }
|
147
145
|
end
|
148
146
|
|
149
|
-
def substr(
|
147
|
+
def substr(_uri, _context, str, left, right)
|
150
148
|
Array(str).map { |x| x[left.to_i..right.to_i] }
|
151
149
|
end
|
152
150
|
|
153
|
-
def strJoin(
|
151
|
+
def strJoin(_uri, _context, str, sep = "", prefix = "", suffix = "")
|
154
152
|
prefix + Array(str).join(sep) + suffix
|
155
153
|
end
|
156
154
|
|
157
|
-
def equals(
|
155
|
+
def equals(_uri, _context, str, other)
|
158
156
|
Array(str).map { |x| x == other }
|
159
157
|
end
|
160
158
|
|
161
|
-
def equalsIgnoreCase(
|
162
|
-
Array(str).map { |x| x.
|
159
|
+
def equalsIgnoreCase(_uri, _context, str, other)
|
160
|
+
Array(str).map { |x| x.casecmp(other) }
|
163
161
|
end
|
164
162
|
|
165
|
-
def contains(
|
163
|
+
def contains(_uri, _context, str, substr)
|
166
164
|
Array(str).map { |x| x.include? substr }
|
167
165
|
end
|
168
166
|
|
169
|
-
def startsWith(
|
167
|
+
def startsWith(_uri, _context, str, suffix)
|
170
168
|
Array(str).map { |x| x.start_with? suffix }
|
171
169
|
end
|
172
170
|
|
173
|
-
def endsWith(
|
171
|
+
def endsWith(_uri, _context, str, suffix)
|
174
172
|
Array(str).map { |x| x.end_with? suffix }
|
175
173
|
end
|
176
174
|
|
177
|
-
def isEmpty(
|
175
|
+
def isEmpty(_uri, _context, str)
|
178
176
|
Array(str).map(&:empty?)
|
179
177
|
end
|
180
178
|
|
181
|
-
def predicates(uri, context, *
|
179
|
+
def predicates(uri, context, *_args)
|
182
180
|
context.query([uri, nil, nil]).map(&:predicate).uniq
|
183
181
|
end
|
184
182
|
|
185
|
-
def xpath(
|
183
|
+
def xpath(_uri, _context, xpath, node)
|
186
184
|
x = Array(xpath).flatten.first
|
187
185
|
Array(node).flatten.compact.map do |n|
|
188
186
|
Nokogiri::XML(n.to_s).xpath(x.to_s, prefixes.map { |k, v| [k, v.to_s] }).map(&:text)
|
189
187
|
end
|
190
188
|
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def deep_flatten_compact(*args)
|
193
|
+
return to_enum(:deep_flatten_compact, *args) unless block_given?
|
194
|
+
|
195
|
+
args.each do |x|
|
196
|
+
if x.is_a? Enumerable
|
197
|
+
x.each { |y| yield y unless y.nil? }
|
198
|
+
else
|
199
|
+
yield x unless x.nil?
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
191
203
|
end
|
192
204
|
end
|
data/lib/ldpath/parser.rb
CHANGED
@@ -116,8 +116,7 @@ module Ldpath
|
|
116
116
|
rule(:identifier) { pn_chars_base >> (str(".").maybe >> pn_chars).repeat }
|
117
117
|
|
118
118
|
rule(:pn_chars_base) do
|
119
|
-
|
120
|
-
match("[A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]")
|
119
|
+
match("[A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u{10000}-\u{EFFFF}]")
|
121
120
|
end
|
122
121
|
|
123
122
|
rule(:pn_chars) do
|
@@ -203,7 +202,7 @@ module Ldpath
|
|
203
202
|
|
204
203
|
# ( x = "xyz", y = "abc" )
|
205
204
|
rule(:field_type_options) do
|
206
|
-
|
205
|
+
group(field_type_option >> (wsp? >> comma >> wsp? >> field_type_option).repeat).as(:options)
|
207
206
|
end
|
208
207
|
|
209
208
|
# x = "xyz"
|
@@ -261,7 +260,8 @@ module Ldpath
|
|
261
260
|
literal_selector |
|
262
261
|
recursive_path_selector |
|
263
262
|
grouped_selector |
|
264
|
-
tap_selector
|
263
|
+
tap_selector |
|
264
|
+
not_property_selector
|
265
265
|
)
|
266
266
|
end
|
267
267
|
|
@@ -284,11 +284,11 @@ module Ldpath
|
|
284
284
|
end
|
285
285
|
|
286
286
|
rule(:function_without_args) do
|
287
|
-
func >> identifier.as(:fname) >>
|
287
|
+
func >> identifier.as(:fname) >> group(wsp?)
|
288
288
|
end
|
289
289
|
|
290
290
|
rule(:function_with_arglist) do
|
291
|
-
func >> identifier.as(:fname) >>
|
291
|
+
func >> identifier.as(:fname) >> group(arglist.as(:arglist))
|
292
292
|
end
|
293
293
|
|
294
294
|
rule(:arglist) do
|
@@ -322,15 +322,21 @@ module Ldpath
|
|
322
322
|
inverse.as(:reverse) >> iri.as(:property)
|
323
323
|
end
|
324
324
|
|
325
|
+
rule(:not_property_selector) do
|
326
|
+
not_one_property_selector
|
327
|
+
end
|
328
|
+
|
329
|
+
rule(:not_one_property_selector) do
|
330
|
+
not_op.as(:not) >> iri.repeat(1, 1).as(:property)
|
331
|
+
end
|
332
|
+
|
325
333
|
rule(:literal_selector) do
|
326
334
|
literal.as(:literal)
|
327
335
|
end
|
328
336
|
|
329
337
|
# (x)?; (x)*; (x)+; (x){3,5}
|
330
338
|
rule(:recursive_path_selector) do
|
331
|
-
|
332
|
-
selector.as(:delegate) >> wsp? >>
|
333
|
-
str(")") >>
|
339
|
+
group(selector.as(:delegate)) >>
|
334
340
|
range.as(:repeat)
|
335
341
|
end
|
336
342
|
|
@@ -346,18 +352,16 @@ module Ldpath
|
|
346
352
|
|
347
353
|
# (<info:a>)
|
348
354
|
rule(:grouped_selector) do
|
349
|
-
|
350
|
-
selector >> wsp? >>
|
351
|
-
str(")")
|
355
|
+
group(selector)
|
352
356
|
end
|
353
357
|
|
354
358
|
# ?<a>(<info:a>)
|
355
359
|
rule(:tap_selector) do
|
356
360
|
question >>
|
357
361
|
str("<") >> wsp? >>
|
358
|
-
|
362
|
+
(str(">").absent? >> any).repeat(1).as(:identifier) >> wsp? >>
|
359
363
|
str(">") >> wsp? >>
|
360
|
-
|
364
|
+
atomic_selector.as(:tap)
|
361
365
|
end
|
362
366
|
|
363
367
|
# Testing Selectors
|
@@ -365,8 +369,7 @@ module Ldpath
|
|
365
369
|
rule(:node_test) do
|
366
370
|
grouped_test |
|
367
371
|
not_test |
|
368
|
-
|
369
|
-
or_test |
|
372
|
+
compound_test |
|
370
373
|
atomic_node_test
|
371
374
|
end
|
372
375
|
|
@@ -380,31 +383,17 @@ module Ldpath
|
|
380
383
|
end
|
381
384
|
|
382
385
|
rule(:grouped_test) do
|
383
|
-
|
384
|
-
node_test >> wsp? >>
|
385
|
-
str(")")
|
386
|
+
group(node_test)
|
386
387
|
end
|
387
388
|
|
388
389
|
rule(:not_test) do
|
389
|
-
(
|
390
|
-
not_op >> node_test.as(:delegate)
|
391
|
-
).as(:not)
|
390
|
+
not_op.as(:not) >> node_test.as(:delegate)
|
392
391
|
end
|
393
392
|
|
394
|
-
rule(:
|
395
|
-
(
|
396
|
-
|
397
|
-
|
398
|
-
node_test.as(:right)
|
399
|
-
).as(:and)
|
400
|
-
end
|
401
|
-
|
402
|
-
rule(:or_test) do
|
403
|
-
(
|
404
|
-
atomic_node_test.as(:left) >> wsp? >>
|
405
|
-
or_op >> wsp? >>
|
406
|
-
node_test.as(:right)
|
407
|
-
).as(:or)
|
393
|
+
rule(:compound_test) do
|
394
|
+
atomic_node_test.as(:left_test) >> wsp? >>
|
395
|
+
compound_operator.as(:op) >> wsp? >>
|
396
|
+
node_test.as(:right_test)
|
408
397
|
end
|
409
398
|
|
410
399
|
# @en
|
@@ -443,5 +432,11 @@ module Ldpath
|
|
443
432
|
atomic_selector
|
444
433
|
)
|
445
434
|
end
|
435
|
+
|
436
|
+
def group(atom)
|
437
|
+
str("(") >> wsp? >>
|
438
|
+
atom >> wsp? >>
|
439
|
+
str(")")
|
440
|
+
end
|
446
441
|
end
|
447
442
|
end
|
data/lib/ldpath/program.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Ldpath
|
2
2
|
class Program
|
3
|
-
|
4
|
-
|
5
|
-
ParseError = Class.new StandardError
|
3
|
+
ParseError = Class.new StandardError
|
6
4
|
|
7
5
|
class << self
|
8
6
|
def parse(program, transform_context = {})
|
@@ -14,7 +12,7 @@ module Ldpath
|
|
14
12
|
def load(program)
|
15
13
|
parser.parse(program, reporter: Parslet::ErrorReporter::Deepest.new)
|
16
14
|
rescue Parslet::ParseFailed => e
|
17
|
-
|
15
|
+
raise ParseError, e.parse_failure_cause.ascii_tree
|
18
16
|
end
|
19
17
|
|
20
18
|
private
|
@@ -28,73 +26,20 @@ module Ldpath
|
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
31
|
-
attr_reader :mappings, :
|
29
|
+
attr_reader :mappings, :prefixes, :filters
|
32
30
|
def initialize(mappings, options = {})
|
33
31
|
@mappings ||= mappings
|
34
|
-
@cache = options[:cache] || RDF::Util::Cache.new
|
35
32
|
@prefixes = options[:prefixes] || {}
|
36
33
|
@filters = options[:filters] || []
|
37
|
-
@loaded = {}
|
38
|
-
end
|
39
|
-
|
40
|
-
def loading(uri, context)
|
41
|
-
if uri.to_s =~ /^http/ && !loaded[uri.to_s]
|
42
|
-
context << load_graph(uri.to_s)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def load_graph(uri)
|
47
|
-
cache[uri] ||= begin
|
48
|
-
Ldpath.logger.debug "[#{object_id}] Loading #{uri.inspect}"
|
49
|
-
|
50
|
-
reader_types = RDF::Format.reader_types.reject { |t| t.to_s =~ /html/ }.map do |t|
|
51
|
-
t.to_s =~ /text\/(?:plain|html)/ ? "#{t};q=0.5" : t
|
52
|
-
end
|
53
|
-
|
54
|
-
RDF::Graph.load(uri, headers: { 'Accept' => reader_types.join(", ") }).tap { loaded[uri] = true }
|
55
|
-
end
|
56
34
|
end
|
57
35
|
|
58
|
-
def evaluate(uri, context
|
59
|
-
|
60
|
-
context ||= load_graph(uri.to_s)
|
61
|
-
|
36
|
+
def evaluate(uri, context: nil, limit_to_context: false)
|
37
|
+
result = Ldpath::Result.new(self, uri, context: context, limit_to_context: limit_to_context)
|
62
38
|
unless filters.empty?
|
63
|
-
return
|
39
|
+
return {} unless filters.all? { |f| f.evaluate(result, uri, result.context) }
|
64
40
|
end
|
65
41
|
|
66
|
-
|
67
|
-
h[m.name] ||= []
|
68
|
-
h[m.name] += case m.selector
|
69
|
-
when Selector
|
70
|
-
m.selector.evaluate(self, uri, context).map do |x|
|
71
|
-
next x unless m.field_type
|
72
|
-
RDF::Literal.new(x.to_s, datatype: m.field_type).canonicalize.object
|
73
|
-
end
|
74
|
-
else
|
75
|
-
Array(m.selector)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
h.merge(meta)
|
80
|
-
end
|
81
|
-
|
82
|
-
def meta
|
83
|
-
@meta ||= {}
|
84
|
-
end
|
85
|
-
|
86
|
-
def func_call(fname, uri, context, *arguments)
|
87
|
-
if function_method? fname
|
88
|
-
public_send(fname, uri, context, *arguments)
|
89
|
-
else
|
90
|
-
raise "No such function: #{fname}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def function_method?(function)
|
97
|
-
Functions.public_instance_methods(false).include? function.to_sym
|
42
|
+
result.to_hash
|
98
43
|
end
|
99
44
|
end
|
100
45
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Ldpath
|
2
|
+
class Result
|
3
|
+
include Ldpath::Functions
|
4
|
+
attr_reader :program, :uri, :cache, :loaded
|
5
|
+
|
6
|
+
def initialize(program, uri, cache: RDF::Util::Cache.new, context: nil, limit_to_context: false)
|
7
|
+
@program = program
|
8
|
+
@uri = uri
|
9
|
+
@cache = cache
|
10
|
+
@loaded = {}
|
11
|
+
@context = context
|
12
|
+
@limit_to_context = limit_to_context
|
13
|
+
end
|
14
|
+
|
15
|
+
def loading(uri, context)
|
16
|
+
return unless uri.to_s =~ /^http/
|
17
|
+
return if loaded[uri.to_s]
|
18
|
+
|
19
|
+
context << load_graph(uri.to_s) unless limit_to_context?
|
20
|
+
context
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_graph(uri)
|
24
|
+
cache[uri] ||= begin
|
25
|
+
Ldpath.logger.debug "[#{object_id}] Loading #{uri.inspect}"
|
26
|
+
|
27
|
+
reader_types = RDF::Format.reader_types.reject { |t| t.to_s =~ /html/ }.map do |t|
|
28
|
+
t.to_s =~ %r{text/(?:plain|html)} ? "#{t};q=0.5" : t
|
29
|
+
end
|
30
|
+
|
31
|
+
RDF::Graph.load(uri, headers: { 'Accept' => reader_types.join(", ") }).tap { loaded[uri] = true }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def [](key)
|
36
|
+
evaluate(mappings.find { |x| x.name == key })
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_hash
|
40
|
+
h = mappings.each_with_object({}) do |mapping, hash|
|
41
|
+
hash[mapping.name] = evaluate(mapping).to_a
|
42
|
+
end
|
43
|
+
|
44
|
+
h.merge(meta)
|
45
|
+
end
|
46
|
+
|
47
|
+
def func_call(fname, uri, context, *arguments)
|
48
|
+
raise "No such function: #{fname}" unless function_method? fname
|
49
|
+
|
50
|
+
public_send(fname, uri, context, *arguments)
|
51
|
+
end
|
52
|
+
|
53
|
+
def context
|
54
|
+
@context ||= load_graph(uri.to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
def prefixes
|
58
|
+
program.prefixes
|
59
|
+
end
|
60
|
+
|
61
|
+
def meta
|
62
|
+
@meta ||= {}
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def evaluate(mapping)
|
68
|
+
mapping.evaluate(self, uri, context)
|
69
|
+
end
|
70
|
+
|
71
|
+
def function_method?(function)
|
72
|
+
Functions.public_instance_methods(false).include? function.to_sym
|
73
|
+
end
|
74
|
+
|
75
|
+
def mappings
|
76
|
+
program.mappings
|
77
|
+
end
|
78
|
+
|
79
|
+
def limit_to_context?
|
80
|
+
@limit_to_context
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|