dubbo.apache.org/dubbo-go/v3@v3.1.1/remoting/polaris/parser/parser.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package parser 19 20 import ( 21 "encoding/json" 22 "regexp" 23 "strconv" 24 "strings" 25 ) 26 27 import ( 28 "github.com/dubbogo/gost/log/logger" 29 30 "github.com/oliveagle/jsonpath" 31 ) 32 33 const ( 34 _pefixParam = "param" 35 _prefixParamArr = "param[" 36 ) 37 38 var ( 39 _arrayRegx, _ = regexp.Compile(`"^.+\\[[0-9]+\\]"`) 40 ) 41 42 // ParseArgumentsByExpression follow https://goessner.net/articles/JsonPath/ 43 // 44 // { 45 // "store":{ 46 // "book":[ 47 // { 48 // "category":"reference", 49 // "author":"Nigel Rees", 50 // "title":"Sayings of the Century", 51 // "price":8.95 52 // }, 53 // { 54 // "category":"fiction", 55 // "author":"Evelyn Waugh", 56 // "title":"Sword of Honor", 57 // "price":12.99 58 // }, 59 // { 60 // "category":"fiction", 61 // "author":"Herman Melville", 62 // "title":"Moby Dick", 63 // "isbn":"0-553-21311-3", 64 // "price":8.99 65 // }, 66 // { 67 // "category":"fiction", 68 // "author":"J. R. R. Tolkien", 69 // "title":"The Lord of the Rings", 70 // "isbn":"0-395-19395-8", 71 // "price":22.99 72 // } 73 // ], 74 // "bicycle":{ 75 // "color":"red", 76 // "price":19.95 77 // } 78 // } 79 // } 80 // 81 // examples 82 // - case 1: param.$.store.book[*].author 83 func ParseArgumentsByExpression(key string, parameters []interface{}) interface{} { 84 index, key := resolveIndex(key) 85 if index == -1 || index >= len(parameters) { 86 logger.Errorf("[Parser][Polaris] invalid expression for : %s", key) 87 return nil 88 } 89 90 data, err := json.Marshal(parameters[index]) 91 if err != nil { 92 logger.Errorf("[Parser][Polaris] marshal parameter %+v fail : %+v", parameters[index], err) 93 return nil 94 } 95 var searchVal interface{} 96 _ = json.Unmarshal(data, &searchVal) 97 res, err := jsonpath.JsonPathLookup(searchVal, key) 98 if err != nil { 99 logger.Errorf("[Parser][Polaris] invalid do json path lookup by key : %s, err : %+v", key, err) 100 } 101 102 return res 103 } 104 105 func resolveIndex(key string) (int, string) { 106 if strings.HasPrefix(key, _prefixParamArr) { 107 // param[0].$. 108 endIndex := strings.Index(key, "]") 109 indexStr := key[len(_prefixParamArr):endIndex] 110 index, err := strconv.ParseInt(indexStr, 10, 32) 111 if err != nil { 112 return -1, "" 113 } 114 startIndex := endIndex + 2 115 if rune(key[endIndex+1]) != rune('.') { 116 startIndex = endIndex + 1 117 } 118 return int(index), key[startIndex:] 119 } else if strings.HasPrefix(key, _pefixParam) { 120 key = strings.TrimPrefix(key, _pefixParam+".") 121 return 0, strings.TrimPrefix(key, _pefixParam+".") 122 } 123 124 return -1, "" 125 }