Skip to content

Commit

Permalink
Merge pull request #148 from TIBCOSoftware/expression-flow-resovler
Browse files Browse the repository at this point in the history
Handle $. to get current scope attr data
  • Loading branch information
lixingwang authored Mar 18, 2018
2 parents 6e7b3e9 + 40d770e commit c59a67f
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 15 deletions.
26 changes: 20 additions & 6 deletions core/data/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ func PathGetValue(value interface{}, path string) (interface{}, error) {
return nil, fmt.Errorf("unable to evaluate path: %s", path)
}
} else if strings.HasPrefix(path, "[") {
newVal, newPath, err = pathGetSetArrayValue(value, path, nil, false)
if objVal, ok := value.(*ComplexObject); ok {
newVal, newPath, err = pathGetSetArrayValue(objVal.Value, path, nil, false)
} else {
newVal, newPath, err = pathGetSetArrayValue(value, path, nil, false)

}
} else {
return nil, fmt.Errorf("unable to evaluate path: %s", path)
}
Expand Down Expand Up @@ -83,7 +88,11 @@ func PathSetValue(attrValue interface{}, path string, value interface{}) error {
}

} else if strings.HasPrefix(path, "[") {
newVal, newPath, err = pathGetSetArrayValue(attrValue, path, value, true)
if objVal, ok := value.(*ComplexObject); ok {
newVal, newPath, err = pathGetSetArrayValue(attrValue, path, objVal.Value, true)
} else {
newVal, newPath, err = pathGetSetArrayValue(attrValue, path, value, true)
}
} else {
return fmt.Errorf("Unable to evaluate path: %s", path)
}
Expand Down Expand Up @@ -116,7 +125,7 @@ func getMapKey(s string) (string, int) {

if s[i] == '"' {
return s[:i], i + 4 // [" "]
}
}

i += 1
}
Expand All @@ -128,7 +137,12 @@ func pathGetSetArrayValue(obj interface{}, path string, value interface{}, set b

arrValue, valid := obj.([]interface{})
if !valid {
return nil, path, errors.New("'" + path + "' not an array")
//Try to convert to a array incase it is a array string
val, err := CoerceToArray(obj)
if err != nil {
return nil, path, errors.New("'" + path + "' not an array")
}
arrValue = val
}

closeIdx := strings.Index(path, "]")
Expand Down Expand Up @@ -203,7 +217,7 @@ func pathGetSetMapValue(objValue map[string]interface{}, path string, value inte

key, npIdx := getMapKey(path[2:])

if set && key + `"]` == path[2:] {
if set && key+`"]` == path[2:] {
//end of path so set the value
objValue[key] = value
return nil, "", nil
Expand All @@ -225,7 +239,7 @@ func pathGetSetMapValue(objValue map[string]interface{}, path string, value inte
func pathGetSetMapParamsValue(params map[string]string, path string, value interface{}, set bool) (interface{}, string, error) {

key, _ := getMapKey(path[2:])
if set && key + `"]` == path[2:] {
if set && key+`"]` == path[2:] {
//end of path so set the value
paramVal, err := CoerceToString(value)

Expand Down
25 changes: 22 additions & 3 deletions core/data/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,25 @@ func (r *BasicResolver) Resolve(toResolve string, scope Scope) (value interface{
logger.Error(err.Error())
return "", err
}
case ".":
//Current scope resolution
attr, exists := scope.GetAttr(details.Property)
if !exists {
return nil, fmt.Errorf("failed to resolve current scope: '%s', not found in scope", details.Property)
}
value = attr.Value()
default:
return nil, fmt.Errorf("unsupported resolver: %s", details.ResolverName)
}

if details.Path != "" {
value, err = PathGetValue(value, details.Path)
if err != nil {
logger.Error(err.Error())
return nil, err
}
}

return value, nil
}

Expand Down Expand Up @@ -124,8 +139,12 @@ func GetResolutionDetails(toResolve string) (*ResolutionDetails, error) {
details.Item = toResolve[itemIdx+1 : dotIdx-1]
details.ResolverName = toResolve[:itemIdx]
} else {
details.ResolverName = toResolve[:dotIdx]

//For the case to get current scope atribute data
if strings.HasPrefix(toResolve, "$.") || strings.HasPrefix(toResolve, ".") {
details.ResolverName = toResolve[:dotIdx+1]
} else {
details.ResolverName = toResolve[:dotIdx]
}
//special case for activity without brackets
if strings.HasPrefix(toResolve, "activity") {
nextDot := strings.Index(toResolve[dotIdx+1:], ".") + dotIdx + 1
Expand Down Expand Up @@ -218,4 +237,4 @@ func GetValueWithResolver(valueMap map[string]interface{}, key string) (interfac
}

return val, true
}
}
30 changes: 27 additions & 3 deletions core/data/resolve_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package data

import (
"github.com/stretchr/testify/assert"
"testing"

"github.com/stretchr/testify/assert"
)

func TestGetResolutionDetails(t *testing.T) {
Expand Down Expand Up @@ -50,7 +51,6 @@ func TestGetResolutionDetails(t *testing.T) {
assert.Equal(t, "myMapAttributeName", details.Property)
assert.Equal(t, `["a.b"]`, details.Path)


// Resolution of second level Activity expression array
a = "activity.myactivityId.myArrayAttributeName[0]"
details, err = GetResolutionDetails(a)
Expand Down Expand Up @@ -165,4 +165,28 @@ func TestGetResolutionDetailsOld(t *testing.T) {
assert.Equal(t, "myArrayAttributeName", details.Property)
assert.Equal(t, "myactivityId", details.Item)
assert.Equal(t, "[0]", details.Path)
}
}

func TestToGetCurrentScope(t *testing.T) {
a := "$.header.Accept"
details, err := GetResolutionDetails(a)
assert.Nil(t, err)
assert.Equal(t, "$.", details.ResolverName)
assert.Equal(t, "header", details.Property)
assert.Equal(t, ".Accept", details.Path)

a = "$.array[0]"
details, err = GetResolutionDetails(a)
assert.Nil(t, err)
assert.Equal(t, "$.", details.ResolverName)
assert.Equal(t, "array", details.Property)
assert.Equal(t, "[0]", details.Path)

a = "$.headers"
details, err = GetResolutionDetails(a)
assert.Nil(t, err)
assert.Equal(t, "$.", details.ResolverName)
assert.Equal(t, "headers", details.Property)
assert.Equal(t, "", details.Path)

}
5 changes: 3 additions & 2 deletions core/mapper/exprmapper/json/field/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

var log = logger.GetLogger("expr-mapper-field")

type MappingField struct {
HasSpecialField bool
HasArray bool
Expand All @@ -22,8 +23,8 @@ func GetAllspecialFields(path string) ([]string, error) {
var lastIndex = 0
matches := re.FindAllStringIndex(path, -1)
for i, match := range matches {
log.Debugf("Mathing index %d", match)
log.Debugf("Mathing string %s", path[match[0]:match[1]])
//log.Debugf("Mathing index %d", match)
//log.Debugf("Mathing string %s", path[match[0]:match[1]])

if i == 0 && lastIndex == 0 {
startPart := trimDot(path[:match[0]])
Expand Down
11 changes: 10 additions & 1 deletion core/mapper/exprmapper/ref/mappingref.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,16 @@ func (m *MappingRef) getValueFromAttribute(inputscope data.Scope, resolver data.
//Only need activity and field name
resolutionDetails.Path = ""
//var newRef string
newRef := resolutionDetails.ResolverName + "[" + resolutionDetails.Item + "]" + "." + resolutionDetails.Property
var newRef string
if resolutionDetails.ResolverName != "$." {
if resolutionDetails.Item != "" {
newRef = resolutionDetails.ResolverName + "[" + resolutionDetails.Item + "]" + "." + resolutionDetails.Property
} else {
newRef = resolutionDetails.ResolverName + "." + resolutionDetails.Property
}
} else {
newRef = resolutionDetails.ResolverName + resolutionDetails.Property
}

log.Debugf("Activity and root field name is: %s", newRef)
value, err := resolver.Resolve(newRef, inputscope)
Expand Down

0 comments on commit c59a67f

Please sign in to comment.