Пример #1
0
        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);
            }
        }
Пример #2
0
        /// <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);
        }
Пример #5
0
        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);
            }
        }