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  }