util/context/context.go

112 lines
1.9 KiB
Go
Raw Normal View History

2017-11-10 07:05:28 +00:00
package context
2017-11-27 16:05:04 +00:00
import (
"reflect"
"sync"
)
2017-11-27 10:51:03 +00:00
2017-11-10 07:05:28 +00:00
type ContextKey string
func (c ContextKey) String() string {
return string(c)
}
2017-11-27 10:51:03 +00:00
func NewContext(parent Context) Context {
c := &defaultContext{
2017-11-27 10:58:54 +00:00
Context: parent,
2017-11-27 10:51:03 +00:00
}
2017-11-27 16:05:04 +00:00
c.attributes = make(map[interface{}]interface{})
2017-11-27 10:51:03 +00:00
return c
}
type Context interface {
2017-11-27 11:01:36 +00:00
Parent() Context
2017-11-27 16:05:04 +00:00
SetAttribute(key interface{}, value interface{})
GetAttribute(key interface{}) (value interface{})
RemoveAttribute(key interface{})
ContainsAttribute(key interface{}) (exist bool)
2017-11-27 10:51:03 +00:00
}
type defaultContext struct {
2017-11-27 10:58:54 +00:00
Context
2017-11-27 16:05:04 +00:00
attributes map[interface{}]interface{}
2017-11-27 10:51:03 +00:00
mtx sync.RWMutex
}
2017-11-27 11:01:36 +00:00
func (dc *defaultContext) Parent() Context {
return dc.Context
}
2017-11-27 16:05:04 +00:00
func (dc *defaultContext) SetAttribute(key interface{}, value interface{}) {
2017-11-27 10:51:03 +00:00
dc.checkInitialized()
2017-11-27 16:05:04 +00:00
if key == nil {
panic("nil key")
}
if !reflect.TypeOf(key).Comparable() {
panic("key is not comparable")
}
2017-11-27 10:51:03 +00:00
dc.mtx.Lock()
defer dc.mtx.Unlock()
dc.attributes[key] = value
}
2017-11-27 16:05:04 +00:00
func (dc *defaultContext) GetAttribute(key interface{}) (value interface{}) {
2017-11-27 10:51:03 +00:00
dc.checkInitialized()
dc.mtx.RLock()
defer dc.mtx.RUnlock()
if _, ok := dc.attributes[key]; ok {
return dc.attributes[key]
}
2017-11-27 10:58:54 +00:00
if nil == dc.Context {
2017-11-27 10:51:03 +00:00
return nil
}
2017-11-27 10:58:54 +00:00
return dc.Context.GetAttribute(key)
2017-11-27 10:51:03 +00:00
}
2017-11-27 16:05:04 +00:00
func (dc *defaultContext) RemoveAttribute(key interface{}) {
2017-11-27 10:51:03 +00:00
dc.checkInitialized()
dc.mtx.Lock()
defer dc.mtx.Unlock()
if _, ok := dc.attributes[key]; ok {
delete(dc.attributes, key)
return
}
2017-11-27 10:58:54 +00:00
if nil == dc.Context {
2017-11-27 10:51:03 +00:00
return
}
2017-11-27 10:58:54 +00:00
dc.Context.RemoveAttribute(key)
2017-11-27 10:51:03 +00:00
}
2017-11-27 16:05:04 +00:00
func (dc *defaultContext) ContainsAttribute(key interface{}) (exist bool) {
2017-11-27 10:51:03 +00:00
dc.checkInitialized()
dc.mtx.RLock()
defer dc.mtx.RUnlock()
if _, ok := dc.attributes[key]; ok {
return true
}
2017-11-27 10:58:54 +00:00
if nil == dc.Context {
2017-11-27 10:51:03 +00:00
return false
}
2017-11-27 10:58:54 +00:00
return dc.Context.ContainsAttribute(key)
2017-11-27 10:51:03 +00:00
}
func (dc *defaultContext) checkInitialized() {
if nil == dc.attributes {
panic("Attribute Manager: must be initialized")
}
}