github.com/TIBCOSoftware/flogo-lib@v0.5.9/core/mapper/exprmapper/json/get.go (about) 1 package json 2 3 import ( 4 "fmt" 5 "github.com/TIBCOSoftware/flogo-lib/core/mapper/exprmapper/json/field" 6 "strconv" 7 "strings" 8 9 "sync" 10 11 "encoding/json" 12 "github.com/TIBCOSoftware/flogo-lib/logger" 13 ) 14 15 var log = logger.GetLogger("json") 16 17 func GetPathValue(value interface{}, refPath string) (interface{}, error) { 18 mappingField, err := field.ParseMappingField(refPath) 19 if err != nil { 20 return nil, fmt.Errorf("parse mapping path [%s] failed, due to %s", refPath, err.Error()) 21 } 22 23 if mappingField == nil || len(mappingField.Getfields()) <= 0 { 24 value, err := makeInterface(value) 25 if err != nil { 26 value = value 27 } 28 return value, nil 29 } 30 return GetFieldValue(value, mappingField) 31 } 32 33 func GetFieldValue(data interface{}, mappingField *field.MappingField) (interface{}, error) { 34 var jsonParsed *Container 35 var err error 36 switch data.(type) { 37 case string: 38 jsonParsed, err = ParseJSON([]byte(data.(string))) 39 default: 40 if IsMapperableType(data) { 41 jsonParsed, err = Consume(data) 42 } else { 43 //Take is as string to handle 44 b, err := json.Marshal(data) 45 if err != nil { 46 return nil, err 47 } 48 jsonParsed, err = ParseJSON(b) 49 } 50 } 51 52 if err != nil { 53 return nil, err 54 55 } 56 return handleGetValue(&JSONData{container: jsonParsed, rw: sync.RWMutex{}}, mappingField.Getfields()) 57 } 58 59 func handleGetValue(jsonData *JSONData, fields []string) (interface{}, error) { 60 jsonData.rw.Lock() 61 defer jsonData.rw.Unlock() 62 63 container := jsonData.container 64 if hasArrayFieldInArray(fields) { 65 arrayFields, fieldNameindex, arrayIndex := getArrayFieldName(fields) 66 //No array field found 67 if fieldNameindex == -1 { 68 return container.S(arrayFields...).Data(), nil 69 } 70 restFields := fields[fieldNameindex+1:] 71 specialField, err := container.ArrayElement(arrayIndex, arrayFields...) 72 if err != nil { 73 return nil, err 74 } 75 log.Debugf("Array element value %s", specialField) 76 if hasArrayFieldInArray(restFields) { 77 return handleGetValue(&JSONData{container: specialField, rw: sync.RWMutex{}}, restFields) 78 } 79 return specialField.S(restFields...).Data(), nil 80 } 81 return container.S(fields...).Data(), nil 82 } 83 84 func getFieldName(fieldName string) string { 85 if strings.Index(fieldName, "[") >= 0 { 86 return fieldName[0:strings.Index(fieldName, "[")] 87 } 88 89 return fieldName 90 } 91 92 func getFieldSliceIndex(fieldName string) (int, error) { 93 if strings.Index(fieldName, "[") >= 0 { 94 index := fieldName[strings.Index(fieldName, "[")+1 : strings.Index(fieldName, "]")] 95 i, err := strconv.Atoi(index) 96 97 if err != nil { 98 return -2, nil 99 } 100 return i, nil 101 } 102 103 return -1, nil 104 } 105 106 func getNameInsideBrancket(fieldName string) string { 107 if strings.Index(fieldName, "[") >= 0 { 108 index := fieldName[strings.Index(fieldName, "[")+1 : strings.Index(fieldName, "]")] 109 return index 110 } 111 112 return "" 113 } 114 115 func makeInterface(value interface{}) (interface{}, error) { 116 117 var paramMap interface{} 118 119 if value == nil { 120 return paramMap, nil 121 } 122 123 switch t := value.(type) { 124 case string: 125 err := json.Unmarshal([]byte(t), ¶mMap) 126 if err != nil { 127 return nil, err 128 } 129 return paramMap, nil 130 default: 131 return value, nil 132 } 133 return paramMap, nil 134 } 135 136 func getArrayFieldName(fields []string) ([]string, int, int) { 137 var tmpFields []string 138 index := -1 139 var arrayIndex int 140 for i, field := range fields { 141 if strings.Index(field, "[") >= 0 && strings.Index(field, "]") >= 0 { 142 arrayIndex, _ = getFieldSliceIndex(field) 143 fieldName := getFieldName(field) 144 index = i 145 if fieldName != "" { 146 tmpFields = append(tmpFields, getFieldName(field)) 147 } 148 break 149 } else { 150 tmpFields = append(tmpFields, field) 151 } 152 } 153 return tmpFields, index, arrayIndex 154 } 155 156 func hasArrayFieldInArray(fields []string) bool { 157 for _, field := range fields { 158 if strings.Index(field, "[") >= 0 && strings.HasSuffix(field, "]") { 159 //Make sure the index are integer 160 _, err := strconv.Atoi(getNameInsideBrancket(field)) 161 if err == nil { 162 return true 163 } 164 } 165 } 166 return false 167 }