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);
        }
Esempio n. 3
0
        private static EventPropertyGetterSPI PropertyGetterNested(
            GetterNestedFactory factory,
            Schema fieldSchema,
            Property property,
            string moduleName,
            EventBeanTypedEventFactory eventAdapterService,
            EventTypeAvroHandler eventTypeAvroHandler,
            AvroEventTypeFragmentTypeCache fragmentTypeCache)
        {
            if (property is SimpleProperty) {
                Field fieldNested = fieldSchema.GetField(property.PropertyNameAtomic);
                if (fieldNested == null) {
                    return null;
                }

                var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                    fieldNested.Schema,
                    moduleName,
                    eventAdapterService,
                    eventTypeAvroHandler,
                    fragmentTypeCache);
                return factory.MakeSimple(
                    fieldNested,
                    fragmentEventType?.FragmentType,
                    AvroTypeUtil.PropertyType(fieldNested.Schema));
            }

            if (property is IndexedProperty indexedProperty) {
                var fieldNested = fieldSchema.GetField(indexedProperty.PropertyNameAtomic);
                if (fieldNested == null) {
                    return null;
                }

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

                var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                    fieldNested.Schema,
                    moduleName,
                    eventAdapterService,
                    eventTypeAvroHandler,
                    fragmentTypeCache);
                
                return factory.MakeIndexed(fieldNested, indexedProperty.Index, fragmentEventType?.FragmentType);
            }

            if (property is MappedProperty mappedProperty) {
                Field fieldNested = fieldSchema.GetField(mappedProperty.PropertyNameAtomic);
                if (fieldNested == null || fieldNested.Schema.Tag != Schema.Type.Map) {
                    return null;
                }

                return factory.MakeMapped(fieldNested, mappedProperty.Key);
            }

            if (property is DynamicProperty) {
                if (property is DynamicSimpleProperty) {
                    return factory.MakeDynamicSimple(property.PropertyNameAtomic);
                }

                throw new NotSupportedException();
            }

            var nested = (NestedProperty) property;
            var allSimple = true;
            foreach (var levelProperty in nested.Properties) {
                if (!(levelProperty is SimpleProperty)) {
                    allSimple = false;
                    break;
                }
            }

            if (allSimple) {
                var currentSchema = fieldSchema;
                var count = 0;
                var path = new Field[nested.Properties.Count];
                var types = new Type[nested.Properties.Count];
                foreach (var levelProperty in nested.Properties) {
                    if (currentSchema.Tag != Schema.Type.Record) {
                        return null;
                    }

                    Field fieldNested = currentSchema.GetField(levelProperty.PropertyNameAtomic);
                    if (fieldNested == null) {
                        return null;
                    }

                    currentSchema = fieldNested.Schema;
                    path[count] = fieldNested;
                    types[count] = AvroTypeUtil.PropertyType(currentSchema);
                    count++;
                }

                var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                    currentSchema,
                    moduleName,
                    eventAdapterService,
                    eventTypeAvroHandler,
                    fragmentTypeCache);
                return factory.MakeNestedSimpleMultiLevel(path, types, fragmentEventType?.FragmentType);
            }

            var getters = new AvroEventPropertyGetter[nested.Properties.Count];
            var countX = 0;
            var currentSchemaX = fieldSchema;
            foreach (var levelProperty in nested.Properties) {
                if (currentSchemaX == null) {
                    return null;
                }

                if (levelProperty is SimpleProperty) {
                    Field fieldNested = currentSchemaX.GetField(levelProperty.PropertyNameAtomic);
                    if (fieldNested == null) {
                        return null;
                    }

                    var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                        fieldNested.Schema,
                        moduleName,
                        eventAdapterService,
                        eventTypeAvroHandler,
                        fragmentTypeCache);
                    var propertyType = AvroTypeUtil.PropertyType(fieldNested.Schema);
                    getters[countX] = new AvroEventBeanGetterSimple(
                        fieldNested,
                        fragmentEventType?.FragmentType,
                        eventAdapterService,
                        propertyType);
                    currentSchemaX = fieldNested.Schema;
                }
                else if (levelProperty is IndexedProperty indexed) {
                    var fieldIndexed = currentSchemaX.GetField(indexed.PropertyNameAtomic);
                    if (fieldIndexed == null) {
                        return null;
                    }

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

                    var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                        fieldIndexed.Schema,
                        moduleName,
                        eventAdapterService,
                        eventTypeAvroHandler,
                        fragmentTypeCache);
                    getters[countX] = new AvroEventBeanGetterIndexed(
                        fieldIndexed,
                        indexed.Index,
                        fragmentEventType?.FragmentType,
                        eventAdapterService);
                    currentSchemaX = fieldIndexed.Schema.AsArraySchema().ItemSchema;
                }
                else if (levelProperty is MappedProperty mapped) {
                    Field fieldMapped = currentSchemaX.GetField(mapped.PropertyNameAtomic);
                    if (fieldMapped == null || fieldMapped.Schema.Tag != Schema.Type.Map) {
                        return null;
                    }

                    getters[countX] = new AvroEventBeanGetterMapped(fieldMapped, mapped.Key);
                    currentSchemaX = fieldMapped.Schema;
                }
                else if (levelProperty is DynamicSimpleProperty) {
                    if (currentSchemaX.Tag != Schema.Type.Record) {
                        return null;
                    }

                    Field fieldDynamic = currentSchemaX.GetField(levelProperty.PropertyNameAtomic);
                    getters[countX] = new AvroEventBeanGetterSimpleDynamic(levelProperty.PropertyNameAtomic);
                    if (fieldDynamic.Schema.Tag == Schema.Type.Record) {
                        currentSchemaX = fieldDynamic.Schema;
                    }
                    else if (fieldDynamic.Schema.Tag == Schema.Type.Union) {
                        currentSchemaX = AvroSchemaUtil.FindUnionRecordSchemaSingle(fieldDynamic.Schema);
                    }
                }
                else {
                    throw new NotSupportedException();
                }

                countX++;
            }

            return factory.MakeNestedPolyMultiLevel(getters);
        }
Esempio n. 4
0
        private static EventPropertyGetter PropertyGetterNested(
            GetterNestedFactory factory,
            Schema fieldSchema,
            Property property,
            EventAdapterService eventAdapterService)
        {
            if (property is SimpleProperty)
            {
                Field fieldNested = fieldSchema.GetField(property.PropertyNameAtomic);
                if (fieldNested == null)
                {
                    return(null);
                }
                var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                    fieldNested.Schema, eventAdapterService);
                return(factory.MakeSimple(
                           fieldNested, fragmentEventType == null ? null : fragmentEventType.FragmentType));
            }

            if (property is IndexedProperty)
            {
                var   indexed     = (IndexedProperty)property;
                Field fieldNested = fieldSchema.GetField(property.PropertyNameAtomic);
                if (fieldNested == null || fieldNested.Schema.Tag != Schema.Type.Array)
                {
                    return(null);
                }
                var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                    fieldNested.Schema, eventAdapterService);
                return(factory.MakeIndexed(
                           fieldNested, indexed.Index, fragmentEventType == null ? null : fragmentEventType.FragmentType));
            }

            if (property is MappedProperty)
            {
                var   mapped      = (MappedProperty)property;
                Field fieldNested = fieldSchema.GetField(property.PropertyNameAtomic);
                if (fieldNested == null || fieldNested.Schema.Tag != Schema.Type.Map)
                {
                    return(null);
                }
                return(factory.MakeMapped(fieldNested, mapped.Key));
            }

            if (property is DynamicProperty)
            {
                if (property is DynamicSimpleProperty)
                {
                    return(factory.MakeDynamicSimple(property.PropertyNameAtomic));
                }
                throw new UnsupportedOperationException();
            }

            var nested    = (NestedProperty)property;
            var allSimple = true;

            foreach (var levelProperty in nested.Properties)
            {
                if (!(levelProperty is SimpleProperty))
                {
                    allSimple = false;
                    break;
                }
            }
            if (allSimple)
            {
                var currentSchemaX = fieldSchema;
                var countX         = 0;
                var path           = new Field[nested.Properties.Count];
                foreach (var levelProperty in nested.Properties)
                {
                    if (currentSchemaX.Tag != Schema.Type.Record)
                    {
                        return(null);
                    }
                    Field fieldNested = currentSchemaX.GetField(levelProperty.PropertyNameAtomic);
                    if (fieldNested == null)
                    {
                        return(null);
                    }
                    currentSchemaX = fieldNested.Schema;
                    path[countX]   = fieldNested;
                    countX++;
                }
                var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                    currentSchemaX, eventAdapterService);
                return(factory.MakeNestedSimpleMultiLevel(
                           path, fragmentEventType == null ? null : fragmentEventType.FragmentType));
            }

            var getters       = new AvroEventPropertyGetter[nested.Properties.Count];
            var count         = 0;
            var currentSchema = fieldSchema;

            foreach (var levelProperty in nested.Properties)
            {
                if (currentSchema == null)
                {
                    return(null);
                }

                if (levelProperty is SimpleProperty)
                {
                    Field fieldNested = currentSchema.GetField(levelProperty.PropertyNameAtomic);
                    if (fieldNested == null)
                    {
                        return(null);
                    }
                    FragmentEventType fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                        fieldNested.Schema, eventAdapterService);
                    getters[count] = new AvroEventBeanGetterSimple(
                        fieldNested, fragmentEventType == null ? null : fragmentEventType.FragmentType,
                        eventAdapterService);
                    currentSchema = fieldNested.Schema;
                }
                else if (levelProperty is IndexedProperty)
                {
                    var   indexed      = (IndexedProperty)levelProperty;
                    Field fieldIndexed = currentSchema.GetField(levelProperty.PropertyNameAtomic);
                    if (fieldIndexed == null || fieldIndexed.Schema.Tag != Schema.Type.Array)
                    {
                        return(null);
                    }
                    var fragmentEventType = AvroFragmentTypeUtil.GetFragmentEventTypeForField(
                        fieldIndexed.Schema, eventAdapterService);
                    getters[count] = new AvroEventBeanGetterIndexed(
                        fieldIndexed, indexed.Index,
                        fragmentEventType == null ? null : fragmentEventType.FragmentType, eventAdapterService);
                    currentSchema = fieldIndexed.Schema.GetElementType();
                }
                else if (levelProperty is MappedProperty)
                {
                    var   mapped      = (MappedProperty)levelProperty;
                    Field fieldMapped = currentSchema.GetField(levelProperty.PropertyNameAtomic);
                    if (fieldMapped == null || fieldMapped.Schema.Tag != Schema.Type.Map)
                    {
                        return(null);
                    }
                    getters[count] = new AvroEventBeanGetterMapped(fieldMapped, mapped.Key);
                    currentSchema  = fieldMapped.Schema;
                }
                else if (levelProperty is DynamicSimpleProperty)
                {
                    if (currentSchema.Tag != Schema.Type.Record)
                    {
                        return(null);
                    }
                    Field fieldDynamic = currentSchema.GetField(levelProperty.PropertyNameAtomic);
                    getters[count] = new AvroEventBeanGetterSimpleDynamic(levelProperty.PropertyNameAtomic);
                    if (fieldDynamic.Schema.Tag == Schema.Type.Record)
                    {
                        currentSchema = fieldDynamic.Schema;
                    }
                    else if (fieldDynamic.Schema.Tag == Schema.Type.Union)
                    {
                        currentSchema = AvroSchemaUtil.FindUnionRecordSchemaSingle(fieldDynamic.Schema);
                    }
                }
                else
                {
                    throw new UnsupportedOperationException();
                }
                count++;
            }
            return(factory.MakeNestedPolyMultiLevel(getters));
        }