bel_parser 1.0.0.alpha.44 → 1.0.0.alpha.45

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,14 +16,21 @@
16
16
  action add_string_value {
17
17
  trace('DEFINE_NAMESPACE add_string_value')
18
18
  string_node = @buffers.delete(:string)
19
- leaf = domain(url(string_node))
19
+ domain = @buffers.delete(:namespace_definition_domain)
20
+ domain <<= string_node
21
+ leaf = domain(domain)
20
22
  leaf.complete = string_node.complete
21
23
  @buffers[:namespace_definition_domain] = leaf
22
24
  }
23
25
 
26
+ action add_uri_domain {
27
+ trace('DEFINE_NAMESPACE add_uri_domain')
28
+ @buffers[:namespace_definition_domain] = uri()
29
+ }
30
+
24
31
  action add_url_domain {
25
32
  trace('DEFINE_NAMESPACE add_url_domain')
26
- @url_domain = true
33
+ @buffers[:namespace_definition_domain] = url()
27
34
  }
28
35
 
29
36
  action define_namespace_end {
@@ -66,6 +73,11 @@
66
73
  %add_string_value
67
74
  ;
68
75
 
76
+ uri_domain =
77
+ KW_URI
78
+ %add_uri_domain
79
+ ;
80
+
69
81
  url_domain =
70
82
  KW_URL
71
83
  %add_url_domain
@@ -79,7 +91,7 @@
79
91
  SP+
80
92
  KW_AS
81
93
  SP+
82
- url_domain
94
+ (url_domain | uri_domain)
83
95
  SP+
84
96
  string_value
85
97
  @eof(define_namespace_node_eof)
@@ -28,6 +28,7 @@ machine bel;
28
28
  KW_LIST = /LIST/i;
29
29
  KW_PATTERN = /PATTERN/i;
30
30
  KW_URL = /URL/i;
31
+ KW_URI = /URI/i;
31
32
  KW_DOCUMENT = /DOCUMENT/i;
32
33
 
33
34
  DEFINE_ANNOTATION =
@@ -30,7 +30,7 @@ module BELParser
30
30
  #
31
31
  # @param [Boolean] reuse_database_files specify +true+ to reuse database
32
32
  # files; +false+ to create new database files (default)
33
- def initialize(reuse_database_files = false)
33
+ def initialize(reuse_database_files = true)
34
34
  @resources = {}
35
35
  @datasets = ResourceURLReader.open_datasets_file
36
36
  @reuse = reuse_database_files
@@ -50,7 +50,7 @@ module BELParser
50
50
  resource = read_resource(resource_identifier)
51
51
  encoding = resource[:values][value]
52
52
  return nil unless encoding
53
- FileResourceValue.new(resource[:dataset], value, encoding)
53
+ [FileResourceValue.new(resource[:dataset], value, encoding)]
54
54
  end
55
55
 
56
56
  def retrieve_values_from_resource(resource_identifier)
@@ -1,14 +1,19 @@
1
+ require 'net/http'
1
2
  require_relative 'resource/sparql_reader'
2
3
  require_relative 'resource/resource_url_reader'
3
4
 
4
5
  module BELParser
5
6
  module Resource
6
7
 
7
- # DEFAULT_SPARQL_ENDPOINT = 'http://sparql.openbel.org/identifiers/sparql'
8
- DEFAULT_SPARQL_ENDPOINT = 'http://localhost:3030/identifiers/sparql'
8
+ DEFAULT_SPARQL_ENDPOINT = 'http://build.openbel.org/sparql'
9
+ #DEFAULT_SPARQL_ENDPOINT = 'http://localhost:3030/identifiers/sparql'
9
10
 
10
- READER_LOCK = Mutex.new
11
+ READER_LOCK = Mutex.new
11
12
  private_constant :READER_LOCK
13
+ RESOLVE_URI_LOCK = Mutex.new
14
+ private_constant :RESOLVE_URI_LOCK
15
+ URISTRING_PATTERN = /^URIString *= *(.*)$/
16
+ private_constant :URISTRING_PATTERN
12
17
 
13
18
  def self.default_uri_reader
14
19
  READER_LOCK.synchronize do
@@ -33,5 +38,47 @@ module BELParser
33
38
  @default_url_reader ||= url_reader
34
39
  end
35
40
  end
41
+
42
+ # Resolves the URI String from the annotation or namespace resource.
43
+ #
44
+ # The resource must contain a _URIString=..._ property.
45
+ #
46
+ # @param [#to_s] resource_url the resource URL to resolve the URI from
47
+ # @return [String] the resource URI specified in the resource
48
+ def self.resolve_uri(resource_url)
49
+ resource_url = resource_url.to_s
50
+
51
+ RESOLVE_URI_LOCK.synchronize do
52
+ @uri_hash ||= {}
53
+ return @uri_hash[resource_url] if @uri_hash.key?(resource_url)
54
+ end
55
+
56
+ uri = URI(resource_url)
57
+ request = Net::HTTP::Get.new(uri)
58
+ request['Range'] = 'bytes=0-5000'
59
+ resource_uri = nil
60
+
61
+ Net::HTTP.start(
62
+ uri.hostname,
63
+ uri.port) { |http|
64
+
65
+ http.request(request) do |response|
66
+ response.read_body do |chunk|
67
+ uristring = chunk.lines.detect { |l| l =~ URISTRING_PATTERN }
68
+ if uristring
69
+ resource_uri = uristring.match(URISTRING_PATTERN)[1]
70
+ break
71
+ end
72
+ end
73
+ end
74
+ }
75
+
76
+ RESOLVE_URI_LOCK.synchronize do
77
+ @uri_hash ||= {}
78
+ @uri_hash[resource_url] = resource_uri
79
+ end
80
+
81
+ resource_uri
82
+ end
36
83
  end
37
84
  end
@@ -0,0 +1,30 @@
1
+ module BELParser
2
+ module Script
3
+ # ApplyResourceURI applies the _uri_ property to
4
+ # {BELParser::Parsers::AST::AnnotationDefinition} and
5
+ # {BELParser::Parsers::AST::NamespaceDefinition} child nodes.
6
+ class ApplyResourceURI
7
+ include AST::Processor::Mixin
8
+
9
+ def on_annotation_definition(node)
10
+ update_uri_property(node)
11
+ end
12
+
13
+ def on_namespace_definition(node)
14
+ update_uri_property(node)
15
+ end
16
+
17
+ private
18
+
19
+ def update_uri_property(node)
20
+ domain = node.domain
21
+ if domain.url?
22
+ resource_url = domain.child.string.string_literal
23
+ node.uri = BELParser::Resource.resolve_uri(resource_url)
24
+ end
25
+
26
+ node
27
+ end
28
+ end
29
+ end
30
+ end
@@ -116,10 +116,11 @@ module BELParser
116
116
  domain: domain_value(type, domain)
117
117
  }
118
118
  end,
119
- namespaces: (ns_defs || []).map do |keyword, uri|
119
+ namespaces: (ns_defs || []).map do |keyword, (type, domain)|
120
120
  {
121
121
  keyword: keyword,
122
- uri: domain_value(:uri, uri)
122
+ type: type,
123
+ domain: domain_value(type, domain)
123
124
  }
124
125
  end
125
126
  }
@@ -151,17 +152,20 @@ if __FILE__ == $PROGRAM_NAME
151
152
  require 'bel_parser/resource/resource_url_reader'
152
153
  include BELParser::Script
153
154
 
154
- rr = BELParser::Resource::ResourceURLReader.new(true)
155
+ uri_reader = BELParser::Resource.default_uri_reader
156
+ url_reader = BELParser::Resource::ResourceURLReader.new(true)
157
+
155
158
  namespaces = Hash[
156
159
  ARGV.map do |ns|
157
160
  prefix, identifier = ns.split('=')
158
- dataset = rr.retrieve_resource(identifier)
161
+ dataset = uri_reader.retrieve_resource(identifier)
159
162
  dataset ? [prefix, dataset] : nil
160
163
  end.compact
161
164
  ]
162
165
 
163
166
  initial_state = {
164
- resource_reader: rr,
167
+ uri_reader: uri_reader,
168
+ url_reader: url_reader,
165
169
  specification: BELParser::Language.specification('2.0'),
166
170
  namespace_definitions: namespaces
167
171
  }
@@ -1,29 +1,38 @@
1
1
  require 'bel_parser/language'
2
- require 'bel_parser/quoting'
3
2
  require 'bel_parser/parsers/ast/node'
4
3
  require 'concurrent/hash'
5
4
  require_relative '../state_function'
5
+ require_relative '../apply_resource_uri'
6
6
 
7
7
  module BELParser
8
8
  module Script
9
9
  module State
10
10
  class AnnotationDefinition
11
11
  extend StateFunction
12
- extend BELParser::Quoting
13
12
 
14
13
  TARGET_NODE = BELParser::Parsers::AST::AnnotationDefinition
15
14
 
16
15
  def self.consume(ast_node, script_context)
17
16
  return nil unless ast_node.is_a?(TARGET_NODE)
18
- resource_reader = script_context[:resource_reader]
17
+ uri_reader = script_context[:uri_reader]
18
+ url_reader = script_context[:url_reader]
19
19
 
20
20
  keyword, domain = ast_node.children
21
21
  prefix = keyword.identifier.string_literal
22
22
  case
23
23
  when domain.list?
24
24
  handle_list(prefix, domain.child, script_context)
25
+ when domain.uri?
26
+ uri = domain.child.string.string_literal
27
+ handle_uri(prefix, uri, script_context)
25
28
  when domain.url?
26
- handle_url(prefix, domain.child, script_context)
29
+ ApplyResourceURI.new.process(ast_node)
30
+ if ast_node.uri
31
+ handle_uri(prefix, ast_node.uri, script_context)
32
+ else
33
+ url = domain.child.string.string_literal
34
+ handle_url(prefix, url, script_context)
35
+ end
27
36
  when domain.pattern?
28
37
  handle_pattern(prefix, domain.child, script_context)
29
38
  end
@@ -34,7 +43,7 @@ module BELParser
34
43
  script_context[:annotation_definitions][prefix] = [
35
44
  :list,
36
45
  list_node.list_items.map do |li|
37
- unquote(li.children[0].string_literal)
46
+ li.children[0].string_literal
38
47
  end
39
48
  ]
40
49
  end
@@ -44,14 +53,20 @@ module BELParser
44
53
  script_context[:annotation_definitions] ||= Concurrent::Hash.new
45
54
  script_context[:annotation_definitions][prefix] = [
46
55
  :pattern,
47
- unquote(pattern_node.string)
56
+ pattern_node.string
48
57
  ]
49
58
  end
50
59
  private_class_method :handle_pattern
51
60
 
52
- def self.handle_url(prefix, url_node, script_context)
53
- url = unquote(url_node.string.string_literal)
54
- dataset = script_context[:resource_reader].retrieve_resource(url)
61
+ def self.handle_uri(prefix, uri, script_context)
62
+ dataset = script_context[:uri_reader].retrieve_resource(uri)
63
+ script_context[:annotation_definitions] ||= Concurrent::Hash.new
64
+ script_context[:annotation_definitions][prefix] = [:uri, dataset]
65
+ end
66
+ private_class_method :handle_uri
67
+
68
+ def self.handle_url(prefix, url, script_context)
69
+ dataset = script_context[:url_reader].retrieve_resource(url)
55
70
  script_context[:annotation_definitions] ||= Concurrent::Hash.new
56
71
  script_context[:annotation_definitions][prefix] = [:url, dataset]
57
72
  end
@@ -1,29 +1,43 @@
1
1
  require 'bel_parser/language'
2
- require 'bel_parser/quoting'
3
2
  require 'bel_parser/parsers/ast/node'
4
3
  require 'concurrent/hash'
5
4
  require_relative '../state_function'
5
+ require_relative '../apply_resource_uri'
6
6
 
7
7
  module BELParser
8
8
  module Script
9
9
  module State
10
10
  class NamespaceDefinition
11
11
  extend StateFunction
12
- extend BELParser::Quoting
13
12
 
14
13
  TARGET_NODE = BELParser::Parsers::AST::NamespaceDefinition
15
14
 
16
15
  def self.consume(ast_node, script_context)
17
16
  return nil unless ast_node.is_a?(TARGET_NODE)
18
- resource_reader = script_context[:resource_reader]
17
+ uri_reader = script_context[:uri_reader]
18
+ url_reader = script_context[:url_reader]
19
19
 
20
20
  keyword, domain = ast_node.children
21
- if domain.url?
22
- prefix = keyword.identifier.string_literal
23
- url = unquote(domain.child.string.string_literal)
24
- dataset = resource_reader.retrieve_resource(url)
21
+ prefix = keyword.identifier.string_literal
22
+
23
+ case
24
+ when domain.uri?
25
+ uri = domain.child.string.string_literal
26
+ dataset = uri_reader.retrieve_resource(uri)
25
27
  script_context[:namespace_definitions] ||= Concurrent::Hash.new
26
- script_context[:namespace_definitions][prefix] = dataset
28
+ script_context[:namespace_definitions][prefix] = [:uri, dataset]
29
+ when domain.url?
30
+ ApplyResourceURI.new.process(ast_node)
31
+ if ast_node.uri
32
+ dataset = uri_reader.retrieve_resource(ast_node.uri)
33
+ script_context[:namespace_definitions] ||= Concurrent::Hash.new
34
+ script_context[:namespace_definitions][prefix] = [:uri, dataset]
35
+ else
36
+ url = domain.child.string.string_literal
37
+ dataset = url_reader.retrieve_resource(url)
38
+ script_context[:namespace_definitions] ||= Concurrent::Hash.new
39
+ script_context[:namespace_definitions][prefix] = [:url, dataset]
40
+ end
27
41
  end
28
42
  end
29
43
  end
@@ -30,13 +30,14 @@ module BELParser
30
30
 
31
31
  def self.expression_validator(script_context)
32
32
  unless defined? @expression_validator
33
- spec, namespaces, reader =
34
- script_context
35
- .values_at(
33
+ spec, namespaces, uri_reader, url_reader =
34
+ script_context.values_at(
36
35
  :specification,
37
36
  :namespace_definitions,
38
- :resource_reader)
39
- @expression_validator = EXP_VALIDATOR.new(spec, namespaces, reader)
37
+ :uri_reader,
38
+ :url_reader)
39
+ @expression_validator = EXP_VALIDATOR.new(
40
+ spec, namespaces, uri_reader, url_reader)
40
41
  end
41
42
  @expression_validator
42
43
  end
@@ -23,16 +23,22 @@ module BELParser
23
23
  name_string = ast_node.name.identifier.string_literal
24
24
 
25
25
  return nil if is_implicit_annotation?(name_string)
26
- dataset = annotation(name_string, script_context)
27
- return nil unless dataset
26
+ type, dataset = annotation(name_string, script_context)
27
+ return nil unless type == :uri || type == :url
28
28
 
29
- rr = script_context[:resource_reader]
29
+ reader =
30
+ case type
31
+ when :uri
32
+ script_context[:uri_reader]
33
+ when :url
34
+ script_context[:url_reader]
35
+ end
30
36
  value_node = ast_node.value.children[0]
31
37
  if value_node.is_a?(LIST_NODE)
32
38
  value_node
33
39
  .list_items.map { |li| li.children[0].string_literal }
34
40
  .map do |string|
35
- map_value(ast_node, name_string, string, dataset.identifier, rr)
41
+ map_value(ast_node, name_string, string, dataset.identifier, reader)
36
42
  end
37
43
  else
38
44
  map_value(
@@ -40,20 +46,19 @@ module BELParser
40
46
  name_string,
41
47
  value_node.string_literal,
42
48
  dataset.identifier,
43
- rr)
49
+ reader)
44
50
  end
45
51
  end
46
52
 
47
53
  def self.annotation(name_string, script_context)
48
54
  hash =
49
55
  script_context[:annotation_definitions] ||= Concurrent::Hash.new
50
- type, definition = hash[name_string]
51
- type == :url ? definition : nil
56
+ hash[name_string]
52
57
  end
53
58
 
54
- def self.map_value(ast_node, name_string, value_string, identifier, rr)
59
+ def self.map_value(ast_node, name_string, value_string, identifier, reader)
55
60
  value_string = unquote(value_string)
56
- value = rr.retrieve_value_from_resource(identifier, value_string)
61
+ value = reader.retrieve_value_from_resource(identifier, value_string)
57
62
  UndefinedAnnotationValueWarning.new(
58
63
  ast_node,
59
64
  name_string,
@@ -1,7 +1,6 @@
1
1
  require 'bel_parser/language'
2
2
  require 'bel_parser/language/syntax_function'
3
3
  require 'bel_parser/language/syntax_error'
4
- require 'bel_parser/quoting'
5
4
  require 'bel_parser/parsers/ast/node'
6
5
  require 'concurrent/hash'
7
6
 
@@ -10,20 +9,28 @@ module BELParser
10
9
  module Syntax
11
10
  class UnresolvableNamespace
12
11
  extend BELParser::Language::Syntax::SyntaxFunction
13
- extend BELParser::Quoting
14
12
 
15
13
  TARGET_NODE = BELParser::Parsers::AST::NamespaceDefinition
16
14
 
17
15
  def self.map(ast_node, script_context)
18
16
  return nil unless ast_node.is_a?(TARGET_NODE)
19
- resource_reader = script_context[:resource_reader]
17
+ uri_reader, url_reader = script_context.values_at(:uri_reader, :url_reader)
20
18
 
21
19
  keyword, domain = ast_node.children
22
20
  if domain.url?
23
- url = unquote(domain.child.string.string_literal)
24
- unless resource_reader.retrieve_resource(url)
25
- prefix = keyword.identifier.string_literal
26
- return UnresolvableNamespaceError.new(ast_node, prefix, url)
21
+ ApplyResourceURI.new.process(ast_node)
22
+ if ast_node.uri
23
+ uri = ast_node.uri
24
+ unless uri_reader.retrieve_resource(uri)
25
+ prefix = keyword.identifier.string_literal
26
+ return UnresolvableNamespaceError.new(ast_node, prefix, uri)
27
+ end
28
+ else
29
+ url = domain.child.string.string_literal
30
+ unless url_reader.retrieve_resource(url)
31
+ prefix = keyword.identifier.string_literal
32
+ return UnresolvableNamespaceError.new(ast_node, prefix, url)
33
+ end
27
34
  end
28
35
  end
29
36
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bel_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.44
4
+ version: 1.0.0.alpha.45
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Bargnesi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-23 00:00:00.000000000 Z
12
+ date: 2016-05-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sparql-client
@@ -350,6 +350,7 @@ files:
350
350
  - lib/bel_parser/resource/sparql_reader.rb
351
351
  - lib/bel_parser/resource/value.rb
352
352
  - lib/bel_parser/script.rb
353
+ - lib/bel_parser/script/apply_resource_uri.rb
353
354
  - lib/bel_parser/script/filter.rb
354
355
  - lib/bel_parser/script/first_node.rb
355
356
  - lib/bel_parser/script/keywords.rb