@@ -2,6 +2,7 @@ package ognl
22
33import (
44 "errors"
5+ "fmt"
56 "reflect"
67 "strconv"
78 "unsafe"
@@ -14,6 +15,8 @@ var ErrMapKeyMustInt = errors.New("map key must be int")
1415var ErrIndexOutOfBounds = errors .New ("index out of bounds" )
1516var ErrStructIndexOutOfBounds = errors .New ("struct index out of bounds" )
1617var ErrParseInt = errors .New ("parse int error" )
18+ var ErrUnableExpand = errors .New ("unable to expand" )
19+ var ErrInvalidValue = errors .New ("invalid value" )
1720
1821// Type is Result type
1922type Type int
@@ -146,7 +149,31 @@ func (r Result) Values() []interface{} {
146149 }
147150 return r .raw .([]interface {})
148151 }
149- return []interface {}{r .raw }
152+
153+ v , t , _ := deployment (reflect .TypeOf (r .raw ), reflect .ValueOf (r .raw ))
154+ if t == Invalid {
155+ return []interface {}{r .raw }
156+ }
157+ return v
158+ }
159+
160+ func (r Result ) ValuesE () ([]interface {}, error ) {
161+
162+ if r .deployment {
163+ if r .raw == nil {
164+ return nil , nil
165+ }
166+ return r .raw .([]interface {}), nil
167+ }
168+
169+ v , t , err := deployment (reflect .TypeOf (r .raw ), reflect .ValueOf (r .raw ))
170+ if err != nil {
171+ return nil , warpError (err , r .raw , "" )
172+ }
173+ if t == Invalid {
174+ return []interface {}{r .raw }, nil
175+ }
176+ return v , nil
150177}
151178
152179func (r Result ) Diagnosis () []error {
@@ -171,14 +198,184 @@ func (r Result) Get(path string) Result {
171198 return Get (r .raw , path )
172199}
173200
201+ func (r Result ) GetE (path string ) (Result , error ) {
202+ if r .deployment {
203+ nr := r
204+ list := nr .raw .([]interface {})
205+ ln := len (list )
206+ for i := 0 ; i < ln ; i ++ {
207+ next , err := GetE (list [i ], path )
208+ if err != nil {
209+ nr .diagnosis = append (nr .diagnosis , warpError (err , list [i ], path ))
210+ }
211+ if next .typ != Invalid {
212+ list = append (list , next .raw )
213+ }
214+ nr .diagnosis = append (nr .diagnosis , next .diagnosis ... )
215+ }
216+ nr .raw = list [ln :]
217+ if len (list [ln :]) == 0 {
218+ return nr , warpError (ErrInvalidValue , list , path )
219+ }
220+ return nr , nil
221+ }
222+ return GetE (r .raw , path )
223+ }
224+
174225func Parse (result interface {}) Result {
175226 return Get (result , "" )
176227}
177228
178- func Get (value interface {}, path string ) Result {
229+ func GetE (value interface {}, path string ) (Result , error ) {
230+ if value == nil && (len (path ) == 0 || validIdentifier (path , 0 )) {
231+ return Result {typ : Interface , raw : value }, nil
232+ }
179233 if value == nil {
234+ return Result {typ : Invalid , raw : value }, warpError (ErrInvalidValue , value , path )
235+ }
236+
237+ var (
238+ index int
239+ result = Result {
240+ typ : Interface ,
241+ raw : value ,
242+ }
243+ )
244+ tp := reflect .TypeOf (value )
245+ tv := reflect .ValueOf (value )
246+
247+ if ! tv .IsValid () {
248+ result .typ = Invalid
249+ return result , warpError (ErrInvalidValue , value , path )
250+ }
251+
252+ for ; index < len (path ); index ++ {
253+ switch path [index ] {
254+ case ' ' , '\t' , '\n' , '\r' , '.' :
255+ switch result .deployment {
256+ case true :
257+ list := result .raw .([]interface {})
258+ ln := len (list )
259+ for i := 0 ; i < ln ; i ++ {
260+ next , err := GetE (list [i ], path [index + 1 :])
261+ if err != nil {
262+ result .diagnosis = append (result .diagnosis , warpError (err , list [i ], path [index + 1 :]))
263+ }
264+ if next .typ != Invalid {
265+ list = append (list , next .raw )
266+ }
267+
268+ result .diagnosis = append (result .diagnosis , next .diagnosis ... )
269+ }
270+ result .raw = list [ln :]
271+ if len (list [ln :]) == 0 {
272+ return result , warpError (ErrInvalidValue , list , string (path [index ]))
273+ }
274+ return result , nil
275+ default :
276+ return GetE (result .raw , path [index + 1 :])
277+ }
278+ case '#' :
279+ // 转化成slice 类型 平铺
280+ switch result .deployment {
281+ case true :
282+ // queue 展开
283+ list := result .raw .([]interface {})
284+ ln := len (list )
285+ for i := 0 ; i < ln ; i ++ {
286+ raw , typ , err := deployment (reflect .TypeOf (list [i ]), reflect .ValueOf (list [i ]))
287+ if err != nil {
288+ result .diagnosis = append (result .diagnosis , warpError (err , list [i ], "#" ))
289+ }
290+ if typ != Invalid {
291+ list = append (list , raw ... )
292+ }
293+ }
294+ result .raw = list [ln :]
295+ if len (list [ln :]) == 0 {
296+ return result , warpError (ErrInvalidValue , list , "#" )
297+ }
298+ default :
299+ result .deployment = true
300+ var err error
301+ result .raw , result .typ , err = deployment (tp , tv )
302+ if err != nil {
303+ return result , warpError (err , value , "#" )
304+ }
305+ result .diagnosis = append (result .diagnosis , err )
306+ }
307+
308+ default :
309+ start := index
310+ loop:
311+ for ; index < len (path ); index ++ {
312+ switch path [index ] {
313+ case '.' , '#' :
314+ index --
315+ break loop
316+ }
317+ }
318+ sv := path [start :min (index + 1 , len (path ))]
319+ v , err := strconv .Atoi (sv )
320+ digit := err == nil && v >= 0
321+ switch result .deployment {
322+ case true :
323+ var (
324+ value interface {}
325+ tp Type
326+ )
327+ list := result .raw .([]interface {})
328+ ln := len (list )
329+ for i := 0 ; i < ln ; i ++ {
330+ if digit {
331+ value , tp , err = parseInt (reflect .TypeOf (list [i ]), reflect .ValueOf (list [i ]), v )
332+ } else {
333+ value , tp , err = parseString (reflect .TypeOf (list [i ]), reflect .ValueOf (list [i ]), sv )
334+ }
335+ if err != nil {
336+ result .diagnosis = append (result .diagnosis , warpError (err , list [i ], sv ))
337+ }
338+ if tp != Invalid {
339+ list = append (list , value )
340+ }
341+ }
342+ result .raw = list [ln :]
343+ if len (list [ln :]) == 0 {
344+ return result , warpError (ErrInvalidValue , list , sv )
345+ }
346+
347+ default :
348+ var (
349+ nv interface {}
350+ tpe Type
351+ )
352+ if digit {
353+ nv , tpe , err = parseInt (tp , tv , v )
354+ } else {
355+ nv , tpe , err = parseString (tp , tv , sv )
356+ }
357+ if err != nil {
358+ return result , warpError (err , value , sv )
359+ }
360+ if tpe == Invalid {
361+ return result , warpError (ErrInvalidValue , value , sv )
362+ }
363+ result .raw = nv
364+ result .typ = tpe
365+ }
366+ }
367+ }
368+
369+ return result , nil
370+ }
371+
372+ func Get (value interface {}, path string ) Result {
373+ if value == nil && (len (path ) == 0 || validIdentifier (path , 0 )) {
180374 return Result {typ : Interface , raw : value }
181375 }
376+ if value == nil {
377+ return Result {typ : Invalid , raw : value , diagnosis : []error {warpError (ErrInvalidValue , value , path )}}
378+ }
182379
183380 var index int
184381
@@ -190,6 +387,7 @@ func Get(value interface{}, path string) Result {
190387 tv := reflect .ValueOf (value )
191388
192389 if ! tv .IsValid () {
390+ result .diagnosis = append (result .diagnosis , warpError (ErrInvalidValue , value , path ))
193391 return result
194392 }
195393
@@ -222,7 +420,7 @@ func Get(value interface{}, path string) Result {
222420 for i := 0 ; i < ln ; i ++ {
223421 raw , typ , err := deployment (reflect .TypeOf (list [i ]), reflect .ValueOf (list [i ]))
224422 if err != nil {
225- result .diagnosis = append (result .diagnosis , err )
423+ result .diagnosis = append (result .diagnosis , warpError ( err , list [ i ], "#" ) )
226424 }
227425 if typ != Invalid {
228426 list = append (list , raw ... )
@@ -234,7 +432,7 @@ func Get(value interface{}, path string) Result {
234432 var err error
235433 result .raw , result .typ , err = deployment (tp , tv )
236434 if err != nil {
237- result .diagnosis = append (result .diagnosis , err )
435+ result .diagnosis = append (result .diagnosis , warpError ( err , value , "#" ) )
238436 }
239437 }
240438
@@ -266,7 +464,7 @@ func Get(value interface{}, path string) Result {
266464 value , tp , err = parseString (reflect .TypeOf (list [i ]), reflect .ValueOf (list [i ]), sv )
267465 }
268466 if err != nil {
269- result .diagnosis = append (result .diagnosis , err )
467+ result .diagnosis = append (result .diagnosis , warpError ( err , list [ i ], sv ) )
270468 }
271469 if tp != Invalid {
272470 list = append (list , value )
@@ -275,18 +473,18 @@ func Get(value interface{}, path string) Result {
275473 result .raw = list [ln :]
276474 default :
277475 var (
278- value interface {}
279- tpe Type
476+ nv interface {}
477+ tpe Type
280478 )
281479 if digit {
282- value , tpe , err = parseInt (tp , tv , v )
480+ nv , tpe , err = parseInt (tp , tv , v )
283481 } else {
284- value , tpe , err = parseString (tp , tv , sv )
482+ nv , tpe , err = parseString (tp , tv , sv )
285483 }
286484 if err != nil {
287- result .diagnosis = append (result .diagnosis , err )
485+ result .diagnosis = append (result .diagnosis , warpError ( err , value , sv ) )
288486 }
289- result .raw = value
487+ result .raw = nv
290488 result .typ = tpe
291489 if tpe == Invalid {
292490 return result
@@ -472,10 +670,29 @@ func deployment(t reflect.Type, v reflect.Value) ([]interface{}, Type, error) {
472670 return ret , Interface , nil
473671
474672 default :
475- return []interface {}{v .Interface ()}, Type (v .Kind ()), nil
673+ return []interface {}{v .Interface ()}, Type (v .Kind ()), ErrUnableExpand
476674 }
477675}
478676
677+ func validIdentifier (path string , limit int ) bool {
678+ count := 0
679+ for _ , v := range path {
680+ switch v {
681+ case ' ' , '\t' , '\n' , '\r' , '.' :
682+ default :
683+ count ++
684+ if count > limit {
685+ return false
686+ }
687+ }
688+ }
689+ return true
690+ }
691+
692+ func warpError (err error , object interface {}, path string ) error {
693+ return fmt .Errorf ("object:%v,path:%s,err: %w" , object , path , err )
694+ }
695+
479696func min (a , b int ) int {
480697 if a > b {
481698 return b
0 commit comments