// generateContexts iterates through the version resources and actions and generates the action // contexts. func (g *Generator) generateContexts(verdir string, api *design.APIDefinition, version *design.APIVersionDefinition) error { ctxFile := filepath.Join(verdir, "contexts.go") ctxWr, err := NewContextsWriter(ctxFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Contexts", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("strconv"), codegen.SimpleImport("strings"), codegen.SimpleImport("time"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } ctxWr.WriteHeader(title, packageName(version), imports) err = version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } return r.IterateActions(func(a *design.ActionDefinition) error { ctxName := codegen.Goify(a.Name, true) + codegen.Goify(a.Parent.Name, true) + "Context" headers := r.Headers.Merge(a.Headers) if headers != nil && len(headers.Type.ToObject()) == 0 { headers = nil // So that {{if .Headers}} returns false in templates } params := a.AllParams() if params != nil && len(params.Type.ToObject()) == 0 { params = nil // So that {{if .Params}} returns false in templates } ctxData := ContextTemplateData{ Name: ctxName, ResourceName: r.Name, ActionName: a.Name, Payload: a.Payload, Params: params, Headers: headers, Routes: a.Routes, Responses: MergeResponses(r.Responses, a.Responses), API: api, Version: version, DefaultPkg: TargetPackage, } return ctxWr.Execute(&ctxData) }) }) g.genfiles = append(g.genfiles, ctxFile) if err != nil { return err } return ctxWr.FormatCode() }
// generateControllers iterates through the version resources and generates the low level // controllers. func (g *Generator) generateControllers(verdir string, version *design.APIVersionDefinition) error { ctlFile := filepath.Join(verdir, "controllers.go") ctlWr, err := NewControllersWriter(ctlFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Controllers", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/julienschmidt/httprouter"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } ctlWr.WriteHeader(title, packageName(version), imports) var controllersData []*ControllerTemplateData version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } data := &ControllerTemplateData{Resource: codegen.Goify(r.Name, true)} err := r.IterateActions(func(a *design.ActionDefinition) error { context := fmt.Sprintf("%s%sContext", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) unmarshal := fmt.Sprintf("unmarshal%s%sPayload", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) action := map[string]interface{}{ "Name": codegen.Goify(a.Name, true), "Routes": a.Routes, "Context": context, "Unmarshal": unmarshal, "Payload": a.Payload, } data.Actions = append(data.Actions, action) return nil }) if err != nil { return err } if len(data.Actions) > 0 { data.Version = version controllersData = append(controllersData, data) } return nil }) g.genfiles = append(g.genfiles, ctlFile) if err = ctlWr.Execute(controllersData); err != nil { return err } return ctlWr.FormatCode() }
// generateHrefs iterates through the version resources and generates the href factory methods. func (g *Generator) generateHrefs(verdir string, version *design.APIVersionDefinition) error { hrefFile := filepath.Join(verdir, "hrefs.go") resWr, err := NewResourcesWriter(hrefFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Resource Href Factories", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), } resWr.WriteHeader(title, packageName(version), imports) err = version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } m := design.Design.MediaTypeWithIdentifier(r.MediaType) var identifier string if m != nil { identifier = m.Identifier } else { identifier = "plain/text" } canoTemplate := r.URITemplate(version) canoTemplate = design.WildcardRegex.ReplaceAllLiteralString(canoTemplate, "/%v") var canoParams []string if ca := r.CanonicalAction(); ca != nil { if len(ca.Routes) > 0 { canoParams = ca.Routes[0].Params(version) } } data := ResourceData{ Name: codegen.Goify(r.Name, true), Identifier: identifier, Description: r.Description, Type: m, CanonicalTemplate: canoTemplate, CanonicalParams: canoParams, } return resWr.Execute(&data) }) g.genfiles = append(g.genfiles, hrefFile) if err != nil { return err } return resWr.FormatCode() }
// generateControllers iterates through the version resources and generates the low level // controllers. func (g *Generator) generateControllers(verdir string, version *design.APIVersionDefinition) error { ctlFile := filepath.Join(verdir, "controllers.go") ctlWr, err := NewControllersWriter(ctlFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Controllers", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("net/http"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } encoderMap, err := BuildEncoderMap(version.Produces, true) if err != nil { return err } decoderMap, err := BuildEncoderMap(version.Consumes, false) if err != nil { return err } encoderImports := make(map[string]bool) for _, data := range encoderMap { encoderImports[data.PackagePath] = true } for _, data := range decoderMap { encoderImports[data.PackagePath] = true } for packagePath := range encoderImports { if !design.IsGoaEncoder(packagePath) { imports = append(imports, codegen.SimpleImport(packagePath)) } } ctlWr.WriteHeader(title, packageName(version), imports) var controllersData []*ControllerTemplateData version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } data := &ControllerTemplateData{API: design.Design, Resource: codegen.Goify(r.Name, true)} err := r.IterateActions(func(a *design.ActionDefinition) error { context := fmt.Sprintf("%s%sContext", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) unmarshal := fmt.Sprintf("unmarshal%s%sPayload", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) action := map[string]interface{}{ "Name": codegen.Goify(a.Name, true), "Routes": a.Routes, "Context": context, "Unmarshal": unmarshal, "Payload": a.Payload, } data.Actions = append(data.Actions, action) return nil }) if err != nil { return err } if len(data.Actions) > 0 { data.EncoderMap = encoderMap data.DecoderMap = decoderMap data.Version = version controllersData = append(controllersData, data) } return nil }) g.genfiles = append(g.genfiles, ctlFile) if err = ctlWr.Execute(controllersData); err != nil { return err } return ctlWr.FormatCode() }