Beispiel #1
0
 /// <summary>Ctor. </summary>
 /// <param name="baseEventUnderlying">base event</param>
 /// <param name="holders">revisions</param>
 /// <param name="lastEvent">prior event</param>
 public RevisionStateDeclared(EventBean baseEventUnderlying,
                              RevisionBeanHolder[] holders,
                              RevisionEventBeanDeclared lastEvent)
 {
     this.baseEventUnderlying = baseEventUnderlying;
     this.holders             = holders;
     this.lastEvent           = lastEvent;
 }
Beispiel #2
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);
        }