From 446daaea37c763d564f6a4f1c0b8b32e47e367d8 Mon Sep 17 00:00:00 2001 From: xiemengjun Date: Mon, 26 Mar 2012 23:18:16 +0800 Subject: [PATCH] modify --- beego/beego.go | 26 +++++- beego/core/controller.go | 19 +++++ beego/core/router.go | 144 +++++++++++++++++++++++++++++++++ beego/server/server.go | 14 ++++ examples/blog/blog.go | 96 ++++++++++++++++++++++ examples/blog/configs/app.yaml | 3 + examples/hello/hello.go | 14 ++++ 7 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 beego/server/server.go create mode 100644 examples/blog/configs/app.yaml diff --git a/beego/beego.go b/beego/beego.go index 18179615..7d63f48d 100644 --- a/beego/beego.go +++ b/beego/beego.go @@ -1,7 +1,27 @@ package beego -import "fmt" +import "./core" -func main(){ - fmt.Printf("hello world") +type C struct { + core.Content +} + +type M struct{ + core.Model +} + +type D struct{ + core.Config +} + +type U struct{ + core.URL +} + +type A struct{ + core.Controller +} + +type V struct{ + core.View } \ No newline at end of file diff --git a/beego/core/controller.go b/beego/core/controller.go index e69de29b..f64c2f14 100644 --- a/beego/core/controller.go +++ b/beego/core/controller.go @@ -0,0 +1,19 @@ +package beego + +// Interface for controller types that handle requests +type Controller interface { + + // When implemented, handles the request + HandleRequest(c *Context) +} + +// The ControllerFunc type is an adapter to allow the use of +// ordinary functions as goweb handlers. If f is a function +// with the appropriate signature, ControllerFunc(f) is a +// Controller object that calls f. +type ControllerFunc func(*Context) + +// HandleRequest calls f(c). +func (f ControllerFunc) HandleRequest(c *Context) { + f(c) +} \ No newline at end of file diff --git a/beego/core/router.go b/beego/core/router.go index e69de29b..ddaf30f4 100644 --- a/beego/core/router.go +++ b/beego/core/router.go @@ -0,0 +1,144 @@ +package beego + +import ( + "regexp" + "strings" +) + +/* + Route +*/ + +// Represents a single route mapping +type Route struct { + pattern string + parameterKeys ParameterKeyMap + extension string + Path string + Controller Controller + MatcherFuncs []RouteMatcherFunc +} + +func (r *Route) String() string { + return "{Route:'" + r.Path + "'}" +} + +// Makes a new route from the given path +func makeRouteFromPath(path string) *Route { + + // get the path segments + segments := getPathSegments(path) + regexSegments := make([]string, len(segments)) + + // prepare the parameter key map + var paramKeys ParameterKeyMap = make(ParameterKeyMap) + + var extension string + + // pull out any dynamic segments + for index, _ := range segments { + + if isDynamicSegment(segments[index]) { + + // e.g. {id} + + paramKeys[strings.Trim(segments[index], "{}")] = index + regexSegments[index] = ROUTE_REGEX_PLACEHOLDER + + } else if isExtensionSegment(segments[index]) { + + // e.g. .json + extension = segments[index] + + // trim off the last space (we don't need it) + regexSegments = regexSegments[0 : len(regexSegments)-1] + + } else { + + // e.g. "groups" + + regexSegments[index] = segments[index] + + } + + } + + patternString := "/" + strings.Join(regexSegments, "/") + + // return a new route + var route *Route = new(Route) + route.pattern = patternString + route.extension = extension + route.parameterKeys = paramKeys + route.Path = path + route.Controller = nil + return route + +} + +// Gets the parameter values for the route from the specified path +func (route *Route) getParameterValueMap(path string) ParameterValueMap { + return getParameterValueMap(route.parameterKeys, path) +} + +// Checks whether a path matches a route or not +func (route *Route) DoesMatchPath(path string) bool { + + match, error := regexp.MatchString(route.pattern, path) + + if error == nil { + if match { + + if len(route.extension) > 0 { + + // make sure the extensions match too + return strings.HasSuffix(strings.ToLower(path), strings.ToLower(route.extension)) + + } else { + return match + } + + } else { + + return false + + } + + } + + // error :-( + return false + +} + +// Checks whether the context for this request matches the route +func (route *Route) DoesMatchContext(c *Context) bool { + + // by default, we match + var match bool = true + + if len(route.MatcherFuncs) > 0 { + + // there are some matcher functions, so don't automatically + // match by default - let the matchers decide + match = false + + // loop through the matcher functions + for _, f := range route.MatcherFuncs { + + // modify 'match' based on the result of the matcher function + switch f(c) { + case NoMatch: + match = false + case Match: + match = true + } + + } + + } + + // return the result + return match + +} \ No newline at end of file diff --git a/beego/server/server.go b/beego/server/server.go new file mode 100644 index 00000000..e5fd1a2d --- /dev/null +++ b/beego/server/server.go @@ -0,0 +1,14 @@ +package server + +import ( + "bufio" + "bytes" + "errors" + "io" + "log" + "net" + "net/url" + "runtime/debug" + "strconv" + "strings" +) \ No newline at end of file diff --git a/examples/blog/blog.go b/examples/blog/blog.go index e69de29b..c9c2f515 100644 --- a/examples/blog/blog.go +++ b/examples/blog/blog.go @@ -0,0 +1,96 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package guestbook + +import ( + "io" + "net/http" + "text/template" + "time" + + "appengine" + "appengine/datastore" + "appengine/user" +) + +type Greeting struct { + Author string + Content string + Date time.Time +} + +func serve404(w http.ResponseWriter) { + w.WriteHeader(http.StatusNotFound) + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + io.WriteString(w, "Not Found") +} + +func serveError(c appengine.Context, w http.ResponseWriter, err error) { + w.WriteHeader(http.StatusInternalServerError) + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + io.WriteString(w, "Internal Server Error") + c.Errorf("%v", err) +} + +var mainPage = template.Must(template.New("guestbook").Parse( + ` +{{range .}} +{{with .Author}}{{.|html}}{{else}}An anonymous person{{end}} +on {{.Date.Format "3:04pm, Mon 2 Jan"}} +wrote
{{.Content|html}}
+{{end}} +
+
+
+
+`)) + +func handleMainPage(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" || r.URL.Path != "/" { + serve404(w) + return + } + c := appengine.NewContext(r) + q := datastore.NewQuery("Greeting").Order("-Date").Limit(10) + var gg []*Greeting + _, err := q.GetAll(c, &gg) + if err != nil { + serveError(c, w, err) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + if err := mainPage.Execute(w, gg); err != nil { + c.Errorf("%v", err) + } +} + +func handleSign(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + serve404(w) + return + } + c := appengine.NewContext(r) + if err := r.ParseForm(); err != nil { + serveError(c, w, err) + return + } + g := &Greeting{ + Content: r.FormValue("content"), + Date: time.Now(), + } + if u := user.Current(c); u != nil { + g.Author = u.String() + } + if _, err := datastore.Put(c, datastore.NewIncompleteKey(c, "Greeting", nil), g); err != nil { + serveError(c, w, err) + return + } + http.Redirect(w, r, "/", http.StatusFound) +} + +func init() { + http.HandleFunc("/", handleMainPage) + http.HandleFunc("/sign", handleSign) +} diff --git a/examples/blog/configs/app.yaml b/examples/blog/configs/app.yaml new file mode 100644 index 00000000..c2f8c6c0 --- /dev/null +++ b/examples/blog/configs/app.yaml @@ -0,0 +1,3 @@ +application: guestbook-go +handlers: +- url: /.* diff --git a/examples/hello/hello.go b/examples/hello/hello.go index e69de29b..e2f83b5e 100644 --- a/examples/hello/hello.go +++ b/examples/hello/hello.go @@ -0,0 +1,14 @@ +package helloworld + +import ( + "fmt" + "net/http" +) + +func init() { + http.HandleFunc("/", handle) +} + +func handle(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, "Hello, World! 세상아 안녕!") +}