143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
package annotation
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
AnnotationTag = "annotation"
|
|
AnnotationMetaTag = "@annotation"
|
|
AnnotationChar = "@"
|
|
AnnotationStartChar = "("
|
|
AnnotationEndChar = ")"
|
|
AnnotationSpliter = ";"
|
|
AnnotationAttributeSpliter = ","
|
|
AnnotationAttributeStartChar = "'"
|
|
AnnotationAttributeEndChar = "'"
|
|
AnnotationKeyValueSpliter = "="
|
|
AnnotationAttributeArrayStartChar = "["
|
|
AnnotationAttributeArrayEndChar = "]"
|
|
AnnotationAttributeArrayItemSpliter = ","
|
|
AnnotationAttributeMapStartChar = "{"
|
|
AnnotationAttributeMapEndChar = "}"
|
|
AnnotationAttributeMapKeyValueSpliter = ":"
|
|
AnnotationAttributeMapItemSpliter = ","
|
|
)
|
|
|
|
type Annotation interface {
|
|
}
|
|
|
|
// @Inject(name? string)
|
|
// @Resource(name? string)
|
|
func ParseAnnotation(tag reflect.StructTag) (map[reflect.Type]Annotation, error) {
|
|
s := strings.Trim(tag.Get(AnnotationTag), " ")
|
|
if "" == s {
|
|
return nil, nil
|
|
}
|
|
|
|
annotations, err := splitAnnotation(s)
|
|
if nil != err {
|
|
return nil, err
|
|
}
|
|
|
|
if nil == annotations || 0 == len(annotations) {
|
|
return nil, nil
|
|
}
|
|
|
|
rKVs := make(map[reflect.Type]Annotation, 0)
|
|
for name, attributes := range annotations {
|
|
t, annotation, err := newAnnotation(name, attributes)
|
|
if nil != err {
|
|
return nil, err
|
|
}
|
|
rKVs[t] = annotation
|
|
}
|
|
|
|
return rKVs, nil
|
|
}
|
|
|
|
func splitAnnotation(s string) (map[string]string, error) {
|
|
ss := make(map[string]string, 0)
|
|
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) {
|
|
ss[aName] = aAttributes
|
|
} else {
|
|
ss[aName] = ""
|
|
}
|
|
|
|
if len(ts) <= (aae + 1) {
|
|
break
|
|
}
|
|
ts = ts[aae+1:]
|
|
}
|
|
|
|
return ss, nil
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func newAnnotation(name string, attributes string) (reflect.Type, Annotation, error) {
|
|
def, ok := annotationRegistry[name]
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("There is no annotation[%s]", name)
|
|
}
|
|
|
|
v := reflect.New(def.rt)
|
|
i := v.Interface().(Annotation)
|
|
|
|
if "" != attributes {
|
|
_json := fmt.Sprintf("{%s}", attributes)
|
|
if err := json.Unmarshal([]byte(_json), i); nil != err {
|
|
return nil, nil, err
|
|
}
|
|
|
|
}
|
|
return def.t, i, nil
|
|
}
|