示例#1
0
        public override void HandleUpdate(bool isBaseEventType,
                                          RevisionStateMerge revisionState,
                                          RevisionEventBeanMerge revisionEvent,
                                          RevisionTypeDesc typesDesc)
        {
            EventBean underlyingEvent = revisionEvent.UnderlyingFullOrDelta;

            NullableObject <Object>[] changeSetValues = revisionState.Overlays;
            if (changeSetValues == null)    // optimization - the full event sets it to null, deltas all get a new one
            {
                changeSetValues = new NullableObject <Object> [spec.ChangesetPropertyNames.Length];
            }
            else
            {
                changeSetValues = ArrayCopy(changeSetValues);   // preserve the last revisions
            }

            // apply all properties of the delta event
            int[] indexes = typesDesc.ChangesetPropertyIndex;
            EventPropertyGetter[] getters = typesDesc.ChangesetPropertyGetters;
            for (int i = 0; i < indexes.Length; i++)
            {
                int index = indexes[i];

                if (!getters[i].IsExistsProperty(underlyingEvent))
                {
                    continue;
                }

                Object value = getters[i].Get(underlyingEvent);
                changeSetValues[index] = new NullableObject <Object>(value);
            }

            revisionState.Overlays = changeSetValues;
        }
示例#2
0
        /// <summary>From a list of property groups that include contributing event types, build a map of contributing event types and their type descriptor. </summary>
        /// <param name="groups">property groups</param>
        /// <param name="changesetProperties">properties that change between groups</param>
        /// <param name="keyProperties">key properties</param>
        /// <returns>map of event type and type information</returns>
        public static IDictionary <EventType, RevisionTypeDesc> GetPerType(PropertyGroupDesc[] groups,
                                                                           String[] changesetProperties,
                                                                           String[] keyProperties)
        {
            IDictionary <EventType, RevisionTypeDesc> perType = new Dictionary <EventType, RevisionTypeDesc>();

            foreach (PropertyGroupDesc group in groups)
            {
                foreach (EventType type in group.Types.Keys)
                {
                    EventPropertyGetter[] changesetGetters = GetGetters(type, changesetProperties);
                    EventPropertyGetter[] keyGetters       = GetGetters(type, keyProperties);
                    var pair = new RevisionTypeDesc(keyGetters, changesetGetters, group);
                    perType.Put(type, pair);
                }
            }
            return(perType);
        }
示例#3
0
 /// <summary>Merge properties. </summary>
 /// <param name="isBaseEventType">true if the event is a base event type</param>
 /// <param name="revisionState">the current state, to be updated.</param>
 /// <param name="revisionEvent">the new event to merge</param>
 /// <param name="typesDesc">descriptor for event type of the new event to merge</param>
 public abstract void HandleUpdate(bool isBaseEventType,
                                   RevisionStateMerge revisionState,
                                   RevisionEventBeanMerge revisionEvent,
                                   RevisionTypeDesc typesDesc);
示例#4
0
        public override void OnUpdate(EventBean[] newData, EventBean[] oldData, NamedWindowRootViewInstance namedWindowRootView, EventTableIndexRepository indexRepository)
        {
            // If new data is filled, it is not a delete
            RevisionEventBeanDeclared revisionEvent;
            Object key;

            if ((newData == null) || (newData.Length == 0))
            {
                // we are removing an event
                revisionEvent = (RevisionEventBeanDeclared)oldData[0];
                key           = revisionEvent.Key;
                _statePerKey.Remove(key);

                // Insert into indexes for fast deletion, if there are any
                foreach (EventTable table in indexRepository.GetTables())
                {
                    table.Remove(oldData);
                }

                // make as not the latest event since its due for removal
                revisionEvent.IsLatest = false;

                namedWindowRootView.UpdateChildren(null, oldData);
                return;
            }

            revisionEvent = (RevisionEventBeanDeclared)newData[0];
            EventBean underlyingEvent    = revisionEvent.UnderlyingFullOrDelta;
            EventType underyingEventType = underlyingEvent.EventType;

            // obtain key values
            key = null;
            RevisionTypeDesc typesDesc       = null;
            bool             isBaseEventType = false;

            if (underyingEventType == _baseEventType)
            {
                key             = PropertyUtility.GetKeys(underlyingEvent, _fullKeyGetters);
                isBaseEventType = true;
            }
            else
            {
                typesDesc = TypeDescriptors.Get(underyingEventType);

                // if this type cannot be found, check all supertypes, if any
                if (typesDesc == null)
                {
                    IEnumerable <EventType> superTypes = underyingEventType.DeepSuperTypes;
                    if (superTypes != null)
                    {
                        foreach (var superType in superTypes)
                        {
                            if (superType == _baseEventType)
                            {
                                key             = PropertyUtility.GetKeys(underlyingEvent, _fullKeyGetters);
                                isBaseEventType = true;
                                break;
                            }
                            typesDesc = TypeDescriptors.Get(superType);
                            if (typesDesc != null)
                            {
                                TypeDescriptors.Put(underyingEventType, typesDesc);
                                key = PropertyUtility.GetKeys(underlyingEvent, typesDesc.KeyPropertyGetters);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    key = PropertyUtility.GetKeys(underlyingEvent, typesDesc.KeyPropertyGetters);
                }
            }

            // get the state for this key value
            RevisionStateDeclared revisionState = _statePerKey.Get(key);

            // Delta event and no full
            if ((!isBaseEventType) && (revisionState == null))
            {
                return; // Ignore the event, its a delta and we don't currently have a full event for it
            }

            // New full event
            if (revisionState == null)
            {
                revisionState = new RevisionStateDeclared(underlyingEvent, null, null);
                _statePerKey.Put(key, revisionState);

                // prepare revison event
                revisionEvent.LastBaseEvent = underlyingEvent;
                revisionEvent.Key           = key;
                revisionEvent.Holders       = null;
                revisionEvent.IsLatest      = true;

                // Insert into indexes for fast deletion, if there are any
                foreach (EventTable table in indexRepository.GetTables())
                {
                    table.Add(newData);
                }

                // post to data window
                revisionState.LastEvent = revisionEvent;
                namedWindowRootView.UpdateChildren(new EventBean[] { revisionEvent }, null);
                return;
            }

            // new version
            long versionNumber = revisionState.IncRevisionNumber();

            // Previously-seen full event
            if (isBaseEventType)
            {
                revisionState.Holders             = null;
                revisionState.BaseEventUnderlying = underlyingEvent;
            }
            // Delta event to existing full event
            else
            {
                var groupNum = typesDesc.Group.GroupNum;
                var holders  = revisionState.Holders;
                if (holders == null)    // optimization - the full event sets it to null, deltas all get a new one
                {
                    holders = new RevisionBeanHolder[_groups.Length];
                }
                else
                {
                    holders = ArrayCopy(holders);   // preserve the last revisions
                }

                // add the new revision for a property group on top
                holders[groupNum]     = new RevisionBeanHolder(versionNumber, underlyingEvent, typesDesc.ChangesetPropertyGetters);
                revisionState.Holders = holders;
            }

            // prepare revision event
            revisionEvent.LastBaseEvent = revisionState.BaseEventUnderlying;
            revisionEvent.Holders       = revisionState.Holders;
            revisionEvent.Key           = key;
            revisionEvent.IsLatest      = true;

            // get prior event
            RevisionEventBeanDeclared lastEvent = revisionState.LastEvent;

            lastEvent.IsLatest = false;

            // data to post
            var newDataPost = new EventBean[] { revisionEvent };
            var oldDataPost = new EventBean[] { lastEvent };

            // Update indexes
            foreach (EventTable table in indexRepository.GetTables())
            {
                table.Remove(oldDataPost);
                table.Add(newDataPost);
            }

            // keep reference to last event
            revisionState.LastEvent = revisionEvent;

            namedWindowRootView.UpdateChildren(newDataPost, oldDataPost);
        }
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="revisioneventTypeName">name</param>
        /// <param name="spec">specification</param>
        /// <param name="statementStopService">for stop handling</param>
        /// <param name="eventAdapterService">for nested property handling</param>
        /// <param name="eventTypeIdGenerator">The event type id generator.</param>
        public VAERevisionProcessorMerge(String revisioneventTypeName, RevisionSpec spec, StatementStopService statementStopService, EventAdapterService eventAdapterService, EventTypeIdGenerator eventTypeIdGenerator)
            : base(spec, revisioneventTypeName, eventAdapterService)
        {
            // on statement stop, remove versions
            statementStopService.StatementStopped += () => _statePerKey.Clear();
            _statePerKey = new Dictionary <Object, RevisionStateMerge>();

            // For all changeset properties, add type descriptors (property number, getter etc)
            var propertyDesc = new Dictionary <String, RevisionPropertyTypeDesc>();
            var count        = 0;

            foreach (String property in spec.ChangesetPropertyNames)
            {
                var fullGetter     = spec.BaseEventType.GetGetter(property);
                var propertyNumber = count;
                var paramList      = new RevisionGetterParameters(property, propertyNumber, fullGetter, null);

                // if there are no groups (full event property only), then simply use the full event getter
                EventPropertyGetter revisionGetter = new ProxyEventPropertyGetter(
                    eventBean =>
                {
                    var riv = (RevisionEventBeanMerge)eventBean;
                    return(riv.GetVersionedValue(paramList));
                },
                    eventBean => null,
                    eventBean => true);

                var type = spec.BaseEventType.GetPropertyType(property);
                if (type == null)
                {
                    foreach (EventType deltaType in spec.DeltaTypes)
                    {
                        var dtype = deltaType.GetPropertyType(property);
                        if (dtype != null)
                        {
                            type = dtype;
                            break;
                        }
                    }
                }

                var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, paramList, type);
                propertyDesc.Put(property, propertyTypeDesc);
                count++;
            }

            count = 0;
            foreach (String property in spec.KeyPropertyNames)
            {
                var keyPropertyNumber = count;
                EventPropertyGetter revisionGetter;
                if (spec.KeyPropertyNames.Length == 1)
                {
                    revisionGetter = new ProxyEventPropertyGetter
                    {
                        ProcGet = eventBean => ((RevisionEventBeanMerge)eventBean).Key,
                        ProcIsExistsProperty = eventBean => true,
                        ProcGetFragment      = eventBean => null
                    };
                }
                else
                {
                    revisionGetter = new ProxyEventPropertyGetter
                    {
                        ProcGet = eventBean =>
                        {
                            var riv = (RevisionEventBeanMerge)eventBean;
                            return(((MultiKeyUntyped)riv.Key).Keys[keyPropertyNumber]);
                        },
                        ProcIsExistsProperty = eventBean => true,
                        ProcGetFragment      = eventBean => null
                    };
                }

                var type = spec.BaseEventType.GetPropertyType(property);
                if (type == null)
                {
                    foreach (EventType deltaType in spec.DeltaTypes)
                    {
                        var dtype = deltaType.GetPropertyType(property);
                        if (dtype != null)
                        {
                            type = dtype;
                            break;
                        }
                    }
                }
                var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, null, type);
                propertyDesc.Put(property, propertyTypeDesc);
                count++;
            }

            // compile for each event type a list of getters and indexes within the overlay
            foreach (EventType deltaType in spec.DeltaTypes)
            {
                RevisionTypeDesc typeDesc = MakeTypeDesc(deltaType, spec.PropertyRevision);
                TypeDescriptors.Put(deltaType, typeDesc);
            }
            _infoFullType = MakeTypeDesc(spec.BaseEventType, spec.PropertyRevision);

            // how to handle updates to a full event
            if (spec.PropertyRevision == PropertyRevisionEnum.MERGE_DECLARED)
            {
                _updateStrategy = new UpdateStrategyDeclared(spec);
            }
            else if (spec.PropertyRevision == PropertyRevisionEnum.MERGE_NON_NULL)
            {
                _updateStrategy = new UpdateStrategyNonNull(spec);
            }
            else if (spec.PropertyRevision == PropertyRevisionEnum.MERGE_EXISTS)
            {
                _updateStrategy = new UpdateStrategyExists(spec);
            }
            else
            {
                throw new ArgumentException("Unknown revision type '" + spec.PropertyRevision + "'");
            }

            EventTypeMetadata metadata = EventTypeMetadata.CreateValueAdd(revisioneventTypeName, TypeClass.REVISION);

            RevisionEventType = new RevisionEventType(metadata, eventTypeIdGenerator.GetTypeId(revisioneventTypeName), propertyDesc, eventAdapterService);
        }
        public override void HandleUpdate(bool isBaseEventType,
                                          RevisionStateMerge revisionState,
                                          RevisionEventBeanMerge revisionEvent,
                                          RevisionTypeDesc typesDesc)
        {
            EventBean underlyingEvent = revisionEvent.UnderlyingFullOrDelta;

            // Previously-seen full event
            if (isBaseEventType)
            {
                // If delta types don't add properties, simply set the overlay to null
                NullableObject <Object>[] changeSetValues;
                if (!spec.IsDeltaTypesAddProperties)
                {
                    changeSetValues = null;
                }
                // If delta types do add properties, set a new overlay
                else
                {
                    changeSetValues = revisionState.Overlays;
                    if (changeSetValues == null)    // optimization - the full event sets it to null, deltas all get a new one
                    {
                        changeSetValues = new NullableObject <Object> [spec.ChangesetPropertyNames.Length];
                    }
                    else
                    {
                        changeSetValues = ArrayCopy(changeSetValues);   // preserve the last revisions
                    }

                    // reset properties not contributed by any delta, leaving all delta-contributed properties in place
                    bool[] changesetPropertyDeltaContributed = spec.ChangesetPropertyDeltaContributed;
                    for (int i = 0; i < changesetPropertyDeltaContributed.Length; i++)
                    {
                        // if contributed then leave the value, else override
                        if (!changesetPropertyDeltaContributed[i])
                        {
                            changeSetValues[i] = null;
                        }
                    }
                }
                revisionState.Overlays            = changeSetValues;
                revisionState.BaseEventUnderlying = underlyingEvent;
            }
            // Delta event to existing full event merge
            else
            {
                NullableObject <Object>[] changeSetValues = revisionState.Overlays;

                if (changeSetValues == null)    // optimization - the full event sets it to null, deltas all get a new one
                {
                    changeSetValues = new NullableObject <Object> [spec.ChangesetPropertyNames.Length];
                }
                else
                {
                    changeSetValues = ArrayCopy(changeSetValues);   // preserve the last revisions
                }

                // apply all properties of the delta event
                int[] indexes = typesDesc.ChangesetPropertyIndex;
                EventPropertyGetter[] getters = typesDesc.ChangesetPropertyGetters;
                for (int i = 0; i < indexes.Length; i++)
                {
                    int    index = indexes[i];
                    Object value = getters[i].Get(underlyingEvent);
                    changeSetValues[index] = new NullableObject <Object>(value);
                }

                revisionState.Overlays = changeSetValues;
            }
        }