JavaApiListener.go 4.8 KB
Newer Older
P
Phodal Huang 已提交
1 2 3
package api

import (
P
Phodal Huang 已提交
4
	"github.com/antlr/antlr4/runtime/Go/antlr"
P
Phodal Huang 已提交
5
	"github.com/phodal/coca/adapter/models"
P
Phodal Huang 已提交
6
	. "github.com/phodal/coca/language/java"
P
Phodal Huang 已提交
7
	"reflect"
P
Phodal Huang 已提交
8 9 10
	"strings"
)

P
Phodal Huang 已提交
11
var jClassNodes []models.JClassNode
P
Phodal Huang 已提交
12

P
Phodal Huang 已提交
13
type RestApi struct {
P
Phodal Huang 已提交
14 15 16 17 18 19
	Uri              string
	HttpMethod       string
	MethodName       string
	ResponseStatus   string
	RequestBodyClass string
	MethodParams     map[string]string
P
Phodal Huang 已提交
20 21 22 23 24 25
}

var hasEnterClass = false
var isSpringRestController = false
var hasEnterRestController = false
var baseApiUrlName = ""
P
Phodal Huang 已提交
26
var localVars = make(map[string]string)
P
Phodal Huang 已提交
27 28 29 30

var currentRestApi RestApi
var RestApis []RestApi

P
Phodal Huang 已提交
31
func NewJavaApiListener() *JavaApiListener {
P
Phodal Huang 已提交
32
	isSpringRestController = false
P
Phodal Huang 已提交
33 34
	params := make(map[string]string)
	currentRestApi = *&RestApi{"", "", "", "", "", params}
P
Phodal Huang 已提交
35
	return &JavaApiListener{}
P
Phodal Huang 已提交
36 37
}

P
Phodal Huang 已提交
38
type JavaApiListener struct {
P
Phodal Huang 已提交
39 40 41
	BaseJavaParserListener
}

P
Phodal Huang 已提交
42
func (s *JavaApiListener) EnterClassDeclaration(ctx *ClassDeclarationContext) {
P
Phodal Huang 已提交
43 44 45
	hasEnterClass = true
}

P
Phodal Huang 已提交
46
func (s *JavaApiListener) EnterAnnotation(ctx *AnnotationContext) {
P
Phodal Huang 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
	annotationName := ctx.QualifiedName().GetText()
	if annotationName == "RestController" {
		isSpringRestController = true
	}

	if !isSpringRestController {
		return
	}

	if !hasEnterClass {
		if annotationName == "RequestMapping" {
			if ctx.ElementValuePairs() != nil {
				firstPair := ctx.ElementValuePairs().GetChild(0).(*ElementValuePairContext)
				if firstPair.IDENTIFIER().GetText() == "value" {
					baseApiUrlName = firstPair.ElementValue().GetText()
				}
			} else {
				baseApiUrlName = "/"
			}
		}
	}

	if !(annotationName == "GetMapping" || annotationName == "PutMapping" || annotationName == "PostMapping" || annotationName == "DeleteMapping") {
		return
	}

	hasEnterRestController = true
	uri := ""
	if ctx.ElementValue() != nil {
		uri = baseApiUrlName + ctx.ElementValue().GetText()
	} else {
		uri = baseApiUrlName
	}

	uriRemoveQuote := strings.ReplaceAll(uri, "\"", "")

P
Phodal Huang 已提交
83
	currentRestApi = RestApi{uriRemoveQuote, "", "", "", "", nil}
P
Phodal Huang 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97
	if hasEnterClass {
		switch annotationName {
		case "GetMapping":
			currentRestApi.HttpMethod = "GET"
		case "PutMapping":
			currentRestApi.HttpMethod = "PUT"
		case "PostMapping":
			currentRestApi.HttpMethod = "POST"
		case "DeleteMapping":
			currentRestApi.HttpMethod = "DELETE"
		}
	}
}

P
Phodal Huang 已提交
98 99
var requestBodyClass string

P
Phodal Huang 已提交
100
func (s *JavaApiListener) EnterMethodDeclaration(ctx *MethodDeclarationContext) {
P
Phodal Huang 已提交
101 102 103 104 105
	if hasEnterRestController && ctx.FormalParameters() != nil {
		if ctx.FormalParameters().GetChild(0) == nil || ctx.FormalParameters().GetText() == "()" || ctx.FormalParameters().GetChild(1) == nil {
			return
		}

P
Phodal Huang 已提交
106 107
		buildRestApi(ctx)
	}
P
Phodal Huang 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

	methodBody := ctx.MethodBody()
	blockContext := methodBody.GetChild(0)
	if reflect.TypeOf(blockContext).String() == "*parser.BlockContext" {
		filterMethodCall(blockContext)
	}
}

func filterMethodCall(blockContext antlr.Tree) {
	blcStatement := blockContext.(*BlockContext).AllBlockStatement()
	for _, rangeStatement := range blcStatement {
		if reflect.TypeOf(rangeStatement.GetChild(0)).String() == "*parser.StatementContext" {
			statement := rangeStatement.GetChild(0).(*StatementContext)
			if reflect.TypeOf(statement.GetChild(0)).String() == "*parser.ExpressionContext" {
				express := statement.GetChild(0).(*ExpressionContext)
P
Phodal Huang 已提交
123
				reflect.TypeOf(express.GetChild(0))
P
Phodal Huang 已提交
124 125 126
			}
		}
	}
P
Phodal Huang 已提交
127
}
P
Phodal Huang 已提交
128

P
Phodal Huang 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
func buildRestApi(ctx *MethodDeclarationContext) {
	parameterList := ctx.FormalParameters().GetChild(1).(*FormalParameterListContext)
	formalParameter := parameterList.AllFormalParameter()
	for _, param := range formalParameter {
		paramContext := param.(*FormalParameterContext)

		modifiers := paramContext.AllVariableModifier()
		hasRequestBody := false
		for _, modifier := range modifiers {
			childType := reflect.TypeOf(modifier.GetChild(0))
			if childType.String() == "*parser.AnnotationContext" {
				qualifiedName := modifier.GetChild(0).(*AnnotationContext).QualifiedName().GetText()
				if qualifiedName == "RequestBody" {
					hasRequestBody = true
				}
P
Phodal Huang 已提交
144 145 146
			}
		}

P
Phodal Huang 已提交
147 148
		paramType := paramContext.TypeType().GetText()
		paramValue := paramContext.VariableDeclaratorId().(*VariableDeclaratorIdContext).IDENTIFIER().GetText()
P
Phodal Huang 已提交
149

P
Phodal Huang 已提交
150 151 152
		if hasRequestBody {
			requestBodyClass = paramType
		}
P
Phodal Huang 已提交
153

P
Phodal Huang 已提交
154
		localVars[paramValue] = paramType
P
Phodal Huang 已提交
155
	}
P
Phodal Huang 已提交
156 157 158
	currentRestApi.RequestBodyClass = requestBodyClass

	buildMethodParameters(requestBodyClass)
P
Phodal Huang 已提交
159

P
Phodal Huang 已提交
160 161 162
	hasEnterRestController = false
	requestBodyClass = ""
	RestApis = append(RestApis, currentRestApi)
P
Phodal Huang 已提交
163
}
P
Phodal Huang 已提交
164

P
Phodal Huang 已提交
165 166 167 168 169 170 171 172 173 174 175 176 177
func buildMethodParameters(requestBodyClass string) {
	params := make(map[string]string)
	for _, clz := range jClassNodes {
		if clz.Class == requestBodyClass {
			for _, field := range clz.Fields {
				params[field.Value] = field.Type
			}
		}
	}

	currentRestApi.MethodParams = params
}

P
Phodal Huang 已提交
178
func (s *JavaApiListener) appendClasses(classes []models.JClassNode) {
P
Phodal Huang 已提交
179
	jClassNodes = classes
P
Phodal Huang 已提交
180
}
P
Phodal Huang 已提交
181

P
Phodal Huang 已提交
182
func (s *JavaApiListener) getClassApis() []RestApi {
P
Phodal Huang 已提交
183 184
	return RestApis
}