forked from go-aah/aah
-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.go
133 lines (109 loc) · 4.03 KB
/
controller.go
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
// go-aah/aah source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
package aah
import (
"path"
"reflect"
"strings"
"aahframework.org/router.v0"
)
const (
// Interceptor Action Name
incpBeforeActionName = "Before"
incpAfterActionName = "After"
incpPanicActionName = "Panic"
incpFinallyActionName = "Finally"
)
var (
emptyArg = make([]reflect.Value, 0)
)
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// app methods
//______________________________________________________________________________
func (a *app) AddController(c interface{}, methods []*MethodInfo) {
cType := actualType(c)
// Method Info
methodMapping := map[string]*MethodInfo{}
for _, method := range methods {
for _, param := range method.Parameters {
param.Type = param.Type.Elem()
param.kind = kind(param.Type)
}
methodMapping[strings.ToLower(method.Name)] = method
}
// Controller Info
key, namespace := createRegistryKeyAndNamespace(cType)
controllerInfo := &controllerInfo{
Name: cType.Name(),
Type: cType,
Namespace: namespace,
Methods: methodMapping,
EmbeddedIndexes: findEmbeddedContext(cType),
}
// Fully qualified name
controllerInfo.FqName = path.Join(controllerInfo.Namespace, controllerInfo.Name)
// No suffix name which maps to controller name towards directory
// name by convention.
// For e.g.: UserController, User ==> User
noSuffixName := controllerInfo.Name
if strings.HasSuffix(noSuffixName, "Controller") {
noSuffixName = noSuffixName[:len(noSuffixName)-len("Controller")]
}
controllerInfo.NoSuffixName = noSuffixName
a.engine.cregistry.Add(key, controllerInfo)
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// ControllerRegistry
//______________________________________________________________________________
// ControllerRegistry struct holds all application controller and related methods.
type controllerRegistry map[string]*controllerInfo
func (cr controllerRegistry) Add(key string, ci *controllerInfo) {
cr[key] = ci
}
// Lookup method returns `controllerInfo` if given route controller and
// action exists in the controller registory.
func (cr controllerRegistry) Lookup(route *router.Route) *controllerInfo {
if ci, found := cr[strings.ToLower(route.Controller)]; found {
return ci
}
for _, ci := range cr {
// match exact character case
if strings.HasSuffix(route.Controller, ci.Name) {
return ci
}
}
return nil
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// ControllerInfo
//______________________________________________________________________________
// ControllerInfo holds information of single controller information.
type controllerInfo struct {
Name string
FqName string
NoSuffixName string
Type reflect.Type
Namespace string
Methods map[string]*MethodInfo
EmbeddedIndexes [][]int
}
// MethodInfo holds information of single method information in the controller.
type MethodInfo struct {
Name string
Parameters []*ParameterInfo
}
// ParameterInfo holds information of single parameter in the method.
type ParameterInfo struct {
Name string
Type reflect.Type
kind reflect.Kind
}
// Lookup method returns the `aah.MethodInfo` by given name
// (case insensitive) otherwise nil.
func (ci *controllerInfo) Lookup(name string) *MethodInfo {
if method, found := ci.Methods[strings.ToLower(name)]; found {
return method
}
return nil
}