namespace.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package beego
  15. import (
  16. "net/http"
  17. "strings"
  18. beecontext "github.com/astaxie/beego/context"
  19. )
  20. type namespaceCond func(*beecontext.Context) bool
  21. // LinkNamespace used as link action
  22. type LinkNamespace func(*Namespace)
  23. // Namespace is store all the info
  24. type Namespace struct {
  25. prefix string
  26. handlers *ControllerRegister
  27. }
  28. // NewNamespace get new Namespace
  29. func NewNamespace(prefix string, params ...LinkNamespace) *Namespace {
  30. ns := &Namespace{
  31. prefix: prefix,
  32. handlers: NewControllerRegister(),
  33. }
  34. for _, p := range params {
  35. p(ns)
  36. }
  37. return ns
  38. }
  39. // Cond set condition function
  40. // if cond return true can run this namespace, else can't
  41. // usage:
  42. // ns.Cond(func (ctx *context.Context) bool{
  43. // if ctx.Input.Domain() == "api.beego.me" {
  44. // return true
  45. // }
  46. // return false
  47. // })
  48. // Cond as the first filter
  49. func (n *Namespace) Cond(cond namespaceCond) *Namespace {
  50. fn := func(ctx *beecontext.Context) {
  51. if !cond(ctx) {
  52. exception("405", ctx)
  53. }
  54. }
  55. if v := n.handlers.filters[BeforeRouter]; len(v) > 0 {
  56. mr := new(FilterRouter)
  57. mr.tree = NewTree()
  58. mr.pattern = "*"
  59. mr.filterFunc = fn
  60. mr.tree.AddRouter("*", true)
  61. n.handlers.filters[BeforeRouter] = append([]*FilterRouter{mr}, v...)
  62. } else {
  63. n.handlers.InsertFilter("*", BeforeRouter, fn)
  64. }
  65. return n
  66. }
  67. // Filter add filter in the Namespace
  68. // action has before & after
  69. // FilterFunc
  70. // usage:
  71. // Filter("before", func (ctx *context.Context){
  72. // _, ok := ctx.Input.Session("uid").(int)
  73. // if !ok && ctx.Request.RequestURI != "/login" {
  74. // ctx.Redirect(302, "/login")
  75. // }
  76. // })
  77. func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace {
  78. var a int
  79. if action == "before" {
  80. a = BeforeRouter
  81. } else if action == "after" {
  82. a = FinishRouter
  83. }
  84. for _, f := range filter {
  85. n.handlers.InsertFilter("*", a, f)
  86. }
  87. return n
  88. }
  89. // Router same as beego.Rourer
  90. // refer: https://godoc.org/github.com/astaxie/beego#Router
  91. func (n *Namespace) Router(rootpath string, c ControllerInterface, mappingMethods ...string) *Namespace {
  92. n.handlers.Add(rootpath, c, mappingMethods...)
  93. return n
  94. }
  95. // AutoRouter same as beego.AutoRouter
  96. // refer: https://godoc.org/github.com/astaxie/beego#AutoRouter
  97. func (n *Namespace) AutoRouter(c ControllerInterface) *Namespace {
  98. n.handlers.AddAuto(c)
  99. return n
  100. }
  101. // AutoPrefix same as beego.AutoPrefix
  102. // refer: https://godoc.org/github.com/astaxie/beego#AutoPrefix
  103. func (n *Namespace) AutoPrefix(prefix string, c ControllerInterface) *Namespace {
  104. n.handlers.AddAutoPrefix(prefix, c)
  105. return n
  106. }
  107. // Get same as beego.Get
  108. // refer: https://godoc.org/github.com/astaxie/beego#Get
  109. func (n *Namespace) Get(rootpath string, f FilterFunc) *Namespace {
  110. n.handlers.Get(rootpath, f)
  111. return n
  112. }
  113. // Post same as beego.Post
  114. // refer: https://godoc.org/github.com/astaxie/beego#Post
  115. func (n *Namespace) Post(rootpath string, f FilterFunc) *Namespace {
  116. n.handlers.Post(rootpath, f)
  117. return n
  118. }
  119. // Delete same as beego.Delete
  120. // refer: https://godoc.org/github.com/astaxie/beego#Delete
  121. func (n *Namespace) Delete(rootpath string, f FilterFunc) *Namespace {
  122. n.handlers.Delete(rootpath, f)
  123. return n
  124. }
  125. // Put same as beego.Put
  126. // refer: https://godoc.org/github.com/astaxie/beego#Put
  127. func (n *Namespace) Put(rootpath string, f FilterFunc) *Namespace {
  128. n.handlers.Put(rootpath, f)
  129. return n
  130. }
  131. // Head same as beego.Head
  132. // refer: https://godoc.org/github.com/astaxie/beego#Head
  133. func (n *Namespace) Head(rootpath string, f FilterFunc) *Namespace {
  134. n.handlers.Head(rootpath, f)
  135. return n
  136. }
  137. // Options same as beego.Options
  138. // refer: https://godoc.org/github.com/astaxie/beego#Options
  139. func (n *Namespace) Options(rootpath string, f FilterFunc) *Namespace {
  140. n.handlers.Options(rootpath, f)
  141. return n
  142. }
  143. // Patch same as beego.Patch
  144. // refer: https://godoc.org/github.com/astaxie/beego#Patch
  145. func (n *Namespace) Patch(rootpath string, f FilterFunc) *Namespace {
  146. n.handlers.Patch(rootpath, f)
  147. return n
  148. }
  149. // Any same as beego.Any
  150. // refer: https://godoc.org/github.com/astaxie/beego#Any
  151. func (n *Namespace) Any(rootpath string, f FilterFunc) *Namespace {
  152. n.handlers.Any(rootpath, f)
  153. return n
  154. }
  155. // Handler same as beego.Handler
  156. // refer: https://godoc.org/github.com/astaxie/beego#Handler
  157. func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace {
  158. n.handlers.Handler(rootpath, h)
  159. return n
  160. }
  161. // Include add include class
  162. // refer: https://godoc.org/github.com/astaxie/beego#Include
  163. func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
  164. n.handlers.Include(cList...)
  165. return n
  166. }
  167. // Namespace add nest Namespace
  168. // usage:
  169. //ns := beego.NewNamespace(“/v1”).
  170. //Namespace(
  171. // beego.NewNamespace("/shop").
  172. // Get("/:id", func(ctx *context.Context) {
  173. // ctx.Output.Body([]byte("shopinfo"))
  174. // }),
  175. // beego.NewNamespace("/order").
  176. // Get("/:id", func(ctx *context.Context) {
  177. // ctx.Output.Body([]byte("orderinfo"))
  178. // }),
  179. // beego.NewNamespace("/crm").
  180. // Get("/:id", func(ctx *context.Context) {
  181. // ctx.Output.Body([]byte("crminfo"))
  182. // }),
  183. //)
  184. func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
  185. for _, ni := range ns {
  186. for k, v := range ni.handlers.routers {
  187. if t, ok := n.handlers.routers[k]; ok {
  188. addPrefix(v, ni.prefix)
  189. n.handlers.routers[k].AddTree(ni.prefix, v)
  190. } else {
  191. t = NewTree()
  192. t.AddTree(ni.prefix, v)
  193. addPrefix(t, ni.prefix)
  194. n.handlers.routers[k] = t
  195. }
  196. }
  197. if ni.handlers.enableFilter {
  198. for pos, filterList := range ni.handlers.filters {
  199. for _, mr := range filterList {
  200. t := NewTree()
  201. t.AddTree(ni.prefix, mr.tree)
  202. mr.tree = t
  203. n.handlers.insertFilterRouter(pos, mr)
  204. }
  205. }
  206. }
  207. }
  208. return n
  209. }
  210. // AddNamespace register Namespace into beego.Handler
  211. // support multi Namespace
  212. func AddNamespace(nl ...*Namespace) {
  213. for _, n := range nl {
  214. for k, v := range n.handlers.routers {
  215. if t, ok := BeeApp.Handlers.routers[k]; ok {
  216. addPrefix(v, n.prefix)
  217. BeeApp.Handlers.routers[k].AddTree(n.prefix, v)
  218. } else {
  219. t = NewTree()
  220. t.AddTree(n.prefix, v)
  221. addPrefix(t, n.prefix)
  222. BeeApp.Handlers.routers[k] = t
  223. }
  224. }
  225. if n.handlers.enableFilter {
  226. for pos, filterList := range n.handlers.filters {
  227. for _, mr := range filterList {
  228. t := NewTree()
  229. t.AddTree(n.prefix, mr.tree)
  230. mr.tree = t
  231. BeeApp.Handlers.insertFilterRouter(pos, mr)
  232. }
  233. }
  234. }
  235. }
  236. }
  237. func addPrefix(t *Tree, prefix string) {
  238. for _, v := range t.fixrouters {
  239. addPrefix(v, prefix)
  240. }
  241. if t.wildcard != nil {
  242. addPrefix(t.wildcard, prefix)
  243. }
  244. for _, l := range t.leaves {
  245. if c, ok := l.runObject.(*controllerInfo); ok {
  246. if !strings.HasPrefix(c.pattern, prefix) {
  247. c.pattern = prefix + c.pattern
  248. }
  249. }
  250. }
  251. }
  252. // NSCond is Namespace Condition
  253. func NSCond(cond namespaceCond) LinkNamespace {
  254. return func(ns *Namespace) {
  255. ns.Cond(cond)
  256. }
  257. }
  258. // NSBefore Namespace BeforeRouter filter
  259. func NSBefore(filiterList ...FilterFunc) LinkNamespace {
  260. return func(ns *Namespace) {
  261. ns.Filter("before", filiterList...)
  262. }
  263. }
  264. // NSAfter add Namespace FinishRouter filter
  265. func NSAfter(filiterList ...FilterFunc) LinkNamespace {
  266. return func(ns *Namespace) {
  267. ns.Filter("after", filiterList...)
  268. }
  269. }
  270. // NSInclude Namespace Include ControllerInterface
  271. func NSInclude(cList ...ControllerInterface) LinkNamespace {
  272. return func(ns *Namespace) {
  273. ns.Include(cList...)
  274. }
  275. }
  276. // NSRouter call Namespace Router
  277. func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) LinkNamespace {
  278. return func(ns *Namespace) {
  279. ns.Router(rootpath, c, mappingMethods...)
  280. }
  281. }
  282. // NSGet call Namespace Get
  283. func NSGet(rootpath string, f FilterFunc) LinkNamespace {
  284. return func(ns *Namespace) {
  285. ns.Get(rootpath, f)
  286. }
  287. }
  288. // NSPost call Namespace Post
  289. func NSPost(rootpath string, f FilterFunc) LinkNamespace {
  290. return func(ns *Namespace) {
  291. ns.Post(rootpath, f)
  292. }
  293. }
  294. // NSHead call Namespace Head
  295. func NSHead(rootpath string, f FilterFunc) LinkNamespace {
  296. return func(ns *Namespace) {
  297. ns.Head(rootpath, f)
  298. }
  299. }
  300. // NSPut call Namespace Put
  301. func NSPut(rootpath string, f FilterFunc) LinkNamespace {
  302. return func(ns *Namespace) {
  303. ns.Put(rootpath, f)
  304. }
  305. }
  306. // NSDelete call Namespace Delete
  307. func NSDelete(rootpath string, f FilterFunc) LinkNamespace {
  308. return func(ns *Namespace) {
  309. ns.Delete(rootpath, f)
  310. }
  311. }
  312. // NSAny call Namespace Any
  313. func NSAny(rootpath string, f FilterFunc) LinkNamespace {
  314. return func(ns *Namespace) {
  315. ns.Any(rootpath, f)
  316. }
  317. }
  318. // NSOptions call Namespace Options
  319. func NSOptions(rootpath string, f FilterFunc) LinkNamespace {
  320. return func(ns *Namespace) {
  321. ns.Options(rootpath, f)
  322. }
  323. }
  324. // NSPatch call Namespace Patch
  325. func NSPatch(rootpath string, f FilterFunc) LinkNamespace {
  326. return func(ns *Namespace) {
  327. ns.Patch(rootpath, f)
  328. }
  329. }
  330. // NSAutoRouter call Namespace AutoRouter
  331. func NSAutoRouter(c ControllerInterface) LinkNamespace {
  332. return func(ns *Namespace) {
  333. ns.AutoRouter(c)
  334. }
  335. }
  336. // NSAutoPrefix call Namespace AutoPrefix
  337. func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace {
  338. return func(ns *Namespace) {
  339. ns.AutoPrefix(prefix, c)
  340. }
  341. }
  342. // NSNamespace add sub Namespace
  343. func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace {
  344. return func(ns *Namespace) {
  345. n := NewNamespace(prefix, params...)
  346. ns.Namespace(n)
  347. }
  348. }
  349. // NSHandler add handler
  350. func NSHandler(rootpath string, h http.Handler) LinkNamespace {
  351. return func(ns *Namespace) {
  352. ns.Handler(rootpath, h)
  353. }
  354. }