github.com/TIBCOSoftware/flogo-lib@v0.5.9/core/data/scope.go (about)

     1  package data
     2  
     3  import (
     4  	"errors"
     5  	"sync"
     6  	"fmt"
     7  )
     8  
     9  //func init() {
    10  //	SetResolver(RES_SCOPE, Resolve)
    11  //}
    12  
    13  // Resolve will resolve a value in the given scope
    14  //func Resolve(scope Scope, value string) (interface{}, bool) {
    15  //	attr, ok := scope.GetAttr(value)
    16  //	if !ok {
    17  //		return nil, false
    18  //	}
    19  //
    20  //	return attr.Value, true
    21  //}
    22  
    23  // Scope is a set of attributes that are accessible
    24  type Scope interface {
    25  	// GetAttr gets the specified attribute
    26  	GetAttr(name string) (attr *Attribute, exists bool)
    27  
    28  	// SetAttrValue sets the value of the specified attribute
    29  	SetAttrValue(name string, value interface{}) error
    30  }
    31  
    32  // MutableScope is a scope that new attributes can be added
    33  type MutableScope interface {
    34  	Scope
    35  
    36  	//AddAttr adds an attribute to the scope
    37  	AddAttr(name string, valueType Type, value interface{}) *Attribute
    38  }
    39  
    40  // SimpleScope is a basic implementation of a scope
    41  type SimpleScope struct {
    42  	parentScope Scope
    43  	attrs       map[string]*Attribute
    44  }
    45  
    46  // NewSimpleScope creates a new SimpleScope
    47  func NewSimpleScope(attrs []*Attribute, parentScope Scope) Scope {
    48  
    49  	return newSimpleScope(attrs, parentScope)
    50  }
    51  
    52  // NewSimpleScope creates a new SimpleScope
    53  func newSimpleScope(attrs []*Attribute, parentScope Scope) *SimpleScope {
    54  
    55  	scope := &SimpleScope{
    56  		parentScope: parentScope,
    57  		attrs:       make(map[string]*Attribute),
    58  	}
    59  
    60  	for _, attr := range attrs {
    61  		scope.attrs[attr.Name()] = attr
    62  	}
    63  
    64  	return scope
    65  }
    66  
    67  // NewSimpleScopeFromMap creates a new SimpleScope
    68  func NewSimpleScopeFromMap(attrs map[string]*Attribute, parentScope Scope) *SimpleScope {
    69  
    70  	scope := &SimpleScope{
    71  		parentScope: parentScope,
    72  		attrs:       attrs,
    73  	}
    74  
    75  	return scope
    76  }
    77  
    78  // GetAttr implements Scope.GetAttr
    79  func (s *SimpleScope) GetAttr(name string) (attr *Attribute, exists bool) {
    80  
    81  	attr, found := s.attrs[name]
    82  
    83  	if found {
    84  		return attr, true
    85  	}
    86  
    87  	if s.parentScope != nil {
    88  		return s.parentScope.GetAttr(name)
    89  	}
    90  
    91  	return nil, false
    92  }
    93  
    94  // SetAttrValue implements Scope.SetAttrValue
    95  func (s *SimpleScope) SetAttrValue(name string, value interface{}) error {
    96  
    97  	attr, found := s.attrs[name]
    98  
    99  	if found {
   100  		attr.SetValue(value)
   101  		return nil
   102  	}
   103  
   104  	return errors.New("attribute not in scope")
   105  }
   106  
   107  // AddAttr implements MutableScope.AddAttr
   108  func (s *SimpleScope) AddAttr(name string, valueType Type, value interface{}) *Attribute {
   109  
   110  	attr, found := s.attrs[name]
   111  
   112  	if found {
   113  		attr.SetValue(value)
   114  	} else {
   115  		//todo handle error, add error to AddAttr signature
   116  		attr, _ = NewAttribute(name, valueType, value)
   117  		s.attrs[name] = attr
   118  	}
   119  
   120  	return attr
   121  }
   122  
   123  // SimpleSyncScope is a basic implementation of a synchronized scope
   124  type SimpleSyncScope struct {
   125  	scope *SimpleScope
   126  	mutex sync.Mutex
   127  }
   128  
   129  // NewSimpleSyncScope creates a new SimpleSyncScope
   130  func NewSimpleSyncScope(attrs []*Attribute, parentScope Scope) MutableScope {
   131  
   132  	var syncScope SimpleSyncScope
   133  	syncScope.scope = newSimpleScope(attrs, parentScope)
   134  
   135  	return &syncScope
   136  }
   137  
   138  // GetAttr implements Scope.GetAttr
   139  func (s *SimpleSyncScope) GetAttr(name string) (value *Attribute, exists bool) {
   140  
   141  	s.mutex.Lock()
   142  	defer s.mutex.Unlock()
   143  
   144  	return s.scope.GetAttr(name)
   145  }
   146  
   147  // SetAttrValue implements Scope.SetAttrValue
   148  func (s *SimpleSyncScope) SetAttrValue(name string, value interface{}) error {
   149  
   150  	s.mutex.Lock()
   151  	defer s.mutex.Unlock()
   152  
   153  	return s.scope.SetAttrValue(name, value)
   154  }
   155  
   156  // AddAttr implements MutableScope.AddAttr
   157  func (s *SimpleSyncScope) AddAttr(name string, valueType Type, value interface{}) *Attribute {
   158  
   159  	s.mutex.Lock()
   160  	defer s.mutex.Unlock()
   161  
   162  	return s.scope.AddAttr(name, valueType, value)
   163  }
   164  
   165  var (
   166  	globalScope = NewSimpleSyncScope(nil, nil)
   167  )
   168  
   169  // GetGlobalScope gets the global scope the application
   170  func GetGlobalScope() MutableScope {
   171  	return globalScope
   172  }
   173  
   174  // FixedScope is an implementation of a empty scope fixed to a particular set of metadata
   175  type FixedScope struct {
   176  	attrs    map[string]*Attribute
   177  	metadata map[string]*Attribute
   178  }
   179  
   180  // NewFixedScope creates a new SimpleScope
   181  func NewFixedScope(metadata map[string]*Attribute) *FixedScope {
   182  
   183  	scope := &FixedScope{
   184  		metadata: make(map[string]*Attribute),
   185  		attrs:    make(map[string]*Attribute),
   186  	}
   187  
   188  	scope.metadata = metadata
   189  
   190  	return scope
   191  }
   192  
   193  func NewFixedScopeFromMap(metadata map[string]*Attribute) *FixedScope {
   194  
   195  	scope := &FixedScope{
   196  		metadata: metadata,
   197  		attrs:    make(map[string]*Attribute),
   198  	}
   199  
   200  	return scope
   201  }
   202  
   203  // GetAttr implements Scope.GetAttr
   204  func (s *FixedScope) GetAttr(name string) (attr *Attribute, exists bool) {
   205  
   206  	attr, found := s.attrs[name]
   207  
   208  	if found {
   209  		return attr, true
   210  	} else {
   211  		metaAttr, found := s.metadata[name]
   212  		if found {
   213  			attr, _ := NewAttribute(name, metaAttr.Type(), metaAttr.value)
   214  			s.attrs[name] = attr
   215  			return attr, true
   216  		}
   217  	}
   218  	return nil, false
   219  }
   220  
   221  // GetAttrs gets the attributes set in the scope
   222  func (s *FixedScope) GetAttrs() map[string]*Attribute {
   223  	return s.attrs
   224  }
   225  
   226  // SetAttrValue implements Scope.SetAttrValue
   227  func (s *FixedScope) SetAttrValue(name string, value interface{}) error {
   228  
   229  	attr, found := s.attrs[name]
   230  
   231  	if found {
   232  		attr.SetValue(value)
   233  		return nil
   234  	} else {
   235  		metaAttr, found := s.metadata[name]
   236  		if found {
   237  			attr, err := NewAttribute(name, metaAttr.Type(), value)
   238  			s.attrs[name] = attr
   239  			return err
   240  		}
   241  	}
   242  
   243  	return fmt.Errorf("attribute '%s' not in scope", name)
   244  }
   245  
   246  //todo fix up all the scopes!
   247  
   248  // FixedScope is an implementation of a empty scope fixed to a particular set of metadata
   249  type FlexableScope struct {
   250  	attrs    map[string]*Attribute
   251  	metadata map[string]*Attribute
   252  }
   253  
   254  // NewFlexableScope creates a new SimpleScope
   255  func NewFlexableScope(metadata map[string]*Attribute) *FlexableScope {
   256  
   257  	scope := &FlexableScope{
   258  		metadata: make(map[string]*Attribute),
   259  		attrs:    make(map[string]*Attribute),
   260  	}
   261  
   262  	scope.metadata = metadata
   263  
   264  	return scope
   265  }
   266  
   267  func NewFlexableScopeFromMap(metadata map[string]*Attribute) *FlexableScope {
   268  
   269  	scope := &FlexableScope{
   270  		metadata: metadata,
   271  		attrs:    make(map[string]*Attribute),
   272  	}
   273  
   274  	return scope
   275  }
   276  
   277  // GetAttr implements Scope.GetAttr
   278  func (s *FlexableScope) GetAttr(name string) (attr *Attribute, exists bool) {
   279  
   280  	attr, found := s.attrs[name]
   281  
   282  	if found {
   283  		return attr, true
   284  	} else {
   285  		metaAttr, found := s.metadata[name]
   286  		if found {
   287  			attr, _ := NewAttribute(name, metaAttr.Type(), metaAttr.value)
   288  			s.attrs[name] = attr
   289  			return attr, true
   290  		}
   291  	}
   292  	return nil, false
   293  }
   294  
   295  // GetAttrs gets the attributes set in the scope
   296  func (s *FlexableScope) GetAttrs() map[string]*Attribute {
   297  	return s.attrs
   298  }
   299  
   300  // SetAttrValue implements Scope.SetAttrValue
   301  func (s *FlexableScope) SetAttrValue(name string, value interface{}) error {
   302  
   303  	attr, found := s.attrs[name]
   304  
   305  	if found {
   306  		attr.SetValue(value)
   307  		return nil
   308  	} else {
   309  		metaAttr, found := s.metadata[name]
   310  		if found {
   311  			attr, err := NewAttribute(name, metaAttr.Type(), value)
   312  			s.attrs[name] = attr
   313  			return err
   314  		}
   315  	}
   316  
   317  	t, err := GetType(value)
   318  	if err != nil {
   319  		t = TypeAny
   320  	}
   321  
   322  	s.attrs[name], err = NewAttribute(name, t, value)
   323  
   324  	return err
   325  }