Class: Jetra::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/jetra/base.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.errorsObject

Returns the value of attribute errors.



195
196
197
# File 'lib/jetra/base.rb', line 195

def errors
  @errors
end

.filtersObject

Returns the value of attribute filters.



195
196
197
# File 'lib/jetra/base.rb', line 195

def filters
  @filters
end

.routesObject

Returns the value of attribute routes.



195
196
197
# File 'lib/jetra/base.rb', line 195

def routes
  @routes
end

Instance Attribute Details

#paramsObject

Returns the value of attribute params.



35
36
37
# File 'lib/jetra/base.rb', line 35

def params
  @params
end

#requestObject

Returns the value of attribute request.



35
36
37
# File 'lib/jetra/base.rb', line 35

def request
  @request
end

#responseObject

Returns the value of attribute response.



35
36
37
# File 'lib/jetra/base.rb', line 35

def response
  @response
end

Class Method Details

.add_filter(type, &block) ⇒ Object



213
214
215
# File 'lib/jetra/base.rb', line 213

def add_filter(type, &block)
  @filters[type] << compile!(&block)
end

.after(&block) ⇒ Object



209
210
211
# File 'lib/jetra/base.rb', line 209

def after(&block)
  add_filter(:after, &block)
end

.before(&block) ⇒ Object



205
206
207
# File 'lib/jetra/base.rb', line 205

def before(&block)
  add_filter(:before, &block)
end

.call(route, params = {}) ⇒ Object



201
202
203
# File 'lib/jetra/base.rb', line 201

def call(route, params={})
  prototype.call(route, params)
end

.compile!(&block) ⇒ Object



236
237
238
239
240
241
242
243
# File 'lib/jetra/base.rb', line 236

def compile!(&block)

  unboundMethod = generateUnboundMethod(&block)

  block.arity != 0 ?
    proc { |a,p| unboundMethod.bind(a).call(*p) } :
    proc { |a,p| unboundMethod.bind(a).call }
end

.copy_errorsObject



274
275
276
277
278
279
280
281
282
283
284
# File 'lib/jetra/base.rb', line 274

def copy_errors
  newErrors = {}
  @errors.each do |key, values|
    newValues = []
    values.each do |value|
      newValues << value
    end
    newErrors[key] = newValues
  end
  newErrors
end

.copy_filtersObject



262
263
264
265
266
267
268
269
270
271
272
# File 'lib/jetra/base.rb', line 262

def copy_filters
  newFilters = {}
  @filters.each do |key, values|
    newValues = []
    values.each do |value|
      newValues << value
    end
    newFilters[key] = newValues
  end
  newFilters
end

.copy_routesObject



254
255
256
257
258
259
260
# File 'lib/jetra/base.rb', line 254

def copy_routes
  newRoutes = {}
  @routes.each do |key, value|
    newRoutes[key] = value
  end
  newRoutes
end

.error(*codes, &block) ⇒ Object



222
223
224
225
226
# File 'lib/jetra/base.rb', line 222

def error(*codes, &block)
  codes = codes.map { |c| Array(c) }.flatten
  codes << Exception if codes.empty?
  codes.each { |c| (@errors[c] ||= []) << compile!(&block) }
end

.generateUnboundMethod(&block) ⇒ Object



228
229
230
231
232
233
234
# File 'lib/jetra/base.rb', line 228

def generateUnboundMethod(&block)
  methodName = :id  #any symbol is ok.
  define_method(methodName, &block)
  method = instance_method methodName
  remove_method methodName
  method
end

.inherited(subclass) ⇒ Object



245
246
247
248
249
250
251
252
# File 'lib/jetra/base.rb', line 245

def inherited(subclass)

  subclass.routes = copy_routes
  subclass.filters = copy_filters
  subclass.errors = copy_errors

  super
end

.prototypeObject



197
198
199
# File 'lib/jetra/base.rb', line 197

def prototype
  @prototype ||= new
end

.route(symbol, &block) ⇒ Object



217
218
219
220
# File 'lib/jetra/base.rb', line 217

def route(symbol, &block)
  block ||= Proc.new { method(symbol).call }
  @routes[symbol] = compile!(&block)
end

.to_appObject



286
287
288
289
290
291
292
293
294
295
296
# File 'lib/jetra/base.rb', line 286

def to_app

  newApp = Jetra::Application.new(self)
  @routes.each_key do |route|
    eval("newApp.define_singleton_method(route) do |params={}| ; @app.call(route, params) ; end ")
  end

  eval("newApp.define_singleton_method(:method_missing) do |methodName, params={}| ; @app.call(methodName, params) ; end ")

  newApp
end

Instance Method Details

#call(route, params) ⇒ Object



37
38
39
# File 'lib/jetra/base.rb', line 37

def call(route, params)
  dup.call!(route, params)
end

#call!(route, params) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/jetra/base.rb', line 41

def call!(route, params)

  @request  = Request.new(route, params)
  @response = Response.new

  @params   = indifferent_params(@request.params)

  invoke { dispatch! }

  @response.finish
end

#current_classObject



53
54
55
# File 'lib/jetra/base.rb', line 53

def current_class
  self.class
end

#dispatch!Object



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/jetra/base.rb', line 95

def dispatch!
  filter! :before
  route!
rescue ::Exception => boom
  gotError = true
  handle_exception!(boom)
ensure
  begin
    filter! :after
  rescue ::Exception => boom
    handle_exception!(boom) unless gotError
  end
end

#error_block!(errorClass, *blockParams) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/jetra/base.rb', line 140

def error_block!(errorClass, *blockParams)

  if errorBlocks = current_class.errors[errorClass]
    errorBlocks.reverse_each do |errorBlock|
      args = [errorBlock]
      args += [blockParams]
      resp = processRoute(*args)
    end
  end

  if errorClass.respond_to? :superclass and errorClass.superclass <= Exception
    error_block!(errorClass.superclass, *blockParams)
  end
end

#failure_response(body, status = -1)) ⇒ Object



175
176
177
178
179
180
181
# File 'lib/jetra/base.rb', line 175

def failure_response(body, status=-1)

  raise "status code must <= -1 when failure" if status > -1

  response.body = body
  response.status = status
end

#filter!(type) ⇒ Object



123
124
125
126
127
# File 'lib/jetra/base.rb', line 123

def filter!(type)
  current_class.filters[type].each do |args|
    processRoute(*args)
  end
end

#halt(*response) ⇒ Object



118
119
120
121
# File 'lib/jetra/base.rb', line 118

def halt(*response)
  response = response.first if response.length == 1
  throw Halt, response
end

#halt_failure(body, status = -1)) ⇒ Object



188
189
190
191
# File 'lib/jetra/base.rb', line 188

def halt_failure(body, status=-1)
  failure_response(body, status)
  halt
end

#halt_success(body, status = 0) ⇒ Object



183
184
185
186
# File 'lib/jetra/base.rb', line 183

def halt_success(body, status=0)
  success_response(body, status)
  halt
end

#handle_exception!(boom) ⇒ Object



109
110
111
112
113
114
115
116
# File 'lib/jetra/base.rb', line 109

def handle_exception!(boom)

  response.status = -1

  error_block!(boom.class, boom)

  raise boom
end

#indifferent_hashObject



70
71
72
# File 'lib/jetra/base.rb', line 70

def indifferent_hash
  Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end

#indifferent_params(object) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/jetra/base.rb', line 57

def indifferent_params(object)
  case object
  when Hash
    newHash = indifferent_hash
    object.each { |key, value| newHash[key] = indifferent_params(value) }
    newHash
  when Array
    object.map { |item| indifferent_params(item) }
  else
    object
  end
end

#invokeObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/jetra/base.rb', line 74

def invoke
  res = catch(Halt) { yield }

  if Array === res
    res = res.dup
    
    if status = res.shift
      response.status = status
    end

    if body = res.shift
      response.body = body
    end
  else
    if res
      response.body = res
    end
  end
  nil
end

#processRoute(block = nil, values = []) ⇒ Object



159
160
161
# File 'lib/jetra/base.rb', line 159

def processRoute(block=nil,values=[])
  block ? block[self,values] : yield(self,values)
end

#route!Object



129
130
131
132
133
134
135
136
137
138
# File 'lib/jetra/base.rb', line 129

def route!

  if block = current_class.routes[@request.route.to_sym]
    processRoute do |*args|
      routeEval { block[*args] }
    end
  end

  route_missing
end

#route_missingObject

Raises:



163
164
165
# File 'lib/jetra/base.rb', line 163

def route_missing
  raise NotFoundException.new("route not found")
end

#routeEvalObject



155
156
157
# File 'lib/jetra/base.rb', line 155

def routeEval
  throw Halt, yield
end

#success_response(body, status = 0) ⇒ Object



167
168
169
170
171
172
173
# File 'lib/jetra/base.rb', line 167

def success_response(body, status=0)

  raise "status code must >= 0 when success" if status < 0

  response.body = body
  response.status = status
end