Commit d5ddd0a9 authored by astaxie's avatar astaxie

support user define function

+//Add("/user",&UserController{})
+//Add("/api/list",&RestController{},"*:ListFood")
+//Add("/api/create",&RestController{},"post:CreateFood")
+//Add("/api/update",&RestController{},"put:UpdateFood")
+//Add("/api/delete",&RestController{},"delete:DeleteFood")
+//Add("/api",&RestController{},"get,post:ApiFunc")
+//Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
parent dff36a18
...@@ -13,11 +13,14 @@ import ( ...@@ -13,11 +13,14 @@ import (
"strings" "strings"
) )
var HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head"}
type controllerInfo struct { type controllerInfo struct {
pattern string pattern string
regex *regexp.Regexp regex *regexp.Regexp
params map[int]string params map[int]string
controllerType reflect.Type controllerType reflect.Type
methods map[string]string
} }
type userHandler struct { type userHandler struct {
...@@ -38,7 +41,16 @@ func NewControllerRegistor() *ControllerRegistor { ...@@ -38,7 +41,16 @@ func NewControllerRegistor() *ControllerRegistor {
return &ControllerRegistor{routers: make([]*controllerInfo, 0), userHandlers: make(map[string]*userHandler)} return &ControllerRegistor{routers: make([]*controllerInfo, 0), userHandlers: make(map[string]*userHandler)}
} }
func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { //methods support like this:
//default methods is the same name as method
//Add("/user",&UserController{})
//Add("/api/list",&RestController{},"*:ListFood")
//Add("/api/create",&RestController{},"post:CreateFood")
//Add("/api/update",&RestController{},"put:UpdateFood")
//Add("/api/delete",&RestController{},"delete:DeleteFood")
//Add("/api",&RestController{},"get,post:ApiFunc")
//Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingMethods ...string) {
parts := strings.Split(pattern, "/") parts := strings.Split(pattern, "/")
j := 0 j := 0
...@@ -82,13 +94,35 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { ...@@ -82,13 +94,35 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) {
} }
} }
} }
t := reflect.Indirect(reflect.ValueOf(c)).Type()
methods := make(map[string]string)
if len(mappingMethods) > 0 {
semi := strings.Split(mappingMethods[0], ";")
for _, v := range semi {
colon := strings.Split(v, ":")
if len(colon) != 2 {
panic("method mapping fomate is error")
}
comma := strings.Split(colon[0], ",")
for _, m := range comma {
if m == "*" || inSlice(strings.ToLower(m), HTTPMETHOD) {
if _, ok := t.MethodByName(colon[1]); ok {
methods[strings.ToLower(m)] = colon[1]
} else {
panic(colon[1] + " method don't exist in the controller " + t.Name())
}
} else {
panic(v + " is an error method mapping,Don't exist method named " + m)
}
}
}
}
if j == 0 { if j == 0 {
//now create the Route //now create the Route
t := reflect.Indirect(reflect.ValueOf(c)).Type()
route := &controllerInfo{} route := &controllerInfo{}
route.pattern = pattern route.pattern = pattern
route.controllerType = t route.controllerType = t
route.methods = methods
p.fixrouters = append(p.fixrouters, route) p.fixrouters = append(p.fixrouters, route)
} else { // add regexp routers } else { // add regexp routers
//recreate the url pattern, with parameters replaced //recreate the url pattern, with parameters replaced
...@@ -102,11 +136,12 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) { ...@@ -102,11 +136,12 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface) {
} }
//now create the Route //now create the Route
t := reflect.Indirect(reflect.ValueOf(c)).Type()
route := &controllerInfo{} route := &controllerInfo{}
route.regex = regex route.regex = regex
route.params = params route.params = params
route.pattern = pattern route.pattern = pattern
route.methods = methods
route.controllerType = t route.controllerType = t
p.routers = append(p.routers, route) p.routers = append(p.routers, route)
} }
...@@ -397,25 +432,53 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -397,25 +432,53 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
//if response has written,yes don't run next //if response has written,yes don't run next
if !w.started { if !w.started {
if r.Method == "GET" { if r.Method == "GET" {
if m, ok := runrouter.methods["get"]; ok {
method = vc.MethodByName(m)
} else {
method = vc.MethodByName("Get") method = vc.MethodByName("Get")
}
method.Call(in) method.Call(in)
} else if r.Method == "HEAD" { } else if r.Method == "HEAD" {
if m, ok := runrouter.methods["head"]; ok {
method = vc.MethodByName(m)
} else {
method = vc.MethodByName("Head") method = vc.MethodByName("Head")
}
method.Call(in) method.Call(in)
} else if r.Method == "DELETE" || (r.Method == "POST" && r.Form.Get("_method") == "delete") { } else if r.Method == "DELETE" || (r.Method == "POST" && r.Form.Get("_method") == "delete") {
if m, ok := runrouter.methods["delete"]; ok {
method = vc.MethodByName(m)
} else {
method = vc.MethodByName("Delete") method = vc.MethodByName("Delete")
}
method.Call(in) method.Call(in)
} else if r.Method == "PUT" || (r.Method == "POST" && r.Form.Get("_method") == "put") { } else if r.Method == "PUT" || (r.Method == "POST" && r.Form.Get("_method") == "put") {
if m, ok := runrouter.methods["put"]; ok {
method = vc.MethodByName(m)
} else {
method = vc.MethodByName("Put") method = vc.MethodByName("Put")
}
method.Call(in) method.Call(in)
} else if r.Method == "POST" { } else if r.Method == "POST" {
if m, ok := runrouter.methods["post"]; ok {
method = vc.MethodByName(m)
} else {
method = vc.MethodByName("Post") method = vc.MethodByName("Post")
}
method.Call(in) method.Call(in)
} else if r.Method == "PATCH" { } else if r.Method == "PATCH" {
if m, ok := runrouter.methods["patch"]; ok {
method = vc.MethodByName(m)
} else {
method = vc.MethodByName("Patch") method = vc.MethodByName("Patch")
}
method.Call(in) method.Call(in)
} else if r.Method == "OPTIONS" { } else if r.Method == "OPTIONS" {
if m, ok := runrouter.methods["options"]; ok {
method = vc.MethodByName(m)
} else {
method = vc.MethodByName("Options") method = vc.MethodByName("Options")
}
method.Call(in) method.Call(in)
} }
gotofunc := vc.Elem().FieldByName("gotofunc").String() gotofunc := vc.Elem().FieldByName("gotofunc").String()
...@@ -432,12 +495,10 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -432,12 +495,10 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
method = vc.MethodByName("Render") method = vc.MethodByName("Render")
method.Call(in) method.Call(in)
} }
if !w.started {
method = vc.MethodByName("Finish") method = vc.MethodByName("Finish")
method.Call(in) method.Call(in)
} }
} }
}
method = vc.MethodByName("Destructor") method = vc.MethodByName("Destructor")
method.Call(in) method.Call(in)
} }
......
...@@ -170,3 +170,12 @@ func Htmlunquote(src string) string { ...@@ -170,3 +170,12 @@ func Htmlunquote(src string) string {
return strings.TrimSpace(text) return strings.TrimSpace(text)
} }
func inSlice(v string, sl []string) bool {
for _, vv := range sl {
if vv == v {
return true
}
}
return false
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment