254 lines
5.6 KiB
Go
254 lines
5.6 KiB
Go
package annotation
|
|
|
|
import (
|
|
"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[string]Annotation, error) {
|
|
// s := strings.Trim(tag.Get(AnnotationTag), " ")
|
|
// if "" == s {
|
|
// return nil, nil
|
|
// }
|
|
|
|
// annotations := strings.Split(s, AnnotationSpliter)
|
|
// if nil == annotations || 0 == len(annotations) {
|
|
// return nil, nil
|
|
// }
|
|
|
|
// rKVs := make(map[string]Annotation, 0)
|
|
// for _, a := range annotations {
|
|
// a = strings.Trim(a, " ")
|
|
// if "" == a {
|
|
// continue
|
|
// }
|
|
// aName, attributes, err := parseAnnotationItem(a)
|
|
// if nil != err {
|
|
// return nil, err
|
|
// }
|
|
// if "" == aName {
|
|
// continue
|
|
// }
|
|
// annotation, err := newAnnotation(aName, attributes)
|
|
// if nil != err {
|
|
// return nil, err
|
|
// }
|
|
// rKVs[aName] = annotation
|
|
// }
|
|
|
|
// return rKVs, nil
|
|
// }
|
|
|
|
// @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]map[string]string, error) {
|
|
ss := make(map[string]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) {
|
|
attributes, err := splitAnnotationAttribute(aAttributes)
|
|
if nil != err {
|
|
return nil, err
|
|
}
|
|
ss[aName] = attributes
|
|
} else {
|
|
ss[aName] = nil
|
|
}
|
|
|
|
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 map[string]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 nil != attributes {
|
|
setMetaAttributes(def, v.Elem(), attributes)
|
|
}
|
|
return def.t, i, nil
|
|
}
|
|
|
|
// func parseAnnotationItem(a string) (name string, attributes map[string]string, err error) {
|
|
// s := strings.Trim(a, " ")
|
|
// if "" == s {
|
|
// return
|
|
// }
|
|
|
|
// 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
|
|
// }
|
|
|
|
// attrs, pErr := parseAttributeString(s[aStart+1 : aEnd])
|
|
// if nil != pErr {
|
|
// err = pErr
|
|
// return
|
|
// }
|
|
|
|
// attributes = attrs
|
|
|
|
// return
|
|
// }
|
|
|
|
// func parseAttributeString(s string) (map[string]string, error) {
|
|
// attr := strings.Trim(s, " ")
|
|
// if "" == attr {
|
|
// return nil, nil
|
|
// }
|
|
|
|
// kvs := strings.Split(attr, AnnotationAttributeSpliter)
|
|
// if nil == kvs || 0 == len(kvs) {
|
|
// 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
|
|
// }
|