github.com/boki/go-xmp@v1.0.1/xmp/registry.go (about) 1 // Copyright (c) 2017-2018 Alexander Eichhorn 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package xmp 16 17 import ( 18 "fmt" 19 "strings" 20 "sync" 21 ) 22 23 type ModelFactory func(name string) Model 24 25 // interface for data models 26 type Model interface { 27 Can(nsName string) bool 28 Namespaces() NamespaceList 29 SyncFromXMP(d *Document) error 30 SyncToXMP(d *Document) error 31 SyncModel(d *Document) error 32 CanTag(tag string) bool 33 GetTag(tag string) (string, error) 34 SetTag(tag, value string) error 35 } 36 37 func emptyFactory(name string) Model { 38 return nil 39 } 40 41 type Registry struct { 42 nsNameMap map[string]*Namespace 43 nsUriMap map[string]*Namespace 44 groupMap map[NamespaceGroup]NamespaceList 45 m sync.RWMutex 46 } 47 48 var NsRegistry Registry = Registry{ 49 nsNameMap: make(map[string]*Namespace), 50 nsUriMap: make(map[string]*Namespace), 51 groupMap: make(map[NamespaceGroup]NamespaceList), 52 } 53 54 func Register(ns *Namespace, groups ...NamespaceGroup) { 55 NsRegistry.RegisterNamespace(ns, groups) 56 } 57 58 func GetNamespace(prefix string) (*Namespace, error) { 59 return NsRegistry.GetNamespace(prefix) 60 } 61 62 func GetGroupNamespaces(group NamespaceGroup) (NamespaceList, error) { 63 return NsRegistry.GetGroupNamespaces(group) 64 } 65 66 func (r *Registry) RegisterNamespace(ns *Namespace, groups NamespaceGroupList) { 67 r.m.Lock() 68 defer r.m.Unlock() 69 r.nsNameMap[ns.GetName()] = ns 70 r.nsUriMap[ns.GetURI()] = ns 71 for _, v := range groups { 72 if v != NoMetadata { 73 g, ok := r.groupMap[v] 74 if !ok { 75 r.groupMap[v] = NamespaceList{ns} 76 } else { 77 r.groupMap[v] = append(g, ns) 78 } 79 } 80 } 81 } 82 83 func (r *Registry) GetGroupNamespaces(group NamespaceGroup) (NamespaceList, error) { 84 r.m.RLock() 85 defer r.m.RUnlock() 86 if l, ok := r.groupMap[group]; ok { 87 v := make(NamespaceList, len(l)) 88 copy(v, l) 89 return v, nil 90 } 91 return nil, fmt.Errorf("xmp: unregistered namespace group '%s'", string(group)) 92 } 93 94 func (r *Registry) GetNamespace(prefix string) (*Namespace, error) { 95 r.m.RLock() 96 defer r.m.RUnlock() 97 if ns, ok := r.nsNameMap[prefix]; ok { 98 return ns, nil 99 } 100 return nil, fmt.Errorf("xmp: unregistered namespace '%s'", prefix) 101 } 102 103 func (r *Registry) GetPrefix(uri string) string { 104 r.m.RLock() 105 defer r.m.RUnlock() 106 if ns, ok := r.nsUriMap[uri]; ok { 107 return ns.GetName() 108 } 109 return "" 110 } 111 112 func (r *Registry) Short(uri, name string) string { 113 pre := r.GetPrefix(uri) 114 if pre != "" { 115 return strings.Join([]string{pre, name}, ":") 116 } 117 return name 118 } 119 120 func (r *Registry) Namespaces() NamespaceList { 121 r.m.RLock() 122 defer r.m.RUnlock() 123 l := make(NamespaceList, 0, len(r.nsUriMap)) 124 for _, v := range r.nsUriMap { 125 l = append(l, v) 126 } 127 return l 128 } 129 130 func (r *Registry) Prefixes() []string { 131 r.m.RLock() 132 defer r.m.RUnlock() 133 l := make([]string, 0, len(r.nsNameMap)) 134 for n, _ := range r.nsNameMap { 135 l = append(l, n) 136 } 137 return l 138 }