internal static FragmentEventType GetFragmentEventTypeForField( Schema fieldSchema, string moduleName, EventBeanTypedEventFactory eventBeanTypedEventFactory, EventTypeAvroHandler eventTypeAvroHandler, AvroEventTypeFragmentTypeCache fragmentTypeCache) { Schema recordSchema; var indexed = false; if (fieldSchema.Tag == Schema.Type.Record) { recordSchema = fieldSchema; } else if (fieldSchema.Tag == Schema.Type.Array && fieldSchema.AsArraySchema().ItemSchema.Tag == Schema.Type.Record) { recordSchema = fieldSchema.AsArraySchema().ItemSchema; indexed = true; } else { return null; } var cached = fragmentTypeCache.Get(recordSchema.Name); if (cached != null) { return new FragmentEventType(cached, indexed, false); } var metadata = new EventTypeMetadata( recordSchema.Name, moduleName, EventTypeTypeClass.STREAM, EventTypeApplicationType.AVRO, NameAccessModifier.TRANSIENT, EventTypeBusModifier.NONBUS, false, EventTypeIdPair.Unassigned()); var config = new ConfigurationCommonEventTypeAvro(); config.AvroSchema = recordSchema; var fragmentType = eventTypeAvroHandler.NewEventTypeFromSchema( metadata, eventBeanTypedEventFactory, config, null, null); fragmentTypeCache.Add(recordSchema.Name, fragmentType); return new FragmentEventType(fragmentType, indexed, false); }
internal static FragmentEventType GetFragmentType( Schema schema, string propertyName, string moduleName, IDictionary<string, PropertySetDescriptorItem> propertyItems, EventBeanTypedEventFactory eventBeanTypedEventFactory, EventTypeAvroHandler eventTypeAvroHandler, AvroEventTypeFragmentTypeCache fragmentTypeCache) { var unescapePropName = StringValue.UnescapeDot(propertyName); var item = propertyItems.Get(unescapePropName); if (item != null) { return item.FragmentEventType; } var property = PropertyParser.ParseAndWalkLaxToSimple(propertyName); var desc = AvroFieldUtil.FieldForProperty(schema, property); if (desc == null) { return null; } if (desc.IsDynamic) { return null; } var fieldSchemaByAccess = desc.Field.Schema; if (desc.IsAccessedByIndex) { fieldSchemaByAccess = fieldSchemaByAccess.AsArraySchema().ItemSchema; } return GetFragmentEventTypeForField( fieldSchemaByAccess, moduleName, eventBeanTypedEventFactory, eventTypeAvroHandler, fragmentTypeCache); }
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; }
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); }