access.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package jsonutils
  15. import (
  16. "strconv"
  17. "strings"
  18. "time"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/sortedmap"
  21. "yunion.io/x/pkg/util/timeutils"
  22. )
  23. type JSONPair struct {
  24. key string
  25. val JSONObject
  26. }
  27. func NewDict(objs ...JSONPair) *JSONDict {
  28. dict := JSONDict{data: sortedmap.NewSortedMapWithCapa(len(objs))}
  29. for _, o := range objs {
  30. dict.Set(o.key, o.val)
  31. }
  32. return &dict
  33. }
  34. func NewArray(objs ...JSONObject) *JSONArray {
  35. arr := JSONArray{data: make([]JSONObject, 0, len(objs))}
  36. for _, o := range objs {
  37. arr.data = append(arr.data, o)
  38. }
  39. return &arr
  40. }
  41. func NewString(val string) *JSONString {
  42. return &JSONString{data: val}
  43. }
  44. func NewInt(val int64) *JSONInt {
  45. return &JSONInt{data: val}
  46. }
  47. //deprecated
  48. func NewFloat(val float64) *JSONFloat {
  49. return &JSONFloat{data: val, bit: 64}
  50. }
  51. func NewFloat64(val float64) *JSONFloat {
  52. return &JSONFloat{data: val, bit: 64}
  53. }
  54. func NewFloat32(val float32) *JSONFloat {
  55. return &JSONFloat{data: float64(val), bit: 32}
  56. }
  57. func NewBool(val bool) *JSONBool {
  58. if val {
  59. return JSONTrue
  60. }
  61. return JSONFalse
  62. }
  63. func (this *JSONDict) Set(key string, value JSONObject) {
  64. this.data = sortedmap.Add(this.data, key, value)
  65. }
  66. func (this *JSONDict) Remove(key string) bool {
  67. return this.remove(key, true)
  68. }
  69. func (this *JSONDict) RemoveIgnoreCase(key string) bool {
  70. someRemoved := false
  71. for {
  72. removed := this.remove(key, false)
  73. if !removed {
  74. break
  75. }
  76. if !someRemoved {
  77. someRemoved = true
  78. }
  79. }
  80. return someRemoved
  81. }
  82. func (this *JSONDict) remove(key string, caseSensitive bool) bool {
  83. exist := false
  84. if !caseSensitive {
  85. this.data, _, exist = sortedmap.DeleteIgnoreCase(this.data, key)
  86. } else {
  87. this.data, exist = sortedmap.Delete(this.data, key)
  88. }
  89. return exist
  90. }
  91. func (this *JSONDict) Add(o JSONObject, keys ...string) error {
  92. obj := this
  93. for i := 0; i < len(keys); i++ {
  94. if i == len(keys)-1 {
  95. obj.Set(keys[i], o)
  96. } else {
  97. o, ok := obj.data.Get(keys[i])
  98. if !ok || o == JSONNull {
  99. obj.Set(keys[i], NewDict())
  100. o, ok = obj.data.Get(keys[i])
  101. }
  102. if ok {
  103. obj, ok = o.(*JSONDict)
  104. if !ok {
  105. return ErrInvalidJsonDict
  106. }
  107. } else {
  108. return ErrJsonDictFailInsert
  109. }
  110. }
  111. }
  112. return nil
  113. }
  114. func (this *JSONArray) SetAt(idx int, obj JSONObject) {
  115. this.data[idx] = obj
  116. }
  117. func (this *JSONArray) Add(objs ...JSONObject) {
  118. for _, o := range objs {
  119. this.data = append(this.data, o)
  120. }
  121. }
  122. func (this *JSONValue) Contains(keys ...string) bool {
  123. return false
  124. }
  125. func (this *JSONValue) ContainsIgnoreCases(keys ...string) bool {
  126. return false
  127. }
  128. func (this *JSONValue) Get(keys ...string) (JSONObject, error) {
  129. return nil, ErrUnsupported
  130. }
  131. func (this *JSONValue) GetIgnoreCases(keys ...string) (JSONObject, error) {
  132. return nil, ErrUnsupported
  133. }
  134. func (this *JSONValue) GetString(keys ...string) (string, error) {
  135. if len(keys) > 0 {
  136. return "", ErrOutOfKeyRange
  137. }
  138. return this.String(), nil
  139. }
  140. func (this *JSONValue) GetAt(i int, keys ...string) (JSONObject, error) {
  141. return nil, ErrUnsupported
  142. }
  143. func (this *JSONValue) Int(keys ...string) (int64, error) {
  144. return 0, ErrUnsupported
  145. }
  146. func (this *JSONValue) Float(keys ...string) (float64, error) {
  147. return 0.0, ErrUnsupported
  148. }
  149. func (this *JSONValue) Bool(keys ...string) (bool, error) {
  150. return false, ErrUnsupported
  151. }
  152. func (this *JSONValue) GetMap(keys ...string) (map[string]JSONObject, error) {
  153. return nil, ErrUnsupported
  154. }
  155. func (this *JSONValue) GetArray(keys ...string) ([]JSONObject, error) {
  156. return nil, ErrUnsupported
  157. }
  158. func (this *JSONDict) Contains(keys ...string) bool {
  159. obj, err := this._get(true, keys)
  160. if err == nil && obj != nil {
  161. return true
  162. }
  163. return false
  164. }
  165. func (this *JSONDict) ContainsIgnoreCases(keys ...string) bool {
  166. obj, err := this._get(false, keys)
  167. if err == nil && obj != nil {
  168. return true
  169. }
  170. return false
  171. }
  172. func (this *JSONDict) Get(keys ...string) (JSONObject, error) {
  173. return this._get(true, keys)
  174. }
  175. func (this *JSONDict) GetIgnoreCases(keys ...string) (JSONObject, error) {
  176. return this._get(false, keys)
  177. }
  178. func (this *JSONDict) _get(caseSensitive bool, keys []string) (JSONObject, error) {
  179. if len(keys) == 0 {
  180. return this, nil
  181. }
  182. for i := 0; i < len(keys); i++ {
  183. key := keys[i]
  184. var val interface{}
  185. var ok bool
  186. if caseSensitive {
  187. val, ok = this.data.Get(key)
  188. } else {
  189. val, _, ok = this.data.GetIgnoreCase(key)
  190. }
  191. if ok {
  192. if i == len(keys)-1 {
  193. return val.(JSONObject), nil
  194. } else {
  195. this, ok = val.(*JSONDict)
  196. if !ok {
  197. return nil, ErrInvalidJsonDict
  198. }
  199. }
  200. } else {
  201. return nil, ErrJsonDictKeyNotFound
  202. }
  203. }
  204. return nil, ErrOutOfKeyRange
  205. }
  206. func (this *JSONDict) GetString(keys ...string) (string, error) {
  207. if len(keys) > 0 {
  208. obj, err := this.Get(keys...)
  209. if err != nil {
  210. return "", errors.Wrap(err, "Get")
  211. }
  212. return obj.GetString()
  213. } else {
  214. return this.String(), nil
  215. }
  216. }
  217. func (this *JSONDict) GetMap(keys ...string) (map[string]JSONObject, error) {
  218. obj, err := this.Get(keys...)
  219. if err != nil {
  220. return nil, errors.Wrap(err, "Get")
  221. }
  222. dict, ok := obj.(*JSONDict)
  223. if !ok {
  224. return nil, ErrInvalidJsonDict
  225. }
  226. // allocate a map to hold the return map
  227. ret := make(map[string]JSONObject, len(this.data))
  228. for iter := sortedmap.NewIterator(dict.data); iter.HasMore(); iter.Next() {
  229. k, v := iter.Get()
  230. ret[k] = v.(JSONObject)
  231. }
  232. return ret, nil
  233. }
  234. func (this *JSONArray) GetAt(i int, keys ...string) (JSONObject, error) {
  235. if len(keys) > 0 {
  236. return nil, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  237. }
  238. if i < 0 {
  239. i = len(this.data) + i
  240. }
  241. if i >= 0 && i < len(this.data) {
  242. return this.data[i], nil
  243. } else {
  244. return nil, ErrOutOfIndexRange // fmt.Errorf("Out of range GetAt(%d)", i)
  245. }
  246. }
  247. func (this *JSONArray) GetString(keys ...string) (string, error) {
  248. if len(keys) > 0 {
  249. return "", ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  250. }
  251. return this.String(), nil
  252. }
  253. func (this *JSONDict) GetAt(i int, keys ...string) (JSONObject, error) {
  254. obj, err := this.Get(keys...)
  255. if err != nil {
  256. return nil, errors.Wrap(err, "Get")
  257. }
  258. arr, ok := obj.(*JSONArray)
  259. if !ok {
  260. return nil, ErrInvalidJsonArray // fmt.Errorf("%s is not an Array", keys)
  261. }
  262. return arr.GetAt(i)
  263. }
  264. func (this *JSONArray) GetArray(keys ...string) ([]JSONObject, error) {
  265. if len(keys) > 0 {
  266. return nil, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  267. }
  268. // Allocate a new array to hold the return array
  269. ret := make([]JSONObject, len(this.data))
  270. for i := range this.data {
  271. ret[i] = this.data[i]
  272. }
  273. return ret, nil
  274. }
  275. func (this *JSONDict) GetArray(keys ...string) ([]JSONObject, error) {
  276. obj, err := this.Get(keys...)
  277. if err != nil {
  278. return nil, errors.Wrap(err, "Get")
  279. }
  280. if _, ok := obj.(*JSONDict); ok {
  281. return nil, ErrInvalidJsonArray
  282. }
  283. return obj.GetArray()
  284. /* arr, ok := obj.(*JSONArray)
  285. if !ok {
  286. return nil, fmt.Errorf("%s is not an Array", keys)
  287. }
  288. return arr.GetArray() */
  289. }
  290. func _getarray(obj JSONObject, keys ...string) ([]JSONObject, error) {
  291. if len(keys) > 0 {
  292. return nil, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  293. }
  294. return []JSONObject{obj}, nil
  295. }
  296. func (this *JSONString) GetArray(keys ...string) ([]JSONObject, error) {
  297. return _getarray(this, keys...)
  298. }
  299. func (this *JSONInt) GetArray(keys ...string) ([]JSONObject, error) {
  300. return _getarray(this, keys...)
  301. }
  302. func (this *JSONFloat) GetArray(keys ...string) ([]JSONObject, error) {
  303. return _getarray(this, keys...)
  304. }
  305. func (this *JSONBool) GetArray(keys ...string) ([]JSONObject, error) {
  306. return _getarray(this, keys...)
  307. }
  308. func (this *JSONInt) Int(keys ...string) (int64, error) {
  309. if len(keys) > 0 {
  310. return 0, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  311. }
  312. return this.data, nil
  313. }
  314. func (this *JSONString) Int(keys ...string) (int64, error) {
  315. if len(keys) > 0 {
  316. return 0, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  317. }
  318. val, e := strconv.ParseInt(this.data, 10, 64)
  319. if e != nil {
  320. return 0, ErrInvalidJsonInt // fmt.Errorf("Invalid number %s", this.data)
  321. } else {
  322. return val, nil
  323. }
  324. }
  325. func (this *JSONInt) GetString(keys ...string) (string, error) {
  326. if len(keys) > 0 {
  327. return "", ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  328. }
  329. return this.String(), nil
  330. }
  331. func (this *JSONDict) Int(keys ...string) (int64, error) {
  332. obj, err := this.Get(keys...)
  333. if err != nil {
  334. return 0, errors.Wrap(err, "Get")
  335. }
  336. return obj.Int()
  337. /* jint, ok := obj.(*JSONInt)
  338. if ! ok {
  339. return 0, fmt.Errorf("%s is not an Int", keys)
  340. }
  341. return jint.Int() */
  342. }
  343. func (this *JSONFloat) Float(keys ...string) (float64, error) {
  344. if len(keys) > 0 {
  345. return 0.0, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  346. }
  347. return this.data, nil
  348. }
  349. func (this *JSONInt) Float(keys ...string) (float64, error) {
  350. if len(keys) > 0 {
  351. return 0.0, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  352. }
  353. return float64(this.data), nil
  354. }
  355. func (this *JSONString) Float(keys ...string) (float64, error) {
  356. if len(keys) > 0 {
  357. return 0.0, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  358. }
  359. val, err := strconv.ParseFloat(this.data, 64)
  360. if err != nil {
  361. return 0.0, ErrInvalidJsonFloat // fmt.Errorf("Not a float %s", this.data)
  362. } else {
  363. return val, nil
  364. }
  365. }
  366. func (this *JSONFloat) GetString(keys ...string) (string, error) {
  367. if len(keys) > 0 {
  368. return "", ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  369. }
  370. return this.String(), nil
  371. }
  372. func (this *JSONDict) Float(keys ...string) (float64, error) {
  373. obj, err := this.Get(keys...)
  374. if err != nil {
  375. return 0, errors.Wrap(err, "Get")
  376. }
  377. return obj.Float()
  378. /* jfloat, ok := obj.(*JSONFloat)
  379. if ! ok {
  380. return 0, fmt.Errorf("%s is not a float", keys)
  381. }
  382. return jfloat.Float() */
  383. }
  384. func (this *JSONBool) Bool(keys ...string) (bool, error) {
  385. if len(keys) > 0 {
  386. return false, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  387. }
  388. return this.data, nil
  389. }
  390. func (this *JSONString) Bool(keys ...string) (bool, error) {
  391. if len(keys) > 0 {
  392. return false, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  393. }
  394. if strings.EqualFold(this.data, "true") || strings.EqualFold(this.data, "on") || strings.EqualFold(this.data, "yes") || this.data == "1" {
  395. return true, nil
  396. } else if strings.EqualFold(this.data, "false") || strings.EqualFold(this.data, "off") || strings.EqualFold(this.data, "no") || this.data == "0" {
  397. return false, nil
  398. } else {
  399. return false, ErrInvalidJsonBoolean // fmt.Errorf("Invalid boolean string %s", this.data)
  400. }
  401. }
  402. func (this *JSONBool) GetString(keys ...string) (string, error) {
  403. if len(keys) > 0 {
  404. return "", ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  405. }
  406. return this.String(), nil
  407. }
  408. func (this *JSONDict) Bool(keys ...string) (bool, error) {
  409. obj, err := this.Get(keys...)
  410. if err != nil {
  411. return false, errors.Wrap(err, "Get")
  412. }
  413. return obj.Bool()
  414. /* jbool, ok := obj.(*JSONBool)
  415. if ! ok {
  416. return false, fmt.Errorf("%s is not a bool", keys)
  417. }
  418. return jbool.Bool() */
  419. }
  420. func (this *JSONValue) GetTime(keys ...string) (time.Time, error) {
  421. return time.Time{}, ErrUnsupported // fmt.Errorf("Unsupported operation GetTime")
  422. }
  423. func (this *JSONString) GetTime(keys ...string) (time.Time, error) {
  424. if len(keys) > 0 {
  425. return time.Time{}, ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  426. }
  427. t, e := timeutils.ParseTimeStr(this.data)
  428. if e == nil {
  429. return t, nil
  430. }
  431. for _, tf := range []string{time.RFC3339, time.RFC1123, time.UnixDate,
  432. time.RFC822,
  433. } {
  434. t, e := time.Parse(tf, this.data)
  435. if e == nil {
  436. return t, nil
  437. }
  438. }
  439. return this.JSONValue.GetTime()
  440. }
  441. func (this *JSONString) GetString(keys ...string) (string, error) {
  442. if len(keys) > 0 {
  443. return "", ErrOutOfKeyRange // fmt.Errorf("Out of key range: %s", keys)
  444. }
  445. return this.data, nil
  446. }
  447. func (this *JSONDict) GetTime(keys ...string) (time.Time, error) {
  448. obj, err := this.Get(keys...)
  449. if err != nil {
  450. return time.Time{}, errors.Wrap(err, "Get")
  451. }
  452. str, ok := obj.(*JSONString)
  453. if !ok {
  454. return time.Time{}, ErrInvalidJsonString // fmt.Errorf("%s is not a string", keys)
  455. }
  456. return str.GetTime()
  457. }
  458. /*
  459. func (this *JSONDict) GetIgnoreCases(key ...string) (JSONObject, bool) {
  460. lkey := strings.ToLower(key)
  461. for k, v := range this.data {
  462. if strings.ToLower(k) == lkey {
  463. return v, true
  464. }
  465. }
  466. return nil, false
  467. }*/