From 5d3d18b7fe156e226e2ed76e3625a1b8d6af49a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9B=E5=93=A5?= Date: Thu, 18 Nov 2021 11:40:23 +0800 Subject: [PATCH] fix go type name for list (#290) * fix go name of POJO for list * split import * rename var * re-order imports * rename --- Makefile | 4 +-- hessian_test/dup_struct_name_test.go | 5 +++ java_unknown_exception_test.go | 2 +- list.go | 6 ++-- pojo.go | 40 +++++++++++++----------- pojo_test.go | 46 ++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 pojo_test.go diff --git a/Makefile b/Makefile index 01238971..c81a38a2 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,9 @@ lint2: golangci-lint run format: - go fmt + gofmt -l -w . test: - go test + go test ./... -v all: format test \ No newline at end of file diff --git a/hessian_test/dup_struct_name_test.go b/hessian_test/dup_struct_name_test.go index 5e8f1494..0c34d44d 100644 --- a/hessian_test/dup_struct_name_test.go +++ b/hessian_test/dup_struct_name_test.go @@ -181,3 +181,8 @@ func checkResponseBody(t *testing.T, decodedResponse *hessian.Response, h *hessi out, _ := hessian.EnsureInterface(hessian.UnpackPtrValue(hessian.EnsurePackValue(decodedResponse.RspObj)), nil) assert.Equal(t, in, out) } + +func TestDuplicatedClassGetGoType(t *testing.T) { + assert.Equal(t, "github.com/apache/dubbo-go-hessian2/hessian_test_test/hessian_test.CaseZ", hessian.GetGoType(&CaseZ{})) + assert.Equal(t, "github.com/apache/dubbo-go-hessian2/hessian_test/hessian_test/hessian_test.CaseZ", hessian.GetGoType(&dupclass.CaseZ{})) +} diff --git a/java_unknown_exception_test.go b/java_unknown_exception_test.go index 8f2743e8..264beafd 100644 --- a/java_unknown_exception_test.go +++ b/java_unknown_exception_test.go @@ -34,7 +34,7 @@ func TestCheckAndGetException(t *testing.T) { assert.True(t, b) assert.Equal(t, s.javaName, "com.test.UserDefinedException") - assert.Equal(t, s.goName, "hessian.UnknownException") + assert.Equal(t, s.goName, "github.com/apache/dubbo-go-hessian2/hessian.UnknownException") clazzInfo2 := &classInfo{ javaName: "com.test.UserDefinedException", diff --git a/list.go b/list.go index 94603c80..0eeef747 100644 --- a/list.go +++ b/list.go @@ -70,9 +70,9 @@ func init() { listTypeNameMapper.Store("float64", "[double") listTypeNameMapper.Store("bool", "[boolean") listTypeNameMapper.Store("time.Time", "[date") - listTypeNameMapper.Store("java_exception.Throwabler", "[java.lang.Throwable") + listTypeNameMapper.Store("github.com/apache/dubbo-go-hessian2/java_exception/java_exception.Throwabler", "[java.lang.Throwable") - listTypeNameMapper.Store("hessian.Object", "[object") + listTypeNameMapper.Store("github.com/apache/dubbo-go-hessian2/hessian.Object", "[object") } func registerTypeName(gotype, javatype string) { @@ -161,7 +161,7 @@ func (e *Encoder) writeTypedList(v interface{}) error { value = UnpackPtrValue(value) goType := UnpackPtrType(value.Type().Elem()) - totype := combineGoName(goType) + totype := combineGoTypeName(goType) typeName := getListTypeName(totype) if typeName == "" { return perrors.New("no this type name: " + totype) diff --git a/pojo.go b/pojo.go index 1257e9db..273ef7c7 100644 --- a/pojo.go +++ b/pojo.go @@ -20,7 +20,6 @@ package hessian import ( "fmt" "reflect" - "regexp" "strings" "sync" "unicode" @@ -102,9 +101,6 @@ var ( } pojoType = reflect.TypeOf((*POJO)(nil)).Elem() javaEnumType = reflect.TypeOf((*POJOEnum)(nil)).Elem() - - goPkgPathWhiteListRegexp = regexp.MustCompile(`^(github\.com/apache/dubbo-go-hessian2|time)`) - goPkgPathBlackListRegexp = regexp.MustCompile(`^(github\.com/apache/dubbo-go-hessian2/hessian_test)`) ) // struct parsing @@ -148,7 +144,7 @@ func RegisterPOJOMapping(javaClassName string, o interface{}) int { ) sttInfo.typ = obtainValueType(o) - sttInfo.goName = getGoName(o) + sttInfo.goName = GetGoType(o) sttInfo.javaName = javaClassName sttInfo.inst = o pojoRegistry.j2g[sttInfo.javaName] = sttInfo.goName @@ -229,7 +225,7 @@ func unRegisterPOJO(o POJO) int { pojoRegistry.Lock() defer pojoRegistry.Unlock() - goName := getGoName(o) + goName := GetGoType(o) if structInfo, ok := pojoRegistry.registry[goName]; ok { delete(pojoRegistry.j2g, structInfo.javaName) @@ -244,20 +240,28 @@ func unRegisterPOJO(o POJO) int { return -1 } -func getGoName(o interface{}) string { - goType := reflect.TypeOf(o) - for reflect.Ptr == goType.Kind() { - goType = goType.Elem() - } - return combineGoName(goType) +// GetGoType get the raw go type name with package. +func GetGoType(o interface{}) string { + return combineGoTypeName(reflect.TypeOf(o)) } -func combineGoName(t reflect.Type) string { +func combineGoTypeName(t reflect.Type) string { + for reflect.Ptr == t.Kind() { + t = t.Elem() + } + + if reflect.Slice == t.Kind() { + goName := t.String() + sliceArrayPrefixIndex := strings.LastIndex(goName, "]") + for reflect.Slice == t.Kind() { + t = t.Elem() + } + return goName[:sliceArrayPrefixIndex+1] + combineGoTypeName(t) + } + pkgPath := t.PkgPath() goName := t.String() - if pkgPath == "" || - (goPkgPathWhiteListRegexp.Match([]byte(pkgPath)) && - !goPkgPathBlackListRegexp.Match([]byte(pkgPath))) { + if pkgPath == "" || strings.HasPrefix(goName, pkgPath) { return goName } return pkgPath + "/" + goName @@ -312,7 +316,7 @@ func RegisterJavaEnum(o POJOEnum) int { default: t.typ = reflect.TypeOf(o) } - t.goName = getGoName(o) + t.goName = GetGoType(o) t.javaName = o.JavaClassName() t.inst = o pojoRegistry.j2g[t.javaName] = t.goName @@ -355,7 +359,7 @@ func loadPOJORegistry(v interface{}) (*structInfo, bool) { ok bool s *structInfo ) - goName := getGoName(v) + goName := GetGoType(v) pojoRegistry.RLock() s, ok = pojoRegistry.registry[goName] pojoRegistry.RUnlock() diff --git a/pojo_test.go b/pojo_test.go new file mode 100644 index 00000000..cf839b17 --- /dev/null +++ b/pojo_test.go @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package hessian + +import ( + "bytes" + "container/list" + "testing" + "time" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go-hessian2/java_exception" + "github.com/apache/dubbo-go-hessian2/java_util" +) + +func TestGetGoType(t *testing.T) { + assert.Equal(t, "time.Time", GetGoType(time.Now())) + assert.Equal(t, "bytes.Buffer", GetGoType(bytes.Buffer{})) + assert.Equal(t, "container/list/list.List", GetGoType(list.New())) + assert.Equal(t, "github.com/apache/dubbo-go-hessian2/hessian.BusinessData", GetGoType(&BusinessData{})) + assert.Equal(t, "github.com/apache/dubbo-go-hessian2/java_util/java_util.UUID", GetGoType(&java_util.UUID{})) + assert.Equal(t, "github.com/apache/dubbo-go-hessian2/java_exception/java_exception.ClassNotFoundException", GetGoType(&java_exception.ClassNotFoundException{})) + + assert.Equal(t, "[]github.com/apache/dubbo-go-hessian2/hessian.BusinessData", GetGoType([]*BusinessData{})) + assert.Equal(t, "[][]github.com/apache/dubbo-go-hessian2/hessian.BusinessData", GetGoType([][]*BusinessData{})) +}