Class: Jetra::Base

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

Constant Summary collapse

Settings =
{}

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.



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

def errors
  @errors
end

.filtersObject

Returns the value of attribute filters.



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

def filters
  @filters
end

.routesObject

Returns the value of attribute routes.



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

def routes
  @routes
end

Instance Attribute Details

#paramsObject

Returns the value of attribute params.



41
42
43
# File 'lib/jetra/base.rb', line 41

def params
  @params
end

#requestObject

Returns the value of attribute request.



41
42
43
# File 'lib/jetra/base.rb', line 41

def request
  @request
end

#responseObject

Returns the value of attribute response.



41
42
43
# File 'lib/jetra/base.rb', line 41

def response
  @response
end

Class Method Details

.add_filter(type, &block) ⇒ Object



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

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

.after(&block) ⇒ Object



199
200
201
# File 'lib/jetra/base.rb', line 199

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

.before(&block) ⇒ Object



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

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

.call(route = nil, params = nil, headers = nil, body = nil) ⇒ Object



191
192
193
# File 'lib/jetra/base.rb', line 191

def call(route=nil, params=nil, headers=nil, body=nil)
  prototype.call(route, params, headers, body)
end

.compile!(&block) ⇒ Object



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

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



265
266
267
268
269
270
271
272
273
274
275
# File 'lib/jetra/base.rb', line 265

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



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

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



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

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

.error(*codes, &block) ⇒ Object



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

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



219
220
221
222
223
224
225
# File 'lib/jetra/base.rb', line 219

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



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

def inherited(subclass)

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

  super
end

.prototypeObject



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

def prototype
  @prototype ||= new
end

.route(string, &block) ⇒ Object



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

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

.to_appObject



277
278
279
280
281
282
283
284
285
286
287
# File 'lib/jetra/base.rb', line 277

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 = nil, params = nil, headers = nil, body = nil) ⇒ Object



43
44
45
46
# File 'lib/jetra/base.rb', line 43

def call(route=nil, params=nil, headers=nil, body=nil)
  request = Request.new(route, params, headers, body)
  dup.call!(request)
end

#call!(request) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/jetra/base.rb', line 48

def call!(request)

  @request = request
  @response = Response.new

  @params   = request.params

  invoke { dispatch! }

  @response.finish
end

#current_classObject



60
61
62
# File 'lib/jetra/base.rb', line 60

def current_class
  self.class
end

#dispatch!Object



85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/jetra/base.rb', line 85

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



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/jetra/base.rb', line 130

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



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

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



113
114
115
116
117
# File 'lib/jetra/base.rb', line 113

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

#halt(*response) ⇒ Object



108
109
110
111
# File 'lib/jetra/base.rb', line 108

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

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



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

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

#halt_success(body, status = 0) ⇒ Object



173
174
175
176
# File 'lib/jetra/base.rb', line 173

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

#handle_exception!(boom) ⇒ Object



99
100
101
102
103
104
105
106
# File 'lib/jetra/base.rb', line 99

def handle_exception!(boom)

  response.status = -1

  error_block!(boom.class, boom)

  raise boom
end

#invokeObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/jetra/base.rb', line 64

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



149
150
151
# File 'lib/jetra/base.rb', line 149

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

#route!Object



119
120
121
122
123
124
125
126
127
128
# File 'lib/jetra/base.rb', line 119

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:



153
154
155
# File 'lib/jetra/base.rb', line 153

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

#routeEvalObject



145
146
147
# File 'lib/jetra/base.rb', line 145

def routeEval
  throw Halt, yield
end

#success_response(body, status = 0) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/jetra/base.rb', line 157

def success_response(body, status=0)

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

  response.body = body
  response.status = status
end