Skip to content
Permalink
Browse files
Java.util.Locale support (#264)
* add license checker

* dd javaProject java8time test code and add go hessian/java8_time strcut Year and testFunc

* alter author and error word

* add java.util.UUID encode

* Revert "reset go.mod after go fmt"

This reverts commit ab7254f

* add UUID test

* alter .travis.yml

* alter code

* add license

* shift count type int, must be unsigned integer

* alter file name and delete test file

* alter file name

* delete file

* alter file name

* alter file name

* add uuid struct info and split import block.

* add java UUID encode and uuid.toString() equals go uuid.ToString() test func

* alter ToString() -> String()

* fix code review

* add go struct Locale = java:java.util.Locale

* alter Locales is const slice

* alter Locales add clearer definition

* alter locales is private

* add ToLocale() and localeMap

* delete fmt.Sprintf()

* alter Locale struct field unexported

Co-authored-by: zouyixian <zouyixian@shein.com>
Co-authored-by: wilson chen <willson.chenwx@gmail.com>
Co-authored-by: wangoo <wongoo@apache.org>
  • Loading branch information
4 people committed Apr 20, 2021
1 parent 0d0b707 commit b16a9bd6de4924d5aa6fc2861edd1d77259054ae
Showing 6 changed files with 331 additions and 12 deletions.
@@ -26,4 +26,7 @@ func init() {
MostSigBits: int64(200),
LeastSigBits: int64(200),
})
RegisterPOJO(&java_util.LocaleHandle{
Value: "",
})
}
@@ -5,3 +5,7 @@
- dubbo-go-hessian2 cannot create UUID strut
- see jdk source code of class:[java.util.UUID] learning how to create UUID struct
- see https://github.com/satori/go.uuid
2. explain dubbo-go-hession2 strut locale
-java object locale -> go struct Locale (PASS), but currently implemented are objects enumerated in java. See class:java.util.Locale
-First convert to struct LocaleHandle and then call `GetLocaleFromHandler(localeHandler *LocaleHandle)` function to convert to struct Locale
-You can use the `language.ParseBase("zh-CN")` function in the `golang.org/x/text/language` package to convert the value of `locale.String()` get go struct and do other things
@@ -5,3 +5,8 @@
- java-server 提供的 uuid 可以解析,可以通过 UUID 的 ToString()函数解析成字符串,但是 go 目前未提供生成 uuid 的功能
- java uuid 生成可以参考 jdk 下 java.util.UUID 类的相关源码
- uuid 结构体创建参考 https://github.com/satori/go.uuid

2. locale对象
- Locale.java中的对象可以转换成go的结构体Locale,但目前实现的是java中枚举的对象,具体见 class:java.util.Locale
- 先转换成LocaleHandle对象,然后调用 `GetLocaleFromHandler(localeHandler *LocaleHandle)` 函数转成Locale对象
- 可以使用 `golang.org/x/text/language` 包中的 `language.ParseBase("zh-CN")` 函数将 `locale.String()` 值转成go中的相关对象进行后续操作
@@ -0,0 +1,202 @@
/*
* 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 java_util

// LocaleEnum is Locale enumeration value
type LocaleEnum int

// Locale struct enum
const (
ENGLISH LocaleEnum = iota
FRENCH
GERMAN
ITALIAN
JAPANESE
KOREAN
CHINESE
SIMPLIFIED_CHINESE
TRADITIONAL_CHINESE
FRANCE
GERMANY
ITALY
JAPAN
KOREA
CHINA
PRC
TAIWAN
UK
US
CANADA
CANADA_FRENCH
ROOT
)

// Locale => java.util.Locale
type Locale struct {
// ID is used to implement enumeration
id LocaleEnum
lang string
county string
}

func (locale *Locale) County() string {
return locale.county
}

func (locale *Locale) Lang() string {
return locale.lang
}

func (locale *Locale) String() string {
if len(locale.county) != 0 {
return locale.lang + "_" + locale.county
}
return locale.lang
}

// LocaleHandle => com.alibaba.com.caucho.hessian.io.LocaleHandle object
type LocaleHandle struct {
Value string `hessian:"value"`
}

func (LocaleHandle) JavaClassName() string {
return "com.alibaba.com.caucho.hessian.io.LocaleHandle"
}

// locales is all const Locale struct slice
// localeMap is key = locale.String() value = locale struct
var (
locales []Locale = make([]Locale, 22, 22)
localeMap map[string](Locale) = make(map[string](Locale), 22)
)

// init java.util.Locale static object
func init() {
locales[ENGLISH] = Locale{
id: ENGLISH,
lang: "en",
county: "",
}
locales[FRENCH] = Locale{
id: FRENCH,
lang: "fr",
county: "",
}
locales[GERMAN] = Locale{
id: GERMAN,
lang: "de",
county: "",
}
locales[ITALIAN] = Locale{
id: ITALIAN,
lang: "it",
county: "",
}
locales[JAPANESE] = Locale{
id: JAPANESE,
lang: "ja",
county: "",
}
locales[KOREAN] = Locale{
id: KOREAN,
lang: "ko",
county: "",
}
locales[CHINESE] = Locale{
id: CHINESE,
lang: "zh",
county: "",
}
locales[SIMPLIFIED_CHINESE] = Locale{
id: SIMPLIFIED_CHINESE,
lang: "zh",
county: "CN",
}
locales[TRADITIONAL_CHINESE] = Locale{
id: TRADITIONAL_CHINESE,
lang: "zh",
county: "TW",
}
locales[FRANCE] = Locale{
id: FRANCE,
lang: "fr",
county: "FR",
}
locales[GERMANY] = Locale{
id: GERMANY,
lang: "de",
county: "DE",
}
locales[ITALY] = Locale{
id: ITALY,
lang: "it",
county: "it",
}
locales[JAPAN] = Locale{
id: JAPAN,
lang: "ja",
county: "JP",
}
locales[KOREA] = Locale{
id: KOREA,
lang: "ko",
county: "KR",
}
locales[CHINA] = locales[SIMPLIFIED_CHINESE]
locales[PRC] = locales[SIMPLIFIED_CHINESE]
locales[TAIWAN] = locales[TRADITIONAL_CHINESE]
locales[UK] = Locale{
id: UK,
lang: "en",
county: "GB",
}
locales[US] = Locale{
id: US,
lang: "en",
county: "US",
}
locales[CANADA] = Locale{
id: CANADA,
lang: "en",
county: "CA",
}
locales[CANADA_FRENCH] = Locale{
id: CANADA_FRENCH,
lang: "fr",
county: "CA",
}
locales[ROOT] = Locale{
id: ROOT,
lang: "",
county: "",
}
for _, locale := range locales {
localeMap[locale.String()] = locale
}
}

// ToLocale get locale from enum
func ToLocale(e LocaleEnum) *Locale {
return &locales[e]
}

// GetLocaleFromHandler is use LocaleHandle get Locale
func GetLocaleFromHandler(localeHandler *LocaleHandle) *Locale {
locale := localeMap[localeHandler.Value]
return &locale
}
@@ -53,3 +53,76 @@ func TestJavaUtil(t *testing.T) {
assert.Equal(t, uuid1.String(), resUuid1String)
assert.Equal(t, (resUuid2.(*java_util.UUID)).String(), resUuid2String)
}

func TestJavaUtilLocale(t *testing.T) {
res, err := decodeJavaResponse(`customReplyLocale`, ``, false)
if err != nil {
t.Error(err)
return
}
m := res.(map[interface{}]interface{})

english := m["english"]
french := m["french"]
german := m["german"]
italian := m["italian"]
japanese := m["japanese"]
korean := m["korean"]
chinese := m["chinese"]
simplified_chinese := m["simplified_chinese"]
traditional_chinese := m["traditional_chinese"]
france := m["france"]
germany := m["germany"]
japan := m["japan"]
korea := m["korea"]
china := m["china"]
prc := m["prc"]
taiwan := m["taiwan"]
uk := m["uk"]
us := m["us"]
canada := m["canada"]
root := m["root"]

assert.NotNil(t, english)
assert.NotNil(t, french)
assert.NotNil(t, german)
assert.NotNil(t, italian)
assert.NotNil(t, japanese)
assert.NotNil(t, korean)
assert.NotNil(t, chinese)
assert.NotNil(t, simplified_chinese)
assert.NotNil(t, traditional_chinese)
assert.NotNil(t, france)
assert.NotNil(t, germany)
assert.NotNil(t, japan)
assert.NotNil(t, korea)
assert.NotNil(t, china)
assert.NotNil(t, prc)
assert.NotNil(t, taiwan)
assert.NotNil(t, uk)
assert.NotNil(t, us)
assert.NotNil(t, canada)
//assert.NotNil(t, canada_french)
assert.NotNil(t, root)

assert.Equal(t, java_util.ToLocale(java_util.ENGLISH), java_util.GetLocaleFromHandler(english.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.FRENCH), java_util.GetLocaleFromHandler(french.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.GERMANY), java_util.GetLocaleFromHandler(germany.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.ITALIAN), java_util.GetLocaleFromHandler(italian.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.JAPANESE), java_util.GetLocaleFromHandler(japanese.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.KOREAN), java_util.GetLocaleFromHandler(korean.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.CHINESE), java_util.GetLocaleFromHandler(chinese.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.SIMPLIFIED_CHINESE), java_util.GetLocaleFromHandler(simplified_chinese.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.TRADITIONAL_CHINESE), java_util.GetLocaleFromHandler(traditional_chinese.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.FRANCE), java_util.GetLocaleFromHandler(france.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.GERMANY), java_util.GetLocaleFromHandler(germany.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.JAPAN), java_util.GetLocaleFromHandler(japan.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.KOREA), java_util.GetLocaleFromHandler(korea.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.CHINA), java_util.GetLocaleFromHandler(china.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.PRC), java_util.GetLocaleFromHandler(prc.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.TAIWAN), java_util.GetLocaleFromHandler(taiwan.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.UK), java_util.GetLocaleFromHandler(uk.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.US), java_util.GetLocaleFromHandler(us.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.CANADA), java_util.GetLocaleFromHandler(canada.(*java_util.LocaleHandle)))
assert.Equal(t, java_util.ToLocale(java_util.ROOT), java_util.GetLocaleFromHandler(root.(*java_util.LocaleHandle)))
}
@@ -31,14 +31,7 @@
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;


public class TestCustomReply {
@@ -433,7 +426,7 @@ public void customReplyTypedFixedList_BigDecimal() throws Exception {
public void customReplyObjectJsonObjectBigDecimal() throws Exception {
JSONObject t = new JSONObject();
BigDecimal decimal = new BigDecimal("100");
t.put("test_BigDecimal",decimal);
t.put("test_BigDecimal", decimal);
output.writeObject(t);
output.flush();
}
@@ -529,8 +522,8 @@ public void customReplyMultipleTypeMap() throws Exception {
map2.put(3L, "c");
map2.put(4L, "d");
Map<Integer, BigDecimal> map3 = new HashMap<Integer, BigDecimal>(4);
map3.put(5,new BigDecimal("55.55"));
map3.put(3,new BigDecimal("33.33"));
map3.put(5, new BigDecimal("55.55"));
map3.put(3, new BigDecimal("33.33"));
Map<String, Object> map = new HashMap<String, Object>(4);
map.put("m1", map1);
map.put("m2", map2);
@@ -557,7 +550,7 @@ public void customReplyListMapListMap() throws Exception {
innerMap.put("S", "string");
items.add(innerMap);

listMap1.put("items",items);
listMap1.put("items", items);

list.add(listMap1);

@@ -617,6 +610,45 @@ public void customReplyUUID() throws Exception {
output.writeObject(map);
output.flush();
}

public void customReplyLocale() throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("english", Locale.ENGLISH);
map.put("french", Locale.FRENCH);
map.put("german", Locale.GERMAN);
map.put("italian", Locale.ITALIAN);
map.put("japanese", Locale.JAPANESE);
map.put("korean", Locale.KOREAN);
map.put("chinese", Locale.CHINESE);
map.put("simplified_chinese", Locale.SIMPLIFIED_CHINESE);
map.put("traditional_chinese", Locale.TRADITIONAL_CHINESE);
map.put("france", Locale.FRANCE);
map.put("germany", Locale.GERMANY);
map.put("japan", Locale.JAPAN);
map.put("korea", Locale.KOREA);
map.put("china", Locale.CHINA);
map.put("prc", Locale.PRC);
map.put("taiwan", Locale.TAIWAN);
map.put("uk", Locale.UK);
map.put("us", Locale.US);
map.put("canada", Locale.CANADA);
map.put("root", Locale.ROOT);
// The two objects below is java hessian bug
// map.put("italy", Locale.ITALY);
// map.put("canada_french", Locale.CANADA_FRENCH);
// LocaleHandle
output.writeObject(map);
output.flush();
}

public void customReplyEnumSet() throws Exception {
Map<String, Object> map = new HashMap<>();
EnumSet<Locale.Category> enumSet = EnumSet.allOf(Locale.Category.class);
map.put("enumset", enumSet);
System.out.println(map);
output.writeObject(map);
output.flush();
}
}

interface Leg {

0 comments on commit b16a9bd

Please sign in to comment.