You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by wo...@apache.org on 2020/03/02 09:24:48 UTC
[dubbo-go-hessian2] branch master updated: Flat anonymous struct
field (#154)
This is an automated email from the ASF dual-hosted git repository.
wongoo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-go-hessian2.git
The following commit(s) were added to refs/heads/master by this push:
new 6ae5479 Flat anonymous struct field (#154)
6ae5479 is described below
commit 6ae5479d93a3c5ef0f9b032554ed920b5a82308b
Author: huiren <zh...@gmail.com>
AuthorDate: Mon Mar 2 17:24:33 2020 +0800
Flat anonymous struct field (#154)
* fix issue 149 - embed struct
* remove serialUID
* mapping extends to all feilds
* flat
* readme
* update readme
---
README.md | 7 +++-
object.go | 37 ++++++++++++-----
object_test.go | 20 ++++++++-
pojo.go | 48 ++++++++++++++++------
.../src/main/java/test/TestCustomDecode.java | 5 +++
5 files changed, 91 insertions(+), 26 deletions(-)
diff --git a/README.md b/README.md
index 5373648..90ddf82 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ It's a golang hessian library used by [Apache/dubbo-go](https://github.com/apach
* [Java Bigdecimal](https://github.com/apache/dubbo-go-hessian2/issues/89)
* [Java Date & Time](https://github.com/apache/dubbo-go-hessian2/issues/90)
* [Java Generic Invokation](https://github.com/apache/dubbo-go-hessian2/issues/84)
+* [Java Extends](https://github.com/apache/dubbo-go-hessian2/issues/157)
* [Dubbo Attachements](https://github.com/apache/dubbo-go-hessian2/issues/49)
* [Skipping unregistered POJO](https://github.com/apache/dubbo-go-hessian2/pull/128)
* [Emoji](https://github.com/apache/dubbo-go-hessian2/issues/129)
@@ -60,11 +61,15 @@ So we can maintain a cross language type mapping:
```go
type Circular struct {
- Num int
+ Value
Previous *Circular
Next *Circular
}
+type Value struct {
+ Num int
+}
+
func (Circular) JavaClassName() string {
return "com.company.Circular"
}
diff --git a/object.go b/object.go
index ba06800..857ae05 100644
--- a/object.go
+++ b/object.go
@@ -160,18 +160,35 @@ func (e *Encoder) encObject(v POJO) error {
e.buffer = encString(e.buffer, v.(POJOEnum).String())
return nil
}
- num = vv.NumField()
- for i = 0; i < num; i++ {
- // skip unexported anonymous field
- if vv.Type().Field(i).PkgPath != "" {
- continue
- }
- field := vv.Field(i)
- if err = e.Encode(field.Interface()); err != nil {
- fieldName := field.Type().String()
- return perrors.Wrapf(err, "failed to encode field: %s, %+v", fieldName, field.Interface())
+ structs := []reflect.Value{vv}
+ for len(structs) > 0 {
+ vv := structs[0]
+ num = vv.NumField()
+ for i = 0; i < num; i++ {
+ // skip unexported anonymous field
+ if vv.Type().Field(i).PkgPath != "" {
+ continue
+ }
+
+ // skip ignored field
+ if tag, _ := vv.Type().Field(i).Tag.Lookup(tagIdentifier); tag == `-` {
+ continue
+ }
+
+ field := vv.Field(i)
+ if vv.Type().Field(i).Anonymous && field.Kind() == reflect.Struct {
+ structs = append(structs, vv.Field(i))
+ continue
+ }
+
+ if err = e.Encode(field.Interface()); err != nil {
+ fieldName := field.Type().String()
+ return perrors.Wrapf(err, "failed to encode field: %s, %+v", fieldName, field.Interface())
+ }
}
+
+ structs = structs[1:]
}
return nil
diff --git a/object_test.go b/object_test.go
index 187661b..81238e1 100644
--- a/object_test.go
+++ b/object_test.go
@@ -563,13 +563,19 @@ type Animal struct {
Name string
}
+type animal struct {
+ Name string
+}
+
func (a Animal) JavaClassName() string {
return "test.Animal"
}
type Dog struct {
Animal
- Gender string
+ animal
+ Gender string
+ DogName string `hessian:"-"`
}
func (dog Dog) JavaClassName() string {
@@ -595,7 +601,7 @@ func TestIssue149_EmbedStructGoDecode(t *testing.T) {
t.Error(err)
}
- want := &Dog{Animal{`a dog`}, `male`}
+ want := &Dog{Animal{`a dog`}, animal{}, `male`, ``}
if !reflect.DeepEqual(got, want) {
t.Errorf("want %v got %v", want, got)
}
@@ -614,3 +620,13 @@ func TestIssue149_EmbedStructGoDecode(t *testing.T) {
}
})
}
+func TestIssue150_EmbedStructJavaDecode(t *testing.T) {
+ RegisterPOJO(&Dog{})
+ RegisterPOJO(&Animal{})
+
+ dog := &Dog{Animal{`a dog`}, animal{}, `male`, `DogName`}
+ bytes, err := encodeTarget(dog)
+ t.Log(string(bytes), err)
+
+ testJavaDecode(t, "customArgTypedFixed_Extends", dog)
+}
diff --git a/pojo.go b/pojo.go
index fb0879c..ed5ab8b 100644
--- a/pojo.go
+++ b/pojo.go
@@ -150,21 +150,43 @@ func RegisterPOJO(o POJO) int {
registerTypeName(structInfo.goName, structInfo.javaName)
// prepare fields info of objectDef
- for i := 0; i < structInfo.typ.NumField(); i++ {
- // skip unexported anonymous filed
- if structInfo.typ.Field(i).PkgPath != "" {
- continue
+ nextStruct := []reflect.Type{structInfo.typ}
+ for len(nextStruct) > 0 {
+ current := nextStruct[0]
+
+ for i := 0; i < current.NumField(); i++ {
+
+ // skip unexported anonymous filed
+ if current.Field(i).PkgPath != "" {
+ continue
+ }
+
+ structField := current.Field(i)
+
+ // skip ignored field
+ tagVal, hasTag := structField.Tag.Lookup(tagIdentifier)
+ if tagVal == `-` {
+ continue
+ }
+
+ // flat anonymous field
+ if structField.Anonymous && structField.Type.Kind() == reflect.Struct {
+ nextStruct = append(nextStruct, structField.Type)
+ continue
+ }
+
+ var fieldName string
+ if hasTag {
+ fieldName = tagVal
+ } else {
+ fieldName = lowerCamelCase(structField.Name)
+ }
+
+ fieldList = append(fieldList, fieldName)
+ bBody = encString(bBody, fieldName)
}
- var fieldName string
- if val, has := structInfo.typ.Field(i).Tag.Lookup(tagIdentifier); has {
- fieldName = val
- } else {
- fieldName = lowerCamelCase(structInfo.typ.Field(i).Name)
- }
-
- fieldList = append(fieldList, fieldName)
- bBody = encString(bBody, fieldName)
+ nextStruct = nextStruct[1:]
}
// prepare header of objectDef
diff --git a/test_hessian/src/main/java/test/TestCustomDecode.java b/test_hessian/src/main/java/test/TestCustomDecode.java
index 9e72a0a..f06fc99 100644
--- a/test_hessian/src/main/java/test/TestCustomDecode.java
+++ b/test_hessian/src/main/java/test/TestCustomDecode.java
@@ -187,6 +187,11 @@ public class TestCustomDecode {
return o.toString().equals("100.256");
}
+ public Object customArgTypedFixed_Extends() throws Exception {
+ Dog o = (Dog) input.readObject();
+ return o.name.equals("a dog") && o.gender.equals("male");
+ }
+
public Object customArgTypedFixed_DateNull() throws Exception {
DateDemo o = (DateDemo) input.readObject();
return o.getDate() == null && o.getDate1() == null;