package javagen import ( "errors" "fmt" "io" "path" "strings" "text/template" "github.com/tal-tech/go-zero/core/stringx" "github.com/tal-tech/go-zero/tools/goctl/api/spec" apiutil "github.com/tal-tech/go-zero/tools/goctl/api/util" "github.com/tal-tech/go-zero/tools/goctl/util" ) const ( componentTemplate = `// Code generated by goctl. DO NOT EDIT. package com.xhb.logic.http.packet.{{.packet}}.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; {{.imports}} {{.componentType}} ` httpResponseData = "import com.xhb.core.response.HttpResponseData;" httpData = "import com.xhb.core.packet.HttpData;" ) type componentsContext struct { api *spec.ApiSpec requestTypes []spec.Type responseTypes []spec.Type imports []string } func genComponents(dir, packetName string, api *spec.ApiSpec) error { types := api.Types if len(types) == 0 { return nil } var requestTypes []spec.Type var responseTypes []spec.Type for _, group := range api.Service.Groups { for _, route := range group.Routes { if route.RequestType != nil { requestTypes = append(requestTypes, route.RequestType) } if route.ResponseType != nil { responseTypes = append(responseTypes, route.ResponseType) } } } context := componentsContext{api: api, requestTypes: requestTypes, responseTypes: responseTypes} for _, ty := range types { if err := context.createComponent(dir, packetName, ty); err != nil { return err } } return nil } func (c *componentsContext) createComponent(dir, packetName string, ty spec.Type) error { defineStruct, ok := ty.(spec.DefineStruct) if !ok { return errors.New("unsupported type %s" + ty.Name()) } for _, item := range c.requestTypes { if item.Name() == defineStruct.Name() { if len(defineStruct.GetFormMembers())+len(defineStruct.GetBodyMembers()) == 0 { return nil } } } modelFile := util.Title(ty.Name()) + ".java" filename := path.Join(dir, modelDir, modelFile) if err := util.RemoveOrQuit(filename); err != nil { return err } fp, created, err := apiutil.MaybeCreateFile(dir, modelDir, modelFile) if err != nil { return err } if !created { return nil } defer fp.Close() tyString, err := c.buildType(defineStruct) if err != nil { return err } t := template.Must(template.New("componentType").Parse(componentTemplate)) return t.Execute(fp, map[string]string{ "componentType": tyString, "packet": packetName, "imports": strings.Join(c.imports, "\n"), }) } func (c *componentsContext) buildType(ty spec.DefineStruct) (string, error) { var builder strings.Builder if err := c.writeType(&builder, ty); err != nil { return "", apiutil.WrapErr(err, "Type "+ty.Name()+" generate error") } return builder.String(), nil } func (c *componentsContext) writeType(writer io.Writer, defineStruct spec.DefineStruct) error { responseData := "HttpData" for _, item := range c.responseTypes { if item.Name() == defineStruct.Name() { responseData = "HttpResponseData" if !stringx.Contains(c.imports, httpResponseData) { c.imports = append(c.imports, httpResponseData) } break } } if responseData == "HttpData" && !stringx.Contains(c.imports, httpData) { c.imports = append(c.imports, httpData) } fmt.Fprintf(writer, "public class %s extends %s {\n", util.Title(defineStruct.Name()), responseData) err := c.writeMembers(writer, defineStruct, 1) if err != nil { return err } genGetSet(writer, defineStruct, 1) fmt.Fprintf(writer, "}") return nil } func (c *componentsContext) writeMembers(writer io.Writer, ty spec.DefineStruct, indent int) error { for _, member := range ty.Members { if member.IsInline { defineStruct, ok := member.Type.(spec.DefineStruct) if ok { err := c.writeMembers(writer, defineStruct, indent) if err != nil { return err } continue } return errors.New("unsupported inline type %s" + member.Type.Name()) } if member.IsBodyMember() || member.IsFormMember() { if err := writeProperty(writer, member, indent); err != nil { return err } } } return nil }