Class: Safrano::Walker

Inherits:
Object
  • Object
show all
Defined in:
lib/odata/walker.rb

Overview

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

Constant Summary collapse

NIL_SERVICE_FATAL =
'Walker is called with a nil service'
EMPTYSTR =
''
SLASH =
'/'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service, path, request, content_id_refs = nil) ⇒ Walker

Returns a new instance of Walker.

Raises:



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 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

Instance Attribute Details

#contextObject

Returns the value of attribute context.



13
14
15
# File 'lib/odata/walker.rb', line 13

def context
  @context
end

#contextsObject

Returns the value of attribute contexts.



12
13
14
# File 'lib/odata/walker.rb', line 12

def contexts
  @contexts
end

#do_countObject

is $count requested?



22
23
24
# File 'lib/odata/walker.rb', line 22

def do_count
  @do_count
end

are $links requested ?



31
32
33
# File 'lib/odata/walker.rb', line 31

def do_links
  @do_links
end

#end_contextObject

Returns the value of attribute end_context.



14
15
16
# File 'lib/odata/walker.rb', line 14

def end_context
  @end_context
end

#errorObject

Returns the value of attribute error.



19
20
21
# File 'lib/odata/walker.rb', line 19

def error
  @error
end

#media_valueObject (readonly)

is $value (of media entity) requested?



28
29
30
# File 'lib/odata/walker.rb', line 28

def media_value
  @media_value
end

#path_doneObject

Returns the value of attribute path_done.



17
18
19
# File 'lib/odata/walker.rb', line 17

def path_done
  @path_done
end

#path_remainObject

Returns the value of attribute path_remain.



16
17
18
# File 'lib/odata/walker.rb', line 16

def path_remain
  @path_remain
end

#path_startObject (readonly)

Returns the value of attribute path_start.



15
16
17
# File 'lib/odata/walker.rb', line 15

def path_start
  @path_start
end

#raw_valueObject (readonly)

is $value (of attribute) requested?



25
26
27
# File 'lib/odata/walker.rb', line 25

def raw_value
  @raw_value
end

#requestObject (readonly)

Returns the value of attribute request.



33
34
35
# File 'lib/odata/walker.rb', line 33

def request
  @request
end

#statusObject

Returns the value of attribute status.



18
19
20
# File 'lib/odata/walker.rb', line 18

def status
  @status
end

Instance Method Details

#do_next_transitionObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/odata/walker.rb', line 119

def do_next_transition
  @context, @status, @error = @tres_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 = @tres_next.path_remain
  @path_done << @tres_next.path_done

  # little hack's
  state_mappings
end

#do_run_with_content_idObject

perform a content-id ($batch changeset ref) transition



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/odata/walker.rb', line 73

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_funcObject

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 )


97
98
99
# File 'lib/odata/walker.rb', line 97

def do_run_with_execute_func
  @context, @status, @error = @context.do_execute_func(@request)
end

#eoObject



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/odata/walker.rb', line 141

def eo
  while @context
    @tres_next = @context.get_next_transresult(@path_remain)
    if @tres_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

#finalizeObject



158
159
160
# File 'lib/odata/walker.rb', line 158

def finalize
  @status == :end ? Contract.valid(@end_context) : @error
end

#state_mappingsObject

little hacks… depending on returned state, set some attributes



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/odata/walker.rb', line 102

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) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/odata/walker.rb', line 64

def unprefixed(prefix, path)
  if (prefix == EMPTYSTR) || (prefix == SLASH)
    path
  else
    path.sub(/\A#{prefix}/, EMPTYSTR)
  end
end