@@ -1,6 +1,8 @@
|
|||||||
package javagen
|
package javagen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -22,9 +24,43 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
{{.imports}}
|
{{.imports}}
|
||||||
|
|
||||||
{{.componentType}}
|
public class {{.className}} extends {{.superClassName}} {
|
||||||
|
|
||||||
|
{{.properties}}
|
||||||
|
{{if .HasProperty}}
|
||||||
|
|
||||||
|
public {{.className}}() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public {{.className}}({{.params}}) {
|
||||||
|
{{.constructorSetter}}
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{.getSet}}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
getSetTemplate = `
|
||||||
|
{{.indent}}{{.decorator}}
|
||||||
|
{{.indent}}public {{.returnType}} get{{.property}}() {
|
||||||
|
{{.indent}} return this.{{.tagValue}};
|
||||||
|
{{.indent}}}
|
||||||
|
|
||||||
|
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
|
||||||
|
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
|
||||||
|
{{.indent}}}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
boolTemplate = `
|
||||||
|
{{.indent}}{{.decorator}}
|
||||||
|
{{.indent}}public {{.returnType}} is{{.property}}() {
|
||||||
|
{{.indent}} return this.{{.tagValue}};
|
||||||
|
{{.indent}}}
|
||||||
|
|
||||||
|
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
|
||||||
|
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
|
||||||
|
{{.indent}}}
|
||||||
|
`
|
||||||
httpResponseData = "import com.xhb.core.response.HttpResponseData;"
|
httpResponseData = "import com.xhb.core.response.HttpResponseData;"
|
||||||
httpData = "import com.xhb.core.packet.HttpData;"
|
httpData = "import com.xhb.core.packet.HttpData;"
|
||||||
)
|
)
|
||||||
@@ -34,6 +70,7 @@ type componentsContext struct {
|
|||||||
requestTypes []spec.Type
|
requestTypes []spec.Type
|
||||||
responseTypes []spec.Type
|
responseTypes []spec.Type
|
||||||
imports []string
|
imports []string
|
||||||
|
members []spec.Member
|
||||||
}
|
}
|
||||||
|
|
||||||
func genComponents(dir, packetName string, api *spec.ApiSpec) error {
|
func genComponents(dir, packetName string, api *spec.ApiSpec) error {
|
||||||
@@ -94,56 +131,86 @@ func (c *componentsContext) createComponent(dir, packetName string, ty spec.Type
|
|||||||
}
|
}
|
||||||
defer fp.Close()
|
defer fp.Close()
|
||||||
|
|
||||||
tyString, err := c.buildType(defineStruct)
|
propertiesString, err := c.buildProperties(defineStruct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
t := template.Must(template.New("componentType").Parse(componentTemplate))
|
getSetString, err := c.buildGetterSetter(defineStruct)
|
||||||
return t.Execute(fp, map[string]string{
|
if err != nil {
|
||||||
"componentType": tyString,
|
return err
|
||||||
"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
|
superClassName := "HttpData"
|
||||||
}
|
|
||||||
|
|
||||||
func (c *componentsContext) writeType(writer io.Writer, defineStruct spec.DefineStruct) error {
|
|
||||||
responseData := "HttpData"
|
|
||||||
for _, item := range c.responseTypes {
|
for _, item := range c.responseTypes {
|
||||||
if item.Name() == defineStruct.Name() {
|
if item.Name() == defineStruct.Name() {
|
||||||
responseData = "HttpResponseData"
|
superClassName = "HttpResponseData"
|
||||||
if !stringx.Contains(c.imports, httpResponseData) {
|
if !stringx.Contains(c.imports, httpResponseData) {
|
||||||
c.imports = append(c.imports, httpResponseData)
|
c.imports = append(c.imports, httpResponseData)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if responseData == "HttpData" && !stringx.Contains(c.imports, httpData) {
|
if superClassName == "HttpData" && !stringx.Contains(c.imports, httpData) {
|
||||||
c.imports = append(c.imports, httpData)
|
c.imports = append(c.imports, httpData)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(writer, "public class %s extends %s {\n", util.Title(defineStruct.Name()), responseData)
|
params, constructorSetter, err := c.buildConstructor()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer := new(bytes.Buffer)
|
||||||
|
t := template.Must(template.New("componentType").Parse(componentTemplate))
|
||||||
|
err = t.Execute(buffer, map[string]interface{}{
|
||||||
|
"properties": propertiesString,
|
||||||
|
"params": params,
|
||||||
|
"constructorSetter": constructorSetter,
|
||||||
|
"getSet": getSetString,
|
||||||
|
"packet": packetName,
|
||||||
|
"imports": strings.Join(c.imports, "\n"),
|
||||||
|
"className": util.Title(defineStruct.Name()),
|
||||||
|
"superClassName": superClassName,
|
||||||
|
"HasProperty": len(strings.TrimSpace(propertiesString)) > 0,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fp.WriteString(formatSource(buffer.String()))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *componentsContext) buildProperties(defineStruct spec.DefineStruct) (string, error) {
|
||||||
|
var builder strings.Builder
|
||||||
|
if err := c.writeType(&builder, defineStruct); err != nil {
|
||||||
|
return "", apiutil.WrapErr(err, "Type "+defineStruct.Name()+" generate error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *componentsContext) buildGetterSetter(defineStruct spec.DefineStruct) (string, error) {
|
||||||
|
var builder strings.Builder
|
||||||
|
if err := c.genGetSet(&builder, defineStruct, 1); err != nil {
|
||||||
|
return "", apiutil.WrapErr(err, "Type "+defineStruct.Name()+" get or set generate error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *componentsContext) writeType(writer io.Writer, defineStruct spec.DefineStruct) error {
|
||||||
|
c.members = make([]spec.Member, 0)
|
||||||
err := c.writeMembers(writer, defineStruct, 1)
|
err := c.writeMembers(writer, defineStruct, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
genGetSet(writer, defineStruct, 1)
|
|
||||||
fmt.Fprintf(writer, "}")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentsContext) writeMembers(writer io.Writer, ty spec.DefineStruct, indent int) error {
|
func (c *componentsContext) writeMembers(writer io.Writer, defineStruct spec.DefineStruct, indent int) error {
|
||||||
for _, member := range ty.Members {
|
for _, member := range defineStruct.Members {
|
||||||
if member.IsInline {
|
if member.IsInline {
|
||||||
defineStruct, ok := member.Type.(spec.DefineStruct)
|
defineStruct, ok := member.Type.(spec.DefineStruct)
|
||||||
if ok {
|
if ok {
|
||||||
@@ -160,7 +227,113 @@ func (c *componentsContext) writeMembers(writer io.Writer, ty spec.DefineStruct,
|
|||||||
if err := writeProperty(writer, member, indent); err != nil {
|
if err := writeProperty(writer, member, indent); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.members = append(c.members, member)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *componentsContext) buildConstructor() (string, string, error) {
|
||||||
|
var params strings.Builder
|
||||||
|
var constructorSetter strings.Builder
|
||||||
|
for index, member := range c.members {
|
||||||
|
tp, err := specTypeToJava(member.Type)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
params.WriteString(fmt.Sprintf("%s %s", tp, util.Untitle(member.Name)))
|
||||||
|
pn, err := member.GetPropertyName()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if index != len(c.members)-1 {
|
||||||
|
params.WriteString(", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
writeIndent(&constructorSetter, 2)
|
||||||
|
constructorSetter.WriteString(fmt.Sprintf("this.%s = %s;", pn, util.Untitle(member.Name)))
|
||||||
|
if index != len(c.members)-1 {
|
||||||
|
constructorSetter.WriteString(util.NL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params.String(), constructorSetter.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *componentsContext) genGetSet(writer io.Writer, defineStruct spec.DefineStruct, indent int) error {
|
||||||
|
var members = defineStruct.GetBodyMembers()
|
||||||
|
members = append(members, defineStruct.GetFormMembers()...)
|
||||||
|
for _, member := range members {
|
||||||
|
javaType, err := specTypeToJava(member.Type)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var property = util.Title(member.Name)
|
||||||
|
var templateStr = getSetTemplate
|
||||||
|
if javaType == "boolean" {
|
||||||
|
templateStr = boolTemplate
|
||||||
|
property = strings.TrimPrefix(property, "Is")
|
||||||
|
property = strings.TrimPrefix(property, "is")
|
||||||
|
}
|
||||||
|
t := template.Must(template.New(templateStr).Parse(getSetTemplate))
|
||||||
|
var tmplBytes bytes.Buffer
|
||||||
|
|
||||||
|
tyString := javaType
|
||||||
|
decorator := ""
|
||||||
|
javaPrimitiveType := []string{"int", "long", "boolean", "float", "double", "short"}
|
||||||
|
if !stringx.Contains(javaPrimitiveType, javaType) {
|
||||||
|
if member.IsOptional() || member.IsOmitEmpty() {
|
||||||
|
decorator = "@Nullable "
|
||||||
|
} else {
|
||||||
|
decorator = "@NotNull "
|
||||||
|
}
|
||||||
|
tyString = decorator + tyString
|
||||||
|
}
|
||||||
|
|
||||||
|
tagName, err := member.GetPropertyName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = t.Execute(&tmplBytes, map[string]string{
|
||||||
|
"property": property,
|
||||||
|
"propertyValue": util.Untitle(member.Name),
|
||||||
|
"tagValue": tagName,
|
||||||
|
"type": tyString,
|
||||||
|
"decorator": decorator,
|
||||||
|
"returnType": javaType,
|
||||||
|
"indent": indentString(indent),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := tmplBytes.String()
|
||||||
|
r = strings.Replace(r, " boolean get", " boolean is", 1)
|
||||||
|
writer.Write([]byte(r))
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatSource(source string) string {
|
||||||
|
var builder strings.Builder
|
||||||
|
scanner := bufio.NewScanner(strings.NewReader(source))
|
||||||
|
preIsBreakLine := false
|
||||||
|
for scanner.Scan() {
|
||||||
|
text := strings.TrimSpace(scanner.Text())
|
||||||
|
if text == "" && preIsBreakLine {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
preIsBreakLine = text == ""
|
||||||
|
builder.WriteString(scanner.Text() + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,43 +1,18 @@
|
|||||||
package javagen
|
package javagen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/tal-tech/go-zero/core/stringx"
|
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
|
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const getSetTemplate = `
|
|
||||||
{{.indent}}{{.decorator}}
|
|
||||||
{{.indent}}public {{.returnType}} get{{.property}}() {
|
|
||||||
{{.indent}} return this.{{.tagValue}};
|
|
||||||
{{.indent}}}
|
|
||||||
|
|
||||||
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
|
|
||||||
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
|
|
||||||
{{.indent}}}
|
|
||||||
`
|
|
||||||
|
|
||||||
const boolTemplate = `
|
|
||||||
{{.indent}}{{.decorator}}
|
|
||||||
{{.indent}}public {{.returnType}} is{{.property}}() {
|
|
||||||
{{.indent}} return this.{{.tagValue}};
|
|
||||||
{{.indent}}}
|
|
||||||
|
|
||||||
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
|
|
||||||
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
|
|
||||||
{{.indent}}}
|
|
||||||
`
|
|
||||||
|
|
||||||
func writeProperty(writer io.Writer, member spec.Member, indent int) error {
|
func writeProperty(writer io.Writer, member spec.Member, indent int) error {
|
||||||
writeIndent(writer, indent)
|
writeIndent(writer, indent)
|
||||||
ty, err := goTypeToJava(member.Type)
|
ty, err := specTypeToJava(member.Type)
|
||||||
ty = strings.Replace(ty, "*", "", 1)
|
ty = strings.Replace(ty, "*", "", 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -53,13 +28,17 @@ func writeProperty(writer io.Writer, member spec.Member, indent int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
writeDefaultValue(writer, member)
|
err = writeDefaultValue(writer, member)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Fprint(writer, ";\n")
|
fmt.Fprint(writer, ";\n")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeDefaultValue(writer io.Writer, member spec.Member) error {
|
func writeDefaultValue(writer io.Writer, member spec.Member) error {
|
||||||
javaType, err := goTypeToJava(member.Type)
|
javaType, err := specTypeToJava(member.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -85,7 +64,7 @@ func indentString(indent int) string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func goTypeToJava(tp spec.Type) (string, error) {
|
func specTypeToJava(tp spec.Type) (string, error) {
|
||||||
switch v := tp.(type) {
|
switch v := tp.(type) {
|
||||||
case spec.DefineStruct:
|
case spec.DefineStruct:
|
||||||
return util.Title(tp.Name()), nil
|
return util.Title(tp.Name()), nil
|
||||||
@@ -96,7 +75,7 @@ func goTypeToJava(tp spec.Type) (string, error) {
|
|||||||
}
|
}
|
||||||
return r, nil
|
return r, nil
|
||||||
case spec.MapType:
|
case spec.MapType:
|
||||||
valueType, err := goTypeToJava(v.Value)
|
valueType, err := specTypeToJava(v.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -107,16 +86,29 @@ func goTypeToJava(tp spec.Type) (string, error) {
|
|||||||
return "byte[]", nil
|
return "byte[]", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
valueType, err := goTypeToJava(v.Value)
|
valueType, err := specTypeToJava(v.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch valueType {
|
||||||
|
case "int":
|
||||||
|
return "Integer[]", nil
|
||||||
|
case "long":
|
||||||
|
return "Long[]", nil
|
||||||
|
case "float":
|
||||||
|
return "Float[]", nil
|
||||||
|
case "double":
|
||||||
|
return "Double[]", nil
|
||||||
|
case "boolean":
|
||||||
|
return "Boolean[]", nil
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("java.util.ArrayList<%s>", util.Title(valueType)), nil
|
return fmt.Sprintf("java.util.ArrayList<%s>", util.Title(valueType)), nil
|
||||||
case spec.InterfaceType:
|
case spec.InterfaceType:
|
||||||
return "Object", nil
|
return "Object", nil
|
||||||
case spec.PointerType:
|
case spec.PointerType:
|
||||||
return goTypeToJava(v.Type)
|
return specTypeToJava(v.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", errors.New("unsupported primitive type " + tp.Name())
|
return "", errors.New("unsupported primitive type " + tp.Name())
|
||||||
@@ -130,7 +122,9 @@ func primitiveType(tp string) (string, bool) {
|
|||||||
return "long", true
|
return "long", true
|
||||||
case "int", "int8", "int32", "uint", "uint8", "uint16", "uint32":
|
case "int", "int8", "int32", "uint", "uint8", "uint16", "uint32":
|
||||||
return "int", true
|
return "int", true
|
||||||
case "float", "float32", "float64":
|
case "float", "float32":
|
||||||
|
return "float", true
|
||||||
|
case "float64":
|
||||||
return "double", true
|
return "double", true
|
||||||
case "bool":
|
case "bool":
|
||||||
return "boolean", true
|
return "boolean", true
|
||||||
@@ -138,59 +132,3 @@ func primitiveType(tp string) (string, bool) {
|
|||||||
|
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
func genGetSet(writer io.Writer, defineStruct spec.DefineStruct, indent int) error {
|
|
||||||
var members = defineStruct.GetBodyMembers()
|
|
||||||
members = append(members, defineStruct.GetFormMembers()...)
|
|
||||||
for _, member := range members {
|
|
||||||
javaType, err := goTypeToJava(member.Type)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var property = util.Title(member.Name)
|
|
||||||
var templateStr = getSetTemplate
|
|
||||||
if javaType == "boolean" {
|
|
||||||
templateStr = boolTemplate
|
|
||||||
property = strings.TrimPrefix(property, "Is")
|
|
||||||
property = strings.TrimPrefix(property, "is")
|
|
||||||
}
|
|
||||||
t := template.Must(template.New(templateStr).Parse(getSetTemplate))
|
|
||||||
var tmplBytes bytes.Buffer
|
|
||||||
|
|
||||||
tyString := javaType
|
|
||||||
decorator := ""
|
|
||||||
javaPrimitiveType := []string{"int", "long", "boolean", "float", "double", "short"}
|
|
||||||
if !stringx.Contains(javaPrimitiveType, javaType) {
|
|
||||||
if member.IsOptional() || member.IsOmitEmpty() {
|
|
||||||
decorator = "@Nullable "
|
|
||||||
} else {
|
|
||||||
decorator = "@NotNull "
|
|
||||||
}
|
|
||||||
tyString = decorator + tyString
|
|
||||||
}
|
|
||||||
|
|
||||||
tagName, err := member.GetPropertyName()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = t.Execute(&tmplBytes, map[string]string{
|
|
||||||
"property": property,
|
|
||||||
"propertyValue": util.Untitle(member.Name),
|
|
||||||
"tagValue": tagName,
|
|
||||||
"type": tyString,
|
|
||||||
"decorator": decorator,
|
|
||||||
"returnType": javaType,
|
|
||||||
"indent": indentString(indent),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
r := tmplBytes.String()
|
|
||||||
r = strings.Replace(r, " boolean get", " boolean is", 1)
|
|
||||||
writer.Write([]byte(r))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
|
|
||||||
)
|
|
||||||
|
|
||||||
var emptyType spec.Type
|
|
||||||
Reference in New Issue
Block a user