Skip to content
This repository was archived by the owner on Sep 24, 2019. It is now read-only.

Commit e4eb5dd

Browse files
author
Anthony Bargnesi
committed
dataset serialization to all bel.rb translators
updated dependencies to support all bel.rb translators refs #99
1 parent b1243d8 commit e4eb5dd

File tree

4 files changed

+106
-27
lines changed

4 files changed

+106
-27
lines changed

Diff for: .gemspec

+10-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,16 @@ Gem::Specification.new do |spec|
3434
# Dependencies
3535

3636
## bel.rb
37-
spec.add_runtime_dependency 'bel', '0.4.3'
37+
spec.add_runtime_dependency 'bel', '0.5.0'
38+
39+
## bel.rb translator dependencies
40+
spec.add_runtime_dependency 'json-ld', '1.99.0'
41+
spec.add_runtime_dependency 'rdf-json', '1.99.0'
42+
spec.add_runtime_dependency 'rdf-rdfa', '1.99.0'
43+
spec.add_runtime_dependency 'rdf-rdfxml', '1.99.0'
44+
spec.add_runtime_dependency 'rdf-trig', '1.99.0.1'
45+
spec.add_runtime_dependency 'rdf-trix', '1.99.0'
46+
spec.add_runtime_dependency 'rdf-turtle', '1.99.0'
3847

3948
## bel.rb plugin - annotation/namespace search
4049
spec.add_runtime_dependency 'bel-search-sqlite', '0.4.2'

Diff for: app/openbel/api/helpers/translators.rb

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
require 'bel'
2+
3+
module OpenBEL
4+
module Helpers
5+
6+
# Helpers for translator functionality based on user's requested media
7+
# type.
8+
module Translators
9+
10+
# Patch {::Sinatra::Helpers::Stream} to respect the +puts+ and +write+
11+
# method. This is necessary because the RDF.rb writers will call theseon
12+
# the IO object (in this case {::Sinatra::Helpers::Stream}).
13+
class ::Sinatra::Helpers::Stream
14+
15+
def puts(*args)
16+
self << (
17+
args.map { |string| "#{string.encode(Encoding::UTF_8)}\n" }.join
18+
)
19+
end
20+
21+
def write(string)
22+
self << string.encode(Encoding::UTF_8)
23+
end
24+
25+
# flush is a no-op; flushing is handled by sinatra/rack server
26+
def flush; end
27+
end
28+
29+
# Find a bel.rb translator plugin by value. The value is commonly the
30+
# id, file extension, or media type associated with the translator
31+
# plugin.
32+
#
33+
# @param [#to_s] value used to look up translator plugin registered
34+
# with bel.rb
35+
# @return [BEL::Translator] the translator instance; or +nil+ if one
36+
# cannot be found
37+
def self.for(value)
38+
BEL.translator(symbolize_value(value))
39+
end
40+
41+
def self.plugin_for(value)
42+
BEL::Translator::Plugins.for(symbolize_value(value))
43+
end
44+
45+
def self.requested_translator_plugin(request, params)
46+
if params && params[:format]
47+
self.plugin_for(params[:format])
48+
else
49+
request.accept.map { |accept_entry|
50+
self.plugin_for(accept_entry)
51+
}.compact.first
52+
end
53+
end
54+
55+
def self.requested_translator(request, params)
56+
if params && params[:format]
57+
self.for(params[:format])
58+
else
59+
request.accept.map { |accept_entry|
60+
self.for(accept_entry)
61+
}.compact.first
62+
end
63+
end
64+
65+
def self.symbolize_value(value)
66+
value.to_s.to_sym
67+
end
68+
private_class_method :symbolize_value
69+
end
70+
end
71+
end

Diff for: app/openbel/api/routes/base.rb

+15-5
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ class Base < Sinatra::Application
2121
include OpenBEL::Resource::Namespaces
2222
include OpenBEL::Schemas
2323

24-
DEFAULT_CONTENT_TYPE = 'application/hal+json'
25-
SPOKEN_CONTENT_TYPES = %w[application/hal+json application/json]
24+
DEFAULT_CONTENT_TYPE = 'application/hal+json'
25+
DEFAULT_CONTENT_TYPE_ID = :hal
26+
SPOKEN_CONTENT_TYPES = %w[application/hal+json application/json]
2627
SPOKEN_CONTENT_TYPES.concat(
2728
BEL::Translator.plugins.values.flat_map { |p| p.media_types.map(&:to_s) }
2829
)
29-
30-
SCHEMA_BASE_URL = 'http://next.belframework.org/schemas/'
31-
RESOURCE_SERIALIZERS = {
30+
SCHEMA_BASE_URL = 'http://next.belframework.org/schemas/'
31+
RESOURCE_SERIALIZERS = {
3232
:annotation => AnnotationResourceSerializer,
3333
:annotation_collection => AnnotationCollectionSerializer,
3434
:annotation_value => AnnotationValueResourceSerializer,
@@ -80,6 +80,16 @@ def schema_url(name)
8080
SCHEMA_BASE_URL + "#{name}.schema.json"
8181
end
8282

83+
def wants_default?
84+
if params[:format]
85+
return params[:format] == DEFAULT_CONTENT_TYPE
86+
end
87+
88+
request.accept.any? { |accept_entry|
89+
accept_entry.to_s == DEFAULT_CONTENT_TYPE
90+
}
91+
end
92+
8393
def validate_media_type!(content_type, options = {})
8494
ctype = request.content_type
8595
valid = ctype.start_with? content_type

Diff for: app/openbel/api/routes/datasets.rb

+10-21
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require 'openbel/api/evidence/facet_filter'
77
require_relative '../resources/evidence_transform'
88
require_relative '../helpers/pager'
9+
require_relative '../helpers/translators'
910

1011
module OpenBEL
1112
module Routes
@@ -37,9 +38,6 @@ def initialize(app)
3738
:tdb_directory => OpenBEL::Settings[:resource_rdf][:jena][:tdb_directory]
3839
)
3940

40-
# Load RDF monkeypatches.
41-
BEL::Translator.plugins[:rdf].create_translator
42-
4341
# Annotations using RdfRepository
4442
annotations = BEL::Resource::Annotations.new(@rr)
4543
@annotation_transform = AnnotationTransform.new(annotations)
@@ -365,18 +363,12 @@ def keys_to_symbols(obj)
365363
filtered_total = @api.count_evidence(filters)
366364
page_results = @api.find_dataset_evidence(dataset, filters, start, size, faceted, max_values_per_facet)
367365

368-
accept_type = request.accept.find { |accept_entry|
369-
ACCEPTED_TYPES.values.include?(accept_entry.to_s)
370-
}
371-
accept_type ||= DEFAULT_TYPE
366+
translator = Translators.requested_translator(request, params)
367+
translator_plugin = Translators.requested_translator_plugin(request, params)
372368

373-
if params[:format]
374-
translator = BEL::Translator.plugins[params[:format].to_sym]
375-
halt 501 if !translator || translator.id == :rdf
376-
accept_type = [translator.media_types].flatten.first
377-
end
378-
379-
if accept_type == DEFAULT_TYPE
369+
# Serialize to HAL if they [Accept]ed it, specified it as ?format, or
370+
# no translator was found to match request.
371+
if wants_default? || !translator
380372
evidence = page_results[:cursor].map { |item|
381373
item.delete('facets')
382374
item
@@ -410,24 +402,21 @@ def keys_to_symbols(obj)
410402

411403
render_collection(evidence, :evidence, options)
412404
else
413-
out_translator = BEL.translator(accept_type)
414-
extension = ACCEPTED_TYPES.key(accept_type.to_s)
405+
extension = translator_plugin.file_extensions.first
415406

416-
response.headers['Content-Type'] = accept_type
407+
response.headers['Content-Type'] = translator_plugin.media_types.first
417408
status 200
418409
attachment "#{dataset[:identifier].gsub(/[^\w]/, '_')}.#{extension}"
419410
stream :keep_open do |response|
420411
cursor = page_results[:cursor]
421-
json_evidence_enum = cursor.lazy.map { |evidence|
412+
dataset_evidence = cursor.lazy.map { |evidence|
422413
evidence.delete('facets')
423414
evidence.delete('_id')
424415
evidence = keys_to_symbols(evidence)
425416
BEL::Model::Evidence.create(evidence)
426417
}
427418

428-
out_translator.write(json_evidence_enum) do |converted_evidence|
429-
response << converted_evidence
430-
end
419+
translator.write(dataset_evidence, response)
431420
end
432421
end
433422
end

0 commit comments

Comments
 (0)