ing
This commit is contained in:
parent
e9205cada3
commit
08db48ce48
|
@ -6,3 +6,12 @@ type Definition struct {
|
||||||
t reflect.Type
|
t reflect.Type
|
||||||
rt reflect.Type
|
rt reflect.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TypeDefinition struct {
|
||||||
|
t reflect.Type
|
||||||
|
rt reflect.Type
|
||||||
|
|
||||||
|
typeAnnotation map[reflect.Type]Annotation
|
||||||
|
fieldAnnotation map[string]map[reflect.Type]Annotation
|
||||||
|
methodAnnotation map[string]map[reflect.Type]Annotation
|
||||||
|
}
|
||||||
|
|
276
registry.go
276
registry.go
|
@ -6,18 +6,26 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
cur "git.loafle.net/overflow/util-go/reflect"
|
our "git.loafle.net/overflow/util-go/reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Registry interface {
|
type Registry interface {
|
||||||
Register(t reflect.Type) error
|
Register(t reflect.Type) error
|
||||||
Get(f *reflect.StructField) (map[reflect.Type]Annotation, error)
|
GetTypeAnnotation(t reflect.Type, at reflect.Type) (Annotation, error)
|
||||||
|
GetTypeAnnotations(t reflect.Type) (map[reflect.Type]Annotation, error)
|
||||||
|
GetFieldAnnotation(t reflect.Type, name string, at reflect.Type) (Annotation, error)
|
||||||
|
GetFieldAnnotations(t reflect.Type, name string) (map[reflect.Type]Annotation, error)
|
||||||
|
GetAllFieldAnnotations(t reflect.Type) (map[string]map[reflect.Type]Annotation, error)
|
||||||
|
GetMethodAnnotation(t reflect.Type, name string, at reflect.Type) (Annotation, error)
|
||||||
|
GetMethodAnnotations(t reflect.Type, name string) (map[reflect.Type]Annotation, error)
|
||||||
|
GetAllMethodAnnotations(t reflect.Type) (map[string]map[reflect.Type]Annotation, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(parent Registry) Registry {
|
func New(parent Registry) Registry {
|
||||||
r := &AnnotationRegistry{
|
r := &AnnotationRegistry{
|
||||||
parent: parent,
|
parent: parent,
|
||||||
definitions: make(map[string]*Definition, 0),
|
definitions: make(map[string]*Definition, 0),
|
||||||
|
typeDefinitions: make(map[reflect.Type]*TypeDefinition, 0),
|
||||||
}
|
}
|
||||||
if nil == r.parent {
|
if nil == r.parent {
|
||||||
r.parent = SystemRegistry
|
r.parent = SystemRegistry
|
||||||
|
@ -28,18 +36,20 @@ func New(parent Registry) Registry {
|
||||||
var SystemRegistry = &AnnotationRegistry{
|
var SystemRegistry = &AnnotationRegistry{
|
||||||
parent: nil,
|
parent: nil,
|
||||||
definitions: make(map[string]*Definition, 0),
|
definitions: make(map[string]*Definition, 0),
|
||||||
|
typeDefinitions: make(map[reflect.Type]*TypeDefinition, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnnotationRegistry struct {
|
type AnnotationRegistry struct {
|
||||||
parent Registry
|
parent Registry
|
||||||
definitions map[string]*Definition
|
definitions map[string]*Definition
|
||||||
|
typeDefinitions map[reflect.Type]*TypeDefinition
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(t reflect.Type) error {
|
func Register(t reflect.Type) error {
|
||||||
return SystemRegistry.Register(t)
|
return SystemRegistry.Register(t)
|
||||||
}
|
}
|
||||||
func (r *AnnotationRegistry) Register(t reflect.Type) error {
|
func (r *AnnotationRegistry) Register(t reflect.Type) error {
|
||||||
rt, _, _ := cur.GetTypeInfo(t)
|
rt, _, _ := our.GetTypeInfo(t)
|
||||||
|
|
||||||
fields := findAnnotatedFields(t, AnnotationType, false)
|
fields := findAnnotatedFields(t, AnnotationType, false)
|
||||||
switch len(fields) {
|
switch len(fields) {
|
||||||
|
@ -68,10 +78,35 @@ func (r *AnnotationRegistry) Register(t reflect.Type) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(f *reflect.StructField) (map[reflect.Type]Annotation, error) {
|
func findAnnotatedFields(t reflect.Type, ft reflect.Type, deep bool) map[string]*reflect.StructField {
|
||||||
return SystemRegistry.Get(f)
|
fields := make(map[string]*reflect.StructField, 0)
|
||||||
|
|
||||||
|
rt, _, _ := our.GetTypeInfo(t)
|
||||||
|
if reflect.Struct != rt.Kind() {
|
||||||
|
return fields
|
||||||
}
|
}
|
||||||
func (r *AnnotationRegistry) Get(f *reflect.StructField) (map[reflect.Type]Annotation, error) {
|
|
||||||
|
LOOP:
|
||||||
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
|
f := rt.Field(i)
|
||||||
|
|
||||||
|
if f.Anonymous {
|
||||||
|
if f.Type == ft {
|
||||||
|
fields[f.Name] = &f
|
||||||
|
continue LOOP
|
||||||
|
}
|
||||||
|
if deep {
|
||||||
|
_fields := findAnnotatedFields(f.Type, ft, deep)
|
||||||
|
for _n, _f := range _fields {
|
||||||
|
fields[_n] = _f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AnnotationRegistry) getAnnotation(f *reflect.StructField) (map[reflect.Type]Annotation, error) {
|
||||||
annotations := make(map[reflect.Type]Annotation, 0)
|
annotations := make(map[reflect.Type]Annotation, 0)
|
||||||
|
|
||||||
tag := strings.TrimSpace(f.Tag.Get(AnnotationTag))
|
tag := strings.TrimSpace(f.Tag.Get(AnnotationTag))
|
||||||
|
@ -129,12 +164,20 @@ func (r *AnnotationRegistry) Get(f *reflect.StructField) (map[reflect.Type]Annot
|
||||||
return annotations, nil
|
return annotations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func findAnnotatedFields(t reflect.Type, ft reflect.Type, deep bool) map[string]*reflect.StructField {
|
func (r *AnnotationRegistry) getTypeDefinition(t reflect.Type) (*TypeDefinition, error) {
|
||||||
fields := make(map[string]*reflect.StructField, 0)
|
rt, _, _ := our.GetTypeInfo(t)
|
||||||
|
|
||||||
rt, _, _ := cur.GetTypeInfo(t)
|
|
||||||
if reflect.Struct != rt.Kind() {
|
if reflect.Struct != rt.Kind() {
|
||||||
return fields
|
return nil, fmt.Errorf("type[%s] is not struct", rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
td, ok := r.typeDefinitions[t]
|
||||||
|
if ok {
|
||||||
|
return td, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
td = &TypeDefinition{
|
||||||
|
t: t,
|
||||||
|
rt: rt,
|
||||||
}
|
}
|
||||||
|
|
||||||
LOOP:
|
LOOP:
|
||||||
|
@ -142,17 +185,214 @@ LOOP:
|
||||||
f := rt.Field(i)
|
f := rt.Field(i)
|
||||||
|
|
||||||
if f.Anonymous {
|
if f.Anonymous {
|
||||||
if f.Type == ft {
|
if f.Type == TypeAnnotationType {
|
||||||
fields[f.Name] = &f
|
if 0 < len(td.typeAnnotation) {
|
||||||
|
return nil, fmt.Errorf("TypeAnnotation of type[%s] be defined one more time", rt.Name())
|
||||||
|
}
|
||||||
|
as, err := r.getAnnotation(&f)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if 0 == len(as) {
|
||||||
continue LOOP
|
continue LOOP
|
||||||
}
|
}
|
||||||
if deep {
|
td.typeAnnotation = as
|
||||||
_fields := findAnnotatedFields(f.Type, ft, deep)
|
}
|
||||||
for _n, _f := range _fields {
|
} else {
|
||||||
fields[_n] = _f
|
if f.Type == MethodAnnotationType {
|
||||||
|
as, err := r.getAnnotation(&f)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if 0 == len(as) {
|
||||||
|
continue LOOP
|
||||||
|
}
|
||||||
|
if 0 == len(td.methodAnnotation) {
|
||||||
|
td.methodAnnotation = make(map[string]map[reflect.Type]Annotation, 0)
|
||||||
|
}
|
||||||
|
td.methodAnnotation[f.Name] = as
|
||||||
|
continue LOOP
|
||||||
|
} else {
|
||||||
|
as, err := r.getAnnotation(&f)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if 0 == len(as) {
|
||||||
|
continue LOOP
|
||||||
|
}
|
||||||
|
if 0 == len(td.fieldAnnotation) {
|
||||||
|
td.fieldAnnotation = make(map[string]map[reflect.Type]Annotation, 0)
|
||||||
|
}
|
||||||
|
td.fieldAnnotation[f.Name] = as
|
||||||
|
continue LOOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.typeDefinitions[t] = td
|
||||||
|
|
||||||
|
return td, nil
|
||||||
}
|
}
|
||||||
return fields
|
|
||||||
|
func GetTypeAnnotation(t reflect.Type, at reflect.Type) (Annotation, error) {
|
||||||
|
return SystemRegistry.GetTypeAnnotation(t, at)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetTypeAnnotation(t reflect.Type, at reflect.Type) (Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.typeAnnotation) {
|
||||||
|
return nil, fmt.Errorf("TypeAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
a, ok := td.typeAnnotation[at]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("Annotation[%s] of type[%s] is not exist", at.Name(), td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTypeAnnotations(t reflect.Type) (map[reflect.Type]Annotation, error) {
|
||||||
|
return SystemRegistry.GetTypeAnnotations(t)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetTypeAnnotations(t reflect.Type) (map[reflect.Type]Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.typeAnnotation) {
|
||||||
|
return nil, fmt.Errorf("TypeAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return td.typeAnnotation, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFieldAnnotation(t reflect.Type, name string, at reflect.Type) (Annotation, error) {
|
||||||
|
return SystemRegistry.GetFieldAnnotation(t, name, at)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetFieldAnnotation(t reflect.Type, name string, at reflect.Type) (Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.fieldAnnotation) {
|
||||||
|
return nil, fmt.Errorf("FieldAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
as, ok := td.fieldAnnotation[name]
|
||||||
|
if !ok || 0 == len(as) {
|
||||||
|
return nil, fmt.Errorf("Field[%s] Annotation of type[%s] is not exist", name, td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
a, ok := as[at]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("Annotation[%s] of field[%s] in type[%s] is not exist", at.Name(), name, td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFieldAnnotations(t reflect.Type, name string) (map[reflect.Type]Annotation, error) {
|
||||||
|
return SystemRegistry.GetFieldAnnotations(t, name)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetFieldAnnotations(t reflect.Type, name string) (map[reflect.Type]Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.fieldAnnotation) {
|
||||||
|
return nil, fmt.Errorf("FieldAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
as, ok := td.fieldAnnotation[name]
|
||||||
|
if !ok || 0 == len(as) {
|
||||||
|
return nil, fmt.Errorf("Field[%s] Annotation of type[%s] is not exist", name, td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return as, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAllFieldAnnotations(t reflect.Type) (map[string]map[reflect.Type]Annotation, error) {
|
||||||
|
return SystemRegistry.GetAllFieldAnnotations(t)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetAllFieldAnnotations(t reflect.Type) (map[string]map[reflect.Type]Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.fieldAnnotation) {
|
||||||
|
return nil, fmt.Errorf("FieldAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return td.fieldAnnotation, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMethodAnnotation(t reflect.Type, name string, at reflect.Type) (Annotation, error) {
|
||||||
|
return SystemRegistry.GetMethodAnnotation(t, name, at)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetMethodAnnotation(t reflect.Type, name string, at reflect.Type) (Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.methodAnnotation) {
|
||||||
|
return nil, fmt.Errorf("MethodAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
as, ok := td.methodAnnotation[name]
|
||||||
|
if !ok || 0 == len(as) {
|
||||||
|
return nil, fmt.Errorf("Method[%s] Annotation of type[%s] is not exist", name, td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
a, ok := as[at]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("Annotation[%s] of method[%s] in type[%s] is not exist", at.Name(), name, td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMethodAnnotations(t reflect.Type, name string) (map[reflect.Type]Annotation, error) {
|
||||||
|
return SystemRegistry.GetMethodAnnotations(t, name)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetMethodAnnotations(t reflect.Type, name string) (map[reflect.Type]Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.methodAnnotation) {
|
||||||
|
return nil, fmt.Errorf("MethodAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
as, ok := td.methodAnnotation[name]
|
||||||
|
if !ok || 0 == len(as) {
|
||||||
|
return nil, fmt.Errorf("Method[%s] Annotation of type[%s] is not exist", name, td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return as, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAllMethodAnnotations(t reflect.Type) (map[string]map[reflect.Type]Annotation, error) {
|
||||||
|
return SystemRegistry.GetAllMethodAnnotations(t)
|
||||||
|
}
|
||||||
|
func (r *AnnotationRegistry) GetAllMethodAnnotations(t reflect.Type) (map[string]map[reflect.Type]Annotation, error) {
|
||||||
|
td, err := r.getTypeDefinition(t)
|
||||||
|
if nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(td.methodAnnotation) {
|
||||||
|
return nil, fmt.Errorf("MethodAnnotation of type[%s] is not exist", td.rt.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return td.methodAnnotation, nil
|
||||||
}
|
}
|
||||||
|
|
10
type.go
10
type.go
|
@ -11,18 +11,16 @@ type Annotation interface {
|
||||||
|
|
||||||
var TypeAnnotationType = reflect.TypeOf((*TypeAnnotation)(nil)).Elem()
|
var TypeAnnotationType = reflect.TypeOf((*TypeAnnotation)(nil)).Elem()
|
||||||
|
|
||||||
|
const TypeAnnotationName = "TypeAnnotation"
|
||||||
|
|
||||||
type TypeAnnotation interface {
|
type TypeAnnotation interface {
|
||||||
Annotation
|
Annotation
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConstructorAnnotationType = reflect.TypeOf((*ConstructorAnnotation)(nil)).Elem()
|
|
||||||
|
|
||||||
type ConstructorAnnotation interface {
|
|
||||||
Annotation
|
|
||||||
}
|
|
||||||
|
|
||||||
var MethodAnnotationType = reflect.TypeOf((*MethodAnnotation)(nil)).Elem()
|
var MethodAnnotationType = reflect.TypeOf((*MethodAnnotation)(nil)).Elem()
|
||||||
|
|
||||||
|
const MethodAnnotationName = "MethodAnnotation"
|
||||||
|
|
||||||
type MethodAnnotation interface {
|
type MethodAnnotation interface {
|
||||||
Annotation
|
Annotation
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user