Skip to content

Commit

Permalink
Invoke interceptors on multi-embedded Controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
robfig committed Apr 1, 2013
1 parent 8bca892 commit 8f6461b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
16 changes: 12 additions & 4 deletions intercept.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,10 @@ func getInterceptors(when InterceptTime, val reflect.Value) []*Interception {
// If the target couldn't be found, the returned Value will have IsValid() == false
func findTarget(val reflect.Value, target reflect.Type) reflect.Value {
// Look through the embedded types (until we reach the *revel.Controller at the top).
for {
valueQueue := []reflect.Value{val}
for len(valueQueue) > 0 {
val, valueQueue = valueQueue[0], valueQueue[1:]

// Check if val is of a similar type to the target type.
if val.Type() == target {
return val
Expand All @@ -193,14 +196,19 @@ func findTarget(val reflect.Value, target reflect.Type) reflect.Value {
// If we reached the *revel.Controller and still didn't find what we were
// looking for, give up.
if val.Type() == controllerPtrType {
break
continue
}

// Else, drill into the first field (which had better be an embedded type).
// Else, add each anonymous field to the queue.
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
val = val.Field(0)

for i := 0; i < val.NumField(); i++ {
if val.Type().Field(i).Anonymous {
valueQueue = append(valueQueue, val.Field(i))
}
}
}

return reflect.Value{}
Expand Down
10 changes: 9 additions & 1 deletion intercept_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ var funcP2 = func(c *Controller) Result { return nil }
type InterceptController struct{ *Controller }
type InterceptControllerN struct{ InterceptController }
type InterceptControllerP struct{ *InterceptController }
type InterceptControllerNP struct {
*Controller
InterceptControllerN
InterceptControllerP
}

func (c InterceptController) methN() Result { return nil }
func (c *InterceptController) methP() Result { return nil }
Expand All @@ -28,7 +33,7 @@ var METHODS_N = []interface{}{
(*InterceptControllerN).methNP,
}

// Methods accessible from InterceptControllerN
// Methods accessible from InterceptControllerP
var METHODS_P = []interface{}{
InterceptController.methN,
(*InterceptController).methP,
Expand All @@ -41,8 +46,11 @@ var METHODS_P = []interface{}{
func TestInvokeArgType(t *testing.T) {
n := InterceptControllerN{InterceptController{&Controller{}}}
p := InterceptControllerP{&InterceptController{&Controller{}}}
np := InterceptControllerNP{&Controller{}, n, p}
testInterceptorController(t, reflect.ValueOf(&n), METHODS_N)
testInterceptorController(t, reflect.ValueOf(&p), METHODS_P)
testInterceptorController(t, reflect.ValueOf(&np), METHODS_N)
testInterceptorController(t, reflect.ValueOf(&np), METHODS_P)
}

func testInterceptorController(t *testing.T, appControllerPtr reflect.Value, methods []interface{}) {
Expand Down

0 comments on commit 8f6461b

Please sign in to comment.