prop

package
v0.0.0-...-986c4a6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 17, 2020 License: MIT Imports: 9 Imported by: 9

Documentation

Index

Constants

View Source
const ISO8601 = "2006-01-02T15:04:05"

Variables

This section is empty.

Functions

func AddEventFactory

func AddEventFactory(annotation string, factory func() Subscriber)

Add a subscriber factory function that corresponds to a given annotation.

func Visit

func Visit(property Property, visitor Visitor) error

Entry point to visit a property in a depth-first-search fashion.

Types

type Container

type Container interface {
	Property

	// Return the number of children properties.
	CountChildren() int

	// Iterate through all children properties and invoke the callback function sequentially.
	// The callback method SHALL NOT block the executing Goroutine.
	ForEachChild(callback func(index int, child Property) error) error

	// Return the child property addressable by the index, or nil.
	ChildAtIndex(index interface{}) Property

	// Add a prototype of the child property to the container,
	// and return the index. Return childNotCreated (-1) to indicate no child was created.
	NewChild() int

	// Consolidate and remove any unwanted child properties. Delete operations may leave some
	// children properties unassigned. The container may decide to remove them from its collection.
	Compact()

	// Propagate the event for a child property.
	Propagate(e *Event) error
}

Special SCIM property that contains other property. This interface shall be implemented by complex and multiValued properties. A container property usually does not hold value on its own. Instead, it serves as a collection of values for its sub properties (i.e. complex property) or element properties (i.e. multiValued property), these contained properties are called "children properties" in this context.

type Event

type Event struct {
	// contains filtered or unexported fields
}

Event payload

func (*Event) StopPropagation

func (e *Event) StopPropagation()

Set the propagate flag of this event to false, thus preventing this event to be further propagated upstream.

func (*Event) Target

func (e *Event) Target() Property

Return the target property of the event

func (*Event) Type

func (e *Event) Type() EventType

Return the type of the event

func (*Event) WillPropagate

func (e *Event) WillPropagate() bool

Returns true if the event should be propagated to the parent of its target.

type EventType

type EventType int

type of an event

const (

	// Event that new value has been assigned to the property.
	// The event entails that the property is now in an "assigned" state, such that
	// calling IsUnassigned shall return false. It is only emitted when value introduced
	// to the property is different than the previous value, otherwise, no event would be
	// emitted.
	EventAssigned EventType
	// Event that property value was deleted and now is an "unassigned" state. Calling
	// IsUnassigned shall return true. It is only emitted that value was deleted from property
	// when it was in an "assigned" state, otherwise, no event would be emitted.
	EventUnassigned
)

func (EventType) NewFrom

func (t EventType) NewFrom(target Property) *Event

Create a new event of this type. By default, the event will propagate.

type FluentNavigator

type FluentNavigator struct {
	// contains filtered or unexported fields
}

FluentNavigator is wrapper around Navigator. It exposes the same API as Navigator, but in a fluent way. In addition, any intermediate error caused by FocusXXX methods are cached internally and turns further FocusXXX methods into a no-op.

func NewFluentNavigator

func NewFluentNavigator(source Property) *FluentNavigator

Create a fluent navigator.

func (*FluentNavigator) Current

func (n *FluentNavigator) Current() Property

func (*FluentNavigator) CurrentAsContainer

func (n *FluentNavigator) CurrentAsContainer() Container

func (*FluentNavigator) Depth

func (n *FluentNavigator) Depth() int

func (*FluentNavigator) Error

func (n *FluentNavigator) Error() error

func (*FluentNavigator) FocusCriteria

func (n *FluentNavigator) FocusCriteria(criteria func(child Property) bool) *FluentNavigator

func (*FluentNavigator) FocusIndex

func (n *FluentNavigator) FocusIndex(index int) *FluentNavigator

func (*FluentNavigator) FocusName

func (n *FluentNavigator) FocusName(name string) *FluentNavigator

func (*FluentNavigator) Retract

func (n *FluentNavigator) Retract() *FluentNavigator
type Navigator struct {
	// contains filtered or unexported fields
}

Navigator is a stack of properties to let caller take control of how to traverse through the property structure, as opposed to Visitor and DFS traversal where the structure itself is in control.

func NewNavigator

func NewNavigator(source Property) *Navigator

Create a new navigator to traverse the property.

func (n *Navigator) Current() Property

Return the currently focused property.

func (n *Navigator) Depth() int

Return the number of properties that was focused, including the currently focused. These properties, excluding the current one, can be refocused by calling Retract, one at a time in the reversed order that were focused. The minimum depth is one.

func (n *Navigator) FocusCriteria(criteria func(child Property) bool) (Property, error)

Focus on the element that meets given criteria, and return the focused property, or a noTarget error. The returned property will be the newly focused property, as reflected in the Current method.

func (n *Navigator) FocusIndex(index int) (Property, error)

Focus on the element at index given index, and return the element property, or a noTarget error. The returned property will be the newly focused property, as reflected in the Current method. This method is intended to be used when the currently focused property is a multiValued property. Any other property will yield a noTarget error. If index is out of range, a noTarget error is also returned.

func (n *Navigator) FocusName(name string) (Property, error)

Focus on the sub property that goes by the given name (case insensitive), and return that sub property, or a noTarget error. The returned property will be the newly focused property, as reflected in the Current method. This method is intended to be used when the currently focused property is singular complex property. Any other property will yield a noTarget error.

func (n *Navigator) Retract()

Go back to the last focused property. Note that the source property that this navigator is created with in NewNavigator cannot be retracted.

type Property

type Property interface {
	// Return a non-nil attribute to describe this property.
	Attribute() *spec.Attribute

	// Return the parent container of this property. If this attribute has no
	// parent container, return nil.
	Parent() Container

	// Return the property's value in Golang's native type. The chosen types corresponding to
	// SCIM attribute types are:
	// string - string
	// integer - int64
	// decimal - float64
	// boolean - bool
	// dateTime - string
	// reference - string
	// binary - string
	// complex - map[string]interface{}
	// multiValued - []interface{}
	// Property implementations are obliged to return in these types, or return a nil in case of
	// unassigned. However, implementations are not obliged to represent data in these types internally.
	Raw() interface{}

	// Return true if this property is unassigned. Unassigned is defined to be nil for singular non-complex
	// typed properties; empty for multiValued properties; and complex properties are unassigned if and only
	// if all its containing sub properties are unassigned.
	IsUnassigned() bool

	// Return true if the two properties match each other. Properties match if and only if
	// their attributes match and their values are comparable according to the attribute.
	// For properties carrying singular non-complex attributes, attributes and values are compared.
	// For complex properties, two complex properties match if and only if all their identity sub
	// properties match.
	// For multiValued properties, match only happens when they have the same number of element properties
	// and the element properties all match correspondingly.
	// Two unassigned properties with the same attribute matches each other.
	Matches(another Property) bool

	// Returns the hash value of this property's value. This will be helpful in comparing two properties.
	// Unassigned values shall return a hash of 0 (zero). Although this will create a potential hash
	// collision, we avoid this problem by checking the unassigned case first before comparing hashes.
	Hash() uint64

	// Return true if the property's value is equal to the given value. If the given value
	// is nil, always return false. This method corresponds to the 'eq' filter operator.
	// If implementation cannot apply the 'eq' operator, return an error.
	EqualsTo(value interface{}) (bool, error)

	// Return true if the property's value starts with the given value. If the given value
	// is nil, always return false. This method corresponds to the 'sw' filter operator.
	// If implementation cannot apply the 'sw' operator, return an error.
	StartsWith(value string) (bool, error)

	// Return true if the property's value ends with the given value. If the given value
	// is nil, always return false. This method corresponds to the 'ew' filter operator.
	// If implementation cannot apply the 'ew' operator, return an error.
	EndsWith(value string) (bool, error)

	// Return true if the property's value contains the given value. If the given value
	// is nil, always return false. This method corresponds to the 'co' filter operator.
	// If implementation cannot apply the 'co' operator, return an error.
	Contains(value string) (bool, error)

	// Return true if the property's value is greater than the given value. If the given value
	// is nil, always return false. This method corresponds to the 'gt' filter operator.
	// If implementation cannot apply the 'gt' operator, return an error.
	GreaterThan(value interface{}) (bool, error)

	// Return true if the property's value is greater than the given value. If the given value
	// is nil, always return false. This method corresponds to the 'lt' filter operator.
	// If implementation cannot apply the 'lt' operator, return an error.
	LessThan(value interface{}) (bool, error)

	// Return true if the property's value is present. Presence is defined to be non-nil and non-empty.
	// This method corresponds to the 'pr' operator and shall be implemented by all implementations.
	Present() bool

	// Add a value to the property. If the value already exists, no change will be made. Otherwise, the value will
	// be added to the underlying data structure and mod count increased by one. For simple properties, calling this
	// method equates to calling Replace.
	Add(value interface{}) error

	// Replace value of this property. If the value equals to the current value, no change will be made. Otherwise,
	// the underlying value will be replaced. Providing a nil value equates to calling Delete.
	Replace(value interface{}) error

	// Delete value from this property. If the property is already unassigned, deleting it again has no effect.
	Delete() error

	// Returns true if any of Add/Replace/Delete method was ever called. This method is necessary to distinguish
	// between a naturally unassigned state and a deleted unassigned state. When a property is first constructed,
	// it has no value, and hence lies in an unassigned state. However, this shall not be considered the same with
	// a property returning to an unassigned state after having its value deleted. Such difference is important as
	// the SCIM specification mandates that user may override the server generated default value for a readWrite
	// property by explicitly providing "null" or "[]" (in case of multiValued) in the JSON payload. In such situations,
	// value generators should back off when an unassigned property is also dirty.
	Dirty() bool

	// Add the subscriber to the properties emitted events
	Subscribe(subscriber Subscriber)

	// Return an exact clone of the property. The cloned property may share the same instance of attribute and
	// subscribers, but must retain individual copies of their values. The cloned property should be attached to
	// the new parent container, which usually is the result of previous Clone call.
	Clone(parent Container) Property
}

Property holds a piece of data and is describe by an Attribute. A property can exist by itself, or it can exist as a sub property of another property, in which case, the containing property is known as a container property.

func New

func New(attr *spec.Attribute, parent Container) Property

Create a new unassigned property based on the given attribute, and set its parent. The method will panic if anything went wrong.

func NewBinary

func NewBinary(attr *spec.Attribute, parent Container) Property

Create a new unassigned binary property. The method will panic if given attribute is not singular binary type.

func NewBinaryOf

func NewBinaryOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new binary property with given base64 encoded value. The method will panic if given attribute is not singular binary type. The property will be marked dirty at the start.

func NewBoolean

func NewBoolean(attr *spec.Attribute, parent Container) Property

Create a new unassigned boolean property. The method will panic if given attribute is not singular boolean type.

func NewBooleanOf

func NewBooleanOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new boolean property with given value. The method will panic if given attribute is not singular boolean type. The property will be marked dirty at the start.

func NewComplex

func NewComplex(attr *spec.Attribute, parent Container) Property

Create a new unassigned complex property. The method will panic if given attribute is not singular complex type.

func NewComplexOf

func NewComplexOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new complex property with given value. The method will panic if given attribute is not singular complex type. The property will be marked dirty at the start unless value is empty

func NewDateTime

func NewDateTime(attr *spec.Attribute, parent Container) Property

Create a new unassigned string property. The method will panic if given attribute is not singular dateTime type.

func NewDateTimeOf

func NewDateTimeOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new string property with given value. The method will panic if given attribute is not singular dateTime type or the value is not of ISO8601 format. The property will be marked dirty at the start.

func NewDecimal

func NewDecimal(attr *spec.Attribute, parent Container) Property

Create a new unassigned decimal property. The method will panic if given attribute is not singular decimal type.

func NewDecimalOf

func NewDecimalOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new decimal property with given value. The method will panic if given attribute is not singular decimal type. The property will be marked dirty at the start.

func NewInteger

func NewInteger(attr *spec.Attribute, parent Container) Property

Create a new unassigned integer property. The method will panic if given attribute is not singular integer type.

func NewIntegerOf

func NewIntegerOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new integer property with given value. The method will panic if given attribute is not singular integer type. The property will be marked dirty at the start.

func NewMulti

func NewMulti(attr *spec.Attribute, parent Container) Property

Create a new unassigned multiValued property. The method will panic if given attribute is not multiValued type.

func NewMultiOf

func NewMultiOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new multiValued property with given value. The method will panic if given attribute is not multiValued type. The property will be marked dirty at the start.

func NewReference

func NewReference(attr *spec.Attribute, parent Container) Property

Create a new unassigned reference property. The method will panic if given attribute is not singular reference type.

func NewReferenceOf

func NewReferenceOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new reference property with given value. The method will panic if given attribute is not singular reference type. The property will be marked dirty at the start.

func NewString

func NewString(attr *spec.Attribute, parent Container) Property

Create a new unassigned string property. The method will panic if given attribute is not singular string type.

func NewStringOf

func NewStringOf(attr *spec.Attribute, parent Container, value interface{}) Property

Create a new string property with given value. The method will panic if given attribute is not singular string type. The property will be marked dirty at the start.

type Resource

type Resource struct {
	// contains filtered or unexported fields
}

Resource represents a SCIM resource. This is the main object of interaction in the SCIM spec. It is implemented as a wrapper around the top level complex property and the resource type.

func NewResource

func NewResource(resourceType *spec.ResourceType) *Resource

Create a new resource of the given resource type. The method panics if something went wrong.

func NewResourceOf

func NewResourceOf(resourceType *spec.ResourceType, value interface{}) *Resource

Create a new resource of the given resource type and value. The method panics if something went wrong.

func (*Resource) Add

func (r *Resource) Add(value interface{}) error

Add value to the top level of the resource.

func (*Resource) Clone

func (r *Resource) Clone() *Resource

Return a clone of this resource. The clone will contain properties that share the same instance of attribute and subscribers with the original property before the clone, but retain separate instance of values.

func (*Resource) Hash

func (r *Resource) Hash() uint64

Return the hash of the resource at its current state.

func (*Resource) ID

func (r *Resource) ID() string

Convenience method to return the ID of the resource. If id does not exist, return empty string.

func (*Resource) Location

func (r *Resource) Location() string

Convenience method to return the meta.location field of the resource, or empty string if it does not exist.

func (*Resource) NewFluentNavigator

func (r *Resource) NewFluentNavigator() *FluentNavigator

Adapting constructor method to return a new fluent navigator for the top level property of the resource.

func (*Resource) NewNavigator

func (r *Resource) NewNavigator() *Navigator

Adapting constructor method to return a new navigator for the top level property of the resource.

func (*Resource) Replace

func (r *Resource) Replace(value interface{}) error

Replace value on the top level of the resource.

func (*Resource) ResourceType

func (r *Resource) ResourceType() *spec.ResourceType

Return the resource type of this resource

func (*Resource) SuperAttribute

func (r *Resource) SuperAttribute() *spec.Attribute

Return the super attribute that describes this resource.

func (*Resource) Version

func (r *Resource) Version() string

Convenience method to return the meta.version field of the resource, or empty string if it does not exist

func (*Resource) Visit

func (r *Resource) Visit(visitor Visitor) error

Adapting method to start a DFS visit on the top level property of the resource.

type Subscriber

type Subscriber interface {
	// Be notified and react to the event. Implementations of this method
	// is allowed to return a non-nil error, which will be regarded as caller's
	// own error. Implementations are not supposed to block the Goroutine and
	// should keep the reaction quick.
	Notify(publisher Property, event *Event) error
}

A subscriber to the event.

func NewAutoCompactSubscriber

func NewAutoCompactSubscriber() Subscriber

Creates a subscriber that automatically compacts multiValued properties. This subscriber listens for EventUnassigned events from its elements (special attributes whose attribute id suffixes "$elem" on its multiValued container). If any element was unassigned, it calls the Compact method on the multiValued container in order to compact the collection.

func NewComplexStateSubscriber

func NewComplexStateSubscriber() Subscriber

Create a subscriber that watches the state of a complex property. The subscriber listens to EventAssigned and EventUnassigned events from the sub properties of the complex property it subscribes to, and re-emit EventAssigned and EventUnassigned events on the complex property. For every EventAssigned event from sub properties, it re-emits EventAssigned events on the complex property; for every EventUnassigned event from sub properties, it checks if the complex property (container) has become unassigned and only emits EventUnassigned event when it became unassigned.

This subscriber is useful when upstream subscribers need a summary of the container state as a whole.

func NewExclusivePrimarySubscriber

func NewExclusivePrimarySubscriber() Subscriber

Create a subscriber that handles the exclusive primary problem. The subscriber listens on the EventAssigned event emitted by a property whose sub attribute is marked as primary. If the value of that property becomes "true", the subscriber will go through all elements of this property (assuming being a multiValued complex property) and delete all other sub properties that went by the same name of the event target. The end result would be that only one primary sub property will have the value "true".

func NewSchemaSyncSubscriber

func NewSchemaSyncSubscriber() Subscriber

Create a new schema sync subscriber. The subscriber is designed to listen on the top level complex property for any emitted EventAssigned and EventUnassigned events from a complex sub property which serves as a container for attributes from one of the schema extensions in the resource type. Such property would have been annotated with "@StateSummary".

When EventAssigned is emitted, it ensures the schema extension URN is present in the "schemas" attribute by adding the URN to it (note multiValued properties do not actually add a new item unless it wasn't part of the collection). When EventUnassigned is emitted, it ensures the schema extension URN is absent from the "schemas" attribute by removing it. The removal does not automatically compact the multiValued "schema" property. As a result, it will have an unassigned element in its collection. The compacting can be done by triggering the AutoCompactSubscriber.

type Visitor

type Visitor interface {
	// Returns true if property should be visited; if false, the property will not be visited.
	ShouldVisit(property Property) bool
	// Visit the property, only when ShouldVisit returns true. If this method returns non-nil error,
	// the rest of the traversal will be aborted.
	Visit(property Property) error
	// Invoked when the children properties of a container property is about to be visited. The containing
	// property is supplied as an argument to provide context information. The container property itself,
	// however, has already been invoked on ShouldVisit and/or Visit.
	BeginChildren(container Container)
	// Invoked when the children properties of a container property has finished. The containing property
	// is supplied as a context argument.
	EndChildren(container Container)
}

Interface to implement for callers to react to a property structure traversal.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL