util/context/attributes.go

119 lines
1.8 KiB
Go
Raw Normal View History

2017-11-27 05:53:04 +00:00
package context
2017-11-27 09:41:29 +00:00
import "sync"
2017-11-27 10:13:19 +00:00
type Attributer interface {
Attributes() Attributes
}
2017-11-27 09:57:43 +00:00
type Attributes interface {
initialize()
Set(key string, value interface{})
Get(key string) (value interface{})
Remove(key string)
2017-11-27 05:53:04 +00:00
Contains(key string) (exist bool)
Destroy()
}
2017-11-27 09:57:43 +00:00
func NewAttributes(parent Attributes) Attributes {
am := &attributes{
Parent: parent,
}
am.initialize()
return am
}
type attributes struct {
Parent Attributes
values map[string]interface{}
2017-11-27 09:41:29 +00:00
mtx sync.RWMutex
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:57:43 +00:00
func (am *attributes) initialize() {
2017-11-27 09:41:29 +00:00
if nil != am.Parent {
2017-11-27 09:57:43 +00:00
am.Parent.initialize()
2017-11-27 09:41:29 +00:00
}
2017-11-27 09:57:43 +00:00
if nil == am.values {
2017-11-27 05:57:26 +00:00
am.Destroy()
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:57:43 +00:00
am.values = make(map[string]interface{})
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:57:43 +00:00
func (am *attributes) Set(key string, value interface{}) {
2017-11-27 09:41:29 +00:00
am.checkInitialized()
am.mtx.Lock()
defer am.mtx.Unlock()
2017-11-27 09:57:43 +00:00
am.values[key] = value
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:57:43 +00:00
func (am *attributes) Get(key string) (value interface{}) {
2017-11-27 09:41:29 +00:00
am.checkInitialized()
am.mtx.RLock()
defer am.mtx.RUnlock()
2017-11-27 09:57:43 +00:00
if _, ok := am.values[key]; ok {
return am.values[key]
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:41:29 +00:00
if nil == am.Parent {
2017-11-27 05:53:04 +00:00
return nil
}
2017-11-27 09:57:43 +00:00
return am.Parent.Get(key)
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:57:43 +00:00
func (am *attributes) Remove(key string) {
2017-11-27 09:41:29 +00:00
am.checkInitialized()
am.mtx.Lock()
defer am.mtx.Unlock()
2017-11-27 09:57:43 +00:00
if _, ok := am.values[key]; ok {
delete(am.values, key)
2017-11-27 09:41:29 +00:00
return
}
if nil == am.Parent {
2017-11-27 05:53:04 +00:00
return
}
2017-11-27 09:41:29 +00:00
2017-11-27 09:57:43 +00:00
am.Parent.Remove(key)
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:57:43 +00:00
func (am *attributes) Contains(key string) (exist bool) {
2017-11-27 09:41:29 +00:00
am.checkInitialized()
am.mtx.RLock()
defer am.mtx.RUnlock()
2017-11-27 09:57:43 +00:00
if _, ok := am.values[key]; ok {
2017-11-27 09:41:29 +00:00
return true
}
if nil == am.Parent {
2017-11-27 05:53:04 +00:00
return false
}
2017-11-27 09:41:29 +00:00
return am.Parent.Contains(key)
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:57:43 +00:00
func (am *attributes) Destroy() {
if nil != am.values {
am.values = nil
2017-11-27 05:53:04 +00:00
}
2017-11-27 09:41:29 +00:00
if nil != am.Parent {
am.Parent.Destroy()
}
}
2017-11-27 09:57:43 +00:00
func (am *attributes) checkInitialized() {
if nil == am.values {
2017-11-27 09:41:29 +00:00
panic("Attribute Manager: must be initialized")
}
2017-11-27 05:53:04 +00:00
}