github.com/TIBCOSoftware/flogo-lib@v0.5.9/core/mapper/exprmapper/json/set.go (about) 1 package json 2 3 import ( 4 "sync" 5 6 "github.com/TIBCOSoftware/flogo-lib/core/mapper/exprmapper/json/field" 7 ) 8 9 type JSONData struct { 10 container *Container 11 rw sync.RWMutex 12 } 13 14 func SetStringValue(data interface{}, jsonData string, mappingField *field.MappingField) (interface{}, error) { 15 jsonParsed, err := ParseJSON([]byte(jsonData)) 16 if err != nil { 17 return nil, err 18 19 } 20 container := &JSONData{container: jsonParsed, rw: sync.RWMutex{}} 21 err = handleSetValue(data, container, mappingField.Getfields()) 22 return container.container.object, err 23 } 24 25 func SetFieldValue(data interface{}, jsonData interface{}, mappingField *field.MappingField) (interface{}, error) { 26 switch t := jsonData.(type) { 27 case string: 28 return SetStringValue(data, t, mappingField) 29 default: 30 jsonParsed, err := Consume(jsonData) 31 if err != nil { 32 return nil, err 33 } 34 container := &JSONData{container: jsonParsed, rw: sync.RWMutex{}} 35 err = handleSetValue(data, container, mappingField.Getfields()) 36 if err != nil { 37 return nil, err 38 } 39 return container.container.object, nil 40 } 41 42 } 43 44 func handleSetValue(value interface{}, jsonData *JSONData, fields []string) error { 45 46 jsonData.rw.Lock() 47 defer jsonData.rw.Unlock() 48 49 container := jsonData.container 50 if hasArrayFieldInArray(fields) { 51 arrayFields, fieldNameindex, arrayIndex := getArrayFieldName(fields) 52 //No array field found 53 if fieldNameindex == -1 { 54 if arrayIndex == -2 { 55 //Append 56 err := container.ArrayAppend(value, arrayFields...) 57 if err != nil { 58 return err 59 } 60 } else { 61 //set to exist index array 62 size, err := container.ArrayCount(arrayFields...) 63 if err != nil { 64 return err 65 } 66 if arrayIndex > size-1 { 67 err := container.ArrayAppend(value, arrayFields...) 68 if err != nil { 69 return err 70 } 71 } else { 72 array := container.S(arrayFields...) 73 _, err := array.SetIndex(value, arrayIndex) 74 if err != nil { 75 return err 76 } 77 } 78 } 79 } else { 80 restFields := fields[fieldNameindex+1:] 81 //Has field before [0] 82 if arrayFields != nil { 83 //check if array field exist 84 if container.Exists(arrayFields...) { 85 if restFields == nil || len(restFields) <= 0 { 86 array, ok := container.Search(arrayFields...).Data().([]interface{}) 87 if ok { 88 if arrayIndex > len(array)-1 { 89 array = append(array, value) 90 } else { 91 array[arrayIndex] = value 92 } 93 } 94 _, err := container.Set(array, arrayFields...) 95 return err 96 } else { 97 var element *Container 98 var err error 99 count, err := container.ArrayCount(arrayFields...) 100 if err != nil { 101 return err 102 } 103 if arrayIndex > count-1 { 104 maps := make(map[string]interface{}) 105 newObject, _ := Consume(maps) 106 _, err = newObject.Set(value, restFields...) 107 log.Debugf("new object %s", newObject.String()) 108 if err != nil { 109 return err 110 } 111 112 err = container.ArrayAppend(maps, arrayFields...) 113 if err != nil { 114 return err 115 } 116 if !hasArrayFieldInArray(restFields) { 117 return nil 118 } 119 120 } 121 122 element, err = container.ArrayElement(arrayIndex, arrayFields...) 123 if err != nil { 124 return err 125 } 126 return handleSetValue(value, &JSONData{container: element, rw: sync.RWMutex{}}, restFields) 127 } 128 } 129 130 } else if fieldNameindex == 0 && getFieldName(fields[fieldNameindex]) == "" { 131 //Root only [0] 132 array, ok := container.Data().([]interface{}) 133 if !ok { 134 var err error 135 array, err = ToArray(container.Data()) 136 if err != nil { 137 array = make([]interface{}, arrayIndex+1) 138 } 139 140 } 141 container.object = array 142 143 if restFields == nil || len(restFields) <= 0 { 144 _, err := container.SetIndex(value, arrayIndex) 145 return err 146 } else { 147 if hasArrayFieldInArray(restFields) { 148 //We need make sure the array element is not empty 149 count, err := container.ArrayCount(arrayFields...) 150 if err != nil { 151 return err 152 } 153 if arrayIndex > count-1 { 154 err = container.ArrayAppend(map[string]interface{}{}) 155 if err != nil { 156 return err 157 } 158 } 159 160 arrayElement, err := container.ArrayElement(arrayIndex) 161 if err != nil { 162 return err 163 } 164 if arrayElement.object == nil { 165 arrayElement.object = map[string]interface{}{} 166 } 167 err = handleSetValue(value, &JSONData{container: arrayElement, rw: sync.RWMutex{}}, restFields) 168 if err != nil { 169 return err 170 } 171 //Set value back to array 172 _, err = container.SetIndex(arrayElement.object, arrayIndex) 173 return err 174 } 175 176 arrayElement, err := getArrayElementValue(container, arrayFields, restFields, arrayIndex, value) 177 if err != nil { 178 return err 179 } 180 181 _, err = container.SetIndex(arrayElement.object, arrayIndex) 182 return err 183 } 184 } 185 186 //Not exist in the exist container, create new one 187 array, err := container.ArrayOfSize(arrayIndex+1, arrayFields...) 188 if err != nil { 189 return err 190 } 191 192 if hasArrayFieldInArray(restFields) { 193 //We need make sure the array element is not empty 194 arrayElement, err := array.ArrayElement(arrayIndex) 195 if err != nil { 196 return err 197 } 198 if arrayElement.object == nil { 199 arrayElement.object = map[string]interface{}{} 200 } 201 202 err = handleSetValue(value, &JSONData{container: arrayElement, rw: sync.RWMutex{}}, restFields) 203 if err != nil { 204 return err 205 } 206 //Set value back to array 207 _, err = container.S(arrayFields...).SetIndex(arrayElement.object, arrayIndex) 208 return err 209 } 210 211 maps := make(map[string]interface{}) 212 newObject, _ := Consume(maps) 213 _, err = newObject.Set(value, restFields...) 214 log.Debugf("new object %s", newObject.String()) 215 if err != nil { 216 return err 217 } 218 _, err = array.SetIndex(newObject.object, arrayIndex) 219 } 220 } else { 221 _, err := jsonData.container.Set(value, fields...) 222 if err != nil { 223 return err 224 } 225 } 226 return nil 227 } 228 229 func getArrayElementValue(container *Container, arrayFields []string, restFields []string, arrayIndex int, value interface{}) (*Container, error) { 230 count, err := container.ArrayCount(arrayFields...) 231 if err != nil { 232 return nil, err 233 } 234 235 if arrayIndex > count-1 { 236 maps := make(map[string]interface{}) 237 newObject, _ := Consume(maps) 238 _, err := newObject.Set(value, restFields...) 239 log.Debugf("new object %s", newObject.String()) 240 if err != nil { 241 return nil, err 242 } 243 value = newObject.object 244 } 245 246 arrayElement, err := container.ArrayElement(arrayIndex) 247 if err != nil { 248 return nil, err 249 } 250 if arrayElement.object == nil { 251 arrayElement.object = map[string]interface{}{} 252 } 253 _, err = arrayElement.Set(value, restFields...) 254 return arrayElement, err 255 }