Skip to content

Commit

Permalink
Merge pull request #222 from apache/master
Browse files Browse the repository at this point in the history
merge for v1.6.3
  • Loading branch information
wongoo authored Sep 3, 2020
2 parents 7370d4e + ef54e11 commit a93b11c
Show file tree
Hide file tree
Showing 21 changed files with 647 additions and 35 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ thanks to [micln](https://github.com/micln), [pantianying](https://github.com/pa
* [Field Alias By Alias](https://github.com/apache/dubbo-go-hessian2/issues/19)
* [Java Bigdecimal](https://github.com/apache/dubbo-go-hessian2/issues/89)
* [Java Date & Time](https://github.com/apache/dubbo-go-hessian2/issues/90)
* [java8 time.Date](https://github.com/apache/dubbo-go-hessian2/pull/212)
* [java8 java.sql.Time & java.sql.Date](https://github.com/apache/dubbo-go-hessian2/pull/219)
* [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)
Expand Down
4 changes: 2 additions & 2 deletions hessian.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (h *HessianCodec) ReadBody(rspObj interface{}) error {
}

// ignore body, but only read attachments
func (h *HessianCodec) ReadAttachments() (map[string]string, error) {
func (h *HessianCodec) ReadAttachments() (map[string]interface{}, error) {
if h.reader.Buffered() < h.bodyLen {
return nil, ErrBodyNotEnough
}
Expand All @@ -237,7 +237,7 @@ func (h *HessianCodec) ReadAttachments() (map[string]string, error) {
if err = unpackRequestBody(NewDecoderWithSkip(buf[:]), rspObj); err != nil {
return nil, perrors.WithStack(err)
}
return rspObj[6].(map[string]string), nil
return rspObj[6].(map[string]interface{}), nil
case PackageResponse:
rspObj := &Response{}
if err = unpackResponseBody(NewDecoderWithSkip(buf[:]), rspObj); err != nil {
Expand Down
15 changes: 13 additions & 2 deletions hessian_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,14 @@ func TestRequest(t *testing.T) {
}

func TestHessianCodec_ReadAttachments(t *testing.T) {
RegisterPOJO(&AttachObject{})
body := &Response{
RspObj: &CaseB{A: "A", B: CaseA{A: "a", B: 1, C: Case{A: "c", B: 2}}},
Exception: nil,
Attachments: map[string]string{DUBBO_VERSION_KEY: "2.6.4"},
Attachments: map[string]interface{}{DUBBO_VERSION_KEY: "2.6.4", "att": AttachObject{Id: 23, Name: "haha"}},
}
resp, err := doTestHessianEncodeHeader(t, PackageResponse, Response_OK, body)
assert.NoError(t, err)

unRegisterPOJOs(&CaseB{}, &CaseA{})
codecR1 := NewHessianCodec(bufio.NewReader(bytes.NewReader(resp)))
codecR2 := NewHessianCodec(bufio.NewReader(bytes.NewReader(resp)))
Expand All @@ -214,6 +214,17 @@ func TestHessianCodec_ReadAttachments(t *testing.T) {
attrs, err := codecR2.ReadAttachments()
assert.NoError(t, err)
assert.Equal(t, "2.6.4", attrs[DUBBO_VERSION_KEY])
assert.Equal(t, AttachObject{Id: 23, Name: "haha"}, *(attrs["att"].(*AttachObject)))
assert.NotEqual(t, AttachObject{Id: 24, Name: "nohaha"}, *(attrs["att"].(*AttachObject)))

t.Log(attrs)
}

type AttachObject struct {
Id int32
Name string `dubbo:name`
}

func (AttachObject) JavaClassName() string {
return "com.test.Test"
}
7 changes: 6 additions & 1 deletion java8_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ func init() {
RegisterPOJO(&java8_time.Period{Years: 2020, Months: 6, Days: 6})
RegisterPOJO(&java8_time.LocalDate{Year: 2020, Month: 6, Day: 6})
RegisterPOJO(&java8_time.LocalTime{Hour: 6, Minute: 6, Second: 0, Nano: 0})
RegisterPOJO(&java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6}})
RegisterPOJO(&java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}})
RegisterPOJO(&java8_time.MonthDay{Month: 6, Day: 6})
RegisterPOJO(&java8_time.Duration{Second: 0, Nano: 0})
RegisterPOJO(&java8_time.Instant{Seconds: 100, Nanos: 0})
RegisterPOJO(&java8_time.ZoneOffSet{Seconds: 0})
RegisterPOJO(&java8_time.OffsetDateTime{DateTime: java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}}, Offset: java8_time.ZoneOffSet{Seconds: -64800}})
RegisterPOJO(&java8_time.OffsetTime{LocalTime: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}, ZoneOffset: java8_time.ZoneOffSet{Seconds: -64800}})
RegisterPOJO(&java8_time.ZonedDateTime{DateTime: java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}}, Offset: java8_time.ZoneOffSet{Seconds: 0}, ZoneId: "Z"})

}
31 changes: 31 additions & 0 deletions java8_time/offset_date_time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 java8_time

type OffsetDateTime struct {
DateTime LocalDateTime `hessian:"dateTime"`
Offset ZoneOffSet `hessian:"offset"`
}

func (OffsetDateTime) JavaClassName() string {
return "com.alibaba.com.caucho.hessian.io.java8.OffsetDateTimeHandle"
}

func (OffsetDateTime) Error() string {
return "encode OffsetDateTime error"
}
31 changes: 31 additions & 0 deletions java8_time/offset_time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 java8_time

type OffsetTime struct {
LocalTime LocalTime `hessian:"localTime"`
ZoneOffset ZoneOffSet `hessian:"zoneOffset"`
}

func (OffsetTime) JavaClassName() string {
return "com.alibaba.com.caucho.hessian.io.java8.OffsetTimeHandle"
}

func (OffsetTime) Error() string {
return "encode OffsetDateTime error"
}
30 changes: 30 additions & 0 deletions java8_time/zone_off_set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 java8_time

type ZoneOffSet struct {
Seconds int32 `hessian:"seconds"`
}

func (ZoneOffSet) JavaClassName() string {
return "com.alibaba.com.caucho.hessian.io.java8.ZoneOffsetHandle"
}

func (ZoneOffSet) Error() string {
return "encode ZoneOffSet error"
}
32 changes: 32 additions & 0 deletions java8_time/zoned_date_time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 java8_time

type ZonedDateTime struct {
DateTime LocalDateTime `hessian:"dateTime"`
Offset ZoneOffSet `hessian:"offset"`
ZoneId string `hessian:"zoneId"`
}

func (ZonedDateTime) JavaClassName() string {
return "com.alibaba.com.caucho.hessian.io.java8.ZonedDateTimeHandle"
}

func (ZonedDateTime) Error() string {
return "encode ZonedDateTime error"
}
6 changes: 5 additions & 1 deletion java8_time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ func TestJava8Time(t *testing.T) {
doTestTime(t, "java8_Year", &java8_time.Year{Year: 2020})
doTestTime(t, "java8_LocalDate", &java8_time.LocalDate{Year: 2020, Month: 6, Day: 6})
doTestTime(t, "java8_LocalTime", &java8_time.LocalTime{Hour: 6, Minute: 6})
doTestTime(t, "java8_LocalDateTime", &java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6}})
doTestTime(t, "java8_LocalDateTime", &java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}})
doTestTime(t, "java8_MonthDay", &java8_time.MonthDay{Month: 6, Day: 6})
doTestTime(t, "java8_Duration", &java8_time.Duration{Second: 0, Nano: 0})
doTestTime(t, "java8_Instant", &java8_time.Instant{Seconds: 100, Nanos: 0})
doTestTime(t, "java8_YearMonth", &java8_time.YearMonth{Year: 2020, Month: 6})
doTestTime(t, "java8_Period", &java8_time.Period{Years: 2020, Months: 6, Days: 6})
doTestTime(t, "java8_ZoneOffset", &java8_time.ZoneOffSet{Seconds: 0})
doTestTime(t, "java8_OffsetDateTime", &java8_time.OffsetDateTime{DateTime: java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}}, Offset: java8_time.ZoneOffSet{Seconds: -64800}})
doTestTime(t, "java8_OffsetTime", &java8_time.OffsetTime{LocalTime: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}, ZoneOffset: java8_time.ZoneOffSet{Seconds: -64800}})
doTestTime(t, "java8_ZonedDateTime", &java8_time.ZonedDateTime{DateTime: java8_time.LocalDateTime{Date: java8_time.LocalDate{Year: 2020, Month: 6, Day: 6}, Time: java8_time.LocalTime{Hour: 6, Minute: 6, Second: 6, Nano: 6}}, Offset: java8_time.ZoneOffSet{Seconds: 0}, ZoneId: "Z"})
}

func doTestTime(t *testing.T, method string, expected interface{}) {
Expand Down
145 changes: 145 additions & 0 deletions java_sql_time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* 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 (
"io"
"reflect"
)

import (
perrors "github.com/pkg/errors"
)

import (
"github.com/apache/dubbo-go-hessian2/java_sql_time"
)

func init() {
RegisterPOJO(&java_sql_time.Date{})
RegisterPOJO(&java_sql_time.Time{})
SetJavaSqlTimeSerialize(&java_sql_time.Date{})
SetJavaSqlTimeSerialize(&java_sql_time.Time{})
}

// SetJavaSqlTimeSerialize register serializer for java.sql.Time & java.sql.Date
func SetJavaSqlTimeSerialize(time java_sql_time.JavaSqlTime) {
name := time.JavaClassName()
SetSerializer(name, JavaSqlTimeSerializer{})
}

// JavaSqlTimeSerializer used to encode & decode java.sql.Time & java.sql.Date
type JavaSqlTimeSerializer struct {
}

// nolint
func (JavaSqlTimeSerializer) EncObject(e *Encoder, vv POJO) error {

var (
i int
idx int
err error
clsDef classInfo
className string
ptrV reflect.Value
)

// ensure ptrV is pointer to know vv is type JavaSqlTime or not
ptrV = reflect.ValueOf(vv)
if reflect.TypeOf(vv).Kind() != reflect.Ptr {
ptrV = PackPtr(ptrV)
}
v, ok := ptrV.Interface().(java_sql_time.JavaSqlTime)
if !ok {
return perrors.New("can not be converted into java sql time object")
}
className = v.JavaClassName()
if className == "" {
return perrors.New("class name empty")
}
tValue := reflect.ValueOf(vv)
// check ref
if n, ok := e.checkRefMap(tValue); ok {
e.buffer = encRef(e.buffer, n)
return nil
}

// write object definition
idx = -1
for i = range e.classInfoList {
if v.JavaClassName() == e.classInfoList[i].javaName {
idx = i
break
}
}
if idx == -1 {
idx, ok = checkPOJORegistry(typeof(vv))
if !ok {
idx = RegisterPOJO(v)
}
_, clsDef, err = getStructDefByIndex(idx)
if err != nil {
return perrors.WithStack(err)
}
idx = len(e.classInfoList)
e.classInfoList = append(e.classInfoList, clsDef)
e.buffer = append(e.buffer, clsDef.buffer...)
}
e.buffer = e.buffer[0 : len(e.buffer)-1]
e.buffer = encInt32(e.buffer, 1)
e.buffer = encString(e.buffer, "value")

// write object instance
if byte(idx) <= OBJECT_DIRECT_MAX {
e.buffer = encByte(e.buffer, byte(idx)+BC_OBJECT_DIRECT)
} else {
e.buffer = encByte(e.buffer, BC_OBJECT)
e.buffer = encInt32(e.buffer, int32(idx))
}
e.buffer = encDateInMs(e.buffer, v.GetTime())
return nil
}

// nolint
func (JavaSqlTimeSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {

if typ.Kind() != reflect.Struct {
return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
}

vRef := reflect.New(typ)
// add pointer ref so that ref the same object
d.appendRefs(vRef.Interface())

tag, err := d.readByte()
if err == io.EOF {
return nil, err
}
date, err := d.decDate(int32(tag))
if err != nil {
return nil, perrors.WithStack(err)
}
sqlTime := vRef.Interface()

result, ok := sqlTime.(java_sql_time.JavaSqlTime)
if !ok {
panic("result type is not sql time, please check the whether the conversion is ok")
}
result.SetTime(date)
return result, nil
}
Loading

0 comments on commit a93b11c

Please sign in to comment.