bel 0.3.3 → 0.4.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +53 -8
  3. data/bel.gemspec +10 -15
  4. data/bin/bel +63 -4
  5. data/bin/bel2rdf.rb +1 -1
  6. data/bin/bel_compare.rb +1 -1
  7. data/bin/bel_parse.rb +1 -1
  8. data/bin/bel_rdfschema.rb +1 -1
  9. data/bin/bel_summarize.rb +1 -1
  10. data/bin/bel_upgrade.rb +1 -1
  11. data/lib/bel.rb +8 -10
  12. data/lib/bel/completion.rb +3 -2
  13. data/lib/bel/completion/value_match_rule.rb +10 -0
  14. data/lib/bel/evidence_model/citation.rb +101 -43
  15. data/lib/bel/evidence_model/evidence.rb +2 -2
  16. data/lib/bel/evidence_model/experiment_context.rb +1 -0
  17. data/lib/bel/evidence_model/metadata.rb +15 -2
  18. data/lib/bel/evidence_model/references.rb +10 -10
  19. data/lib/bel/json.rb +63 -0
  20. data/lib/bel/json/adapter/multi_json.rb +36 -0
  21. data/lib/bel/json/adapter/oj.rb +65 -0
  22. data/lib/bel/json/adapter/ruby_json.rb +28 -0
  23. data/lib/bel/json/reader.rb +9 -0
  24. data/lib/bel/json/writer.rb +9 -0
  25. data/lib/bel/libbel.rb +1 -4
  26. data/lib/bel/parser.rb +2 -2
  27. data/lib/bel/rdf_repository.rb +18 -0
  28. data/lib/bel/rdf_repository/plugins/memory.rb +28 -0
  29. data/lib/bel/rdf_repository/plugins/mongo.rb +28 -0
  30. data/lib/bel/resource.rb +24 -0
  31. data/lib/bel/resource/namespace.rb +122 -0
  32. data/lib/bel/resource/namespace_value.rb +69 -0
  33. data/lib/bel/resource/namespaces.rb +83 -0
  34. data/lib/bel/resource/search.rb +26 -0
  35. data/lib/bel/resource/search/api.rb +36 -0
  36. data/lib/bel/resource/search/search_result.rb +32 -0
  37. data/lib/bel/translate.rb +108 -0
  38. data/lib/bel/translator.rb +69 -0
  39. data/lib/bel/translator/plugins/bel_script.rb +36 -0
  40. data/lib/bel/translator/plugins/bel_script/bel_yielder.rb +144 -0
  41. data/lib/bel/translator/plugins/bel_script/evidence_yielder.rb +95 -0
  42. data/lib/bel/translator/plugins/bel_script/translator.rb +24 -0
  43. data/lib/bel/translator/plugins/jgf.rb +37 -0
  44. data/lib/bel/translator/plugins/jgf/translator.rb +160 -0
  45. data/lib/bel/translator/plugins/json_evidence.rb +38 -0
  46. data/lib/bel/translator/plugins/json_evidence/translator.rb +90 -0
  47. data/lib/bel/translator/plugins/rdf.rb +48 -0
  48. data/lib/bel/translator/plugins/rdf/bel_schema.rb +339 -0
  49. data/lib/bel/translator/plugins/rdf/monkey_patch.rb +310 -0
  50. data/lib/bel/translator/plugins/rdf/reader.rb +173 -0
  51. data/lib/bel/translator/plugins/rdf/translator.rb +40 -0
  52. data/lib/bel/translator/plugins/rdf/writer.rb +45 -0
  53. data/lib/bel/translator/plugins/xbel.rb +36 -0
  54. data/lib/bel/translator/plugins/xbel/evidence_handler.rb +468 -0
  55. data/lib/bel/translator/plugins/xbel/evidence_yielder.rb +24 -0
  56. data/lib/bel/translator/plugins/xbel/translator.rb +24 -0
  57. data/lib/bel/translator/plugins/xbel/xbel_yielder.rb +414 -0
  58. data/lib/bel/vendor/little-plugger.rb +323 -0
  59. data/lib/bel/version.rb +1 -1
  60. metadata +44 -158
  61. data/lib/bel/extension.rb +0 -37
  62. data/lib/bel/extension_format.rb +0 -207
  63. data/lib/bel/extensions/bel.rb +0 -258
  64. data/lib/bel/extensions/jgf.rb +0 -219
  65. data/lib/bel/extensions/json/jrjackson.rb +0 -31
  66. data/lib/bel/extensions/json/json.rb +0 -133
  67. data/lib/bel/extensions/json/multi_json.rb +0 -29
  68. data/lib/bel/extensions/json/oj.rb +0 -68
  69. data/lib/bel/extensions/json/ruby_json.rb +0 -29
  70. data/lib/bel/extensions/rdf/bel_rdf.rb +0 -338
  71. data/lib/bel/extensions/rdf/rdf.rb +0 -584
  72. data/lib/bel/extensions/xbel.rb +0 -923
  73. data/lib/bel/format.rb +0 -58
@@ -0,0 +1,40 @@
1
+ # Load RDF library dependencies
2
+ begin
3
+ require 'rdf'
4
+ require 'addressable/uri'
5
+ require 'uuid'
6
+ rescue LoadError => e
7
+ # Raise LoadError if the requirements were not met.
8
+ raise
9
+ end
10
+
11
+ require_relative 'bel_schema'
12
+ require_relative 'monkey_patch'
13
+ require_relative 'reader'
14
+ require_relative 'writer'
15
+
16
+ module BEL::Translator::Plugins
17
+
18
+ module Rdf
19
+
20
+ class RdfTranslator
21
+
22
+ include ::BEL::Translator
23
+
24
+ def read(data, options = {})
25
+ Reader::UnbufferedEvidenceYielder.new(data)
26
+ end
27
+
28
+ def write(objects, writer = StringIO.new, options = {})
29
+ format = options[:format] || :ntriples
30
+ rdf_writer = Writer::RDFYielder.new(writer, format)
31
+
32
+ objects.each do |evidence|
33
+ rdf_writer << evidence
34
+ end
35
+ rdf_writer.done
36
+ writer
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ module BEL::Translator::Plugins
2
+
3
+ module Rdf::Writer
4
+
5
+ class RDFYielder
6
+ attr_reader :writer
7
+
8
+ def initialize(io, format)
9
+ rdf_writer = find_writer(format)
10
+ @writer = rdf_writer.new(io, { :stream => true })
11
+ end
12
+
13
+ def <<(evidence)
14
+ triples = evidence.bel_statement.to_rdf[1]
15
+ triples.each do |triple|
16
+ @writer.write_statement(::RDF::Statement(*triple))
17
+ end
18
+ end
19
+
20
+ def done
21
+ @writer.write_epilogue
22
+ end
23
+
24
+ private
25
+
26
+ def find_writer(format)
27
+ case format.to_s.to_sym
28
+ when :nquads
29
+ BEL::RDF::RDF::NQuads::Writer
30
+ when :turtle
31
+ begin
32
+ require 'rdf/turtle'
33
+ BEL::RDF::RDF::Turtle::Writer
34
+ rescue LoadError
35
+ $stderr.puts """Turtle format not supported.
36
+ Install the 'rdf-turtle' gem."""
37
+ raise
38
+ end
39
+ when :ntriples
40
+ Rdf::BEL::RDF::RDF::NTriples::Writer
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ module BEL::Translator::Plugins
2
+
3
+ module Xbel
4
+
5
+ ID = :xbel
6
+ NAME = 'XBEL Translator'
7
+ DESCRIPTION = 'A translator that can read and write evidence to XBEL (version 1.0). XBEL is an XML dialect. XML Schema for version 1.0 is published here (http://resource.belframework.org/belframework/1.0/schema/xbel.xsd).'
8
+ MEDIA_TYPES = %i(application/xml)
9
+ EXTENSIONS = %i(xml xbel)
10
+
11
+ def self.create_translator(options = {})
12
+ require_relative 'xbel/translator'
13
+ XbelTranslator.new
14
+ end
15
+
16
+ def self.id
17
+ ID
18
+ end
19
+
20
+ def self.name
21
+ NAME
22
+ end
23
+
24
+ def self.description
25
+ DESCRIPTION
26
+ end
27
+
28
+ def self.media_types
29
+ MEDIA_TYPES
30
+ end
31
+
32
+ def self.file_extensions
33
+ EXTENSIONS
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,468 @@
1
+ require 'rexml/streamlistener'
2
+
3
+ module BEL::Translator::Plugins
4
+
5
+ module Xbel
6
+
7
+ class EvidenceHandler
8
+ include REXML::StreamListener
9
+ include ::BEL::Model
10
+
11
+ ANNOTATION = "annotation"
12
+ ANNOTATION_DEFINITION_GROUP = "annotationDefinitionGroup"
13
+ ANNOTATION_GROUP = "annotationGroup"
14
+ AUTHOR = "author"
15
+ AUTHOR_GROUP = "authorGroup"
16
+ CITATION = "citation"
17
+ COMMENT = "comment"
18
+ CONTACT_INFO = "contactInfo"
19
+ COPYRIGHT = "copyright"
20
+ DATE = "date"
21
+ DESCRIPTION = "description"
22
+ DOCUMENT = "document"
23
+ EVIDENCE = "evidence"
24
+ EXTERNAL_ANNOTATION_DEFINITION = "externalAnnotationDefinition"
25
+ FUNCTION = "function"
26
+ HEADER = "header"
27
+ ID = "id"
28
+ INTERNAL_ANNOTATION_DEFINITION = "internalAnnotationDefinition"
29
+ LICENSE = "license"
30
+ LICENSE_GROUP = "licenseGroup"
31
+ LIST_ANNOTATION = "listAnnotation"
32
+ LIST_VALUE = "listValue"
33
+ NAME = "name"
34
+ NAMESPACE = "namespace"
35
+ NAMESPACE_GROUP = "namespaceGroup"
36
+ NS = "ns"
37
+ OBJECT = "object"
38
+ PARAMETER = "parameter"
39
+ PATTERN_ANNOTATION = "patternAnnotation"
40
+ PREFIX = "prefix"
41
+ REFERENCE = "reference"
42
+ REF_ID = "refID"
43
+ RELATIONSHIP = "relationship"
44
+ RESOURCE_LOCATION = "resourceLocation"
45
+ STATEMENT = "statement"
46
+ STATEMENT_GROUP = "statementGroup"
47
+ SUBJECT = "subject"
48
+ TERM = "term"
49
+ TYPE = "type"
50
+ URL = "url"
51
+ USAGE = "usage"
52
+ VERSION = "version"
53
+
54
+ def initialize(callable)
55
+ @callable = callable
56
+ @element_stack = []
57
+ @text = nil
58
+ @evidence = Evidence.new
59
+ end
60
+
61
+ # Called on element start by REXML.
62
+ def tag_start(name, attributes)
63
+ name.
64
+ sub!(/^bel:/, '').
65
+ gsub!(/([A-Z])/) { |match| "_#{match.downcase}" }
66
+
67
+ start_method = "start_#{name}"
68
+ if self.respond_to? start_method
69
+ self.send(start_method, attributes)
70
+ end
71
+ end
72
+
73
+ # Called on element end by REXML.
74
+ def tag_end(name)
75
+ name.
76
+ sub!(/^bel:/, '').
77
+ gsub!(/([A-Z])/) { |match| "_#{match.downcase}" }
78
+
79
+ end_method = "end_#{name}"
80
+ if self.respond_to? end_method
81
+ self.send end_method
82
+ end
83
+ end
84
+
85
+ # Called on text node by REXML.
86
+ def text(*args)
87
+ if args.size.zero?
88
+ @text = ''
89
+ else
90
+ @text = args.first
91
+ end
92
+ end
93
+
94
+ # Start element methods, dynamically invoked.
95
+
96
+ def start_header(attributes)
97
+ @element_stack << :header
98
+ end
99
+
100
+ def start_namespace_group(attributes)
101
+ @element_stack << :namespace_group
102
+ end
103
+
104
+ def start_annotation_definition_group(attributes)
105
+ @element_stack << :annotation_definition_group
106
+ end
107
+
108
+ def start_namespace(attributes)
109
+ if stack_top == :namespace_group
110
+ prefix = attr_value(attributes, PREFIX)
111
+ resource_location = attr_value(attributes, RESOURCE_LOCATION)
112
+ @evidence.references.namespaces[prefix] = resource_location
113
+ end
114
+ @element_stack << :namespace
115
+ end
116
+
117
+ def start_external_annotation_definition(attributes)
118
+ if stack_top == :annotation_definition_group
119
+ id = attr_value(attributes, ID)
120
+ url = attr_value(attributes, URL)
121
+ @evidence.references.annotations[id] = {
122
+ :type => :url,
123
+ :domain => url
124
+ }
125
+ end
126
+ @element_stack << :external_annotation_definition
127
+ end
128
+
129
+ def start_internal_annotation_definition(attributes)
130
+ if stack_top == :annotation_definition_group
131
+ id = attr_value(attributes, ID)
132
+ @current_anno_def = {}
133
+ @evidence.references.annotations[id] = @current_anno_def
134
+ end
135
+ @element_stack << :internal_annotation_definition
136
+ end
137
+
138
+ def start_list_annotation(attributes)
139
+ if stack_top == :internal_annotation_definition
140
+ @current_anno_def[:type] = :list
141
+ @current_anno_def[:domain] = []
142
+ end
143
+ @element_stack << :list_annotation
144
+ end
145
+
146
+ def start_pattern_annotation(attributes)
147
+ if stack_top == :internal_annotation_definition
148
+ @current_anno_def[:type] = :pattern
149
+ end
150
+ @element_stack << :pattern_annotation
151
+ end
152
+
153
+ def start_statement_group(attributes)
154
+ @element_stack << :statement_group
155
+ end
156
+
157
+ def start_statement(attributes)
158
+ stmt = Statement.new
159
+ stmt.relationship = attr_value(attributes, RELATIONSHIP)
160
+ if stack_top == :statement_group
161
+ @statement_stack = []
162
+ @statement_stack << stmt
163
+ elsif stack_top == :object
164
+ @statement_stack.last.object = stmt
165
+ @statement_stack << stmt
166
+ end
167
+
168
+ @element_stack << :statement
169
+ end
170
+
171
+ def start_subject(attributes)
172
+ @element_stack << :subject
173
+ end
174
+
175
+ def start_object(attributes)
176
+ @element_stack << :object
177
+ end
178
+
179
+ def start_term(attributes)
180
+ term = Term.new(attr_value(attributes, FUNCTION), [])
181
+ if stack_top == :subject || stack_top == :object
182
+ # outer term
183
+ @term_stack = []
184
+ elsif stack_top == :term
185
+ # nested term
186
+ @term_stack.last.arguments << term
187
+ end
188
+
189
+ @term_stack << term
190
+ @element_stack << :term
191
+ end
192
+
193
+ def start_parameter(attributes)
194
+ if stack_top == :term
195
+ ns_id = attr_value(attributes, NS)
196
+ # XXX Hitting a SystemStackError on line 174 (inside call).
197
+ # Example: large_corpus.xbel
198
+ ns = {
199
+ :prefix => ns_id,
200
+ :url => @evidence.references.namespaces[ns_id]
201
+ }
202
+ @current_parameter = Parameter.new(ns, nil)
203
+ end
204
+ @element_stack << :parameter
205
+ end
206
+
207
+ def start_annotation_group(attributes)
208
+ @annotation_id = nil
209
+ @element_stack << :annotation_group
210
+ end
211
+
212
+ def start_annotation(attributes)
213
+ if @element_stack[-2] == :statement
214
+ ref_id = attr_value(attributes, REF_ID)
215
+ @annotation_id = ref_id
216
+ @element_stack << :annotation
217
+ end
218
+ end
219
+
220
+ def start_citation(attributes)
221
+ type = attr_value(attributes, TYPE)
222
+ @evidence.citation.type = type
223
+ @element_stack << :citation
224
+ end
225
+
226
+ def start_evidence(attributes)
227
+ @element_stack << :evidence
228
+ end
229
+
230
+ # End element methods, dynamically invoked.
231
+
232
+ def end_header
233
+ @element_stack.pop
234
+ end
235
+
236
+ def end_version
237
+ if stack_top == :header
238
+ @evidence.metadata.document_header['version'] = @text
239
+ end
240
+ end
241
+
242
+ def end_copyright
243
+ if stack_top == :header
244
+ @evidence.metadata.document_header['copyright'] = @text
245
+ end
246
+ end
247
+
248
+ def end_contact_info
249
+ if stack_top == :header
250
+ @evidence.metadata.document_header['contactInfo'] = @text
251
+ end
252
+ end
253
+
254
+ def end_license
255
+ if stack_top == :header
256
+ @evidence.metadata.document_header['licenses'] ||= []
257
+ @evidence.metadata.document_header['licenses'] << @text
258
+ end
259
+ end
260
+
261
+ def end_namespace_group
262
+ @element_stack.pop
263
+ end
264
+
265
+ def end_annotation_definition_group
266
+ @element_stack.pop
267
+ end
268
+
269
+ def end_namespace
270
+ @element_stack.pop
271
+ end
272
+
273
+ def end_external_annotation_definition
274
+ @element_stack.pop
275
+ end
276
+
277
+ def end_internal_annotation_definition
278
+ @element_stack.pop
279
+ end
280
+
281
+ def end_list_annotation
282
+ @element_stack.pop
283
+ end
284
+
285
+ def end_pattern_annotation
286
+ begin
287
+ @current_anno_def[:domain] = Regexp.new(@text)
288
+ rescue RegexpError
289
+ @text = Regexp.escape(@text)
290
+ retry
291
+ end
292
+ @element_stack.pop
293
+ end
294
+
295
+ def end_description
296
+ if stack_top == :header
297
+ @evidence.metadata.document_header['description'] = @text
298
+ end
299
+
300
+ if stack_top == :internal_annotation_definition
301
+ @current_anno_def[:description] = @text
302
+ end
303
+ end
304
+
305
+ def end_usage
306
+ if stack_top == :internal_annotation_definition
307
+ @current_anno_def[:usage] = @text
308
+ end
309
+ end
310
+
311
+ def end_list_value
312
+ if stack_top == :list_annotation
313
+ @current_anno_def[:domain] << @text
314
+ end
315
+ end
316
+
317
+ def end_statement_group
318
+ @element_stack.pop
319
+ end
320
+
321
+ def end_statement
322
+ @element_stack.pop
323
+
324
+ stmt = @statement_stack.pop
325
+ if @statement_stack.empty?
326
+ # create new evidence from parsed data
327
+ evidence_copy = Evidence.create({
328
+ :bel_statement => stmt,
329
+ :citation => @evidence.citation.to_h,
330
+ :summary_text => @evidence.summary_text.value,
331
+ :experiment_context => @evidence.experiment_context.values.dup,
332
+ :references => @evidence.references.values.dup,
333
+ :metadata => @evidence.metadata.values.dup
334
+ })
335
+
336
+ # yield evidence
337
+ @callable.call(evidence_copy)
338
+
339
+ # clear evidence parser state
340
+ # note:
341
+ # - preserve @evidence.references
342
+ # - preserve @evidence.metadata.document_header
343
+ @evidence.bel_statement = nil
344
+ @evidence.citation = nil
345
+ @evidence.summary_text = nil
346
+ @evidence.experiment_context = nil
347
+ @evidence.metadata.delete_if { |key|
348
+ key != :document_header
349
+ }
350
+ end
351
+ end
352
+
353
+ def end_subject
354
+ @statement_stack.last.subject = @term_stack.last
355
+ @element_stack.pop
356
+ end
357
+
358
+ def end_object
359
+ if @statement_stack.last.object == nil
360
+ # sets object if it wasn't already set by OBJECT STATEMENT
361
+ @statement_stack.last.object = @term_stack.last
362
+ end
363
+ @element_stack.pop
364
+ end
365
+
366
+ def end_term
367
+ @element_stack.pop
368
+
369
+ if @term_stack.size > 1
370
+ @term_stack.pop
371
+ @current_term = @term_stack.last
372
+ end
373
+ end
374
+
375
+ def end_parameter
376
+ @current_parameter.value = @text
377
+ @term_stack.last.arguments << @current_parameter
378
+ @element_stack.pop
379
+ end
380
+
381
+ def end_annotation_group
382
+ @element_stack.pop
383
+ end
384
+
385
+ def end_annotation
386
+ if @element_stack[-3] == :statement
387
+ ref_id = @annotation_id
388
+
389
+ annotation = @evidence.experiment_context.find { |annotation|
390
+ annotation[:name] == ref_id
391
+ }
392
+ if annotation
393
+ # create array for multiple values by refID
394
+ annotation[:value] = [annotation[:value], @text].flatten
395
+ else
396
+ @evidence.experiment_context << {
397
+ :name => ref_id,
398
+ :value => @text
399
+ }
400
+ end
401
+ end
402
+
403
+ @element_stack.pop
404
+ end
405
+
406
+ def end_evidence
407
+ if @element_stack[-3] == :statement
408
+ @evidence.summary_text.value = @text
409
+ end
410
+
411
+ @element_stack.pop
412
+ end
413
+
414
+ def end_citation
415
+ @element_stack.pop
416
+ end
417
+
418
+ def end_reference
419
+ if stack_top == :citation
420
+ @evidence.citation.id = @text
421
+ end
422
+ end
423
+
424
+ def end_name
425
+ if stack_top == :header
426
+ @evidence.metadata.document_header['name'] = @text
427
+ end
428
+
429
+ if stack_top == :citation
430
+ @evidence.citation.name = @text
431
+ end
432
+ end
433
+
434
+ def end_date
435
+ if stack_top == :citation
436
+ @evidence.citation.date = @text
437
+ end
438
+ end
439
+
440
+ def end_author
441
+ if stack_top == :header
442
+ @evidence.metadata.document_header['authors'] ||= []
443
+ @evidence.metadata.document_header['authors'] << @text
444
+ end
445
+
446
+ if stack_top == :citation
447
+ (@evidence.citation.authors ||= []) << @text
448
+ end
449
+ end
450
+
451
+ def end_comment
452
+ if stack_top == :citation
453
+ @evidence.citation.comment = @text
454
+ end
455
+ end
456
+
457
+ private
458
+
459
+ def stack_top
460
+ @element_stack.last
461
+ end
462
+
463
+ def attr_value(attributes, attr_name)
464
+ attributes["bel:#{attr_name}"]
465
+ end
466
+ end
467
+ end
468
+ end