github.com/boki/go-xmp@v1.0.1/xmp/namespace.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 "encoding/xml" 19 "fmt" 20 "strings" 21 ) 22 23 type UnknownNamespaceError struct { 24 Name xml.Name 25 } 26 27 func (e *UnknownNamespaceError) Error() string { 28 if e.Name.Space == "" { 29 return fmt.Sprintf("xmp: undefined XML namespace for node %s", e.Name.Local) 30 } else { 31 return fmt.Sprintf("xmp: undefined XML namespace for node %s:%s", e.Name.Space, e.Name.Local) 32 } 33 } 34 35 type Namespace struct { 36 Name string 37 URI string 38 Factory ModelFactory 39 } 40 41 // Namespace Groups 42 type NamespaceGroup string 43 type NamespaceGroupList []NamespaceGroup 44 45 const ( 46 NoMetadata NamespaceGroup = "" 47 XmpMetadata NamespaceGroup = "xmp" 48 ImageMetadata NamespaceGroup = "image" 49 MusicMetadata NamespaceGroup = "music" 50 MovieMetadata NamespaceGroup = "movie" 51 SoundMetadata NamespaceGroup = "sound" 52 CameraMetadata NamespaceGroup = "camera" 53 VfxMetadata NamespaceGroup = "vfx" 54 RightsMetadata NamespaceGroup = "rights" 55 ) 56 57 func ParseNamespaceGroup(s string) NamespaceGroup { 58 switch s { 59 case "xmp": 60 return XmpMetadata 61 case "image": 62 return ImageMetadata 63 case "music": 64 return MusicMetadata 65 case "movie": 66 return MovieMetadata 67 case "sound": 68 return SoundMetadata 69 case "camera": 70 return CameraMetadata 71 case "vfx": 72 return VfxMetadata 73 case "rights": 74 return RightsMetadata 75 default: 76 return NoMetadata 77 } 78 } 79 80 func (g NamespaceGroup) Namespaces() NamespaceList { 81 l, _ := GetGroupNamespaces(g) 82 return l 83 } 84 85 func (g NamespaceGroup) Contains(ns *Namespace) bool { 86 for _, v := range g.Namespaces() { 87 if v.GetName() == ns.GetName() { 88 return true 89 } 90 } 91 return false 92 } 93 94 func (l NamespaceGroupList) Contains(ns *Namespace) bool { 95 for _, v := range l { 96 if v.Contains(ns) { 97 return true 98 } 99 } 100 return false 101 } 102 103 func NewNamespace(name, uri string, factory ModelFactory) *Namespace { 104 return &Namespace{ 105 Name: name, 106 URI: uri, 107 Factory: factory, 108 } 109 } 110 111 func (n Namespace) NewModel() Model { 112 if n.Factory != nil { 113 return n.Factory(n.GetName()) 114 } 115 return nil 116 } 117 118 func (n Namespace) MatchAttrName(name string) bool { 119 return getPrefix(name) == n.Name 120 } 121 122 func (n Namespace) MatchXMLName(name xml.Name) bool { 123 if name.Space != "" { 124 return name.Space == n.URI 125 } 126 return getPrefix(name.Local) == n.Name 127 } 128 129 func (n Namespace) Expand(local string) string { 130 if local == "" { 131 return n.GetName() 132 } 133 return strings.Join([]string{n.GetName(), local}, ":") 134 } 135 136 func (n Namespace) Split(name string) string { 137 return stripPrefix(name) 138 } 139 140 func (n Namespace) GetName() string { 141 return n.Name 142 } 143 144 func (n Namespace) GetURI() string { 145 return n.URI 146 } 147 148 func (n Namespace) GetAttr() Attr { 149 return Attr{Name: xml.Name{Local: "xmlns:" + n.Name}, Value: n.URI} 150 } 151 152 func (n Namespace) XMLName(local string) xml.Name { 153 return xml.Name{ 154 Space: "", 155 Local: n.Expand(local), 156 } 157 } 158 159 func (n Namespace) RootName() xml.Name { 160 return xml.Name{ 161 Space: "", 162 Local: n.Name, 163 } 164 } 165 166 type NamespaceList []*Namespace 167 168 func (l NamespaceList) Contains(ns *Namespace) bool { 169 if ns == nil { 170 return false 171 } 172 for _, v := range l { 173 if v.GetName() == ns.GetName() { 174 return true 175 } 176 } 177 return false 178 } 179 180 func (l NamespaceList) ContainsName(n string) bool { 181 if n == "" { 182 return false 183 } 184 for _, v := range l { 185 if v.GetName() == n { 186 return true 187 } 188 } 189 return false 190 } 191 192 func (l *NamespaceList) RemoveDups() NamespaceList { 193 found := make(map[string]bool) 194 j := 0 195 for i, v := range *l { 196 u := v.GetURI() 197 if !found[u] { 198 found[u] = true 199 (*l)[j] = (*l)[i] 200 j++ 201 } 202 } 203 *l = (*l)[:j] 204 return *l 205 } 206 207 func stripPrefix(n string) string { 208 if i := strings.Index(n, ":"); i > -1 { 209 return n[i+1:] 210 } 211 return n 212 } 213 214 func getPrefix(n string) string { 215 if i := strings.Index(n, ":"); i > -1 { 216 return n[:i] 217 } 218 return n 219 } 220 221 // true when n has a non-empty namespace prefix 222 func hasPrefix(n string) bool { 223 return strings.Index(n, ":") > 0 224 }