di/annotation/annotation.go

149 lines
2.9 KiB
Go
Raw Permalink Normal View History

2017-12-05 13:28:42 +00:00
package annotation
import (
"fmt"
"reflect"
"strings"
)
const (
2017-12-08 10:32:59 +00:00
AnnotationTag = "annotation"
2018-03-15 13:19:44 +00:00
AnnotationMetaTag = "annotation-meta"
2017-12-06 06:07:44 +00:00
AnnotationChar = "@"
2017-12-05 13:28:42 +00:00
AnnotationStartChar = "("
AnnotationEndChar = ")"
2017-12-06 06:07:44 +00:00
AnnotationSpliter = ";"
2017-12-05 13:28:42 +00:00
AnnotationAttributeSpliter = ","
AnnotationKeyValueSpliter = "="
)
type Annotation interface {
}
// @Inject(name? string)
// @Resource(name? string)
2017-12-08 10:32:59 +00:00
func ParseAnnotation(tag reflect.StructTag) (map[string]Annotation, error) {
s := strings.Trim(tag.Get(AnnotationTag), " ")
2017-12-06 06:07:44 +00:00
if "" == s {
2017-12-05 13:28:42 +00:00
return nil, nil
}
2017-12-06 06:07:44 +00:00
annotations := strings.Split(s, AnnotationSpliter)
if nil == annotations || 0 == len(annotations) {
return nil, nil
2017-12-05 13:28:42 +00:00
}
2017-12-08 10:32:59 +00:00
rKVs := make(map[string]Annotation, 0)
2017-12-06 06:07:44 +00:00
for _, a := range annotations {
a = strings.Trim(a, " ")
if "" == a {
continue
}
2018-03-15 13:19:44 +00:00
aName, attributes, err := parseAnnotationItem(a)
2017-12-06 06:07:44 +00:00
if nil != err {
return nil, err
}
if "" == aName {
continue
}
2018-03-15 13:19:44 +00:00
annotation, err := newAnnotation(aName, attributes)
2017-12-06 06:07:44 +00:00
if nil != err {
return nil, err
}
2017-12-08 10:32:59 +00:00
rKVs[aName] = annotation
2017-12-05 13:28:42 +00:00
}
return rKVs, nil
}
2018-03-15 13:19:44 +00:00
func newAnnotation(name string, attributes map[string]string) (Annotation, error) {
def, ok := annotationRegistry[name]
2017-12-06 06:07:44 +00:00
if !ok {
return nil, fmt.Errorf("There is no annotation[%s]", name)
2017-12-05 13:28:42 +00:00
}
2018-03-15 13:19:44 +00:00
v := reflect.New(def.rt)
2017-12-06 06:07:44 +00:00
i := v.Interface().(Annotation)
if nil != attributes {
2018-03-15 13:19:44 +00:00
setMetaAttributes(def, v.Elem(), attributes)
2017-12-06 06:07:44 +00:00
}
return i, nil
}
2018-03-15 13:19:44 +00:00
func parseAnnotationItem(a string) (name string, attributes map[string]string, err error) {
2017-12-06 06:07:44 +00:00
s := strings.Trim(a, " ")
if "" == s {
return
2017-12-05 13:28:42 +00:00
}
2017-12-06 06:07:44 +00:00
i := strings.Index(s, AnnotationChar)
if -1 == i {
err = fmt.Errorf("Syntax error: annotation must be started %s", AnnotationChar)
return
}
aStart := strings.Index(s, AnnotationStartChar)
if -1 == aStart {
// This is pure annotation ex)@Resource
name = s
return
}
name = s[:aStart]
aEnd := strings.Index(s, AnnotationEndChar)
if -1 == aEnd {
// This is syntax error ex)@Resource(
err = fmt.Errorf("Syntax error: annotation must be ended %s", AnnotationEndChar)
return
}
if 1 >= aEnd-aStart {
return
}
attr := s[aStart+1 : aEnd]
attr = strings.Trim(attr, " ")
if "" == attr {
return
}
2018-03-15 13:19:44 +00:00
attrs, pErr := parseAttributeString(s[aStart+1 : aEnd])
2017-12-06 06:07:44 +00:00
if nil != pErr {
err = pErr
return
}
attributes = attrs
return
}
2018-03-15 13:19:44 +00:00
func parseAttributeString(s string) (map[string]string, error) {
2017-12-06 06:07:44 +00:00
attr := strings.Trim(s, " ")
if "" == attr {
return nil, nil
2017-12-05 13:28:42 +00:00
}
2017-12-06 06:07:44 +00:00
kvs := strings.Split(attr, AnnotationAttributeSpliter)
if nil == kvs || 0 == len(kvs) {
2017-12-05 13:28:42 +00:00
return nil, nil
}
rKVs := make(map[string]string)
for i := 0; i < len(kvs); i++ {
s := strings.Trim(kvs[i], " ")
if "" == s {
continue
}
kv := strings.Split(s, AnnotationKeyValueSpliter)
k := strings.Trim(kv[0], " ")
v := strings.Trim(kv[1], " ")
rKVs[k] = v
}
return rKVs, nil
}