ldpath 0.1.0 → 0.2.0

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