class Safrano::Walker
handle navigation in the Datamodel tree of entities/attributes input is the url path. Url parameters ($filter etc…) are NOT handled here This uses a state transition algorithm
Constants
- EMPTYSTR
- NIL_SERVICE_FATAL
- SLASH
Attributes
context[RW]
contexts[RW]
do_count[RW]
is $count requested?
do_links[R]
are $links requested ?
end_context[RW]
error[RW]
media_value[R]
is $value (of media entity) requested?
path_done[RW]
path_remain[RW]
path_start[R]
raw_value[R]
is $value (of attribute) requested?
request[R]
status[RW]
Public Class Methods
new(service, path, request, content_id_refs = nil)
click to toggle source
# File lib/odata/walker.rb, line 39 def initialize(service, path, request, content_id_refs = nil) raise NIL_SERVICE_FATAL unless service path = URI.decode_www_form_component(path) @context = service @content_id_refs = content_id_refs # needed because for function import we need access to the url parameters (req.params) # who contains the functions params @request = request @contexts = [@context] @path_start = @path_remain = if service unprefixed(service.xpath_prefix, path) else # This is for batch function path end @path_done = String.new @status = :start @end_context = nil @do_count = nil eo end
Public Instance Methods
do_next_transition()
click to toggle source
# File lib/odata/walker.rb, line 146 def do_next_transition @context, @status, @error = @tr_next.do_transition(@context) # little hack's case @status # we dont have the content-id references data on service level # but we have it here, so in case of a $content-id transition # the returned context is just the id, and we get the final result # entity reference here and place it in @context when :run_with_content_id do_run_with_content_id when :run_with_execute_func do_run_with_execute_func end @contexts << @context @path_remain = @tr_next.path_remain @path_done << @tr_next.path_done # little hack's state_mappings end
do_run_with_content_id()
click to toggle source
perform a content-id ($batch changeset ref) transition
# File lib/odata/walker.rb, line 100 def do_run_with_content_id if @content_id_refs.is_a? Hash if (@context = @content_id_refs[@context.to_s]) @status = :run else @context = nil @status = :error # TODO: more appropriate error handling @error = Safrano::ErrorNotFound end else @context = nil @status = :error # TODO: more appropriate error handling @error = Safrano::ErrorNotFound end end
do_run_with_execute_func()
click to toggle source
execute function import with request parameters input: @context containt the function to exectute,
@request.params should normally contain the params
result: validate the params for the given function, execute the function and
return it's result back into @context, and finaly set status :end (or error if anyting went wrong )
# File lib/odata/walker.rb, line 124 def do_run_with_execute_func @context, @status, @error = @context.do_execute_func(@request) end
eo()
click to toggle source
# File lib/odata/walker.rb, line 168 def eo while @context get_next_transition if @tr_next do_next_transition else @context = nil @status = :error @error = Safrano::ErrorNotFoundSegment.new(@path_remain) end end # TODO: shouldnt we raise an error here if @status != :end ? return false unless @status == :end @end_context = @contexts.size >= 2 ? @contexts[-2] : @contexts[1] end
finalize()
click to toggle source
# File lib/odata/walker.rb, line 185 def finalize (@status == :end) ? Contract.valid(@end_context) : @error end
get_next_transition()
click to toggle source
# File lib/odata/walker.rb, line 74 def get_next_transition # this does not work if there are multiple valid transitions # like when we have attributes that are substring of each other # --> instead of using detect (ie take first transition) # we need to use select and then find the longest match # tr_next = @context.allowed_transitions.detect do |t| # t.do_match(@path_remain) # end valid_tr = @context.allowed_transitions.select do |t| t.do_match(@path_remain) end # this is a very fragile and obscure but required hack (wanted: a # better one) to make attributes that are substrings of each other # work well @tr_next = if valid_tr if valid_tr.size == 1 valid_tr.first elsif valid_tr.size > 1 valid_tr.max_by { |t| t.match_result[1].size } end end end
state_mappings()
click to toggle source
little hacks… depending on returned state, set some attributes
# File lib/odata/walker.rb, line 129 def state_mappings case @status when :end_with_count @do_count = true @status = :end when :end_with_value @raw_value = true @status = :end when :end_with_media_value @media_value = true @status = :end when :run_with_links @do_links = true @status = :run end end
unprefixed(prefix, path)
click to toggle source
# File lib/odata/walker.rb, line 64 def unprefixed(prefix, path) if (prefix == EMPTYSTR) || (prefix == SLASH) path else # path.sub!(/\A#{prefix}/, '') # TODO check path.sub(/\A#{prefix}/, EMPTYSTR) end end