public Type GetPropertyType(String propertyName) { RevisionPropertyTypeDesc desc = _propertyDesc.Get(propertyName); if (desc != null) { if (desc.PropertyType is Type) { return((Type)desc.PropertyType); } return(null); } // dynamic property names note allowed if (propertyName.IndexOf('?') != -1) { return(null); } // see if this is a nested property int index = ASTUtil.UnescapedIndexOfDot(propertyName); if (index == -1) { return(null); } // Map event types allow 2 types of properties inside: // - a property that is a Java object is interrogated via bean property getters and BeanEventType // - a property that is a Map itself is interrogated via map property getters // Take apart the nested property into a map key and a nested value class property name String propertyMap = ASTUtil.UnescapeDot(propertyName.Substring(0, index)); String propertyNested = propertyName.Substring(index + 1); desc = _propertyDesc.Get(propertyMap); if (desc == null) { return(null); // prefix not a known property } else if (desc.PropertyType is Type) { Type simpleClass = (Type)desc.PropertyType; EventType nestedEventType = _eventAdapterService.AddBeanType(simpleClass.FullName, simpleClass, false, false, false); return(nestedEventType.GetPropertyType(propertyNested)); } else { return(null); } }
/// <summary>Creates property descriptors for revision. </summary> /// <param name="spec">specifies revision</param> /// <param name="groups">the groups that group properties</param> /// <returns>map of property and descriptor</returns> public static IDictionary <String, RevisionPropertyTypeDesc> CreatePropertyDescriptors(RevisionSpec spec, PropertyGroupDesc[] groups) { IDictionary <String, int[]> propsPerGroup = PropertyUtility.GetGroupsPerProperty(groups); IDictionary <String, RevisionPropertyTypeDesc> propertyDesc = new Dictionary <String, RevisionPropertyTypeDesc>(); int count = 0; foreach (String property in spec.ChangesetPropertyNames) { var fullGetter = spec.BaseEventType.GetGetter(property); var propertyNumber = count; var propGroupsProperty = propsPerGroup.Get(property); var paramList = new RevisionGetterParameters(property, propertyNumber, fullGetter, propGroupsProperty); // if there are no groups (full event property only), then simply use the full event getter EventPropertyGetter revisionGetter = new ProxyEventPropertyGetter( eventBean => ((RevisionEventBeanDeclared)eventBean).GetVersionedValue(paramList), eventBean => null, eventBean => true); var type = spec.BaseEventType.GetPropertyType(property); var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, paramList, type); propertyDesc.Put(property, propertyTypeDesc); count++; } foreach (String property in spec.BaseEventOnlyPropertyNames) { EventPropertyGetter fullGetter = spec.BaseEventType.GetGetter(property); // if there are no groups (full event property only), then simply use the full event getter EventPropertyGetter revisionGetter = new ProxyEventPropertyGetter( eventBean => { var riv = (RevisionEventBeanDeclared)eventBean; var bean = riv.LastBaseEvent; return(bean == null ? null : fullGetter.Get(bean)); }, eventBean => null, eventBean => true); var type = spec.BaseEventType.GetPropertyType(property); var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, null, type); propertyDesc.Put(property, propertyTypeDesc); count++; } count = 0; foreach (String property in spec.KeyPropertyNames) { int keyPropertyNumber = count; EventPropertyGetter revisionGetter; if (spec.KeyPropertyNames.Length == 1) { revisionGetter = new ProxyEventPropertyGetter { ProcGet = eventBean => ((RevisionEventBeanDeclared)eventBean).Key, ProcIsExistsProperty = eventBean => true, ProcGetFragment = eventBean => null }; } else { revisionGetter = new ProxyEventPropertyGetter { ProcGet = eventBean => { var riv = (RevisionEventBeanDeclared)eventBean; return(((MultiKeyUntyped)riv.Key).Keys[keyPropertyNumber]); }, ProcIsExistsProperty = eventBean => true, ProcGetFragment = eventBean => null }; } var type = spec.BaseEventType.GetPropertyType(property); var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, null, type); propertyDesc.Put(property, propertyTypeDesc); count++; } return(propertyDesc); }
/// <summary>Creates property descriptors for revision. </summary> /// <param name="spec">specifies revision</param> /// <param name="groups">the groups that group properties</param> /// <returns>map of property and descriptor</returns> public static IDictionary <string, RevisionPropertyTypeDesc> CreatePropertyDescriptors( RevisionSpec spec, PropertyGroupDesc[] groups) { var propsPerGroup = PropertyUtility.GetGroupsPerProperty(groups); IDictionary <string, RevisionPropertyTypeDesc> propertyDesc = new Dictionary <string, RevisionPropertyTypeDesc>(); var count = 0; foreach (var property in spec.ChangesetPropertyNames) { var fullGetter = spec.BaseEventType.GetGetter(property); var propertyNumber = count; var propGroupsProperty = propsPerGroup.Get(property); var paramList = new RevisionGetterParameters(property, propertyNumber, fullGetter, propGroupsProperty); // if there are no groups (full event property only), then simply use the full event getter var revisionGetter = new VAERevisionEventPropertyGetterDeclaredGetVersioned(paramList); var type = spec.BaseEventType.GetPropertyType(property); var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, paramList, type); propertyDesc.Put(property, propertyTypeDesc); count++; } foreach (var property in spec.BaseEventOnlyPropertyNames) { var fullGetter = ((EventTypeSPI)spec.BaseEventType).GetGetterSPI(property); // if there are no groups (full event property only), then simply use the full event getter var revisionGetter = new VAERevisionEventPropertyGetterDeclaredLast(fullGetter); var type = spec.BaseEventType.GetPropertyType(property); var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, null, type); propertyDesc.Put(property, propertyTypeDesc); count++; } count = 0; foreach (var property in spec.KeyPropertyNames) { var keyPropertyNumber = count; EventPropertyGetterSPI revisionGetter; if (spec.KeyPropertyNames.Length == 1) { revisionGetter = new VAERevisionEventPropertyGetterDeclaredOneKey(); } else { revisionGetter = new VAERevisionEventPropertyGetterDeclaredNKey(keyPropertyNumber); } var type = spec.BaseEventType.GetPropertyType(property); var propertyTypeDesc = new RevisionPropertyTypeDesc(revisionGetter, null, type); propertyDesc.Put(property, propertyTypeDesc); count++; } return(propertyDesc); }
/// <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 EventPropertyGetter GetGetter(String propertyName) { RevisionPropertyTypeDesc desc = _propertyDesc.Get(propertyName); if (desc != null) { return(desc.RevisionGetter); } // dynamic property names note allowed if (propertyName.IndexOf('?') != -1) { return(null); } // see if this is a nested property int index = ASTUtil.UnescapedIndexOfDot(propertyName); if (index == -1) { Property prop = PropertyParser.ParseAndWalk(propertyName); if (prop is SimpleProperty) { // there is no such property since it wasn't found earlier return(null); } String atomic = null; if (prop is IndexedProperty) { var indexedprop = (IndexedProperty)prop; atomic = indexedprop.PropertyNameAtomic; } if (prop is MappedProperty) { var indexedprop = (MappedProperty)prop; atomic = indexedprop.PropertyNameAtomic; } desc = _propertyDesc.Get(atomic); if (desc == null) { return(null); } if (!(desc.PropertyType is Type)) { return(null); } var nestedClass = (Type)desc.PropertyType; var complexProperty = (BeanEventType)_eventAdapterService.AddBeanType(nestedClass.Name, nestedClass, false, false, false); return(prop.GetGetter(complexProperty, _eventAdapterService)); } // Map event types allow 2 types of properties inside: // - a property that is a Java object is interrogated via bean property getters and BeanEventType // - a property that is a Map itself is interrogated via map property getters // Take apart the nested property into a map key and a nested value class property name String propertyMap = ASTUtil.UnescapeDot(propertyName.Substring(0, index)); String propertyNested = propertyName.Substring(index + 1); desc = _propertyDesc.Get(propertyMap); if (desc == null) { return(null); // prefix not a known property } // only nested classes supported for revision event types since deep property information not currently exposed by EventType if (desc.PropertyType is Type) { // ask the nested class to resolve the property Type simpleClass = (Type)desc.PropertyType; EventType nestedEventType = _eventAdapterService.AddBeanType(simpleClass.FullName, simpleClass, false, false, false); EventPropertyGetter nestedGetter = nestedEventType.GetGetter(propertyNested); if (nestedGetter == null) { return(null); } // construct getter for nested property return(new RevisionNestedPropertyGetter(desc.RevisionGetter, nestedGetter, _eventAdapterService)); } else { return(null); } }