ldpath 0.1.0 → 0.2.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.
@@ -1,10 +1,9 @@
1
1
  module Ldpath
2
2
  class Program
3
-
4
3
  include Ldpath::Functions
5
4
 
6
5
  class << self
7
- def parse program, transform_context = {}
6
+ def parse(program, transform_context = {})
8
7
  parsed = parser.parse(program)
9
8
  ast = transform.apply parsed, transform_context
10
9
 
@@ -12,6 +11,7 @@ module Ldpath
12
11
  end
13
12
 
14
13
  private
14
+
15
15
  def transform
16
16
  Ldpath::Transform.new
17
17
  end
@@ -20,36 +20,35 @@ module Ldpath
20
20
  @parser ||= Ldpath::Parser.new
21
21
  end
22
22
  end
23
-
24
- attr_reader :mappings, :cache, :loaded, :prefixes, :filters
25
- def initialize mappings, options = {}
26
23
 
24
+ attr_reader :mappings, :cache, :loaded, :prefixes, :filters
25
+ def initialize(mappings, options = {})
27
26
  @mappings ||= mappings
28
27
  @cache = options[:cache] || RDF::Util::Cache.new
29
28
  @prefixes = options[:prefixes] || {}
30
29
  @filters = options[:filters] || []
31
30
  @loaded = {}
32
31
  end
33
-
34
- def loading uri, context
35
- if uri.to_s =~ /^http/ and !loaded[uri.to_s]
32
+
33
+ def loading(uri, context)
34
+ if uri.to_s =~ /^http/ && !loaded[uri.to_s]
36
35
  context << load_graph(uri.to_s)
37
36
  end
38
37
  end
39
38
 
40
- def load_graph uri
39
+ def load_graph(uri)
41
40
  cache[uri] ||= begin
42
- Ldpath.logger.debug "[#{self.object_id}] Loading #{uri.inspect}"
41
+ Ldpath.logger.debug "[#{object_id}] Loading #{uri.inspect}"
43
42
 
44
43
  reader_types = RDF::Format.reader_types.reject { |t| t.to_s =~ /html/ }.map do |t|
45
- t.to_s =~ /text\/(?:plain|html)/ ? "#{t};q=0.5" : t
44
+ t.to_s =~ /text\/(?:plain|html)/ ? "#{t};q=0.5" : t
46
45
  end
47
46
 
48
47
  RDF::Graph.load(uri, headers: { 'Accept' => reader_types.join(", ") }).tap { loaded[uri] = true }
49
48
  end
50
49
  end
51
50
 
52
- def evaluate uri, context = nil
51
+ def evaluate(uri, context = nil)
53
52
  h = {}
54
53
  context ||= load_graph(uri.to_s)
55
54
 
@@ -60,14 +59,14 @@ module Ldpath
60
59
  mappings.each do |m|
61
60
  h[m.name] ||= []
62
61
  h[m.name] += case m.selector
63
- when Selector
64
- m.selector.evaluate(self, uri, context).map do |x|
65
- next x unless m.field_type
66
- RDF::Literal.new(x.to_s, datatype: m.field_type).canonicalize.object
67
- end
68
- else
69
- Array(m.selector)
70
- end
62
+ when Selector
63
+ m.selector.evaluate(self, uri, context).map do |x|
64
+ next x unless m.field_type
65
+ RDF::Literal.new(x.to_s, datatype: m.field_type).canonicalize.object
66
+ end
67
+ else
68
+ Array(m.selector)
69
+ end
71
70
  end
72
71
 
73
72
  h.merge(meta)
@@ -76,8 +75,8 @@ module Ldpath
76
75
  def meta
77
76
  @meta ||= {}
78
77
  end
79
-
80
- def func_call fname, uri, context, *arguments
78
+
79
+ def func_call(fname, uri, context, *arguments)
81
80
  if function_method? fname
82
81
  public_send(fname, uri, context, *arguments)
83
82
  else
@@ -86,9 +85,9 @@ module Ldpath
86
85
  end
87
86
 
88
87
  private
89
- def function_method? function
88
+
89
+ def function_method?(function)
90
90
  Functions.public_instance_methods(false).include? function.to_sym
91
91
  end
92
-
93
92
  end
94
93
  end
@@ -1,32 +1,32 @@
1
1
  module Ldpath
2
2
  class Selector
3
- def evaluate program, uris, context
3
+ def evaluate(program, uris, context)
4
4
  Array(uris).map do |uri|
5
5
  loading program, uri, context
6
6
  evaluate_one uri, context
7
7
  end.flatten.compact
8
8
  end
9
-
10
- def loading program, uri, context
9
+
10
+ def loading(program, uri, context)
11
11
  program.loading uri, context
12
12
  end
13
13
  end
14
-
14
+
15
15
  class SelfSelector < Selector
16
- def evaluate_one uri, context
16
+ def evaluate_one(uri, context)
17
17
  uri
18
- end
18
+ end
19
19
  end
20
-
20
+
21
21
  class FunctionSelector < Selector
22
22
  attr_reader :fname, :arguments
23
23
 
24
- def initialize fname, arguments = []
24
+ def initialize(fname, arguments = [])
25
25
  @fname = fname
26
26
  @arguments = Array(arguments)
27
27
  end
28
-
29
- def evaluate program, uris, context
28
+
29
+ def evaluate(program, uris, context)
30
30
  Array(uris).map do |uri|
31
31
  loading program, uri, context
32
32
  args = arguments.map do |i|
@@ -41,25 +41,25 @@ module Ldpath
41
41
  end.flatten.compact
42
42
  end
43
43
  end
44
-
44
+
45
45
  class PropertySelector < Selector
46
46
  attr_reader :property
47
- def initialize property
47
+ def initialize(property)
48
48
  @property = property
49
49
  end
50
50
 
51
- def evaluate_one uri, context
51
+ def evaluate_one(uri, context)
52
52
  context.query([uri, property, nil]).map(&:object)
53
53
  end
54
54
  end
55
-
55
+
56
56
  class LoosePropertySelector < Selector
57
57
  attr_reader :property
58
- def initialize property
58
+ def initialize(property)
59
59
  @property = property
60
60
  end
61
61
 
62
- def evaluate_one uri, context
62
+ def evaluate_one(uri, context)
63
63
  return PropertySelector.new(property).evaluate_one(uri_context) unless defined? RDF::Reasoner
64
64
 
65
65
  context.query([uri, nil, nil]).select do |result|
@@ -67,83 +67,83 @@ module Ldpath
67
67
  end.map(&:object)
68
68
  end
69
69
  end
70
-
70
+
71
71
  class WildcardSelector < Selector
72
- def evaluate_one uri, context
72
+ def evaluate_one(uri, context)
73
73
  context.query([uri, nil, nil]).map(&:object)
74
74
  end
75
75
  end
76
-
76
+
77
77
  class ReversePropertySelector < Selector
78
78
  attr_reader :property
79
- def initialize property
79
+ def initialize(property)
80
80
  @property = property
81
81
  end
82
-
83
- def evaluate_one uri, context
82
+
83
+ def evaluate_one(uri, context)
84
84
  context.query([nil, property, uri]).map(&:subject)
85
85
  end
86
86
  end
87
-
87
+
88
88
  class RecursivePathSelector < Selector
89
89
  attr_reader :property, :repeat
90
- def initialize property, repeat
90
+ def initialize(property, repeat)
91
91
  @property = property
92
92
  @repeat = repeat
93
93
  end
94
-
95
- def evaluate program, uris, context
94
+
95
+ def evaluate(program, uris, context)
96
96
  result = []
97
97
  input = Array(uris)
98
-
99
- Range.new(0,repeat.min,true).each do
98
+
99
+ Range.new(0, repeat.min, true).each do
100
100
  input = property.evaluate program, input, context
101
101
  end
102
-
102
+
103
103
  repeat.each_with_index do |i, idx|
104
- break if input.empty? or idx > 25 # we're probably lost..
104
+ break if input.empty? || idx > 25 # we're probably lost..
105
105
  input = property.evaluate program, input, context
106
106
  result |= input
107
107
  end
108
108
  result.flatten.compact
109
109
  end
110
110
  end
111
-
111
+
112
112
  class CompoundSelector < Selector
113
113
  attr_reader :left, :right
114
- def initialize left, right
114
+ def initialize(left, right)
115
115
  @left = left
116
116
  @right = right
117
117
  end
118
118
  end
119
-
119
+
120
120
  class PathSelector < CompoundSelector
121
- def evaluate program, uris, context
121
+ def evaluate(program, uris, context)
122
122
  output = left.evaluate(program, uris, context)
123
123
  right.evaluate(program, output, context)
124
124
  end
125
125
  end
126
-
126
+
127
127
  class UnionSelector < CompoundSelector
128
- def evaluate program, uris, context
128
+ def evaluate(program, uris, context)
129
129
  left.evaluate(program, uris, context) | right.evaluate(program, uris, context)
130
130
  end
131
131
  end
132
132
 
133
- class IntersectionSelector < CompoundSelector
134
- def evaluate program, uris, context
133
+ class IntersectionSelector < CompoundSelector
134
+ def evaluate(program, uris, context)
135
135
  left.evaluate(program, uris, context) & right.evaluate(program, uris, context)
136
136
  end
137
137
  end
138
138
 
139
139
  class TapSelector < Selector
140
140
  attr_reader :identifier, :tap
141
- def initialize identifier, tap
141
+ def initialize(identifier, tap)
142
142
  @identifier = identifier
143
143
  @tap = tap
144
144
  end
145
145
 
146
- def evaluate program, uris, context
146
+ def evaluate(program, uris, context)
147
147
  program.meta[identifier] = tap.evaluate(program, uris, context).map { |x| RDF::Literal.new(x.to_s).canonicalize.object }
148
148
 
149
149
  Array(uris).map do |uri|
@@ -151,10 +151,9 @@ module Ldpath
151
151
  evaluate_one uri, context
152
152
  end.flatten.compact
153
153
  end
154
-
155
- def evaluate_one uri, context
154
+
155
+ def evaluate_one(uri, context)
156
156
  uri
157
157
  end
158
158
  end
159
-
160
159
  end
data/lib/ldpath/tests.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  module Ldpath
2
-
3
2
  class TestSelector < Selector
4
3
  attr_reader :delegate, :test
5
4
 
6
- def initialize delegate, test
5
+ def initialize(delegate, test)
7
6
  @delegate = delegate
8
7
  @test = test
9
8
  end
10
9
 
11
- def evaluate program, uris, context
10
+ def evaluate(program, uris, context)
12
11
  entries = delegate.evaluate program, uris, context
13
12
  entries.select do |uri|
14
13
  Array(test.evaluate(program, uri, context)).any? do |x|
@@ -20,82 +19,80 @@ module Ldpath
20
19
 
21
20
  class LanguageTest < TestSelector
22
21
  attr_reader :lang
23
- def initialize lang
22
+ def initialize(lang)
24
23
  @lang = lang
25
24
  end
26
25
 
27
- def evaluate program, uri, context
26
+ def evaluate(program, uri, context)
28
27
  return unless uri.literal?
29
- if (lang == "none" && !uri.has_language?) or uri.language == lang
30
- uri
28
+ if (lang == "none" && !uri.has_language?) || uri.language == lang
29
+ uri
31
30
  end
32
31
  end
33
32
  end
34
33
 
35
34
  class TypeTest < TestSelector
36
35
  attr_reader :type
37
- def initialize type
36
+ def initialize(type)
38
37
  @type = type
39
38
  end
40
39
 
41
- def evaluate program, uri, context
40
+ def evaluate(program, uri, context)
42
41
  return unless uri.literal?
43
- if uri.has_datatype? and uri.datatype == type
42
+ if uri.has_datatype? && uri.datatype == type
44
43
  uri
45
44
  end
46
45
  end
47
46
  end
48
-
47
+
49
48
  class NotTest < TestSelector
50
49
  attr_reader :delegate
51
-
52
- def initialize delegate
50
+
51
+ def initialize(delegate)
53
52
  @delegate = delegate
54
53
  end
55
-
56
- def evaluate program, uri, context
54
+
55
+ def evaluate(program, uri, context)
57
56
  !Array(delegate.evaluate(program, uri, context)).any? { |x| x }
58
57
  end
59
58
  end
60
59
 
61
60
  class OrTest < TestSelector
62
61
  attr_reader :left, :right
63
-
64
- def initialize left, right
62
+
63
+ def initialize(left, right)
65
64
  @left = left
66
65
  @right = right
67
66
  end
68
-
69
- def evaluate program, uri, context
67
+
68
+ def evaluate(program, uri, context)
70
69
  left.evaluate(program, uri, context).any? || right.evaluate(program, uri, context).any?
71
70
  end
72
71
  end
73
72
 
74
- class AndTest < TestSelector
75
-
73
+ class AndTest < TestSelector
76
74
  attr_reader :left, :right
77
-
78
- def initialize left, right
75
+
76
+ def initialize(left, right)
79
77
  @left = left
80
78
  @right = right
81
79
  end
82
80
 
83
- def evaluate program, uri, context
81
+ def evaluate(program, uri, context)
84
82
  left.evaluate(program, uri, context).compact.any? &&
85
- right.evaluate(program, uri, context).compact.any?
83
+ right.evaluate(program, uri, context).compact.any?
86
84
  end
87
85
  end
88
-
86
+
89
87
  class IsTest < TestSelector
90
-
91
88
  attr_reader :left, :right
92
-
93
- def initialize left, right
89
+
90
+ def initialize(left, right)
94
91
  @left = left
95
92
  @right = right
96
93
  end
97
-
98
- def evaluate program, uri, context
94
+
95
+ def evaluate(program, uri, context)
99
96
  left.evaluate(program, uri, context).compact.include?(right)
100
97
  end
101
98
  end
@@ -1,5 +1,6 @@
1
1
  module Ldpath
2
2
  class Transform < Parslet::Transform
3
+ attr_reader :prefixes
3
4
 
4
5
  class << self
5
6
  def default_prefixes
@@ -9,37 +10,38 @@ module Ldpath
9
10
  "owl" => RDF::Vocabulary.new("http://www.w3.org/2002/07/owl#"),
10
11
  "skos" => RDF::Vocabulary.new("http://www.w3.org/2004/02/skos/core#"),
11
12
  "dc" => RDF::Vocabulary.new("http://purl.org/dc/elements/1.1/"),
12
- "xsd" => RDF::Vocabulary.new("http://www.w3.org/2001/XMLSchema#"),# (LMF base index datatypes/XML Schema)
13
- "lmf" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/types/1.0/"),# (LMF extended index datatypes)
14
- "fn" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/functions/1.0/"),# (LMF index functions)
13
+ "xsd" => RDF::Vocabulary.new("http://www.w3.org/2001/XMLSchema#"), # (LMF base index datatypes/XML Schema)
14
+ "lmf" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/types/1.0/"), # (LMF extended index datatypes)
15
+ "fn" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/functions/1.0/"), # (LMF index functions)
15
16
  "foaf" => RDF::Vocabulary.new("http://xmlns.com/foaf/0.1/"),
16
17
  "info" => RDF::Vocabulary.new("info:"),
17
- "urn" => RDF::Vocabulary.new("urn:"),
18
+ "urn" => RDF::Vocabulary.new("urn:"),
18
19
  }
19
20
  end
20
21
  end
21
22
 
22
- def apply obj, context = nil
23
- context ||= { }
23
+ def apply(obj, context = nil)
24
+ context ||= {}
24
25
  context[:filters] ||= []
25
26
  context[:prefixes] ||= {}.merge(self.class.default_prefixes)
27
+ @prefixes = context[:prefixes]
26
28
  super obj, context
27
29
  end
28
-
30
+
29
31
  # Core types
30
32
  rule(literal: simple(:literal)) { literal.to_s }
31
- rule(uri: simple(:uri)) { RDF::URI.new(uri) }
32
-
33
+ rule(iri: simple(:iri)) { RDF::IRI.new(iri) }
34
+
33
35
  # Namespaces
34
- rule(namespace: subtree(:namespace)) do
35
- prefixes[namespace[:id].to_s] = RDF::Vocabulary.new(namespace[:uri])
36
+ rule(prefixID: subtree(:prefixID)) do
37
+ prefixes[prefixID[:id].to_s] = RDF::Vocabulary.new(prefixID[:iri])
36
38
  nil
37
39
  end
38
-
40
+
39
41
  rule(prefix: simple(:prefix), localName: simple(:localName)) do
40
42
  (prefixes[prefix.to_s] || RDF::Vocabulary.new(prefix.to_s))[localName]
41
43
  end
42
-
44
+
43
45
  rule(filter: subtree(:filter)) do
44
46
  filters << filter[:test]
45
47
  nil
@@ -50,18 +52,16 @@ module Ldpath
50
52
  nil
51
53
  end
52
54
 
53
-
54
55
  # Mappings
55
-
56
+
56
57
  rule(mapping: subtree(:mapping)) do
57
58
  FieldMapping.new mapping[:name].to_s, mapping[:selector], mapping[:field_type]
58
59
  end
59
60
 
60
61
  ## Selectors
61
-
62
-
62
+
63
63
  ### Atomic Selectors
64
- rule(self: simple(:self)) do
64
+ rule(self: simple(:self)) do
65
65
  SelfSelector.new
66
66
  end
67
67
 
@@ -72,12 +72,12 @@ module Ldpath
72
72
  rule(fname: simple(:fname), arglist: subtree(:arglist)) do
73
73
  FunctionSelector.new fname.to_s, arglist
74
74
  end
75
-
75
+
76
76
  rule(property: simple(:property)) do
77
77
  PropertySelector.new property
78
78
  end
79
-
80
- rule(loose_property: simple(:property)) do
79
+
80
+ rule(loose: simple(:loose), property: simple(:property)) do
81
81
  LoosePropertySelector.new property
82
82
  end
83
83
 
@@ -85,31 +85,31 @@ module Ldpath
85
85
  WildcardSelector.new
86
86
  end
87
87
 
88
- rule(reverse_property: simple(:property)) do
88
+ rule(reverse: simple(:reverse), property: simple(:property)) do
89
89
  ReversePropertySelector.new property
90
90
  end
91
91
 
92
92
  rule(range: subtree(:range)) do
93
- range.fetch(:min,0).to_i..range.fetch(:max, Infinity).to_f
94
- end
95
-
96
- rule(recursive: subtree(:properties)) do
97
- repeat = case properties[:repeat]
93
+ case range
98
94
  when "*"
99
95
  0..Infinity
100
96
  when "+"
101
97
  1..Infinity
102
- when Range
103
- properties[:repeat]
98
+ when "?"
99
+ 0..1
100
+ else
101
+ range.fetch(:min, 0).to_i..range.fetch(:max, Infinity).to_f
104
102
  end
103
+ end
105
104
 
106
- RecursivePathSelector.new properties[:delegate], repeat
105
+ rule(delegate: subtree(:delegate), repeat: simple(:repeat)) do
106
+ RecursivePathSelector.new delegate, repeat
107
107
  end
108
108
 
109
109
  rule(identifier: simple(:identifier), tap: subtree(:tap)) do
110
110
  TapSelector.new identifier.to_s, tap
111
111
  end
112
-
112
+
113
113
  ### Test Selectors
114
114
 
115
115
  rule(delegate: subtree(:delegate), test: subtree(:test)) do
@@ -127,15 +127,15 @@ module Ldpath
127
127
  rule(type: simple(:type)) do
128
128
  TypeTest.new type
129
129
  end
130
-
130
+
131
131
  rule(not: subtree(:not_op)) do
132
132
  NotTest.new not_op[:delegate]
133
133
  end
134
-
134
+
135
135
  rule(and: subtree(:op)) do
136
136
  AndTest.new op[:left], op[:right]
137
137
  end
138
-
138
+
139
139
  rule(or: subtree(:op)) do
140
140
  OrTest.new op[:left], op[:right]
141
141
  end
@@ -143,25 +143,23 @@ module Ldpath
143
143
  rule(is: subtree(:is)) do
144
144
  IsTest.new PropertySelector.new(is[:property]), is[:right]
145
145
  end
146
-
146
+
147
147
  rule(is_a: subtree(:is_a)) do
148
148
  IsTest.new PropertySelector.new(RDF.type), is_a[:right]
149
149
  end
150
+
150
151
  ### Compound Selectors
151
-
152
- rule(path: subtree(:path)) do
153
- PathSelector.new path[:left], path[:right]
154
- end
155
-
156
- rule(union: subtree(:union)) do
157
- UnionSelector.new union[:left], union[:right]
158
- end
159
-
160
- rule(intersection: subtree(:intersection)) do
161
- IntersectionSelector.new intersection[:left], intersection[:right]
152
+ rule(left: subtree(:left), op: simple(:op), right: subtree(:right)) do
153
+ case op
154
+ when "/"
155
+ PathSelector.new left, right
156
+ when "|"
157
+ UnionSelector.new left, right
158
+ when "&"
159
+ IntersectionSelector.new left, right
160
+ end
162
161
  end
163
162
 
164
-
165
163
  Infinity = 1.0 / 0.0
166
164
  end
167
165
  end