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
@@ -1,37 +0,0 @@
1
- module BEL
2
-
3
- # The {Extension} module defines specific areas of customization within the
4
- # *bel* gem:
5
- #
6
- # - Document formats: see {BEL::Extension::Format}
7
- module Extension
8
-
9
- # Loads BEL extensions from the +$LOAD_PATH+ under the path
10
- # +bel/extensions/{extension}+. These extensions are merely ruby scripts
11
- # meant to extend functionality within the *bel* gem.
12
- #
13
- # For example, let's say we created the foo.rb file containing a Foo
14
- # extension. We must do the following to load it:
15
- #
16
- # - Locate foo.rb at +bel/extensions/foo.rb+ anywhere on the +$LOAD_PATH+.
17
- # - Instantiate and register our extension.
18
- # - Call +BEL.extension :foo+ to load the extension.
19
- #
20
- # @param [Array<#to_s>] extensions the extensions to load
21
- def self.load_extension(*extensions)
22
- extensions.each do |ext|
23
- Kernel.require "bel/extensions/#{ext}"
24
- end
25
- end
26
-
27
- class ExtensionRegistrationError < StandardError
28
-
29
- attr_reader :extension
30
-
31
- def initialize(extension, msg = "Extension error for #{extension}")
32
- super(msg)
33
- @extension = extension
34
- end
35
- end
36
- end
37
- end
@@ -1,207 +0,0 @@
1
- module BEL
2
- module Extension
3
-
4
- # The {Format} module defines a framework for adding new document formats.
5
- # This is useful when reading, writing, and {BEL::Translation translating}
6
- # BEL data.
7
- #
8
- # A {Format} extension is defined and registered in the following steps:
9
- #
10
- # - Create a ruby source file located under +bel/extensions/+ on the
11
- # +$LOAD_PATH+.
12
- # - Within the file, create a class that implements the protocol specified
13
- # by {Format::Formatter}.
14
- # - Instantiate and register your format extension by calling
15
- # {Format.register_formatter}.
16
- #
17
- # To see how to define a new format extension have a look at the
18
- # {Format::Formatter} module.
19
- #
20
- module Format
21
-
22
- FORMATTER_MUTEX = Mutex.new
23
- private_constant :FORMATTER_MUTEX
24
-
25
- # Registers the +formatter+ object as available to callers. The
26
- # +formatter+ should respond to the methods defined in the
27
- # {Format::Formatter} module.
28
- #
29
- # @param [Format::Formatter] formatter the formatter to register
30
- # @return [Format::Formatter] the +formatter+ parameter is returned
31
- # for convenience
32
- def self.register_formatter(formatter)
33
- FORMATTER_MUTEX.synchronize {
34
- @@formatters ||= []
35
- # vivified hash, like: { :foo => { :bar => [] } }
36
- @@index ||= (
37
- Hash.new do |h0, k0|
38
- h0[k0] = Hash.new do |h1, k1|
39
- h1[k1] = []
40
- end
41
- end
42
- )
43
-
44
- if _formatters(formatter.id)
45
- raise ExtensionRegistrationError.new(formatter.id)
46
- end
47
-
48
- # track registered formatters
49
- @@formatters << formatter
50
-
51
- # index formatter by its id
52
- @@index[:id][symbolize(formatter.id)] << formatter
53
-
54
- # index formatter by one or more file extensions
55
- [formatter.file_extensions].flatten.compact.to_a.each do |file_ext|
56
- @@index[:file_extension][symbolize(file_ext)] << formatter
57
- end
58
-
59
- # index formatter by one or more media types
60
- [formatter.media_types].flatten.compact.to_a.each do |media_type|
61
- @@index[:media_type][symbolize(media_type)] << formatter
62
- end
63
-
64
- formatter
65
- }
66
- end
67
-
68
- # Returns the {Format::Formatter formatters} found for the +values+
69
- # splat. The returned matches have the same cardinality as the +values+
70
- # splat to allow destructuring.
71
- #
72
- # @example Retrieve a single formatter by id.
73
- # bel_formatter = Format.formatters(:bel)
74
- # @example Retrieve a single formatter by file extension.
75
- # xbel_formatter = Format.formatters(:xml)
76
- # @example Retrieve a single formatter by media type.
77
- # json_formatter = Format.formatters(%s(application/json))
78
- # @example Retrieve multiple formatters using mixed values.
79
- # belf, xbelf, jsonf = Format.formatters(:bel, :xml, "application/json")
80
- #
81
- # @param [Array<#to_s>] values the splat that identifies formatters
82
- # @return [Format::Formatter Array<Format::Formatter>] for each
83
- # consecutive value in the +values+ splat; if the +values+ splat
84
- # contains one value then a single formatter reference is returned
85
- # (e.g. not an Array)
86
- def self.formatters(*values)
87
- FORMATTER_MUTEX.synchronize {
88
- _formatters(*values)
89
- }
90
- end
91
-
92
- def self._formatters(*values)
93
- if values.empty?
94
- Array.new @@formatters
95
- else
96
- index = (@@index ||= {})
97
- matches = values.map { |value|
98
- value = symbolize(value)
99
- @@index.values_at(:id, :file_extension, :media_type).
100
- compact.
101
- inject([]) { |result, coll|
102
- if coll.has_key?(value)
103
- result.concat(coll[value])
104
- end
105
- result
106
- }.uniq.first
107
- }
108
- matches.size == 1 ? matches.first : matches
109
- end
110
- end
111
- private_class_method :_formatters
112
-
113
- def self.symbolize(key)
114
- key.to_s.to_sym
115
- end
116
- private_class_method :symbolize
117
-
118
- # The Formatter module defines methods to be implemented by a format
119
- # extension +Class+. It is broken up into three parts:
120
- #
121
- # - Metadata
122
- # - {#id}: the runtime-wide unique extension id
123
- # - {#media_types}: the media types this format supports
124
- # - {#file_extensions}: the file extensions this format supports
125
- # - Deserialize
126
- # - {#deserialize}: read the implemented document format and return
127
- # {::BEL::Model::Evidence} objects
128
- # - Serialize
129
- # - {#serialize}: write {::BEL::Model::Evidence} objects to the
130
- # implemented document format
131
- #
132
- # @example Typical creation of a {Formatter} class.
133
- # class FormatYAML
134
- # include BEL::Extension::Format::Formatter
135
- # # override methods
136
- # end
137
- #
138
- # @example Create a YAML format extension.
139
- # class FormatYAML
140
- # include BEL::Extension::Format::Formatter
141
- #
142
- # ID = :yaml
143
- # MEDIA_TYPES = %i(text/yaml)
144
- # EXTENSIONS = %i(yaml)
145
- #
146
- # def id
147
- # ID
148
- # end
149
- #
150
- # def media_types
151
- # MEDIA_TYPES
152
- # end
153
- #
154
- # def file_extensions
155
- # EXTENSIONS
156
- # end
157
- #
158
- # def deserialize(data)
159
- # YAML.load(data)
160
- # end
161
- #
162
- # def serialize(data)
163
- # YAML.dump(data)
164
- # end
165
- # end
166
- module Formatter
167
-
168
- def id
169
- raise NotImplementedError.new("#{__method__} is not implemented.")
170
- end
171
-
172
- def media_types
173
- # optional
174
- nil
175
- end
176
-
177
- def file_extensions
178
- # optional
179
- nil
180
- end
181
-
182
- def evidence_hash(object)
183
- raise NotImplementedError.new("#{__method__} is not implemented.")
184
- end
185
-
186
- def deserialize(data)
187
- raise NotImplementedError.new("#{__method__} is not implemented.")
188
- end
189
-
190
- def serialize(data, writer = nil)
191
- raise NotImplementedError.new("#{__method__} is not implemented.")
192
- end
193
- end
194
-
195
- # FormatError represents an error when the specified format is not
196
- # supported by the {Format} extension framework.
197
- class FormatError < StandardError
198
-
199
- FORMAT_ERROR = %Q{Format "%s" is not supported.}
200
-
201
- def initialize(format)
202
- super(FORMAT_ERROR % format)
203
- end
204
- end
205
- end
206
- end
207
- end
@@ -1,258 +0,0 @@
1
- require 'bel'
2
-
3
- module BEL::Extension::Format
4
-
5
- class FormatBEL
6
-
7
- include Formatter
8
-
9
- ID = :bel
10
- MEDIA_TYPES = %i(application/bel)
11
- EXTENSIONS = %i(bel)
12
-
13
- def id
14
- ID
15
- end
16
-
17
- def media_types
18
- MEDIA_TYPES
19
- end
20
-
21
- def file_extensions
22
- EXTENSIONS
23
- end
24
-
25
- def deserialize(data, &block)
26
- EvidenceYielder.new(data)
27
- end
28
-
29
- def serialize(objects, writer = StringIO.new, options = {})
30
- BELYielder.new(objects).each { |bel_part|
31
- writer << "#{bel_part}"
32
- writer.flush
33
- }
34
- end
35
- end
36
-
37
- class EvidenceYielder
38
- include ::BEL::Model
39
- include ::BEL::Quoting
40
-
41
- SPECIAL_ANNOTATIONS = {
42
- 'Citation' => true,
43
- 'Evidence' => true,
44
- }
45
-
46
- def initialize(data)
47
- @data = data
48
- @references = References.new
49
- @metadata = Metadata.new
50
- end
51
-
52
- def each
53
- if block_given?
54
- ::BEL::Script.parse(@data).each { |parsed_obj|
55
- case parsed_obj
56
- when ::BEL::Language::DocumentProperty
57
- @metadata.document_header[parsed_obj.name] = parsed_obj.value
58
- when ::BEL::Model::Statement
59
- yield to_evidence(parsed_obj, @references, @metadata)
60
- when ::BEL::Language::AnnotationDefinition
61
- @references.annotation_definitions[parsed_obj.prefix] = {
62
- :type => parsed_obj.type,
63
- :domain => parsed_obj.value
64
- }
65
- when ::BEL::Namespace::NamespaceDefinition
66
- @references.namespace_definitions[parsed_obj.prefix] = parsed_obj.url
67
- end
68
- }
69
- else
70
- to_enum(:each)
71
- end
72
- end
73
-
74
- private
75
-
76
- def to_evidence(statement, references, metadata)
77
- evidence = Evidence.new
78
- evidence.bel_statement = statement
79
-
80
- if statement.annotations.include? 'Citation'
81
- fields = statement.annotations['Citation'].value
82
- if fields.respond_to? :each
83
- evidence.citation = Citation.new(
84
- *fields.map { |field|
85
- remove_quotes(field)
86
- }.to_a
87
- )
88
- end
89
- end
90
-
91
- if statement.annotations.include? 'Evidence'
92
- value = statement.annotations['Evidence'].value
93
- evidence.summary_text.value = value
94
- end
95
-
96
- annotations = statement.annotations.dup
97
- annotations.delete_if { |k, _| SPECIAL_ANNOTATIONS[k] }
98
- evidence.experiment_context = ExperimentContext.new(
99
- annotations.map { |k, v|
100
- value = v.value
101
- obj = {
102
- :name => k,
103
- :value => value
104
- }
105
-
106
- annotation_def = references.annotation_definitions[k]
107
- if annotation_def
108
- type, domain = annotation_def.values_at(:type, :domain)
109
- if type == :url
110
- obj[:uri] = "#{domain}/#{value}"
111
- obj[:url] = domain
112
- end
113
- end
114
-
115
- obj
116
- }
117
- )
118
-
119
- evidence.references = references
120
- evidence.metadata = metadata
121
- evidence
122
- end
123
- end
124
-
125
- class BELYielder
126
-
127
- def initialize(data, options = {})
128
- @data = data
129
- @write_header = (options[:write_header] || true)
130
- end
131
-
132
- def each
133
- if block_given?
134
- header_flag = true
135
- @data.each { |evidence|
136
- bel = to_bel(evidence)
137
- if @write_header && header_flag
138
- yield document_header(evidence.metadata.document_header)
139
- yield namespace_definitions(
140
- evidence.references.namespace_definitions
141
- )
142
- yield annotation_definitions(
143
- evidence.references.annotation_definitions
144
- )
145
- header_flag = false
146
- end
147
-
148
- yield bel
149
- }
150
- else
151
- to_enum(:each)
152
- end
153
- end
154
-
155
- private
156
-
157
- def document_header(header)
158
- return "" unless header
159
-
160
- header.reduce("") { |bel, (name, value)|
161
- name_s = name.to_s
162
- value_s =
163
- if value.respond_to?(:each)
164
- value.join('|')
165
- else
166
- value.to_s
167
- end
168
-
169
- # handle casing for document properties (special case, contactinfo)
170
- name_s = (name_s.downcase == 'contactinfo') ?
171
- 'ContactInfo' :
172
- name_s.capitalize
173
-
174
- bel << %Q{SET DOCUMENT #{name_s} = "#{value_s}"\n}
175
- bel
176
- }
177
- end
178
-
179
- def annotation_definitions(annotation_definitions)
180
- return "" unless annotation_definitions
181
-
182
- annotation_definitions.reduce("") { |bel, (prefix, annotation)|
183
- bel << "DEFINE ANNOTATION #{prefix} AS "
184
- type = annotation[:type] || annotation["type"]
185
- domain = annotation[:domain] || annotation["domain"]
186
- case type.to_sym
187
- when :url
188
- bel << %Q{URL "#{domain}"\n}
189
- when :pattern
190
- bel << %Q{PATTERN "#{domain}"\n}
191
- when :list
192
- bel << %Q|LIST {#{domain.inspect[1...-1]}}\n|
193
- end
194
- bel
195
- }
196
- end
197
-
198
- def namespace_definitions(namespace_definitions)
199
- return "" unless namespace_definitions
200
-
201
- namespace_definitions.reduce("") { |bel, (prefix, url)|
202
- bel << %Q{DEFINE NAMESPACE #{prefix} AS URL "#{url}"\n}
203
- bel
204
- }
205
- end
206
-
207
- def to_bel(evidence)
208
- bel = ""
209
-
210
- # Citation
211
- citation = evidence.citation
212
- if citation && citation.values.any?
213
- values = citation.values
214
- values.map! { |v| v || "" }
215
- values.map! { |v|
216
- if v.respond_to?(:each)
217
- v.join('|')
218
- else
219
- v
220
- end
221
- }
222
- value_string = values.inspect[1...-1]
223
- bel << "SET Citation = {#{value_string}}\n"
224
- end
225
-
226
- # Evidence
227
- summary_text = evidence.summary_text
228
- if summary_text && summary_text.value
229
- value = summary_text.value
230
- value.gsub!("\n", "")
231
- value.gsub!('"', %Q{\\"})
232
- bel << %Q{SET Evidence = "#{value}"\n}
233
- end
234
-
235
- # Annotation
236
- experiment_context = evidence.experiment_context
237
- if experiment_context
238
- experiment_context.
239
- sort_by { |obj| obj[:name] }.
240
- each { |obj|
241
- name, value = obj.values_at(:name, :value)
242
- if value.respond_to? :each
243
- value = "{#{value.inspect[1...-1]}}"
244
- else
245
- value = value.inspect
246
- end
247
- bel << "SET #{name} = #{value}\n"
248
- }
249
- end
250
-
251
- # BEL statement
252
- bel << "#{evidence.bel_statement.to_s}\n"
253
- bel
254
- end
255
- end
256
-
257
- register_formatter(FormatBEL.new)
258
- end