ldpath 0.3.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|