jsonpath.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package jsonpath
  14. import (
  15. "bytes"
  16. "fmt"
  17. "io"
  18. "reflect"
  19. "strings"
  20. "k8s.io/kubernetes/third_party/forked/golang/template"
  21. )
  22. type JSONPath struct {
  23. name string
  24. parser *Parser
  25. stack [][]reflect.Value //push and pop values in different scopes
  26. cur []reflect.Value //current scope values
  27. beginRange int
  28. inRange int
  29. endRange int
  30. }
  31. func New(name string) *JSONPath {
  32. return &JSONPath{
  33. name: name,
  34. beginRange: 0,
  35. inRange: 0,
  36. endRange: 0,
  37. }
  38. }
  39. // Parse parse the given template, return error
  40. func (j *JSONPath) Parse(text string) (err error) {
  41. j.parser, err = Parse(j.name, text)
  42. return
  43. }
  44. // Execute bounds data into template and write the result
  45. func (j *JSONPath) Execute(wr io.Writer, data interface{}) error {
  46. fullResults, err := j.FindResults(data)
  47. if err != nil {
  48. return err
  49. }
  50. for ix := range fullResults {
  51. if err := j.PrintResults(wr, fullResults[ix]); err != nil {
  52. return err
  53. }
  54. }
  55. return nil
  56. }
  57. func (j *JSONPath) FindResults(data interface{}) ([][]reflect.Value, error) {
  58. if j.parser == nil {
  59. return nil, fmt.Errorf("%s is an incomplete jsonpath template", j.name)
  60. }
  61. j.cur = []reflect.Value{reflect.ValueOf(data)}
  62. nodes := j.parser.Root.Nodes
  63. fullResult := [][]reflect.Value{}
  64. for i := 0; i < len(nodes); i++ {
  65. node := nodes[i]
  66. results, err := j.walk(j.cur, node)
  67. if err != nil {
  68. return nil, err
  69. }
  70. //encounter an end node, break the current block
  71. if j.endRange > 0 && j.endRange <= j.inRange {
  72. j.endRange -= 1
  73. break
  74. }
  75. //encounter a range node, start a range loop
  76. if j.beginRange > 0 {
  77. j.beginRange -= 1
  78. j.inRange += 1
  79. for k, value := range results {
  80. j.parser.Root.Nodes = nodes[i+1:]
  81. if k == len(results)-1 {
  82. j.inRange -= 1
  83. }
  84. nextResults, err := j.FindResults(value.Interface())
  85. if err != nil {
  86. return nil, err
  87. }
  88. fullResult = append(fullResult, nextResults...)
  89. }
  90. break
  91. }
  92. fullResult = append(fullResult, results)
  93. }
  94. return fullResult, nil
  95. }
  96. // PrintResults write the results into writer
  97. func (j *JSONPath) PrintResults(wr io.Writer, results []reflect.Value) error {
  98. for i, r := range results {
  99. text, err := j.evalToText(r)
  100. if err != nil {
  101. return err
  102. }
  103. if i != len(results)-1 {
  104. text = append(text, ' ')
  105. }
  106. if _, err = wr.Write(text); err != nil {
  107. return err
  108. }
  109. }
  110. return nil
  111. }
  112. // walk visits tree rooted at the given node in DFS order
  113. func (j *JSONPath) walk(value []reflect.Value, node Node) ([]reflect.Value, error) {
  114. switch node := node.(type) {
  115. case *ListNode:
  116. return j.evalList(value, node)
  117. case *TextNode:
  118. return []reflect.Value{reflect.ValueOf(node.Text)}, nil
  119. case *FieldNode:
  120. return j.evalField(value, node)
  121. case *ArrayNode:
  122. return j.evalArray(value, node)
  123. case *FilterNode:
  124. return j.evalFilter(value, node)
  125. case *IntNode:
  126. return j.evalInt(value, node)
  127. case *FloatNode:
  128. return j.evalFloat(value, node)
  129. case *WildcardNode:
  130. return j.evalWildcard(value, node)
  131. case *RecursiveNode:
  132. return j.evalRecursive(value, node)
  133. case *UnionNode:
  134. return j.evalUnion(value, node)
  135. case *IdentifierNode:
  136. return j.evalIdentifier(value, node)
  137. default:
  138. return value, fmt.Errorf("unexpected Node %v", node)
  139. }
  140. }
  141. // evalInt evaluates IntNode
  142. func (j *JSONPath) evalInt(input []reflect.Value, node *IntNode) ([]reflect.Value, error) {
  143. result := make([]reflect.Value, len(input))
  144. for i := range input {
  145. result[i] = reflect.ValueOf(node.Value)
  146. }
  147. return result, nil
  148. }
  149. // evalFloat evaluates FloatNode
  150. func (j *JSONPath) evalFloat(input []reflect.Value, node *FloatNode) ([]reflect.Value, error) {
  151. result := make([]reflect.Value, len(input))
  152. for i := range input {
  153. result[i] = reflect.ValueOf(node.Value)
  154. }
  155. return result, nil
  156. }
  157. // evalList evaluates ListNode
  158. func (j *JSONPath) evalList(value []reflect.Value, node *ListNode) ([]reflect.Value, error) {
  159. var err error
  160. curValue := value
  161. for _, node := range node.Nodes {
  162. curValue, err = j.walk(curValue, node)
  163. if err != nil {
  164. return curValue, err
  165. }
  166. }
  167. return curValue, nil
  168. }
  169. // evalIdentifier evaluates IdentifierNode
  170. func (j *JSONPath) evalIdentifier(input []reflect.Value, node *IdentifierNode) ([]reflect.Value, error) {
  171. results := []reflect.Value{}
  172. switch node.Name {
  173. case "range":
  174. j.stack = append(j.stack, j.cur)
  175. j.beginRange += 1
  176. results = input
  177. case "end":
  178. if j.endRange < j.inRange { //inside a loop, break the current block
  179. j.endRange += 1
  180. break
  181. }
  182. // the loop is about to end, pop value and continue the following execution
  183. if len(j.stack) > 0 {
  184. j.cur, j.stack = j.stack[len(j.stack)-1], j.stack[:len(j.stack)-1]
  185. } else {
  186. return results, fmt.Errorf("not in range, nothing to end")
  187. }
  188. default:
  189. return input, fmt.Errorf("unrecognized identifier %v", node.Name)
  190. }
  191. return results, nil
  192. }
  193. // evalArray evaluates ArrayNode
  194. func (j *JSONPath) evalArray(input []reflect.Value, node *ArrayNode) ([]reflect.Value, error) {
  195. result := []reflect.Value{}
  196. for _, value := range input {
  197. value, isNil := template.Indirect(value)
  198. if isNil {
  199. continue
  200. }
  201. if value.Kind() != reflect.Array && value.Kind() != reflect.Slice {
  202. return input, fmt.Errorf("%v is not array or slice", value.Type())
  203. }
  204. params := node.Params
  205. if !params[0].Known {
  206. params[0].Value = 0
  207. }
  208. if params[0].Value < 0 {
  209. params[0].Value += value.Len()
  210. }
  211. if !params[1].Known {
  212. params[1].Value = value.Len()
  213. }
  214. if params[1].Value < 0 {
  215. params[1].Value += value.Len()
  216. }
  217. sliceLength := value.Len()
  218. if params[1].Value != params[0].Value { // if you're requesting zero elements, allow it through.
  219. if params[0].Value >= sliceLength {
  220. return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[0].Value, sliceLength)
  221. }
  222. if params[1].Value > sliceLength {
  223. return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[1].Value-1, sliceLength)
  224. }
  225. }
  226. if !params[2].Known {
  227. value = value.Slice(params[0].Value, params[1].Value)
  228. } else {
  229. value = value.Slice3(params[0].Value, params[1].Value, params[2].Value)
  230. }
  231. for i := 0; i < value.Len(); i++ {
  232. result = append(result, value.Index(i))
  233. }
  234. }
  235. return result, nil
  236. }
  237. // evalUnion evaluates UnionNode
  238. func (j *JSONPath) evalUnion(input []reflect.Value, node *UnionNode) ([]reflect.Value, error) {
  239. result := []reflect.Value{}
  240. for _, listNode := range node.Nodes {
  241. temp, err := j.evalList(input, listNode)
  242. if err != nil {
  243. return input, err
  244. }
  245. result = append(result, temp...)
  246. }
  247. return result, nil
  248. }
  249. func (j *JSONPath) findFieldInValue(value *reflect.Value, node *FieldNode) (reflect.Value, error) {
  250. t := value.Type()
  251. var inlineValue *reflect.Value
  252. for ix := 0; ix < t.NumField(); ix++ {
  253. f := t.Field(ix)
  254. jsonTag := f.Tag.Get("json")
  255. parts := strings.Split(jsonTag, ",")
  256. if len(parts) == 0 {
  257. continue
  258. }
  259. if parts[0] == node.Value {
  260. return value.Field(ix), nil
  261. }
  262. if len(parts[0]) == 0 {
  263. val := value.Field(ix)
  264. inlineValue = &val
  265. }
  266. }
  267. if inlineValue != nil {
  268. if inlineValue.Kind() == reflect.Struct {
  269. // handle 'inline'
  270. match, err := j.findFieldInValue(inlineValue, node)
  271. if err != nil {
  272. return reflect.Value{}, err
  273. }
  274. if match.IsValid() {
  275. return match, nil
  276. }
  277. }
  278. }
  279. return value.FieldByName(node.Value), nil
  280. }
  281. // evalField evaluates filed of struct or key of map.
  282. func (j *JSONPath) evalField(input []reflect.Value, node *FieldNode) ([]reflect.Value, error) {
  283. results := []reflect.Value{}
  284. // If there's no input, there's no output
  285. if len(input) == 0 {
  286. return results, nil
  287. }
  288. for _, value := range input {
  289. var result reflect.Value
  290. value, isNil := template.Indirect(value)
  291. if isNil {
  292. continue
  293. }
  294. if value.Kind() == reflect.Struct {
  295. var err error
  296. if result, err = j.findFieldInValue(&value, node); err != nil {
  297. return nil, err
  298. }
  299. } else if value.Kind() == reflect.Map {
  300. mapKeyType := value.Type().Key()
  301. nodeValue := reflect.ValueOf(node.Value)
  302. // node value type must be convertible to map key type
  303. if !nodeValue.Type().ConvertibleTo(mapKeyType) {
  304. return results, fmt.Errorf("%s is not convertible to %s", nodeValue, mapKeyType)
  305. }
  306. result = value.MapIndex(nodeValue.Convert(mapKeyType))
  307. }
  308. if result.IsValid() {
  309. results = append(results, result)
  310. }
  311. }
  312. if len(results) == 0 {
  313. return results, fmt.Errorf("%s is not found", node.Value)
  314. }
  315. return results, nil
  316. }
  317. // evalWildcard extract all contents of the given value
  318. func (j *JSONPath) evalWildcard(input []reflect.Value, node *WildcardNode) ([]reflect.Value, error) {
  319. results := []reflect.Value{}
  320. for _, value := range input {
  321. value, isNil := template.Indirect(value)
  322. if isNil {
  323. continue
  324. }
  325. kind := value.Kind()
  326. if kind == reflect.Struct {
  327. for i := 0; i < value.NumField(); i++ {
  328. results = append(results, value.Field(i))
  329. }
  330. } else if kind == reflect.Map {
  331. for _, key := range value.MapKeys() {
  332. results = append(results, value.MapIndex(key))
  333. }
  334. } else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String {
  335. for i := 0; i < value.Len(); i++ {
  336. results = append(results, value.Index(i))
  337. }
  338. }
  339. }
  340. return results, nil
  341. }
  342. // evalRecursive visit the given value recursively and push all of them to result
  343. func (j *JSONPath) evalRecursive(input []reflect.Value, node *RecursiveNode) ([]reflect.Value, error) {
  344. result := []reflect.Value{}
  345. for _, value := range input {
  346. results := []reflect.Value{}
  347. value, isNil := template.Indirect(value)
  348. if isNil {
  349. continue
  350. }
  351. kind := value.Kind()
  352. if kind == reflect.Struct {
  353. for i := 0; i < value.NumField(); i++ {
  354. results = append(results, value.Field(i))
  355. }
  356. } else if kind == reflect.Map {
  357. for _, key := range value.MapKeys() {
  358. results = append(results, value.MapIndex(key))
  359. }
  360. } else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String {
  361. for i := 0; i < value.Len(); i++ {
  362. results = append(results, value.Index(i))
  363. }
  364. }
  365. if len(results) != 0 {
  366. result = append(result, value)
  367. output, err := j.evalRecursive(results, node)
  368. if err != nil {
  369. return result, err
  370. }
  371. result = append(result, output...)
  372. }
  373. }
  374. return result, nil
  375. }
  376. // evalFilter filter array according to FilterNode
  377. func (j *JSONPath) evalFilter(input []reflect.Value, node *FilterNode) ([]reflect.Value, error) {
  378. results := []reflect.Value{}
  379. for _, value := range input {
  380. value, _ = template.Indirect(value)
  381. if value.Kind() != reflect.Array && value.Kind() != reflect.Slice {
  382. return input, fmt.Errorf("%v is not array or slice and cannot be filtered", value)
  383. }
  384. for i := 0; i < value.Len(); i++ {
  385. temp := []reflect.Value{value.Index(i)}
  386. lefts, err := j.evalList(temp, node.Left)
  387. //case exists
  388. if node.Operator == "exists" {
  389. if len(lefts) > 0 {
  390. results = append(results, value.Index(i))
  391. }
  392. continue
  393. }
  394. if err != nil {
  395. return input, err
  396. }
  397. var left, right interface{}
  398. if len(lefts) != 1 {
  399. return input, fmt.Errorf("can only compare one element at a time")
  400. }
  401. left = lefts[0].Interface()
  402. rights, err := j.evalList(temp, node.Right)
  403. if err != nil {
  404. return input, err
  405. }
  406. if len(rights) != 1 {
  407. return input, fmt.Errorf("can only compare one element at a time")
  408. }
  409. right = rights[0].Interface()
  410. pass := false
  411. switch node.Operator {
  412. case "<":
  413. pass, err = template.Less(left, right)
  414. case ">":
  415. pass, err = template.Greater(left, right)
  416. case "==":
  417. pass, err = template.Equal(left, right)
  418. case "!=":
  419. pass, err = template.NotEqual(left, right)
  420. case "<=":
  421. pass, err = template.LessEqual(left, right)
  422. case ">=":
  423. pass, err = template.GreaterEqual(left, right)
  424. default:
  425. return results, fmt.Errorf("unrecognized filter operator %s", node.Operator)
  426. }
  427. if err != nil {
  428. return results, err
  429. }
  430. if pass {
  431. results = append(results, value.Index(i))
  432. }
  433. }
  434. }
  435. return results, nil
  436. }
  437. // evalToText translates reflect value to corresponding text
  438. func (j *JSONPath) evalToText(v reflect.Value) ([]byte, error) {
  439. iface, ok := template.PrintableValue(v)
  440. if !ok {
  441. return nil, fmt.Errorf("can't print type %s", v.Type())
  442. }
  443. var buffer bytes.Buffer
  444. fmt.Fprint(&buffer, iface)
  445. return buffer.Bytes(), nil
  446. }