Example #1
0
func explodeURL(reg rdl.TypeRegistry, r *rdl.Resource) string {
	path := r.Path
	params := ""
	delim := ""
	for _, v := range r.Inputs {
		k := v.Name
		gk := goName(string(k))
		if v.PathParam {
			//
			if v.Type == "String" {
				path = strings.Replace(path, "{"+string(k)+"}", "\" + "+gk+" + \"", -1)
			} else {
				path = strings.Replace(path, "{"+string(k)+"}", "\" + fmt.Sprint("+gk+") + \"", -1)
			}
		} else if v.QueryParam != "" {
			qp := v.QueryParam
			item := ""
			if reg.IsArrayTypeName(v.Type) {
				item = "encodeListParam(\"" + qp + "\"," + gk + ")"
			} else {
				baseType := reg.BaseTypeName(v.Type)
				if v.Optional && baseType != "String" {
					item = "encodeOptional" + string(baseType) + "Param(\"" + qp + "\", " + gk + ")"
				} else {
					def := goLiteral(v.Default, string(baseType))
					if baseType == "Enum" {
						def = "\"" + def + "\""
						item = "encodeStringParam(\"" + qp + "\", " + gk + ".String(), " + def + ")"
					} else {
						item = "encode" + string(baseType) + "Param(\"" + qp + "\", " + strings.ToLower(string(baseType)) + "(" + gk + "), " + def + ")"
					}
				}
			}
			params += delim + item
			delim = ", "
		}
	}
	path = "\"" + path
	if strings.HasSuffix(path, " + \"") {
		path = path[0 : len(path)-4]
	} else {
		path += "\""
	}
	if params != "" {
		path = path + " + encodeParams(" + params + ")"
	}
	return path
}
Example #2
0
func goHandlerBody(reg rdl.TypeRegistry, name string, r *rdl.Resource, precise bool, prefixEnums bool) string {
	s := ""
	var fargs []string
	bodyName := ""
	for _, in := range r.Inputs {
		name := "arg" + capitalize(string(in.Name))
		if in.QueryParam != "" {
			qname := in.QueryParam
			if in.Optional || in.Default != nil {
				s += goParamInit(reg, qname, name, in.Type, in.Default, in.Optional, precise, prefixEnums)
			} else {
				log.Println("RDL error: queryparam must either be optional or have a default value")
			}
			fargs = append(fargs, name)
		} else if in.PathParam {
			bt := reg.BaseTypeName(in.Type)
			switch bt {
			case "Enum":
				s += fmt.Sprintf("\t%s := New%s(context.Params[%q])\n", name, in.Type, in.Name)
			case "Int32", "Int64", "Int16", "Int8":
				if precise {
					s += fmt.Sprintf("\t%s := %s(intFromString(context.Params[%q]))\n", name, in.Type, in.Name)
				} else {
					s += fmt.Sprintf("\t%s := intFromString(context.Params[%q])\n", name, in.Name)
				}
			case "Float32", "Float64":
				if precise {
					s += fmt.Sprintf("\t%s := %s(floatFromString(context.Params[%q]))\n", name, in.Type, in.Name)
				} else {
					s += fmt.Sprintf("\t%s := floatFromString(context.Params[%q])\n", name, in.Name)
				}
			default:
				if precise && strings.ToLower(string(in.Type)) != "string" {
					s += fmt.Sprintf("\t%s := %s(context.Params[%q])\n", name, in.Type, in.Name)
				} else {
					s += fmt.Sprintf("\t%s := context.Params[%q]\n", name, in.Name)
				}
			}
			fargs = append(fargs, name)
		} else if in.Header != "" {
			hname := in.Header
			def := ""
			if in.Default != nil {
				switch v := in.Default.(type) {
				case string:
					def = fmt.Sprintf("%q", v)
				default:
					panic(fmt.Sprintf("implement me, default value: %v", in))
				}
				s += "\t" + name + "Optional := " + def + "\n"
				s += fmt.Sprintf("\t%s := rdl.HeaderParam(request, %q, %sOptional)\n", name, hname, name)
			} else if in.Optional {
				s += fmt.Sprintf("\t%s := rdl.OptionalHeaderParam(request, %q)\n", name, hname)
			} else {
				s += fmt.Sprintf("\t%s := rdl.HeaderParam(request, %q, \"\")\n", name, hname)
			}
			fargs = append(fargs, name)
		} else {
			bodyName = name
			s += "\tbody, oserr := ioutil.ReadAll(request.Body)\n"
			s += "\tif oserr != nil {\n"
			s += "\t\trdl.JSONResponse(writer, http.StatusBadRequest, rdl.ResourceError{Code: http.StatusBadRequest, Message: \"Bad request: \" + oserr.Error()})\n"
			s += "\t\treturn\n"
			s += "\t}\n"
			pgtype := goType(reg, in.Type, false, "", "", precise, true)
			s += "\tvar " + bodyName + " " + pgtype + "\n"
			s += "\toserr = json.Unmarshal(body, &" + bodyName + ")\n"
			s += "\tif oserr != nil {\n"
			s += "\t\trdl.JSONResponse(writer, http.StatusBadRequest, rdl.ResourceError{Code: http.StatusBadRequest, Message: \"Bad request: \" + oserr.Error()})\n"
			s += "\t\treturn\n"
			s += "\t}\n"
			fargs = append(fargs, bodyName)
		}
	}
	if r.Auth != nil {
		if r.Auth.Authenticate {
			s += authenticateTemplate
		} else if r.Auth.Action != "" && r.Auth.Resource != "" {
			resource := r.Auth.Resource
			i := strings.Index(resource, "{")
			for i >= 0 {
				j := strings.Index(resource[i:], "}")
				if j < 0 {
					break
				}
				j += i
				val := "string(arg" + capitalize(resource[i+1:j]) + ")"
				resource = resource[0:i] + "\" + " + val + " + \"" + resource[j+1:]
				i = strings.Index(resource, "{")
			}
			resource = "\"" + resource
			if strings.HasSuffix(resource, "+ \"") {
				resource = resource[0 : len(resource)-3]
			} else {
				resource = resource + "\""
			}
			if strings.HasPrefix(resource, "\"\" + ") {
				resource = resource[5:]
			}
			s += fmt.Sprintf(authorizeTemplate, r.Auth.Action, resource)
		} else {
			log.Println("*** Badly formed auth spec in resource input:", r)
		}
	}
	methName, _ := goMethodName(reg, r, precise)
	sargs := ""
	if len(fargs) > 0 {
		sargs = ", " + strings.Join(fargs, ", ")
	}
	outHeaders := ""
	for _, v := range r.Outputs {
		outHeaders += ", " + string(v.Name)
	}
	noContent := r.Expected == "NO_CONTENT" && len(r.Alternatives) == 0
	if noContent {
		s += "\terr" + outHeaders + " := adaptor.impl." + capitalize(methName) + "(context" + sargs + ")\n"
	} else {
		s += "\tdata" + outHeaders + ", err := adaptor.impl." + capitalize(methName) + "(context" + sargs + ")\n"
	}
	s += "\tif err != nil {\n"
	s += "\t\tswitch e := err.(type) {\n"
	s += "\t\tcase *rdl.ResourceError:\n"
	//special case the 304 response, which MUST have an etag in it
	for _, v := range r.Outputs {
		if strings.ToLower(v.Header) == "etag" {
			s += "\t\t\tif e.Code == 304 && " + string(v.Name) + " != \"\" {\n"
			s += "\t\t\t\twriter.Header().Set(\"" + v.Header + "\", " + string(v.Name) + ")\n"
			s += "\t\t\t}\n"
			break
		}
	}

	s += "\t\t\trdl.JSONResponse(writer, e.Code, err)\n"
	s += "\t\tdefault:\n"
	s += "\t\t\trdl.JSONResponse(writer, 500, &rdl.ResourceError{Code: 500, Message: e.Error()})\n"
	s += "\t\t}\n"
	s += "\t} else {\n"
	for _, v := range r.Outputs {
		vname := string(v.Name)
		if v.Optional {
			s += "\t\tif " + vname + " != nil {\n"
			s += "\t\t\twriter.Header().Set(\"" + v.Header + "\", " + vname + ")\n"
			s += "\t\t}\n"
		} else {
			s += "\t\twriter.Header().Set(\"" + v.Header + "\", " + vname + ")\n"
		}
	}
	if noContent { //other non-content responses?
		s += fmt.Sprintf("\t\twriter.WriteHeader(204)\n")
	} else {
		//fixme: handle alternative responses. How deos the handler pass them back?
		s += fmt.Sprintf("\t\trdl.JSONResponse(writer, %s, data)\n", rdl.StatusCode(r.Expected))
	}
	s += "\t}\n"
	return s
}