di-go/annotation/annotation.go

143 lines
3.2 KiB
Go
Raw Permalink Normal View History

2018-04-03 09:02:31 +00:00
package annotation
import (
2019-11-11 14:22:27 +00:00
"encoding/json"
2018-04-03 09:02:31 +00:00
"fmt"
"reflect"
"strings"
)
const (
2018-04-10 12:08:21 +00:00
AnnotationTag = "annotation"
AnnotationMetaTag = "@annotation"
AnnotationChar = "@"
AnnotationStartChar = "("
AnnotationEndChar = ")"
AnnotationSpliter = ";"
AnnotationAttributeSpliter = ","
AnnotationAttributeStartChar = "'"
AnnotationAttributeEndChar = "'"
AnnotationKeyValueSpliter = "="
AnnotationAttributeArrayStartChar = "["
AnnotationAttributeArrayEndChar = "]"
AnnotationAttributeArrayItemSpliter = ","
AnnotationAttributeMapStartChar = "{"
AnnotationAttributeMapEndChar = "}"
AnnotationAttributeMapKeyValueSpliter = ":"
AnnotationAttributeMapItemSpliter = ","
2018-04-03 09:02:31 +00:00
)
type Annotation interface {
}
// @Inject(name? string)
// @Resource(name? string)
2018-04-10 12:30:57 +00:00
func ParseAnnotation(tag reflect.StructTag) (map[reflect.Type]Annotation, error) {
2018-04-03 09:02:31 +00:00
s := strings.Trim(tag.Get(AnnotationTag), " ")
if "" == s {
return nil, nil
}
2018-04-10 12:08:21 +00:00
annotations, err := splitAnnotation(s)
if nil != err {
return nil, err
}
2018-04-03 09:02:31 +00:00
if nil == annotations || 0 == len(annotations) {
return nil, nil
}
2018-04-10 12:30:57 +00:00
rKVs := make(map[reflect.Type]Annotation, 0)
2018-04-10 12:08:21 +00:00
for name, attributes := range annotations {
2018-04-10 12:30:57 +00:00
t, annotation, err := newAnnotation(name, attributes)
2018-04-03 09:02:31 +00:00
if nil != err {
return nil, err
}
2018-04-10 12:30:57 +00:00
rKVs[t] = annotation
2018-04-03 09:02:31 +00:00
}
return rKVs, nil
}
2019-11-11 14:22:27 +00:00
func splitAnnotation(s string) (map[string]string, error) {
ss := make(map[string]string, 0)
2018-04-10 12:08:21 +00:00
ts := s
for {
as := strings.Index(ts, AnnotationChar)
if -1 == as {
break
}
aas := strings.Index(ts, AnnotationStartChar)
aae := strings.Index(ts, AnnotationEndChar)
aName := ts[as:aas]
aAttributes := ts[aas+1 : aae]
if 0 < len(aAttributes) {
2019-11-11 14:22:27 +00:00
ss[aName] = aAttributes
2018-04-10 12:08:21 +00:00
} else {
2019-11-11 14:22:27 +00:00
ss[aName] = ""
2018-04-10 12:08:21 +00:00
}
2018-04-03 09:02:31 +00:00
2018-04-10 12:08:21 +00:00
if len(ts) <= (aae + 1) {
break
}
ts = ts[aae+1:]
2018-04-03 09:02:31 +00:00
}
2018-04-10 12:08:21 +00:00
return ss, nil
}
2018-04-03 09:02:31 +00:00
2019-11-11 14:41:01 +00:00
// func splitAnnotationAttribute(s string) (map[string]string, error) {
// ss := make(map[string]string, 0)
// ts := s
// for {
// as := strings.Index(ts, AnnotationKeyValueSpliter)
// if -1 == as {
// break
// }
// aName := ts[:as]
// aas := strings.Index(ts[as:], AnnotationAttributeStartChar)
// aae := strings.Index(ts[as+aas+1:], AnnotationAttributeEndChar)
// if -1 == aas && -1 == aae {
// ss[aName] = ts[as+1 : len(ts)]
// } else if -1 != aas && -1 != aae {
// ss[aName] = ts[as+aas+1 : as+aas+aae+1]
// } else {
// return nil, fmt.Errorf("not valid string %s", ts)
// }
// asi := strings.Index(ts[as+aae:], AnnotationAttributeSpliter)
// if -1 == asi {
// break
// }
// if len(ts) <= (as + aae + asi + 1) {
// break
// }
// ts = strings.TrimSpace(ts[as+aae+asi+1:])
// }
// return ss, nil
// }
2018-04-03 09:02:31 +00:00
2019-11-11 14:22:27 +00:00
func newAnnotation(name string, attributes string) (reflect.Type, Annotation, error) {
2018-04-10 12:08:21 +00:00
def, ok := annotationRegistry[name]
if !ok {
2018-04-10 12:30:57 +00:00
return nil, nil, fmt.Errorf("There is no annotation[%s]", name)
2018-04-03 09:02:31 +00:00
}
2018-04-10 12:08:21 +00:00
v := reflect.New(def.rt)
i := v.Interface().(Annotation)
2018-04-03 09:02:31 +00:00
2019-11-11 14:22:27 +00:00
if "" != attributes {
_json := fmt.Sprintf("{%s}", attributes)
if err := json.Unmarshal([]byte(_json), i); nil != err {
return nil, nil, err
}
2018-04-03 09:02:31 +00:00
}
2018-04-10 12:30:57 +00:00
return def.t, i, nil
2018-04-03 09:02:31 +00:00
}