1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
package revel
import (
"reflect"
)
// Autocalls any defined before and after methods on the target controller
// If either calls returns a value then the result is returned
func BeforeAfterFilter(c *Controller, fc []Filter) {
defer func() {
if resultValue := beforeAfterFilterInvoke(FINALLY, c); resultValue != nil && !resultValue.IsNil() {
c.Result = resultValue.Interface().(Result)
}
}()
defer func() {
if err := recover(); err != nil {
if resultValue := beforeAfterFilterInvoke(PANIC, c); resultValue != nil && !resultValue.IsNil() {
c.Result = resultValue.Interface().(Result)
}
panic(err)
}
}()
if resultValue := beforeAfterFilterInvoke(BEFORE, c); resultValue != nil && !resultValue.IsNil() {
c.Result = resultValue.Interface().(Result)
return
}
fc[0](c, fc[1:])
if resultValue := beforeAfterFilterInvoke(AFTER, c); resultValue != nil && !resultValue.IsNil() {
c.Result = resultValue.Interface().(Result)
}
}
func beforeAfterFilterInvoke(method When, c *Controller) (r *reflect.Value) {
if c.Type == nil {
return
}
var index []*ControllerFieldPath
switch method {
case BEFORE:
index = c.Type.ControllerEvents.Before
case AFTER:
index = c.Type.ControllerEvents.After
case FINALLY:
index = c.Type.ControllerEvents.Finally
case PANIC:
index = c.Type.ControllerEvents.Panic
}
if len(index) == 0 {
return
}
for _, function := range index {
result := function.Invoke(reflect.ValueOf(c.AppController), nil)[0]
if !result.IsNil() {
return &result
}
}
return
}
|