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; }
/// <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); }
/// <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);
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; } }