beego:namespace support nest
ns := NewNamespace("/v3",
NSAutoRouter(&TestController{}),
NSNamespace("/shop",
NSGet("/order/:id", func(ctx *context.Context) {
ctx.Output.Body([]byte(ctx.Input.Param(":id")))
}),
),
)
Showing
3 changed files
with
207 additions
and
9 deletions
| ... | @@ -14,6 +14,8 @@ import ( | ... | @@ -14,6 +14,8 @@ import ( |
| 14 | 14 | ||
| 15 | type namespaceCond func(*beecontext.Context) bool | 15 | type namespaceCond func(*beecontext.Context) bool |
| 16 | 16 | ||
| 17 | type innnerNamespace func(*Namespace) | ||
| 18 | |||
| 17 | // Namespace is store all the info | 19 | // Namespace is store all the info |
| 18 | type Namespace struct { | 20 | type Namespace struct { |
| 19 | prefix string | 21 | prefix string |
| ... | @@ -21,12 +23,15 @@ type Namespace struct { | ... | @@ -21,12 +23,15 @@ type Namespace struct { |
| 21 | } | 23 | } |
| 22 | 24 | ||
| 23 | // get new Namespace | 25 | // get new Namespace |
| 24 | func NewNamespace(prefix string) *Namespace { | 26 | func NewNamespace(prefix string, params ...innnerNamespace) *Namespace { |
| 25 | cr := NewControllerRegistor() | 27 | ns := &Namespace{ |
| 26 | return &Namespace{ | ||
| 27 | prefix: prefix, | 28 | prefix: prefix, |
| 28 | handlers: cr, | 29 | handlers: NewControllerRegistor(), |
| 30 | } | ||
| 31 | for _, p := range params { | ||
| 32 | p(ns) | ||
| 29 | } | 33 | } |
| 34 | return ns | ||
| 30 | } | 35 | } |
| 31 | 36 | ||
| 32 | // set condtion function | 37 | // set condtion function |
| ... | @@ -68,14 +73,16 @@ func (n *Namespace) Cond(cond namespaceCond) *Namespace { | ... | @@ -68,14 +73,16 @@ func (n *Namespace) Cond(cond namespaceCond) *Namespace { |
| 68 | // ctx.Redirect(302, "/login") | 73 | // ctx.Redirect(302, "/login") |
| 69 | // } | 74 | // } |
| 70 | // }) | 75 | // }) |
| 71 | func (n *Namespace) Filter(action string, filter FilterFunc) *Namespace { | 76 | func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace { |
| 72 | var a int | 77 | var a int |
| 73 | if action == "before" { | 78 | if action == "before" { |
| 74 | a = BeforeRouter | 79 | a = BeforeRouter |
| 75 | } else if action == "after" { | 80 | } else if action == "after" { |
| 76 | a = FinishRouter | 81 | a = FinishRouter |
| 77 | } | 82 | } |
| 78 | n.handlers.InsertFilter("*", a, filter) | 83 | for _, f := range filter { |
| 84 | n.handlers.InsertFilter("*", a, f) | ||
| 85 | } | ||
| 79 | return n | 86 | return n |
| 80 | } | 87 | } |
| 81 | 88 | ||
| ... | @@ -163,6 +170,13 @@ func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace { | ... | @@ -163,6 +170,13 @@ func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace { |
| 163 | return n | 170 | return n |
| 164 | } | 171 | } |
| 165 | 172 | ||
| 173 | // add include class | ||
| 174 | // refer: https://godoc.org/github.com/astaxie/beego#Include | ||
| 175 | func (n *Namespace) Include(cList ...ControllerInterface) *Namespace { | ||
| 176 | n.handlers.Include(cList...) | ||
| 177 | return n | ||
| 178 | } | ||
| 179 | |||
| 166 | // nest Namespace | 180 | // nest Namespace |
| 167 | // usage: | 181 | // usage: |
| 168 | //ns := beego.NewNamespace(“/v1”). | 182 | //ns := beego.NewNamespace(“/v1”). |
| ... | @@ -230,3 +244,116 @@ func AddNamespace(nl ...*Namespace) { | ... | @@ -230,3 +244,116 @@ func AddNamespace(nl ...*Namespace) { |
| 230 | } | 244 | } |
| 231 | } | 245 | } |
| 232 | } | 246 | } |
| 247 | |||
| 248 | // Namespace Condition | ||
| 249 | func NSCond(cond namespaceCond) innnerNamespace { | ||
| 250 | return func(ns *Namespace) { | ||
| 251 | ns.Cond(cond) | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | // Namespace BeforeRouter filter | ||
| 256 | func NSBefore(filiterList ...FilterFunc) innnerNamespace { | ||
| 257 | return func(ns *Namespace) { | ||
| 258 | ns.Filter("before", filiterList...) | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | // Namespace FinishRouter filter | ||
| 263 | func NSAfter(filiterList ...FilterFunc) innnerNamespace { | ||
| 264 | return func(ns *Namespace) { | ||
| 265 | ns.Filter("after", filiterList...) | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 269 | // Namespace Include ControllerInterface | ||
| 270 | func NSInclude(cList ...ControllerInterface) innnerNamespace { | ||
| 271 | return func(ns *Namespace) { | ||
| 272 | ns.Include(cList...) | ||
| 273 | } | ||
| 274 | } | ||
| 275 | |||
| 276 | // Namespace Router | ||
| 277 | func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) innnerNamespace { | ||
| 278 | return func(ns *Namespace) { | ||
| 279 | ns.Router(rootpath, c, mappingMethods...) | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | // Namespace Get | ||
| 284 | func NSGet(rootpath string, f FilterFunc) innnerNamespace { | ||
| 285 | return func(ns *Namespace) { | ||
| 286 | ns.Get(rootpath, f) | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | // Namespace Post | ||
| 291 | func NSPost(rootpath string, f FilterFunc) innnerNamespace { | ||
| 292 | return func(ns *Namespace) { | ||
| 293 | ns.Post(rootpath, f) | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | // Namespace Head | ||
| 298 | func NSHead(rootpath string, f FilterFunc) innnerNamespace { | ||
| 299 | return func(ns *Namespace) { | ||
| 300 | ns.Head(rootpath, f) | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | // Namespace Put | ||
| 305 | func NSPut(rootpath string, f FilterFunc) innnerNamespace { | ||
| 306 | return func(ns *Namespace) { | ||
| 307 | ns.Put(rootpath, f) | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | // Namespace Delete | ||
| 312 | func NSDelete(rootpath string, f FilterFunc) innnerNamespace { | ||
| 313 | return func(ns *Namespace) { | ||
| 314 | ns.Delete(rootpath, f) | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | // Namespace Any | ||
| 319 | func NSAny(rootpath string, f FilterFunc) innnerNamespace { | ||
| 320 | return func(ns *Namespace) { | ||
| 321 | ns.Any(rootpath, f) | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | // Namespace Options | ||
| 326 | func NSOptions(rootpath string, f FilterFunc) innnerNamespace { | ||
| 327 | return func(ns *Namespace) { | ||
| 328 | ns.Options(rootpath, f) | ||
| 329 | } | ||
| 330 | } | ||
| 331 | |||
| 332 | // Namespace Patch | ||
| 333 | func NSPatch(rootpath string, f FilterFunc) innnerNamespace { | ||
| 334 | return func(ns *Namespace) { | ||
| 335 | ns.Patch(rootpath, f) | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | //Namespace AutoRouter | ||
| 340 | func NSAutoRouter(c ControllerInterface) innnerNamespace { | ||
| 341 | return func(ns *Namespace) { | ||
| 342 | ns.AutoRouter(c) | ||
| 343 | } | ||
| 344 | } | ||
| 345 | |||
| 346 | // Namespace AutoPrefix | ||
| 347 | func NSAutoPrefix(prefix string, c ControllerInterface) innnerNamespace { | ||
| 348 | return func(ns *Namespace) { | ||
| 349 | ns.AutoPrefix(prefix, c) | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | // Namespace add sub Namespace | ||
| 354 | func NSNamespace(prefix string, params ...innnerNamespace) innnerNamespace { | ||
| 355 | return func(ns *Namespace) { | ||
| 356 | n := NewNamespace(prefix, params...) | ||
| 357 | ns.Namespace(n) | ||
| 358 | } | ||
| 359 | } | ... | ... |
| ... | @@ -143,3 +143,21 @@ func TestNamespaceCond(t *testing.T) { | ... | @@ -143,3 +143,21 @@ func TestNamespaceCond(t *testing.T) { |
| 143 | t.Errorf("TestNamespaceCond can't run get the result " + strconv.Itoa(w.Code)) | 143 | t.Errorf("TestNamespaceCond can't run get the result " + strconv.Itoa(w.Code)) |
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| 146 | |||
| 147 | func TestNamespaceInside(t *testing.T) { | ||
| 148 | r, _ := http.NewRequest("GET", "/v3/shop/order/123", nil) | ||
| 149 | w := httptest.NewRecorder() | ||
| 150 | ns := NewNamespace("/v3", | ||
| 151 | NSAutoRouter(&TestController{}), | ||
| 152 | NSNamespace("/shop", | ||
| 153 | NSGet("/order/:id", func(ctx *context.Context) { | ||
| 154 | ctx.Output.Body([]byte(ctx.Input.Param(":id"))) | ||
| 155 | }), | ||
| 156 | ), | ||
| 157 | ) | ||
| 158 | AddNamespace(ns) | ||
| 159 | BeeApp.Handlers.ServeHTTP(w, r) | ||
| 160 | if w.Body.String() != "123" { | ||
| 161 | t.Errorf("TestNamespaceInside can't run, get the response is " + w.Body.String()) | ||
| 162 | } | ||
| 163 | } | ... | ... |
| ... | @@ -6,14 +6,18 @@ | ... | @@ -6,14 +6,18 @@ |
| 6 | package beego | 6 | package beego |
| 7 | 7 | ||
| 8 | import ( | 8 | import ( |
| 9 | "encoding/json" | ||
| 9 | "errors" | 10 | "errors" |
| 10 | "fmt" | 11 | "fmt" |
| 11 | "go/ast" | 12 | "go/ast" |
| 12 | "go/parser" | 13 | "go/parser" |
| 13 | "go/token" | 14 | "go/token" |
| 15 | "io/ioutil" | ||
| 14 | "os" | 16 | "os" |
| 15 | "path" | 17 | "path" |
| 16 | "strings" | 18 | "strings" |
| 19 | |||
| 20 | "github.com/astaxie/beego/utils" | ||
| 17 | ) | 21 | ) |
| 18 | 22 | ||
| 19 | var globalRouterTemplate = `package routers | 23 | var globalRouterTemplate = `package routers |
| ... | @@ -27,13 +31,22 @@ func init() { | ... | @@ -27,13 +31,22 @@ func init() { |
| 27 | } | 31 | } |
| 28 | ` | 32 | ` |
| 29 | 33 | ||
| 30 | var genInfoList map[string][]ControllerComments | 34 | var ( |
| 35 | lastupdateFilename string = "lastupdate.tmp" | ||
| 36 | pkgLastupdate map[string]int64 | ||
| 37 | genInfoList map[string][]ControllerComments | ||
| 38 | ) | ||
| 31 | 39 | ||
| 32 | func init() { | 40 | func init() { |
| 41 | pkgLastupdate = make(map[string]int64) | ||
| 33 | genInfoList = make(map[string][]ControllerComments) | 42 | genInfoList = make(map[string][]ControllerComments) |
| 34 | } | 43 | } |
| 35 | 44 | ||
| 36 | func parserPkg(pkgRealpath, pkgpath string) error { | 45 | func parserPkg(pkgRealpath, pkgpath string) error { |
| 46 | if !compareFile(pkgRealpath) { | ||
| 47 | Info(pkgRealpath + " don't has updated") | ||
| 48 | return nil | ||
| 49 | } | ||
| 37 | fileSet := token.NewFileSet() | 50 | fileSet := token.NewFileSet() |
| 38 | astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool { | 51 | astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool { |
| 39 | name := info.Name() | 52 | name := info.Name() |
| ... | @@ -54,6 +67,7 @@ func parserPkg(pkgRealpath, pkgpath string) error { | ... | @@ -54,6 +67,7 @@ func parserPkg(pkgRealpath, pkgpath string) error { |
| 54 | } | 67 | } |
| 55 | } | 68 | } |
| 56 | genRouterCode() | 69 | genRouterCode() |
| 70 | savetoFile(pkgRealpath) | ||
| 57 | return nil | 71 | return nil |
| 58 | } | 72 | } |
| 59 | 73 | ||
| ... | @@ -119,8 +133,14 @@ func genRouterCode() { | ... | @@ -119,8 +133,14 @@ func genRouterCode() { |
| 119 | } | 133 | } |
| 120 | params = strings.TrimRight(params, ",") + "}" | 134 | params = strings.TrimRight(params, ",") + "}" |
| 121 | } | 135 | } |
| 122 | globalinfo = globalinfo + fmt.Sprintln(`beego.GlobalControllerRouter["`+k+`"] = append(beego.GlobalControllerRouter["`+k+`"], beego.ControllerComments{"`+ | 136 | globalinfo = globalinfo + ` |
| 123 | strings.TrimSpace(c.Method)+`", "`+c.Router+`", `+allmethod+", "+params+"})") | 137 | beego.GlobalControllerRouter["` + k + `"] = append(beego.GlobalControllerRouter["` + k + `"], |
| 138 | beego.ControllerComments{ | ||
| 139 | "` + strings.TrimSpace(c.Method) + `", | ||
| 140 | "` + c.Router + `", | ||
| 141 | ` + allmethod + `, | ||
| 142 | ` + params + `}) | ||
| 143 | ` | ||
| 124 | } | 144 | } |
| 125 | } | 145 | } |
| 126 | if globalinfo != "" { | 146 | if globalinfo != "" { |
| ... | @@ -132,3 +152,36 @@ func genRouterCode() { | ... | @@ -132,3 +152,36 @@ func genRouterCode() { |
| 132 | f.WriteString(strings.Replace(globalRouterTemplate, "{{.globalinfo}}", globalinfo, -1)) | 152 | f.WriteString(strings.Replace(globalRouterTemplate, "{{.globalinfo}}", globalinfo, -1)) |
| 133 | } | 153 | } |
| 134 | } | 154 | } |
| 155 | |||
| 156 | func compareFile(pkgRealpath string) bool { | ||
| 157 | if utils.FileExists(path.Join(AppPath, lastupdateFilename)) { | ||
| 158 | content, err := ioutil.ReadFile(path.Join(AppPath, lastupdateFilename)) | ||
| 159 | if err != nil { | ||
| 160 | return true | ||
| 161 | } | ||
| 162 | json.Unmarshal(content, &pkgLastupdate) | ||
| 163 | ft, err := os.Lstat(pkgRealpath) | ||
| 164 | if err != nil { | ||
| 165 | return true | ||
| 166 | } | ||
| 167 | if v, ok := pkgLastupdate[pkgRealpath]; ok { | ||
| 168 | if ft.ModTime().UnixNano() > v { | ||
| 169 | return false | ||
| 170 | } | ||
| 171 | } | ||
| 172 | } | ||
| 173 | return true | ||
| 174 | } | ||
| 175 | |||
| 176 | func savetoFile(pkgRealpath string) { | ||
| 177 | ft, err := os.Lstat(pkgRealpath) | ||
| 178 | if err != nil { | ||
| 179 | return | ||
| 180 | } | ||
| 181 | pkgLastupdate[pkgRealpath] = ft.ModTime().UnixNano() | ||
| 182 | d, err := json.Marshal(pkgLastupdate) | ||
| 183 | if err != nil { | ||
| 184 | return | ||
| 185 | } | ||
| 186 | ioutil.WriteFile(path.Join(AppPath, lastupdateFilename), d, os.ModePerm) | ||
| 187 | } | ... | ... |
-
Please register or sign in to post a comment