Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for .properties configuration file #1806

Merged
merged 12 commits into from
May 13, 2022
15 changes: 8 additions & 7 deletions encoding/gjson/gjson.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import (
)

const (
ContentTypeJson = `json`
ContentTypeJs = `js`
ContentTypeXml = `xml`
ContentTypeIni = `ini`
ContentTypeYaml = `yaml`
ContentTypeYml = `yml`
ContentTypeToml = `toml`
ContentTypeJson = `json`
ContentTypeJs = `js`
ContentTypeXml = `xml`
ContentTypeIni = `ini`
ContentTypeYaml = `yaml`
ContentTypeYml = `yml`
ContentTypeToml = `toml`
ContentTypeProperties = `properties`
)

const (
Expand Down
28 changes: 28 additions & 0 deletions encoding/gjson/gjson_api_encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package gjson

import (
"github.com/gogf/gf/v2/encoding/gini"
"github.com/gogf/gf/v2/encoding/gproperties"
"github.com/gogf/gf/v2/encoding/gtoml"
"github.com/gogf/gf/v2/encoding/gxml"
"github.com/gogf/gf/v2/encoding/gyaml"
Expand Down Expand Up @@ -197,3 +198,30 @@ func (j *Json) MustToIni() []byte {
func (j *Json) MustToIniString() string {
return string(j.MustToIni())
}

// ========================================================================
// properties
// ========================================================================
// Toproperties json to properties
func (j *Json) ToProperties() ([]byte, error) {
return gproperties.Encode(j.Map())
}

// TopropertiesString properties to string
func (j *Json) ToPropertiesString() (string, error) {
b, e := j.ToProperties()
return string(b), e
}

func (j *Json) MustToProperties() []byte {
result, err := j.ToProperties()
if err != nil {
panic(err)
}
return result
}

// MustTopropertiesString
func (j *Json) MustToPropertiesString() string {
return string(j.MustToProperties())
}
21 changes: 20 additions & 1 deletion encoding/gjson/gjson_api_new_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"reflect"

"github.com/gogf/gf/v2/encoding/gini"
"github.com/gogf/gf/v2/encoding/gproperties"
"github.com/gogf/gf/v2/encoding/gtoml"
"github.com/gogf/gf/v2/encoding/gxml"
"github.com/gogf/gf/v2/encoding/gyaml"
Expand Down Expand Up @@ -174,6 +175,17 @@ func LoadToml(data interface{}, safe ...bool) (*Json, error) {
return doLoadContentWithOptions(gconv.Bytes(data), option)
}

// LoadProperties creates a Json object from given TOML format content.
func LoadProperties(data interface{}, safe ...bool) (*Json, error) {
option := Options{
Type: ContentTypeProperties,
}
if len(safe) > 0 && safe[0] {
option.Safe = true
}
return doLoadContentWithOptions(gconv.Bytes(data), option)
}

// LoadContent creates a Json object from given content, it checks the data type of `content`
// automatically, supporting data content type as follows:
// JSON, XML, INI, YAML and TOML.
Expand Down Expand Up @@ -222,7 +234,8 @@ func IsValidDataType(dataType string) bool {
ContentTypeYaml,
ContentTypeYml,
ContentTypeToml,
ContentTypeIni:
ContentTypeIni,
ContentTypeProperties:
return true
}
return false
Expand Down Expand Up @@ -288,6 +301,10 @@ func doLoadContentWithOptions(data []byte, options Options) (*Json, error) {
if data, err = gini.ToJson(data); err != nil {
return nil, err
}
case ContentTypeProperties:
if data, err = gproperties.ToJson(data); err != nil {
return nil, err
}

default:
err = gerror.NewCodef(
Expand Down Expand Up @@ -335,6 +352,8 @@ func checkDataType(content []byte) string {
(gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*".+"`, content) || gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*\w+`, content)) {
// Must contain "[xxx]" section.
return ContentTypeIni
} else if gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*\w+`, content) {
return ContentTypeProperties
} else {
return ""
}
Expand Down
15 changes: 15 additions & 0 deletions encoding/gjson/gjson_z_example_load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ func ExampleIsValidDataType() {
fmt.Println(gjson.IsValidDataType("txt"))
fmt.Println(gjson.IsValidDataType(""))
fmt.Println(gjson.IsValidDataType(".json"))
fmt.Println(gjson.IsValidDataType(".properties"))

// Output:
// true
Expand All @@ -192,6 +193,7 @@ func ExampleIsValidDataType() {
// false
// false
// true
// true
}

func ExampleLoad_Xml() {
Expand All @@ -200,3 +202,16 @@ func ExampleLoad_Xml() {
fmt.Println(j.Get("doc.name"))
fmt.Println(j.Get("doc.score"))
}

func ExampleLoad_Properties() {
jsonFilePath := gtest.DataPath("properties", "data1.properties")
j, _ := gjson.Load(jsonFilePath)
fmt.Println(j.Get("pr.name"))
fmt.Println(j.Get("pr.score"))
fmt.Println(j.Get("pr.sex"))

//Output:
// john
// 100
// 0
}
74 changes: 74 additions & 0 deletions encoding/gjson/gjson_z_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,80 @@ func ExampleJson_MustToIniString() {
//Name=John
}

// ========================================================================
// Properties
// ========================================================================
func ExampleJson_ToProperties() {
type BaseInfo struct {
Name string
Age int
}

info := BaseInfo{
Name: "John",
Age: 18,
}

j := gjson.New(info)
pr, _ := j.ToProperties()
fmt.Println(string(pr))

// May Output:
// name = John
// age = 18
}

func ExampleJson_ToPropertiesString() {
type BaseInfo struct {
Name string
}

info := BaseInfo{
Name: "John",
}

j := gjson.New(info)
pr, _ := j.ToPropertiesString()
fmt.Println(pr)

// Output:
// name = John
}

func ExampleJson_MustToProperties() {
type BaseInfo struct {
Name string
}

info := BaseInfo{
Name: "John",
}

j := gjson.New(info)
pr := j.MustToProperties()
fmt.Println(string(pr))

// Output:
// name = John
}

func ExampleJson_MustToPropertiesString() {
type BaseInfo struct {
Name string
}

info := BaseInfo{
Name: "John",
}

j := gjson.New(info)
pr := j.MustToPropertiesString()
fmt.Println(pr)

// Output:
// name = John
}

func ExampleJson_MarshalJSON() {
type BaseInfo struct {
Name string
Expand Down
55 changes: 55 additions & 0 deletions encoding/gjson/gjson_z_unit_feature_load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,58 @@ gfcli:
t.AssertNil(err)
})
}

func Test_Load_Properties(t *testing.T) {
var data = `

#注释


addr.ip = 127.0.0.1
addr.port=9001
addr.enable=true
DBINFO.type=mysql
DBINFO.user=root
DBINFO.password=password

`

gtest.C(t, func(t *gtest.T) {
j, err := gjson.LoadContent(data)
if err != nil {
gtest.Fatal(err)
}

t.Assert(j.Get("addr.ip").String(), "127.0.0.1")
t.Assert(j.Get("addr.port").String(), "9001")
t.Assert(j.Get("addr.enable").String(), "true")
t.Assert(j.Get("DBINFO.type").String(), "mysql")
t.Assert(j.Get("DBINFO.user").String(), "root")
t.Assert(j.Get("DBINFO.password").String(), "password")

_, err = j.ToProperties()
if err != nil {
gtest.Fatal(err)
}
})

gtest.C(t, func(t *gtest.T) {
j, err := gjson.LoadProperties(data, true)
if err != nil {
gtest.Fatal(err)
}

t.Assert(j.Get("addr.ip").String(), "127.0.0.1")
t.Assert(j.Get("addr.port").String(), "9001")
t.Assert(j.Get("addr.enable").String(), "true")
t.Assert(j.Get("DBINFO.type").String(), "mysql")
t.Assert(j.Get("DBINFO.user").String(), "root")
t.Assert(j.Get("DBINFO.password").String(), "password")
})

gtest.C(t, func(t *gtest.T) {
errData := []byte("i\\u1 : 123456789")
_, err := gjson.LoadContentType("properties", errData, true)
t.AssertNE(err, nil)
})
}
3 changes: 3 additions & 0 deletions encoding/gjson/testdata/properties/data1.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pr.name=john
pr.score=100
pr.sex=0
Loading