98 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package context
 | 
						|
 | 
						|
import "sync"
 | 
						|
 | 
						|
type ContextKey string
 | 
						|
 | 
						|
func (c ContextKey) String() string {
 | 
						|
	return string(c)
 | 
						|
}
 | 
						|
 | 
						|
func NewContext(parent Context) Context {
 | 
						|
	c := &defaultContext{
 | 
						|
		Context: parent,
 | 
						|
	}
 | 
						|
	c.attributes = make(map[string]interface{})
 | 
						|
 | 
						|
	return c
 | 
						|
}
 | 
						|
 | 
						|
type Context interface {
 | 
						|
	SetAttribute(key string, value interface{})
 | 
						|
	GetAttribute(key string) (value interface{})
 | 
						|
	RemoveAttribute(key string)
 | 
						|
	ContainsAttribute(key string) (exist bool)
 | 
						|
}
 | 
						|
 | 
						|
type defaultContext struct {
 | 
						|
	Context
 | 
						|
	attributes map[string]interface{}
 | 
						|
 | 
						|
	mtx sync.RWMutex
 | 
						|
}
 | 
						|
 | 
						|
func (dc *defaultContext) SetAttribute(key string, value interface{}) {
 | 
						|
	dc.checkInitialized()
 | 
						|
 | 
						|
	dc.mtx.Lock()
 | 
						|
	defer dc.mtx.Unlock()
 | 
						|
 | 
						|
	dc.attributes[key] = value
 | 
						|
}
 | 
						|
 | 
						|
func (dc *defaultContext) GetAttribute(key string) (value interface{}) {
 | 
						|
	dc.checkInitialized()
 | 
						|
 | 
						|
	dc.mtx.RLock()
 | 
						|
	defer dc.mtx.RUnlock()
 | 
						|
 | 
						|
	if _, ok := dc.attributes[key]; ok {
 | 
						|
		return dc.attributes[key]
 | 
						|
	}
 | 
						|
 | 
						|
	if nil == dc.Context {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return dc.Context.GetAttribute(key)
 | 
						|
}
 | 
						|
 | 
						|
func (dc *defaultContext) RemoveAttribute(key string) {
 | 
						|
	dc.checkInitialized()
 | 
						|
 | 
						|
	dc.mtx.Lock()
 | 
						|
	defer dc.mtx.Unlock()
 | 
						|
 | 
						|
	if _, ok := dc.attributes[key]; ok {
 | 
						|
		delete(dc.attributes, key)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if nil == dc.Context {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	dc.Context.RemoveAttribute(key)
 | 
						|
}
 | 
						|
 | 
						|
func (dc *defaultContext) ContainsAttribute(key string) (exist bool) {
 | 
						|
	dc.checkInitialized()
 | 
						|
 | 
						|
	dc.mtx.RLock()
 | 
						|
	defer dc.mtx.RUnlock()
 | 
						|
 | 
						|
	if _, ok := dc.attributes[key]; ok {
 | 
						|
		return true
 | 
						|
	}
 | 
						|
 | 
						|
	if nil == dc.Context {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	return dc.Context.ContainsAttribute(key)
 | 
						|
}
 | 
						|
 | 
						|
func (dc *defaultContext) checkInitialized() {
 | 
						|
	if nil == dc.attributes {
 | 
						|
		panic("Attribute Manager: must be initialized")
 | 
						|
	}
 | 
						|
}
 |