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