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); }
public override void OnUpdate(EventBean[] newData, EventBean[] oldData, NamedWindowRootViewInstance namedWindowRootView, EventTableIndexRepository indexRepository) { // If new data is filled, it is not a delete RevisionEventBeanMerge revisionEvent; Object key; if ((newData == null) || (newData.Length == 0)) { // we are removing an event revisionEvent = (RevisionEventBeanMerge)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 = (RevisionEventBeanMerge)newData[0]; EventBean underlyingEvent = revisionEvent.UnderlyingFullOrDelta; EventType underyingEventType = underlyingEvent.EventType; // obtain key values key = null; RevisionTypeDesc typesDesc; Boolean isBaseEventType = false; if (underyingEventType == RevisionSpec.BaseEventType) { typesDesc = _infoFullType; key = PropertyUtility.GetKeys(underlyingEvent, _infoFullType.KeyPropertyGetters); isBaseEventType = true; } else { typesDesc = TypeDescriptors.Get(underyingEventType); // if this type cannot be found, check all supertypes, if any if (typesDesc == null) { EventType[] superTypes = underyingEventType.DeepSuperTypes; if (superTypes != null) { foreach (var superType in superTypes) { if (superType == RevisionSpec.BaseEventType) { typesDesc = _infoFullType; key = PropertyUtility.GetKeys(underlyingEvent, _infoFullType.KeyPropertyGetters); 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 RevisionStateMerge 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 RevisionStateMerge(underlyingEvent, null, null); _statePerKey.Put(key, revisionState); // prepare revison event revisionEvent.LastBaseEvent = underlyingEvent; revisionEvent.Key = key; revisionEvent.Overlay = 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; } // handle Update, changing revision state and event as required _updateStrategy.HandleUpdate(isBaseEventType, revisionState, revisionEvent, typesDesc); // prepare revision event revisionEvent.LastBaseEvent = revisionState.BaseEventUnderlying; revisionEvent.Overlay = revisionState.Overlays; revisionEvent.Key = key; revisionEvent.IsLatest = true; // get prior event RevisionEventBeanMerge 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); }