package annotation import ( "reflect" "strings" cur "git.loafle.net/commons/util-go/reflect" ) type AnnotationFieldMeta struct { fieldName string options anotationMetaOptions } type anotationMetaOptions string func (o anotationMetaOptions) Contains(optionName string) bool { if len(o) == 0 { return false } s := string(o) for s != "" { var next string i := strings.Index(s, AnnotationAttributeSpliter) if i >= 0 { s, next = s[:i], s[i+1:] } if s == optionName { return true } s = next } return false } func getMetaFields(t reflect.Type) map[string]*AnnotationFieldMeta { fields := make(map[string]*AnnotationFieldMeta, 0) rt, _, _ := cur.GetTypeInfo(t) if reflect.Struct != rt.Kind() { return fields } for i := 0; i < rt.NumField(); i++ { f := rt.Field(i) if f.Anonymous { pFields := getMetaFields(f.Type) for k, v := range pFields { fields[k] = v } } else { name, metaOptions := parseAnnotationMeta(f.Tag) if "" == name { continue } fields[name] = &AnnotationFieldMeta{ fieldName: f.Name, options: metaOptions, } } } return fields } func parseAnnotationMeta(tag reflect.StructTag) (string, anotationMetaOptions) { s := strings.Trim(tag.Get(AnnotationMetaTag), " ") if "" == s { return "", "" } if idx := strings.Index(s, AnnotationAttributeSpliter); idx != -1 { return s[:idx], anotationMetaOptions(s[idx+1:]) } return s, anotationMetaOptions("") } // func setMetaAttributes(def *AnnotationDefinition, rv reflect.Value, attributes map[string]string) { // META_LOOP: // for k, v := range attributes { // meta := def.fields[k] // if nil == meta { // log.Printf("Attribute[%s] of Type[%s] is not exist", k, def.rt.Name()) // continue META_LOOP // } // f := rv.FieldByName(meta.fieldName) // switch f.Type().Kind() { // case reflect.Array: // log.Printf("Array not support") // case reflect.Slice: // s, err := convertSlice(v, f.Type()) // if nil != err { // continue META_LOOP // } // f.Set(reflect.ValueOf(s)) // case reflect.Map: // s, err := convertMap(v, f.Type()) // if nil != err { // continue META_LOOP // } // f.Set(reflect.ValueOf(s)) // case reflect.Struct: // log.Printf("Struct not support") // case reflect.Ptr: // log.Printf("Pointer not support") // default: // f.Set(reflect.ValueOf(v)) // } // } // } // func convertSlice(s string, t reflect.Type) (interface{}, error) { // ts := s // as := strings.Index(ts, AnnotationAttributeArrayStartChar) // if -1 == as { // return nil, fmt.Errorf("Value is not contain %s", AnnotationAttributeArrayStartChar) // } // ts = ts[as+1:] // ae := strings.Index(ts, AnnotationAttributeArrayEndChar) // if -1 == ae { // return nil, fmt.Errorf("Value is not contain %s", AnnotationAttributeArrayEndChar) // } // ts = ts[:ae] // is := strings.Split(ts, AnnotationAttributeArrayItemSpliter) // if nil == is || 0 == len(is) { // return nil, nil // } // for i, v := range is { // is[i] = strings.TrimSpace(v) // } // return cur.ConvertToType(is, t) // } // func convertMap(s string, t reflect.Type) (interface{}, error) { // ts := s // as := strings.Index(ts, AnnotationAttributeMapStartChar) // if -1 == as { // return nil, fmt.Errorf("Value is not contain %s", AnnotationAttributeMapStartChar) // } // ts = ts[as+1:] // ae := strings.Index(ts, AnnotationAttributeMapEndChar) // if -1 == ae { // return nil, fmt.Errorf("Value is not contain %s", AnnotationAttributeMapEndChar) // } // ts = ts[:ae] // is := strings.Split(ts, AnnotationAttributeMapItemSpliter) // if nil == is || 0 == len(is) { // return nil, nil // } // ms := make(map[string]string) // for _, s := range is { // kvs := strings.Split(s, AnnotationAttributeMapKeyValueSpliter) // if 2 != len(kvs) { // return nil, fmt.Errorf("Map Value format k:v but %s", s) // } // k := strings.TrimSpace(kvs[0]) // v := strings.TrimSpace(kvs[1]) // ms[k] = v // } // return cur.ConvertToType(ms, t) // }