/
assign.go
128 lines (112 loc) · 3.76 KB
/
assign.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package assign
import (
"errors"
"fmt"
"github.com/TIBCOSoftware/flogo-lib/core/data"
"github.com/TIBCOSoftware/flogo-lib/core/mapper/exprmapper/json"
"github.com/TIBCOSoftware/flogo-lib/core/mapper/exprmapper/json/field"
"github.com/TIBCOSoftware/flogo-lib/core/mapper/exprmapper/ref"
"github.com/TIBCOSoftware/flogo-lib/logger"
"strings"
)
var log = logger.GetLogger("assign-mapper")
func MapAssign(mapping *data.MappingDef, inputScope, outputScope data.Scope, resolver data.Resolver) error {
mappingValue, err := GetMappingValue(mapping.Value, inputScope, resolver)
if err != nil {
return err
}
err = SetValueToOutputScope(mapping.MapTo, outputScope, mappingValue)
if err != nil {
err = fmt.Errorf("Set value %+v to output [%s] error - %s", mappingValue, mapping.MapTo, err.Error())
log.Error(err)
return err
}
log.Debugf("Set value %+v to %s Done", mappingValue, mapping.MapTo)
return nil
}
func GetMappingValue(mappingV interface{}, inputScope data.Scope, resolver data.Resolver) (interface{}, error) {
mappingValue, ok := mappingV.(string)
if !ok {
return mappingV, nil
}
if !isMappingRef(mappingValue) {
log.Debug("Mapping value is literal set directly to field")
log.Debugf("Mapping ref %s and value %+v", mappingValue, mappingValue)
return mappingValue, nil
} else {
mappingref := ref.NewMappingRef(mappingValue)
mappingValue, err := mappingref.GetValue(inputScope, resolver)
if err != nil {
return nil, fmt.Errorf("Get value from ref [%s] error - %s", mappingref.GetRef(), err.Error())
}
log.Debugf("Mapping ref %s and value %+v", mappingValue, mappingValue)
return mappingValue, nil
}
return nil, nil
}
func isMappingRef(mappingref string) bool {
if mappingref == "" || !strings.HasPrefix(mappingref, "$") {
return false
}
return true
}
func SetValueToOutputScope(mapTo string, outputScope data.Scope, value interface{}) error {
mapField, err := field.ParseMappingField(mapTo)
if err != nil {
return err
}
actRootField, err := ref.GetMapToAttrName(mapField)
if err != nil {
return err
}
fields := mapField.Getfields()
if len(fields) == 1 && !ref.HasArray(fields[0]) {
//No complex mapping exist
return SetAttribute(actRootField, value, outputScope)
} else if ref.HasArray(fields[0]) || len(fields) > 1 {
//Complex mapping
return settValue(mapField, actRootField, outputScope, value)
} else {
return fmt.Errorf("No field name found for mapTo [%s]", mapTo)
}
}
func settValue(mapField *field.MappingField, fieldName string, outputScope data.Scope, value interface{}) error {
existValue, err := ref.GetValueFromOutputScope(mapField, outputScope)
if err != nil {
return err
}
newValue, err2 := SetPathValue(existValue, mapField, value)
if err2 != nil {
return err2
}
return SetAttribute(fieldName, newValue, outputScope)
}
func SetPathValue(value interface{}, mapField *field.MappingField, attrvalue interface{}) (interface{}, error) {
pathfields, err := ref.GetMapToPathFields(mapField)
if err != nil {
return nil, err
}
log.Debugf("Set value %+v to fields %s", value, pathfields)
value, err = json.SetFieldValue(attrvalue, value, pathfields)
if err != nil {
return nil, err
}
return value, nil
}
func SetAttribute(fieldName string, value interface{}, outputScope data.Scope) error {
//Set Attribute value back to attribute
attribute, exist := outputScope.GetAttr(fieldName)
if exist {
switch attribute.Type() {
case data.TypeComplexObject:
complexObject := attribute.Value().(*data.ComplexObject)
newComplexObject := &data.ComplexObject{Metadata: complexObject.Metadata, Value: value}
outputScope.SetAttrValue(fieldName, newComplexObject)
default:
outputScope.SetAttrValue(fieldName, value)
}
} else {
return errors.New("Cannot found attribute " + fieldName + " at output scope")
}
return nil
}