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.



203
204
205
# File 'lib/jetra/base.rb', line 203

def errors
  @errors
end

.filtersObject

Returns the value of attribute filters.



203
204
205
# File 'lib/jetra/base.rb', line 203

def filters
  @filters
end

.routesObject

Returns the value of attribute routes.



203
204
205
# File 'lib/jetra/base.rb', line 203

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

.addFilter(type, &block) ⇒ Object



221
222
223
# File 'lib/jetra/base.rb', line 221

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

.after(&block) ⇒ Object



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

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

.before(&block) ⇒ Object



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

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

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



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

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

.compile!(&block) ⇒ Object



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

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

.copyErrorsObject



282
283
284
285
286
287
288
289
290
291
292
# File 'lib/jetra/base.rb', line 282

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

.copyFiltersObject



270
271
272
273
274
275
276
277
278
279
280
# File 'lib/jetra/base.rb', line 270

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

.copyRoutesObject



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

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

.error(*codes, &block) ⇒ Object



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

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



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

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



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

def inherited(subclass)

  subclass.routes = copyRoutes
  subclass.filters = copyFilters
  subclass.errors = copyErrors

  super
end

.prototypeObject



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

def prototype
  @prototype ||= new
end

.route(symbol, &block) ⇒ Object



225
226
227
228
# File 'lib/jetra/base.rb', line 225

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

.to_appObject



294
295
296
297
298
299
300
301
302
303
304
# File 'lib/jetra/base.rb', line 294

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   = indifferentParams(@request.params)

  invoke { dispatch! }

  @response.finish
end

#currentClassObject



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

def currentClass
  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
  handleException!(boom)
ensure
  begin
    filter! :after
  rescue ::Exception => boom
    handleException!(boom) unless gotError
  end
end

#errorBlock!(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 errorBlock!(errorClass, *blockParams)

  if errorBlocks = currentClass.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
    errorBlock!(errorClass.superclass, *blockParams)
  end
end

#failureResponse(body, args = {status: -1}) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/jetra/base.rb', line 180

def failureResponse(body, args = {status: -1})
  status = args[:status]
  raise "status code must <= -1 when using failure" if status > -1

  if body.class == String
    body = {msg: body}
  end

  response.body = body
  response.status = status
  nil
end

#filter!(type) ⇒ Object



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

def filter!(type)
  currentClass.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

#haltFailure(body, args = {status: -1}) ⇒ Object



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

def haltFailure(body, args ={status: -1})
  halt failureResponse(body, args)
end

#haltSuccess(body, args = {status: 1}) ⇒ Object



193
194
195
# File 'lib/jetra/base.rb', line 193

def haltSuccess(body, args = {status: 1})
  halt successResponse(body, args)
end

#handleException!(boom) ⇒ Object



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

def handleException!(boom)

  response.status = 0

  errorBlock!(boom.class, boom)

  raise boom
end

#indifferentHashObject



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

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

#indifferentParams(object) ⇒ Object



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

def indifferentParams(object)
  case object
  when Hash
    newHash = indifferentHash
    object.each { |key, value| newHash[key] = indifferentParams(value) }
    newHash
  when Array
    object.map { |item| indifferentParams(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 = currentClass.routes[@request.route.to_sym]
    processRoute do |*args|
      routeEval { block[*args] }
    end
  end

  routeMissing
end

#routeEvalObject



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

def routeEval
  throw Halt, yield
end

#routeMissingObject

Raises:



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

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

#successResponse(body, args = {status: 1}) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/jetra/base.rb', line 167

def successResponse(body, args = {status: 1})
  status = args[:status]
  raise "status code must >= 1 when using success" if status < 1

  if body.class == String
    body = {msg: body}
  end

  response.body = body
  response.status = status
  nil
end