github.com/TIBCOSoftware/flogo-lib@v0.5.9/core/mapper/exprmapper/json/field/field.go (about) 1 package field 2 3 import ( 4 "fmt" 5 "strings" 6 "text/scanner" 7 "unicode" 8 ) 9 10 type MappingField struct { 11 fields []string 12 ref string 13 s *scanner.Scanner 14 } 15 16 func NewMappingField(fields []string) *MappingField { 17 return &MappingField{fields: fields} 18 } 19 20 func ParseMappingField(mRef string) (*MappingField, error) { 21 //Remove any . at beginning 22 if strings.HasPrefix(mRef, ".") { 23 mRef = mRef[1:] 24 } 25 g := &MappingField{ref: mRef} 26 27 err := g.Start(mRef) 28 if err != nil { 29 return nil, fmt.Errorf("parse mapping [%s] failed, due to %s", mRef, err.Error()) 30 } 31 return g, nil 32 } 33 34 func (m *MappingField) GetRef() string { 35 return m.ref 36 } 37 38 func (m *MappingField) Getfields() []string { 39 return m.fields 40 } 41 42 func (m *MappingField) paserName() error { 43 fieldName := "" 44 switch ch := m.s.Scan(); ch { 45 case '.': 46 return m.Parser() 47 case '[': 48 //Done 49 if fieldName != "" { 50 m.fields = append(m.fields, fieldName) 51 } 52 m.s.Mode = scanner.ScanInts 53 nextAfterBracket := m.s.Scan() 54 if nextAfterBracket == '"' || nextAfterBracket == '\'' { 55 //Special charactors 56 m.s.Mode = scanner.ScanIdents 57 return m.handleSpecialField(nextAfterBracket) 58 } else { 59 //HandleArray 60 if m.fields == nil || len(m.fields) <= 0 { 61 m.fields = append(m.fields, "["+m.s.TokenText()+"]") 62 } else { 63 m.fields[len(m.fields)-1] = m.fields[len(m.fields)-1] + "[" + m.s.TokenText() + "]" 64 } 65 ch := m.s.Scan() 66 if ch != ']' { 67 return fmt.Errorf("Inliad array format") 68 } 69 m.s.Mode = scanner.ScanIdents 70 return m.Parser() 71 } 72 case scanner.EOF: 73 if fieldName != "" { 74 m.fields = append(m.fields, fieldName) 75 } 76 default: 77 fieldName = fieldName + m.s.TokenText() 78 if fieldName != "" { 79 m.fields = append(m.fields, fieldName) 80 } 81 return m.Parser() 82 } 83 84 return nil 85 } 86 87 func (m *MappingField) handleSpecialField(startQutoes int32) error { 88 fieldName := "" 89 run := true 90 91 for run { 92 switch ch := m.s.Scan(); ch { 93 case startQutoes: 94 //Check if end with startQutoes] 95 nextAfterQuotes := m.s.Scan() 96 if nextAfterQuotes == ']' { 97 //end specialfield, startover 98 m.fields = append(m.fields, fieldName) 99 run = false 100 return m.Parser() 101 } else { 102 fieldName = fieldName + string(startQutoes) 103 fieldName = fieldName + m.s.TokenText() 104 } 105 default: 106 fieldName = fieldName + m.s.TokenText() 107 } 108 } 109 return nil 110 } 111 112 func (m *MappingField) Parser() error { 113 switch ch := m.s.Scan(); ch { 114 case '.': 115 return m.paserName() 116 case '[': 117 m.s.Mode = scanner.ScanInts 118 nextAfterBracket := m.s.Scan() 119 if nextAfterBracket == '"' || nextAfterBracket == '\'' { 120 //Special charactors 121 m.s.Mode = scanner.ScanIdents 122 return m.handleSpecialField(nextAfterBracket) 123 } else { 124 //HandleArray 125 if m.fields == nil || len(m.fields) <= 0 { 126 m.fields = append(m.fields, "["+m.s.TokenText()+"]") 127 } else { 128 m.fields[len(m.fields)-1] = m.fields[len(m.fields)-1] + "[" + m.s.TokenText() + "]" 129 } 130 //m.handleArray() 131 ch := m.s.Scan() 132 if ch != ']' { 133 return fmt.Errorf("Inliad array format") 134 } 135 m.s.Mode = scanner.ScanIdents 136 return m.Parser() 137 } 138 case scanner.EOF: 139 //Done 140 return nil 141 default: 142 m.fields = append(m.fields, m.s.TokenText()) 143 return m.paserName() 144 } 145 return nil 146 } 147 148 func (m *MappingField) Start(jsonPath string) error { 149 m.s = new(scanner.Scanner) 150 m.s.IsIdentRune = IsIdentRune 151 m.s.Init(strings.NewReader(jsonPath)) 152 m.s.Mode = scanner.ScanIdents 153 //Donot skip space and new line 154 m.s.Whitespace ^= 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' ' 155 return m.Parser() 156 } 157 158 func IsIdentRune(ch rune, i int) bool { 159 return ch == '$' || ch == '-' || ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0 160 }