Esempio n. 1
0
        public static EventPropertyGetterSPI GetGetter(
            Schema avroSchema,
            string moduleName,
            Dictionary<string, EventPropertyGetterSPI> propertyGetterCache,
            IDictionary<string, PropertySetDescriptorItem> propertyDescriptors,
            string propertyName,
            bool addToCache,
            EventBeanTypedEventFactory eventAdapterService,
            EventTypeAvroHandler eventTypeAvroHandler,
            AvroEventTypeFragmentTypeCache fragmentTypeCache)
        {
            var getter = propertyGetterCache.Get(propertyName);
            if (getter != null) {
                return getter;
            }

            var unescapePropName = StringValue.UnescapeDot(propertyName);
            var item = propertyDescriptors.Get(unescapePropName);
            if (item != null) {
                getter = item.PropertyGetter;
                MayAddToGetterCache(propertyName, propertyGetterCache, getter, true);
                return getter;
            }

            // see if this is a nested property
            var index = StringValue.UnescapedIndexOfDot(propertyName);
            if (index == -1) {
                var prop = PropertyParser.ParseAndWalkLaxToSimple(propertyName);
                if (prop is IndexedProperty indexedProp) {
                    var field = avroSchema.GetField(indexedProp.PropertyNameAtomic);
                    if (field == null) {
                        return null;
                    }

                    if ((field.Schema.Tag != Schema.Type.Array) &&
                        (field.Schema.Tag != Schema.Type.String)) {
                        return null;
                    }

                    var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                        field.Schema,
                        moduleName,
                        eventAdapterService,
                        eventTypeAvroHandler,
                        fragmentTypeCache);
                    getter = new AvroEventBeanGetterIndexed(
                        field,
                        indexedProp.Index,
                        fragmentEventType?.FragmentType,
                        eventAdapterService);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return getter;
                }

                if (prop is MappedProperty mappedProp) {
                    Field field = avroSchema.GetField(mappedProp.PropertyNameAtomic);
                    if (field == null || field.Schema.Tag != Schema.Type.Map) {
                        return null;
                    }

                    getter = new AvroEventBeanGetterMapped(field, mappedProp.Key);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return getter;
                }

                if (prop is DynamicIndexedProperty dynamicIndexedProp) {
                    getter = new AvroEventBeanGetterIndexedDynamic(
                        dynamicIndexedProp.PropertyNameAtomic,
                        dynamicIndexedProp.Index);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return getter;
                }

                if (prop is DynamicMappedProperty dynamicMappedProp) {
                    getter = new AvroEventBeanGetterMappedDynamic(
                        dynamicMappedProp.PropertyNameAtomic,
                        dynamicMappedProp.Key);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return getter;
                }

                if (prop is DynamicSimpleProperty) {
                    getter = new AvroEventBeanGetterSimpleDynamic(prop.PropertyNameAtomic);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return getter;
                }

                return null; // simple property already cached
            }

            // Take apart the nested property into a map key and a nested value class property name
            var propertyTop = StringValue.UnescapeDot(propertyName.Substring(0, index));
            var propertyNested = propertyName.Substring(index + 1);
            var isRootedDynamic = false;

            // If the property is dynamic, remove the ? since the property type is defined without
            if (propertyTop.EndsWith("?")) {
                propertyTop = propertyTop.Substring(0, propertyTop.Length - 1);
                isRootedDynamic = true;
            }

            var propTop = PropertyParser.ParseAndWalkLaxToSimple(propertyTop);
            Field fieldTop = avroSchema.GetField(propTop.PropertyNameAtomic);

            // field is known and is a record
            if (fieldTop != null && fieldTop.Schema.Tag == Schema.Type.Record && propTop is SimpleProperty) {
                var factory = new GetterNestedFactoryRootedSimple(eventAdapterService, fieldTop);
                var property = PropertyParser.ParseAndWalk(propertyNested, isRootedDynamic);
                getter = PropertyGetterNested(
                    factory,
                    fieldTop.Schema,
                    property,
                    moduleName,
                    eventAdapterService,
                    eventTypeAvroHandler,
                    fragmentTypeCache);
                MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                return getter;
            }

            // field is known and is a record
            if (fieldTop != null && propTop is IndexedProperty indexedProperty) {
                if ((fieldTop.Schema.Tag == Schema.Type.Array) ||
                    (fieldTop.Schema.Tag == Schema.Type.String)) {
                    var factory = new GetterNestedFactoryRootedIndexed(
                        eventAdapterService,
                        fieldTop,
                        indexedProperty.Index);
                    var property = PropertyParser.ParseAndWalk(propertyNested, isRootedDynamic);
                    getter = PropertyGetterNested(
                        factory,
                        fieldTop.Schema.AsArraySchema().ItemSchema,
                        property,
                        moduleName,
                        eventAdapterService,
                        eventTypeAvroHandler,
                        fragmentTypeCache);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return getter;
                }
            }

            // field is not known or is not a record
            if (!isRootedDynamic) {
                return null;
            }

            var propertyX = PropertyParser.ParseAndWalk(propertyNested, true);
            var innerGetter = GetDynamicGetter(propertyX);
            getter = new AvroEventBeanGetterNestedDynamicPoly(propertyTop, innerGetter);
            MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
            return getter;
        }
Esempio n. 2
0
        public static EventPropertyGetter GetGetter(
            Schema avroSchema,
            Dictionary <string, EventPropertyGetter> propertyGetterCache,
            IDictionary <string, PropertySetDescriptorItem> propertyDescriptors,
            string propertyName,
            bool addToCache,
            EventAdapterService eventAdapterService)
        {
            var getter = propertyGetterCache.Get(propertyName);

            if (getter != null)
            {
                return(getter);
            }

            var unescapePropName = ASTUtil.UnescapeDot(propertyName);
            var item             = propertyDescriptors.Get(unescapePropName);

            if (item != null)
            {
                getter = item.PropertyGetter;
                MayAddToGetterCache(propertyName, propertyGetterCache, getter, true);
                return(getter);
            }

            // see if this is a nested property
            var index = ASTUtil.UnescapedIndexOfDot(propertyName);

            if (index == -1)
            {
                var prop = PropertyParser.ParseAndWalkLaxToSimple(propertyName);
                if (prop is IndexedProperty)
                {
                    var   indexedProp = (IndexedProperty)prop;
                    Field field       = avroSchema.GetField(prop.PropertyNameAtomic);
                    if (field == null)
                    {
                        return(null);
                    }
                    switch (field.Schema.Tag)
                    {
                    case Schema.Type.Array:
                        var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                            field.Schema, eventAdapterService);
                        getter = new AvroEventBeanGetterIndexed(
                            field, indexedProp.Index,
                            fragmentEventType == null ? null : fragmentEventType.FragmentType, eventAdapterService);
                        MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                        return(getter);

                    case Schema.Type.String:
                        getter = new AvroEventBeanGetterStringIndexed(field, indexedProp.Index);
                        MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                        return(getter);

                    default:
                        return(null);
                    }
                }
                else if (prop is MappedProperty)
                {
                    var   mappedProp = (MappedProperty)prop;
                    Field field      = avroSchema.GetField(prop.PropertyNameAtomic);
                    if (field == null || field.Schema.Tag != Schema.Type.Map)
                    {
                        return(null);
                    }
                    getter = new AvroEventBeanGetterMapped(field, mappedProp.Key);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return(getter);
                }
                if (prop is DynamicIndexedProperty)
                {
                    var dynamicIndexedProp = (DynamicIndexedProperty)prop;
                    getter = new AvroEventBeanGetterIndexedDynamic(prop.PropertyNameAtomic, dynamicIndexedProp.Index);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return(getter);
                }
                if (prop is DynamicMappedProperty)
                {
                    var dynamicMappedProp = (DynamicMappedProperty)prop;
                    getter = new AvroEventBeanGetterMappedDynamic(prop.PropertyNameAtomic, dynamicMappedProp.Key);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return(getter);
                }
                else if (prop is DynamicSimpleProperty)
                {
                    getter = new AvroEventBeanGetterSimpleDynamic(prop.PropertyNameAtomic);
                    MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                    return(getter);
                }
                return(null); // simple property already cached
            }

            // Take apart the nested property into a map key and a nested value class property name
            var propertyTop     = ASTUtil.UnescapeDot(propertyName.Substring(0, index));
            var propertyNested  = propertyName.Substring(index + 1);
            var isRootedDynamic = false;

            // If the property is dynamic, remove the ? since the property type is defined without
            if (propertyTop.EndsWith("?"))
            {
                propertyTop     = propertyTop.Substring(0, propertyTop.Length - 1);
                isRootedDynamic = true;
            }

            var   propTop  = PropertyParser.ParseAndWalkLaxToSimple(propertyTop);
            Field fieldTop = avroSchema.GetField(propTop.PropertyNameAtomic);

            // field is known and is a record
            if (fieldTop != null && fieldTop.Schema.Tag == Schema.Type.Record && propTop is SimpleProperty)
            {
                var factory  = new GetterNestedFactoryRootedSimple(eventAdapterService, fieldTop);
                var property = PropertyParser.ParseAndWalk(propertyNested, isRootedDynamic);
                getter = PropertyGetterNested(factory, fieldTop.Schema, property, eventAdapterService);
                MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                return(getter);
            }

            // field is known and is a record
            if (fieldTop != null && fieldTop.Schema.Tag == Schema.Type.Array && propTop is IndexedProperty)
            {
                var factory = new GetterNestedFactoryRootedIndexed(
                    eventAdapterService, fieldTop, ((IndexedProperty)propTop).Index);
                var property = PropertyParser.ParseAndWalk(propertyNested, isRootedDynamic);
                getter = PropertyGetterNested(factory, fieldTop.Schema.GetElementType(), property, eventAdapterService);
                MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
                return(getter);
            }

            // field is not known or is not a record
            if (!isRootedDynamic)
            {
                return(null);
            }
            var propertyX   = PropertyParser.ParseAndWalk(propertyNested, true);
            var innerGetter = GetDynamicGetter(propertyX);

            getter = new AvroEventBeanGetterNestedDynamicPoly(propertyTop, innerGetter);
            MayAddToGetterCache(propertyName, propertyGetterCache, getter, addToCache);
            return(getter);
        }