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 <zhr...@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;