public override void Run(EPServiceProvider epService)
        {
            // Note that XPath Node results when transposed must be queried by XPath that is also absolute.
            // For example: "nested1" => "/n0:simpleEvent/n0:nested1" results in a Node.
            // That result Node's "prop1" =>  "/n0:simpleEvent/n0:nested1/n0:prop1" and "/n0:nested1/n0:prop1" does NOT result in a value.
            // Therefore property transposal is disabled for Property-XPath expressions.
            var eventTypeMeta = new ConfigurationEventTypeXMLDOM();

            eventTypeMeta.RootElementName = "simpleEvent";
            string schemaUri = SupportContainer.Instance.ResourceManager().ResolveResourceURL(CLASSLOADER_SCHEMA_URI).ToString();

            eventTypeMeta.SchemaResource      = schemaUri;
            eventTypeMeta.IsXPathPropertyExpr = true;       // <== note this
            eventTypeMeta.AddNamespacePrefix("ss", "samples:schemas:simpleSchema");
            epService.EPAdministrator.Configuration.AddEventType("TestXMLSchemaType", eventTypeMeta);

            // note class not a fragment
            EPStatement stmtInsert = epService.EPAdministrator.CreateEPL("insert into MyNestedStream select nested1 from TestXMLSchemaType#lastevent");

            EPAssertionUtil.AssertEqualsAnyOrder(new EventPropertyDescriptor[] {
                new EventPropertyDescriptor("nested1", typeof(XmlNode), null, false, false, false, false, false),
            }, stmtInsert.EventType.PropertyDescriptors);
            SupportEventTypeAssertionUtil.AssertConsistency(stmtInsert.EventType);

            EventType type = ((EPServiceProviderSPI)epService).EventAdapterService.GetEventTypeByName("TestXMLSchemaType");

            SupportEventTypeAssertionUtil.AssertConsistency(type);
            Assert.IsNull(type.GetFragmentType("nested1"));
            Assert.IsNull(type.GetFragmentType("nested1.nested2"));

            SupportXML.SendDefaultEvent(epService.EPRuntime, "ABC");
            SupportEventTypeAssertionUtil.AssertConsistency(stmtInsert.First());
        }
        private void RunAssertionTypeValidProp(EPServiceProvider epService, string typeName, object underlying)
        {
            EventType eventType = epService.EPAdministrator.Configuration.GetEventType(typeName);

            var expectedType = new[]
            {
                new object[] { "indexed", typeof(string[]), null, null },
                new object[] { "mapped", typeof(StringMap), null, null }
            };

            SupportEventTypeAssertionUtil.AssertEventTypeProperties(expectedType, eventType, SupportEventTypeAssertionEnumExtensions.GetSetWithFragment());

            EPAssertionUtil.AssertEqualsAnyOrder(new[] { "indexed", "mapped" }, eventType.PropertyNames);

            Assert.IsNotNull(eventType.GetGetter("mapped"));
            Assert.IsNotNull(eventType.GetGetter("mapped('a')"));
            Assert.IsNotNull(eventType.GetGetter("indexed"));
            Assert.IsNotNull(eventType.GetGetter("indexed[0]"));
            Assert.IsTrue(eventType.IsProperty("mapped"));
            Assert.IsTrue(eventType.IsProperty("mapped('a')"));
            Assert.IsTrue(eventType.IsProperty("indexed"));
            Assert.IsTrue(eventType.IsProperty("indexed[0]"));
            Assert.AreEqual(typeof(StringMap), eventType.GetPropertyType("mapped"));
            Assert.AreEqual(typeof(string), eventType.GetPropertyType("mapped('a')"));
            Assert.AreEqual(typeof(string[]), eventType.GetPropertyType("indexed"));
            Assert.AreEqual(typeof(string), eventType.GetPropertyType("indexed[0]"));

            Assert.AreEqual(new EventPropertyDescriptor("indexed", typeof(string[]), typeof(string), false, false, true, false, false), eventType.GetPropertyDescriptor("indexed"));
            Assert.AreEqual(new EventPropertyDescriptor("mapped", typeof(StringMap), typeof(string), false, false, false, true, false), eventType.GetPropertyDescriptor("mapped"));

            Assert.IsNull(eventType.GetFragmentType("indexed"));
            Assert.IsNull(eventType.GetFragmentType("mapped"));
        }
Exemplo n.º 3
0
        public void TestExpressionSimpleXPathGetter()
        {
            var eventTypeMeta = new ConfigurationEventTypeXMLDOM();

            eventTypeMeta.RootElementName = "simpleEvent";
            var schemaUri = ResourceManager.ResolveResourceURL(CLASSLOADER_SCHEMA_URI).ToString();

            eventTypeMeta.SchemaResource      = schemaUri;
            eventTypeMeta.IsXPathPropertyExpr = true;           // <== note this
            eventTypeMeta.AddNamespacePrefix("ss", "samples:schemas:simpleSchema");
            _epService.EPAdministrator.Configuration.AddEventType("TestXMLSchemaType", eventTypeMeta);

            // note class not a fragment
            var stmtInsert = _epService.EPAdministrator.CreateEPL("insert into MyNestedStream select nested1 from TestXMLSchemaType#lastevent");

            EPAssertionUtil.AssertEqualsAnyOrder(new EventPropertyDescriptor[] {
                new EventPropertyDescriptor("nested1", typeof(XmlNode), null, false, false, false, false, false),
            }, stmtInsert.EventType.PropertyDescriptors);
            SupportEventTypeAssertionUtil.AssertConsistency(stmtInsert.EventType);

            EventType type = ((EPServiceProviderSPI)_epService).EventAdapterService.GetEventTypeByName("TestXMLSchemaType");

            SupportEventTypeAssertionUtil.AssertConsistency(type);
            Assert.IsNull(type.GetFragmentType("nested1"));
            Assert.IsNull(type.GetFragmentType("nested1.nested2"));

            SupportXML.SendDefaultEvent(_epService.EPRuntime, "ABC");
            SupportEventTypeAssertionUtil.AssertConsistency(stmtInsert.First());
        }
Exemplo n.º 4
0
        private void TryAssertionMapTranspose(EPServiceProvider epService, EventRepresentationChoice eventRepresentationEnum)
        {
            var innerTypeOne = new Dictionary <string, object>();

            innerTypeOne.Put("i1", typeof(int));
            var innerTypeTwo = new Dictionary <string, object>();

            innerTypeTwo.Put("i2", typeof(int));
            var outerType = new Dictionary <string, object>();

            outerType.Put("one", "T1");
            outerType.Put("two", "T2");
            epService.EPAdministrator.Configuration.AddEventType("T1", innerTypeOne);
            epService.EPAdministrator.Configuration.AddEventType("T2", innerTypeTwo);
            epService.EPAdministrator.Configuration.AddEventType("OuterType", outerType);

            // create window
            string      stmtTextCreate = eventRepresentationEnum.GetAnnotationText() + " create window MyWindowMT#keepall as select one, two from OuterType";
            EPStatement stmtCreate     = epService.EPAdministrator.CreateEPL(stmtTextCreate);

            Assert.IsTrue(eventRepresentationEnum.MatchesClass(stmtCreate.EventType.UnderlyingType));
            var listenerWindow = new SupportUpdateListener();

            stmtCreate.Events += listenerWindow.Update;
            EPAssertionUtil.AssertEqualsAnyOrder(stmtCreate.EventType.PropertyNames, new string[] { "one", "two" });
            EventType eventType = stmtCreate.EventType;

            Assert.AreEqual("T1", eventType.GetFragmentType("one").FragmentType.Name);
            Assert.AreEqual("T2", eventType.GetFragmentType("two").FragmentType.Name);

            // create insert into
            string stmtTextInsertOne = "insert into MyWindowMT select one, two from OuterType";

            epService.EPAdministrator.CreateEPL(stmtTextInsertOne);

            var innerDataOne = new Dictionary <string, object>();

            innerDataOne.Put("i1", 1);
            var innerDataTwo = new Dictionary <string, object>();

            innerDataTwo.Put("i2", 2);
            var outerData = new Dictionary <string, object>();

            outerData.Put("one", innerDataOne);
            outerData.Put("two", innerDataTwo);

            epService.EPRuntime.SendEvent(outerData, "OuterType");
            EPAssertionUtil.AssertProps(listenerWindow.AssertOneGetNewAndReset(), "one.i1,two.i2".Split(','), new object[] { 1, 2 });

            epService.EPAdministrator.DestroyAllStatements();
            epService.EPAdministrator.Configuration.RemoveEventType("MyWindowMT", true);
        }
Exemplo n.º 5
0
        public static ExprDotEnumerationSourceForProps GetPropertyEnumerationSource(string propertyName, int streamId, EventType streamType, bool allowEnumType, bool disablePropertyExpressionEventCollCache)
        {
            var propertyType = streamType.GetPropertyType(propertyName);
            var typeInfo     = EPTypeHelper.SingleValue(propertyType); // assume scalar for now

            // no enumeration methods, no need to expose as an enumeration
            if (!allowEnumType)
            {
                return(new ExprDotEnumerationSourceForProps(null, typeInfo, streamId, null));
            }

            var fragmentEventType = streamType.GetFragmentType(propertyName);
            var getter            = streamType.GetGetter(propertyName);

            ExprEvaluatorEnumeration enumEvaluator = null;

            if (getter != null && fragmentEventType != null)
            {
                if (fragmentEventType.IsIndexed)
                {
                    enumEvaluator = new PropertyExprEvaluatorEventCollection(propertyName, streamId, fragmentEventType.FragmentType, getter, disablePropertyExpressionEventCollCache);
                    typeInfo      = EPTypeHelper.CollectionOfEvents(fragmentEventType.FragmentType);
                }
                else
                {   // we don't want native to require an eventbean instance
                    enumEvaluator = new PropertyExprEvaluatorEventSingle(streamId, fragmentEventType.FragmentType, getter);
                    typeInfo      = EPTypeHelper.SingleEvent(fragmentEventType.FragmentType);
                }
            }
            else
            {
                var desc = EventTypeUtility.GetNestablePropertyDescriptor(streamType, propertyName);
                if (desc != null && desc.IsIndexed && !desc.RequiresIndex && desc.PropertyComponentType != null)
                {
                    if (propertyType.IsGenericCollection())
                    {
                        enumEvaluator = new PropertyExprEvaluatorScalarCollection(propertyName, streamId, getter, desc.PropertyComponentType);
                    }
                    else if (propertyType.IsImplementsInterface(typeof(System.Collections.IEnumerable)))
                    {
                        enumEvaluator = new PropertyExprEvaluatorScalarIterable(propertyName, streamId, getter, desc.PropertyComponentType);
                    }
                    else if (propertyType.IsArray)
                    {
                        enumEvaluator = new PropertyExprEvaluatorScalarArray(propertyName, streamId, getter, desc.PropertyComponentType);
                    }
                    else
                    {
                        throw new IllegalStateException("Property indicated indexed-type but failed to find proper collection adapter for use with enumeration methods");
                    }
                    typeInfo = EPTypeHelper.CollectionOfSingleValue(desc.PropertyComponentType);
                }
            }
            var enumEvaluatorGivenEvent = (ExprEvaluatorEnumerationGivenEvent)enumEvaluator;

            return(new ExprDotEnumerationSourceForProps(enumEvaluator, typeInfo, streamId, enumEvaluatorGivenEvent));
        }
Exemplo n.º 6
0
        private PropertyResolutionDescriptor FindByPropertyNameExplicitProps(String propertyName, bool obtainFragment)
        {
            var       index      = 0;
            var       foundIndex = 0;
            var       foundCount = 0;
            EventType streamType = null;

            for (var i = 0; i < _eventTypes.Length; i++)
            {
                if (_eventTypes[i] != null)
                {
                    var  descriptors  = _eventTypes[i].PropertyDescriptors;
                    Type propertyType = null;
                    var  found        = false;
                    FragmentEventType fragmentEventTypeX = null;

                    foreach (var desc in descriptors)
                    {
                        if (desc.PropertyName.Equals(propertyName))
                        {
                            propertyType = desc.PropertyType;
                            found        = true;
                            if (obtainFragment && desc.IsFragment)
                            {
                                fragmentEventTypeX = _eventTypes[i].GetFragmentType(propertyName);
                            }
                        }
                    }

                    if (found)
                    {
                        streamType = _eventTypes[i];
                        foundCount++;
                        foundIndex = index;

                        // If the property could be resolved from stream 0 then we don't need to look further
                        if ((i == 0) && _isStreamZeroUnambigous)
                        {
                            return(new PropertyResolutionDescriptor(_streamNames[0], _eventTypes[0], propertyName, 0, propertyType, fragmentEventTypeX));
                        }
                    }
                }
                index++;
            }

            HandleFindExceptions(propertyName, foundCount, streamType);

            FragmentEventType fragmentEventType = null;

            if (obtainFragment)
            {
                fragmentEventType = streamType.GetFragmentType(propertyName);
            }

            return(new PropertyResolutionDescriptor(_streamNames[foundIndex], _eventTypes[foundIndex], propertyName, foundIndex, streamType.GetPropertyType(propertyName), fragmentEventType));
        }
Exemplo n.º 7
0
        public static object ExtractFragmentTypeIsIndexed(EventPropertyDescriptor desc, EventType eventType)
        {
            FragmentEventType fragType = eventType.GetFragmentType(desc.PropertyName);

            if (fragType == null)
            {
                return(null);
            }
            return(fragType.IsIndexed);
        }
Exemplo n.º 8
0
        private void AssertFragment(String prop, EventType eventType, String fragmentTypeName, bool indexed)
        {
            var desc = eventType.GetPropertyDescriptor(prop);

            Assert.AreEqual(true, desc.IsFragment);
            var fragment = eventType.GetFragmentType(prop);

            Assert.AreEqual(fragmentTypeName, fragment.FragmentType.Name);
            Assert.AreEqual(false, fragment.IsNative);
            Assert.AreEqual(indexed, fragment.IsIndexed);
        }
Exemplo n.º 9
0
        private static void AssertConsistencyRecursive(EventType eventType, ICollection <EventType> alreadySeenTypes)
        {
            if (alreadySeenTypes.Contains(eventType))
            {
                return;
            }
            alreadySeenTypes.Add(eventType);

            AssertConsistencyProperties(eventType);

            // test fragments
            foreach (var descriptor in eventType.PropertyDescriptors)
            {
                var failedMessage = "failed assertion for property '" + descriptor.PropertyName + "' ";
                if (!descriptor.IsFragment)
                {
                    Assert.IsNull(eventType.GetFragmentType(descriptor.PropertyName), failedMessage);
                    continue;
                }

                var fragment = eventType.GetFragmentType(descriptor.PropertyName);
                if (!descriptor.RequiresIndex)
                {
                    Assert.NotNull(fragment, failedMessage);
                    if (fragment.IsIndexed)
                    {
                        Assert.IsTrue(descriptor.IsIndexed);
                    }
                    AssertConsistencyRecursive(fragment.FragmentType, alreadySeenTypes);
                }
                else
                {
                    fragment = eventType.GetFragmentType(descriptor.PropertyName + "[0]");
                    Assert.NotNull(fragment, failedMessage);
                    Assert.IsTrue(descriptor.IsIndexed);
                    AssertConsistencyRecursive(fragment.FragmentType, alreadySeenTypes);
                }
            }
        }
Exemplo n.º 10
0
        private static void AssertConsistencyRecursive(EventType eventType, ISet<EventType> alreadySeenTypes)
        {
            if (alreadySeenTypes.Contains(eventType))
            {
                return;
            }
            alreadySeenTypes.Add(eventType);

            AssertConsistencyProperties(eventType);

            // test fragments
            foreach (EventPropertyDescriptor descriptor in eventType.PropertyDescriptors)
            {
                string failedMessage = "failed assertion for property '" + descriptor.PropertyName + "' ";
                if (!descriptor.IsFragment)
                {
                    ScopeTestHelper.AssertNull(failedMessage, eventType.GetFragmentType(descriptor.PropertyName));
                    continue;
                }

                FragmentEventType fragment = eventType.GetFragmentType(descriptor.PropertyName);
                if (!descriptor.RequiresIndex)
                {
                    ScopeTestHelper.AssertNotNull(failedMessage, fragment);
                    if (fragment.IsIndexed)
                    {
                        ScopeTestHelper.AssertTrue(descriptor.IsIndexed);
                    }
                    AssertConsistencyRecursive(fragment.FragmentType, alreadySeenTypes);
                }
                else
                {
                    fragment = eventType.GetFragmentType(descriptor.PropertyName + "[0]");
                    ScopeTestHelper.AssertNotNull(failedMessage, fragment);
                    ScopeTestHelper.AssertTrue(descriptor.IsIndexed);
                    AssertConsistencyRecursive(fragment.FragmentType, alreadySeenTypes);
                }
            }
        }
Exemplo n.º 11
0
        private static void PlanPropertiesMayRecurse(
            EventType eventType,
            IList <StmtClassForgeableFactory> additionalForgeables,
            StatementRawInfo raw,
            SerdeEventTypeCompileTimeRegistry registry,
            SerdeCompileTimeResolver resolver)
        {
            foreach (var desc in eventType.PropertyDescriptors)
            {
                if (!desc.IsFragment)
                {
                    continue;
                }

                var fragmentEventType = eventType.GetFragmentType(desc.PropertyName);
                if (fragmentEventType == null || registry.EventTypes.ContainsKey(fragmentEventType.FragmentType))
                {
                    continue;
                }

                PlanRecursive(additionalForgeables, fragmentEventType.FragmentType, raw, registry, resolver);
            }
        }
Exemplo n.º 12
0
        private PropertyResolutionDescriptor FindByPropertyName(String propertyName, bool obtainFragment)
        {
            var       index      = 0;
            var       foundIndex = 0;
            var       foundCount = 0;
            EventType streamType = null;

            for (var i = 0; i < _eventTypes.Length; i++)
            {
                if (_eventTypes[i] != null)
                {
                    Type propertyType = null;
                    var  found        = false;
                    FragmentEventType fragmentEventTypeX = null;

                    if (_eventTypes[i].IsProperty(propertyName))
                    {
                        propertyType = _eventTypes[i].GetPropertyType(propertyName);
                        if (obtainFragment)
                        {
                            fragmentEventTypeX = _eventTypes[i].GetFragmentType(propertyName);
                        }
                        found = true;
                    }
                    else
                    {
                        // mapped(expression) or array(expression) are not property names but expressions against a property by name "mapped" or "array"
                        var descriptor = _eventTypes[i].GetPropertyDescriptor(propertyName);
                        if (descriptor != null)
                        {
                            found        = true;
                            propertyType = descriptor.PropertyType;
                            if (descriptor.IsFragment && obtainFragment)
                            {
                                fragmentEventTypeX = _eventTypes[i].GetFragmentType(propertyName);
                            }
                        }
                    }

                    if (found)
                    {
                        streamType = _eventTypes[i];
                        foundCount++;
                        foundIndex = index;

                        // If the property could be resolved from stream 0 then we don't need to look further
                        if ((i == 0) && _isStreamZeroUnambigous)
                        {
                            return(new PropertyResolutionDescriptor(_streamNames[0], _eventTypes[0], propertyName, 0, propertyType, fragmentEventTypeX));
                        }
                    }
                }
                index++;
            }

            HandleFindExceptions(propertyName, foundCount, streamType);

            FragmentEventType fragmentEventType = null;

            if (obtainFragment)
            {
                fragmentEventType = streamType.GetFragmentType(propertyName);
            }

            return(new PropertyResolutionDescriptor(_streamNames[foundIndex], _eventTypes[foundIndex], propertyName, foundIndex, streamType.GetPropertyType(propertyName), fragmentEventType));
        }
Exemplo n.º 13
0
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="eventType">to render</param>
        /// <param name="stack">the stack of properties to avoid looping</param>
        /// <param name="options">rendering options</param>
        public RendererMeta(EventType eventType, Stack <EventTypePropertyPair> stack, RendererMetaOptions options)
        {
            var gettersSimple  = new List <GetterPair>();
            var gettersIndexed = new List <GetterPair>();
            var gettersMapped  = new List <GetterPair>();
            var gettersNested  = new List <NestedGetterPair>();

            var descriptors = eventType.PropertyDescriptors;

            foreach (EventPropertyDescriptor desc in descriptors)
            {
                String propertyName = desc.PropertyName;

                if ((!desc.IsIndexed) && (!desc.IsMapped) && (!desc.IsFragment))
                {
                    var getter = eventType.GetGetter(propertyName);
                    if (getter == null)
                    {
                        log.Warn("No getter returned for event type '" + eventType.Name + "' and property '" +
                                 propertyName + "'");
                        continue;
                    }
                    gettersSimple.Add(new GetterPair(getter, propertyName,
                                                     OutputValueRendererFactory.GetOutputValueRenderer(
                                                         desc.PropertyType, options)));
                }

                if (desc.IsIndexed && !desc.RequiresIndex && (!desc.IsFragment))
                {
                    var getter = eventType.GetGetter(propertyName);
                    if (getter == null)
                    {
                        log.Warn("No getter returned for event type '" + eventType.Name + "' and property '" +
                                 propertyName + "'");
                        continue;
                    }
                    gettersIndexed.Add(new GetterPair(getter, propertyName,
                                                      OutputValueRendererFactory.GetOutputValueRenderer(
                                                          desc.PropertyType, options)));
                }

                if (desc.IsMapped && !desc.RequiresMapKey && (!desc.IsFragment))
                {
                    var getter = eventType.GetGetter(propertyName);
                    if (getter == null)
                    {
                        log.Warn("No getter returned for event type '" + eventType.Name + "' and property '" +
                                 propertyName + "'");
                        continue;
                    }
                    gettersMapped.Add(new GetterPair(getter, propertyName,
                                                     OutputValueRendererFactory.GetOutputValueRenderer(
                                                         desc.PropertyType, options)));
                }

                if (desc.IsFragment)
                {
                    var getter       = eventType.GetGetter(propertyName);
                    var fragmentType = eventType.GetFragmentType(propertyName);
                    if (getter == null)
                    {
                        log.Warn("No getter returned for event type '" + eventType.Name + "' and property '" +
                                 propertyName + "'");
                        continue;
                    }
                    if (fragmentType == null)
                    {
                        log.Warn("No fragment type returned for event type '" + eventType.Name + "' and property '" +
                                 propertyName + "'");
                        continue;
                    }

                    var pair = new EventTypePropertyPair(fragmentType.FragmentType, propertyName);
                    if ((options.PreventLooping && stack.Contains(pair)))
                    {
                        continue; // prevent looping behavior on self-references
                    }

                    stack.Push(pair);
                    var fragmentMetaData = new RendererMeta(fragmentType.FragmentType, stack, options);
                    stack.Pop();

                    gettersNested.Add(new NestedGetterPair(getter, propertyName, fragmentMetaData,
                                                           fragmentType.IsIndexed));
                }
            }

            gettersSimple.Sort((gp1, gp2) => gp1.Name.CompareTo(gp2.Name));
            gettersIndexed.Sort((gp1, gp2) => gp1.Name.CompareTo(gp2.Name));
            gettersMapped.Sort((gp1, gp2) => gp1.Name.CompareTo(gp2.Name));
            gettersNested.Sort((gp1, gp2) => gp1.Name.CompareTo(gp2.Name));

            simpleProperties = gettersSimple.ToArray();
            indexProperties  = gettersIndexed.ToArray();
            mappedProperties = gettersMapped.ToArray();
            nestedProperties = gettersNested.ToArray();
        }
Exemplo n.º 14
0
 public FragmentTypeEval(int streamId, EventType eventType, string resolvedPropertyName)
 {
     _streamId     = streamId;
     _getter       = eventType.GetGetter(resolvedPropertyName);
     _fragmentType = eventType.GetFragmentType(resolvedPropertyName).FragmentType.Name;
 }
Exemplo n.º 15
0
        private PropertyResolutionDescriptor FindByStreamNameOnly(String propertyName, String streamName, bool explicitPropertiesOnly, bool obtainFragment)
        {
            var       index      = 0;
            EventType streamType = null;

            // Stream name resultion examples:
            // A)  select A1.price from Event.price as A2  => mismatch stream name, cannot resolve
            // B)  select Event1.price from Event2.price   => mismatch event type name, cannot resolve
            // C)  select default.Event2.price from Event2.price   => possible prefix of engine name
            for (var i = 0; i < _eventTypes.Length; i++)
            {
                if (_eventTypes[i] == null)
                {
                    index++;
                    continue;
                }
                if ((_streamNames[i] != null) && (_streamNames[i].Equals(streamName)))
                {
                    streamType = _eventTypes[i];
                    break;
                }

                // If the stream name is the event type name, that is also acceptable
                if ((_eventTypes[i].Name != null) && (_eventTypes[i].Name.Equals(streamName)))
                {
                    streamType = _eventTypes[i];
                    break;
                }

                index++;
            }

            if (streamType == null)
            {
                var message = "Failed to find a stream named '" + streamName + "'";
                var msgGen  = new StreamNotFoundExceptionSuggestionGen(_eventTypes, _streamNames, streamName);
                throw new StreamNotFoundException(message, msgGen.GetSuggestion);
            }

            Type propertyType = null;
            FragmentEventType fragmentEventType = null;

            if (!explicitPropertiesOnly)
            {
                propertyType = streamType.GetPropertyType(propertyName);
                if (propertyType == null)
                {
                    var desc = streamType.GetPropertyDescriptor(propertyName);
                    if (desc == null)
                    {
                        throw HandlePropertyNotFound(propertyName, streamName, streamType);
                    }
                    propertyType = desc.PropertyType;
                    if (obtainFragment && desc.IsFragment)
                    {
                        fragmentEventType = streamType.GetFragmentType(propertyName);
                    }
                }
                else
                {
                    if (obtainFragment)
                    {
                        fragmentEventType = streamType.GetFragmentType(propertyName);
                    }
                }
            }
            else
            {
                var explicitProps = streamType.PropertyDescriptors;
                var found         = false;
                foreach (var prop in explicitProps)
                {
                    if (prop.PropertyName.Equals(propertyName))
                    {
                        propertyType = prop.PropertyType;
                        if (obtainFragment && prop.IsFragment)
                        {
                            fragmentEventType = streamType.GetFragmentType(propertyName);
                        }
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    throw HandlePropertyNotFound(propertyName, streamName, streamType);
                }
            }

            return(new PropertyResolutionDescriptor(streamName, streamType, propertyName, index, propertyType, fragmentEventType));
        }
Exemplo n.º 16
0
        public static EventBeanUpdateHelper Make(
            string updatedWindowOrTableName,
            EventTypeSPI eventTypeSPI,
            IList <OnTriggerSetAssignment> assignments,
            string updatedAlias,
            EventType optionalTriggeringEventType,
            bool isCopyOnWrite)
        {
            IList <EventBeanUpdateItem> updateItems = new List <EventBeanUpdateItem>();
            IList <string> properties = new List <string>();

            for (var i = 0; i < assignments.Count; i++)
            {
                var assignment = assignments[i];
                EventBeanUpdateItem updateItem;

                // determine whether this is a "property=value" assignment, we use property setters in this case
                var possibleAssignment = ExprNodeUtility.CheckGetAssignmentToProp(assignment.Expression);

                // handle assignment "property = value"
                if (possibleAssignment != null)
                {
                    var propertyName     = possibleAssignment.First;
                    var writableProperty = eventTypeSPI.GetWritableProperty(propertyName);

                    // check assignment to indexed or mapped property
                    if (writableProperty == null)
                    {
                        var nameWriteablePair = CheckIndexedOrMappedProp(possibleAssignment.First, updatedWindowOrTableName, updatedAlias, eventTypeSPI);
                        propertyName     = nameWriteablePair.First;
                        writableProperty = nameWriteablePair.Second;
                    }

                    var evaluator        = possibleAssignment.Second.ExprEvaluator;
                    var writers          = eventTypeSPI.GetWriter(propertyName);
                    var notNullableField = writableProperty.PropertyType.IsPrimitive;

                    properties.Add(propertyName);
                    var widener = TypeWidenerFactory.GetCheckPropertyAssignType(ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(possibleAssignment.Second), possibleAssignment.Second.ExprEvaluator.ReturnType,
                                                                                writableProperty.PropertyType, propertyName);

                    // check event type assignment
                    if (optionalTriggeringEventType != null && possibleAssignment.Second is ExprIdentNode)
                    {
                        var node        = (ExprIdentNode)possibleAssignment.Second;
                        var fragmentRHS = optionalTriggeringEventType.GetFragmentType(node.ResolvedPropertyName);
                        var fragmentLHS = eventTypeSPI.GetFragmentType(possibleAssignment.First);
                        if (fragmentRHS != null && fragmentLHS != null && !EventTypeUtility.IsTypeOrSubTypeOf(fragmentRHS.FragmentType, fragmentLHS.FragmentType))
                        {
                            throw new ExprValidationException("Invalid assignment to property '" +
                                                              possibleAssignment.First + "' event type '" + fragmentLHS.FragmentType.Name +
                                                              "' from event type '" + fragmentRHS.FragmentType.Name + "'");
                        }
                    }

                    updateItem = new EventBeanUpdateItem(evaluator, propertyName, writers, notNullableField, widener);
                }
                // handle non-assignment, i.e. UDF or other expression
                else
                {
                    var evaluator = assignment.Expression.ExprEvaluator;
                    updateItem = new EventBeanUpdateItem(evaluator, null, null, false, null);
                }

                updateItems.Add(updateItem);
            }

            // copy-on-write is the default event semantics as events are immutable
            EventBeanCopyMethod copyMethod;

            if (isCopyOnWrite)
            {
                // obtain copy method
                IList <string> propertiesUniqueList = new List <string>(new HashSet <string>(properties));
                var            propertiesArray      = propertiesUniqueList.ToArray();
                copyMethod = eventTypeSPI.GetCopyMethod(propertiesArray);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Event type does not support event bean copy");
                }
            }
            else
            {
                // for in-place update, determine assignment expressions to use "initial" to access prior-change values
                // the copy-method is optional
                copyMethod = null;
                var propertiesInitialValue = DeterminePropertiesInitialValue(assignments);
                if (!propertiesInitialValue.IsEmpty())
                {
                    var propertiesInitialValueArray = propertiesInitialValue.ToArray();
                    copyMethod = eventTypeSPI.GetCopyMethod(propertiesInitialValueArray);
                }
            }

            var updateItemsArray = updateItems.ToArray();

            return(new EventBeanUpdateHelper(copyMethod, updateItemsArray));
        }
Exemplo n.º 17
0
        public FragmentEventType GetFragmentType(String propertyName)
        {
            var item = _propertyItems.Get(propertyName);

            if (item != null) // may contain null values
            {
                return(item.FragmentEventType);
            }

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

            if (index == -1)
            {
                // dynamic simple property
                if (propertyName.EndsWith("?"))
                {
                    return(null);
                }

                // parse, can be an indexed property
                var property = PropertyParser.ParseAndWalk(propertyName);
                if (property is IndexedProperty)
                {
                    var indexedProp = (IndexedProperty)property;
                    var type        = NestableTypes.Get(indexedProp.PropertyNameAtomic);
                    if (type == null)
                    {
                        return(null);
                    }
                    else if (type is EventType[])
                    {
                        var eventType = ((EventType[])type)[0];
                        return(new FragmentEventType(eventType, false, false));
                    }
                    else if (type is String)
                    {
                        var propTypeName = type.ToString();
                        var isArray      = EventTypeUtility.IsPropertyArray(propTypeName);
                        if (!isArray)
                        {
                            return(null);
                        }
                        propTypeName = EventTypeUtility.GetPropertyRemoveArray(propTypeName);
                        EventType innerType = EventAdapterService.GetEventTypeByName(propTypeName);
                        if (!(innerType is BaseNestableEventType))
                        {
                            return(null);
                        }
                        return(new FragmentEventType(innerType, false, false)); // false since an index is present
                    }
                    if (!(type is Type))
                    {
                        return(null);
                    }
                    if (!((Type)type).IsArray)
                    {
                        return(null);
                    }
                    // its an array
                    return(EventBeanUtility.CreateNativeFragmentType(((Type)type).GetElementType(), null, EventAdapterService));
                }
                else if (property is MappedProperty)
                {
                    // No type information available for the inner event
                    return(null);
                }
                else
                {
                    return(null);
                }
            }

            // Map event types allow 2 types of properties inside:
            //   - a property that is a object is interrogated via bean property getters and BeanEventType
            //   - a property that is a Map itself is interrogated via map property getters
            // The property getters therefore act on

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

            // If the property is dynamic, it cannot be a fragment
            if (propertyMap.EndsWith("?"))
            {
                return(null);
            }

            var nestedType = NestableTypes.Get(propertyMap);

            if (nestedType == null)
            {
                // parse, can be an indexed property
                var property = PropertyParser.ParseAndWalk(propertyMap);
                if (property is IndexedProperty)
                {
                    var indexedProp = (IndexedProperty)property;
                    var type        = NestableTypes.Get(indexedProp.PropertyNameAtomic);
                    if (type == null)
                    {
                        return(null);
                    }
                    // handle map-in-map case
                    if (type is String)
                    {
                        var propTypeName = type.ToString();
                        var isArray      = EventTypeUtility.IsPropertyArray(propTypeName);
                        if (isArray)
                        {
                            propTypeName = EventTypeUtility.GetPropertyRemoveArray(propTypeName);
                        }
                        EventType innerType = EventAdapterService.GetEventTypeByName(propTypeName);
                        if (!(innerType is BaseNestableEventType))
                        {
                            return(null);
                        }
                        return(innerType.GetFragmentType(propertyNested));
                    }
                    // handle eventtype[] in map
                    else if (type is EventType[])
                    {
                        var innerType = ((EventType[])type)[0];
                        return(innerType.GetFragmentType(propertyNested));
                    }
                    // handle array class in map case
                    else
                    {
                        if (!(type is Type))
                        {
                            return(null);
                        }
                        if (!((Type)type).IsArray)
                        {
                            return(null);
                        }
                        var fragmentParent = EventBeanUtility.CreateNativeFragmentType(
                            (Type)type, null, EventAdapterService);
                        if (fragmentParent == null)
                        {
                            return(null);
                        }
                        return(fragmentParent.FragmentType.GetFragmentType(propertyNested));
                    }
                }
                else if (property is MappedProperty)
                {
                    // No type information available for the property's map value
                    return(null);
                }
                else
                {
                    return(null);
                }
            }

            // If there is a map value in the map, return the Object value if this is a dynamic property
            if (ReferenceEquals(nestedType, typeof(IDictionary <string, object>)))
            {
                return(null);
            }
            else if (nestedType is IDictionary <string, object> )
            {
                return(null);
            }
            else if (nestedType is Type)
            {
                var simpleClass = (Type)nestedType;
                if (!TypeHelper.IsFragmentableType(simpleClass))
                {
                    return(null);
                }
                EventType nestedEventType =
                    EventAdapterService.BeanEventTypeFactory.CreateBeanTypeDefaultName(simpleClass);
                return(nestedEventType.GetFragmentType(propertyNested));
            }
            else if (nestedType is EventType)
            {
                var innerType = (EventType)nestedType;
                return(innerType.GetFragmentType(propertyNested));
            }
            else if (nestedType is EventType[])
            {
                var innerType = (EventType[])nestedType;
                return(innerType[0].GetFragmentType(propertyNested));
            }
            else if (nestedType is String)
            {
                var nestedName = nestedType.ToString();
                var isArray    = EventTypeUtility.IsPropertyArray(nestedName);
                if (isArray)
                {
                    nestedName = EventTypeUtility.GetPropertyRemoveArray(nestedName);
                }
                var innerType = EventAdapterService.GetEventTypeByName(nestedName);
                if (!(innerType is BaseNestableEventType))
                {
                    return(null);
                }
                return(innerType.GetFragmentType(propertyNested));
            }
            else
            {
                var message = "Nestable map type configuration encountered an unexpected value type of '"
                              + nestedType.GetType() + " for property '" + propertyName +
                              "', expected Class, typeof(Map) or IDictionary<String, Object> as value type";
                throw new PropertyAccessException(message);
            }
        }
        public static EventBeanUpdateHelperForge Make(
            string updatedWindowOrTableName,
            EventTypeSPI eventTypeSPI,
            IList <OnTriggerSetAssignment> assignments,
            string updatedAlias,
            EventType optionalTriggeringEventType,
            bool isCopyOnWrite,
            string statementName,
            EventTypeAvroHandler avroHandler)
        {
            IList <EventBeanUpdateItemForge> updateItems = new List <EventBeanUpdateItemForge>();
            IList <string> properties = new List <string>();

            TypeWidenerCustomizer typeWidenerCustomizer = avroHandler.GetTypeWidenerCustomizer(eventTypeSPI);

            for (int i = 0; i < assignments.Count; i++)
            {
                OnTriggerSetAssignment desc       = assignments[i];
                ExprAssignment         assignment = desc.Validated;
                if (assignment == null)
                {
                    throw new IllegalStateException("Assignment has not been validated");
                }

                try {
                    EventBeanUpdateItemForge updateItem;
                    if (assignment is ExprAssignmentStraight)
                    {
                        ExprAssignmentStraight straight = (ExprAssignmentStraight)assignment;

                        // handle assignment "property = value"
                        if (straight.Lhs is ExprAssignmentLHSIdent)
                        {
                            ExprAssignmentLHSIdent ident = (ExprAssignmentLHSIdent)straight.Lhs;

                            string propertyName = ident.Ident;
                            EventPropertyDescriptor writableProperty = eventTypeSPI.GetWritableProperty(propertyName);

                            // check assignment to indexed or mapped property
                            if (writableProperty == null)
                            {
                                Pair <string, EventPropertyDescriptor> nameWriteablePair = CheckIndexedOrMappedProp(
                                    propertyName,
                                    updatedWindowOrTableName,
                                    updatedAlias,
                                    eventTypeSPI);
                                propertyName     = nameWriteablePair.First;
                                writableProperty = nameWriteablePair.Second;
                            }

                            ExprNode  rhsExpr             = straight.Rhs;
                            ExprForge rhsForge            = rhsExpr.Forge;
                            EventPropertyWriterSPI writer = eventTypeSPI.GetWriter(propertyName);
                            bool notNullableField         = writableProperty.PropertyType.IsPrimitive;

                            properties.Add(propertyName);
                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(rhsExpr),
                                    rhsForge.EvaluationType,
                                    writableProperty.PropertyType,
                                    propertyName,
                                    false,
                                    typeWidenerCustomizer,
                                    statementName);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            // check event type assignment
                            bool useUntypedAssignment = false;
                            bool useTriggeringEvent   = false;
                            if (optionalTriggeringEventType != null)
                            {
                                // handle RHS is ident node
                                if (rhsExpr is ExprIdentNode)
                                {
                                    ExprIdentNode     node        = (ExprIdentNode)rhsExpr;
                                    FragmentEventType fragmentRHS = optionalTriggeringEventType.GetFragmentType(node.ResolvedPropertyName);
                                    FragmentEventType fragmentLHS = eventTypeSPI.GetFragmentType(propertyName);
                                    if (fragmentRHS != null && fragmentLHS != null)
                                    {
                                        if (!EventTypeUtility.IsTypeOrSubTypeOf(fragmentRHS.FragmentType, fragmentLHS.FragmentType))
                                        {
                                            throw MakeEventTypeMismatch(propertyName, fragmentLHS.FragmentType, fragmentRHS.FragmentType);
                                        }
                                    }

                                    // we don't need to cast if it is a self-assignment and LHS is an event and target needs no writer
                                    if (node.StreamId == 0 && fragmentLHS != null && eventTypeSPI is BaseNestableEventType)
                                    {
                                        useUntypedAssignment = true;
                                    }
                                }

                                // handle RHS is a stream of the triggering event itself
                                if (rhsExpr is ExprStreamUnderlyingNode)
                                {
                                    ExprStreamUnderlyingNode und = (ExprStreamUnderlyingNode)rhsExpr;
                                    if (und.StreamId == 1)
                                    {
                                        FragmentEventType fragmentLHS = eventTypeSPI.GetFragmentType(propertyName);
                                        if (fragmentLHS != null &&
                                            optionalTriggeringEventType is BaseNestableEventType &&
                                            !EventTypeUtility.IsTypeOrSubTypeOf(optionalTriggeringEventType, fragmentLHS.FragmentType))
                                        {
                                            throw MakeEventTypeMismatch(propertyName, fragmentLHS.FragmentType, optionalTriggeringEventType);
                                        }

                                        // we use the event itself for assignment and target needs no writer
                                        if (eventTypeSPI is BaseNestableEventType)
                                        {
                                            useUntypedAssignment = true;
                                            useTriggeringEvent   = true;
                                        }
                                    }
                                }
                            }

                            updateItem = new EventBeanUpdateItemForge(
                                rhsForge,
                                propertyName,
                                writer,
                                notNullableField,
                                widener,
                                useUntypedAssignment,
                                useTriggeringEvent,
                                null);
                        }
                        else if (straight.Lhs is ExprAssignmentLHSArrayElement)
                        {
                            // handle "property[expr] = value"
                            ExprAssignmentLHSArrayElement arrayElementLHS = (ExprAssignmentLHSArrayElement)straight.Lhs;
                            string   arrayPropertyName = arrayElementLHS.Ident;
                            ExprNode rhs            = straight.Rhs;
                            Type     evaluationType = rhs.Forge.EvaluationType;
                            Type     propertyType   = eventTypeSPI.GetPropertyType(arrayPropertyName);
                            if (!eventTypeSPI.IsProperty(arrayPropertyName))
                            {
                                throw new ExprValidationException("Property '" + arrayPropertyName + "' could not be found");
                            }

                            if (propertyType == null || !propertyType.IsArray)
                            {
                                throw new ExprValidationException("Property '" + arrayPropertyName + "' is not an array");
                            }

                            EventPropertyGetterSPI getter = eventTypeSPI.GetGetterSPI(arrayPropertyName);
                            Type componentType            = propertyType.GetElementType();
                            if (!TypeHelper.IsAssignmentCompatible(evaluationType, componentType))
                            {
                                throw new ExprValidationException(
                                          "Invalid assignment to property '" +
                                          arrayPropertyName +
                                          "' component type '" +
                                          componentType.CleanName() +
                                          "' from expression returning '" +
                                          evaluationType.CleanName() +
                                          "'");
                            }

                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(straight.Rhs),
                                    evaluationType,
                                    componentType,
                                    arrayPropertyName,
                                    false,
                                    typeWidenerCustomizer,
                                    statementName);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            EventBeanUpdateItemArray arrayInfo = new EventBeanUpdateItemArray(
                                arrayPropertyName,
                                arrayElementLHS.IndexExpression,
                                propertyType,
                                getter);
                            updateItem = new EventBeanUpdateItemForge(
                                rhs.Forge,
                                arrayPropertyName,
                                null,
                                false,
                                widener,
                                false,
                                false,
                                arrayInfo);
                        }
                        else
                        {
                            throw new IllegalStateException("Unrecognized LHS assignment " + straight);
                        }
                    }
                    else if (assignment is ExprAssignmentCurly)
                    {
                        // handle non-assignment, i.e. UDF or other expression
                        ExprAssignmentCurly dot = (ExprAssignmentCurly)assignment;
                        updateItem = new EventBeanUpdateItemForge(
                            dot.Expression.Forge,
                            null,
                            null,
                            false,
                            null,
                            false,
                            false,
                            null);
                    }
                    else
                    {
                        throw new IllegalStateException("Unrecognized assignment " + assignment);
                    }

                    updateItems.Add(updateItem);
                }
                catch (ExprValidationException ex) {
                    throw new ExprValidationException(
                              "Failed to validate assignment expression '" +
                              ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignment.OriginalExpression) +
                              "': " +
                              ex.Message,
                              ex);
                }
            }

            // copy-on-write is the default event semantics as events are immutable
            EventBeanCopyMethodForge copyMethod;

            if (isCopyOnWrite)
            {
                // obtain copy method
                List <string> propertiesUniqueList = new List <string>(new HashSet <string>(properties));
                string[]      propertiesArray      = propertiesUniqueList.ToArray();
                copyMethod = eventTypeSPI.GetCopyMethodForge(propertiesArray);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Event type does not support event bean copy");
                }
            }
            else
            {
                // for in-place update, determine assignment expressions to use "initial" to access prior-change values
                // the copy-method is optional
                copyMethod = null;
                ISet <string> propertiesInitialValue = DeterminePropertiesInitialValue(assignments);
                if (!propertiesInitialValue.IsEmpty())
                {
                    string[] propertiesInitialValueArray = propertiesInitialValue.ToArray();
                    copyMethod = eventTypeSPI.GetCopyMethodForge(propertiesInitialValueArray);
                }
            }

            EventBeanUpdateItemForge[] updateItemsArray = updateItems.ToArray();
            return(new EventBeanUpdateHelperForge(eventTypeSPI, copyMethod, updateItemsArray));
        }
Exemplo n.º 19
0
        public FragmentEventType GetFragmentType(string propertyName)
        {
            var item = _propertyItems.Get(propertyName);
            if (item != null) {
                // may contain null values
                return item.FragmentEventType;
            }

            // see if this is a nested property
            var index = StringValue.UnescapedIndexOfDot(propertyName);
            if (index == -1) {
                // dynamic simple property
                if (propertyName.EndsWith("?")) {
                    return null;
                }

                // parse, can be an indexed property
                var property = PropertyParser.ParseAndWalkLaxToSimple(propertyName);
                if (property is IndexedProperty indexedProp) {
                    var type = _nestableTypes.Get(indexedProp.PropertyNameAtomic);
                    if (type == null) {
                        return null;
                    }

                    if (type is EventType[] eventTypesArray) {
                        var eventType = eventTypesArray[0];
                        return new FragmentEventType(eventType, false, false);
                    }

                    if (type is TypeBeanOrUnderlying[] beanOrUnderlyings) {
                        var innerType = beanOrUnderlyings[0].EventType;
                        if (!(innerType is BaseNestableEventType)) {
                            return null;
                        }

                        return new FragmentEventType(innerType, false, false); // false since an index is present
                    }

                    if (!(type is Type)) {
                        return null;
                    }

                    if (!((Type) type).IsArray) {
                        return null;
                    }

                    // its an array
                    return EventBeanUtility.CreateNativeFragmentType(
                        ((Type) type).GetElementType(),
                        null,
                        _beanEventTypeFactory,
                        _publicFields);
                }

                if (property is MappedProperty) {
                    // No type information available for the inner event
                    return null;
                }

                return null;
            }

            // Map event types allow 2 types of properties inside:
            //   - a property that is a object is interrogated via bean property getters and BeanEventType
            //   - a property that is a Map itself is interrogated via map property getters
            // The property getters therefore act on

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

            // If the property is dynamic, it cannot be a fragment
            if (propertyMap.EndsWith("?")) {
                return null;
            }

            var nestedType = _nestableTypes.Get(propertyMap);
            if (nestedType == null) {
                // parse, can be an indexed property
                var property = PropertyParser.ParseAndWalkLaxToSimple(propertyMap);
                if (property is IndexedProperty indexedProp) {
                    var type = _nestableTypes.Get(indexedProp.PropertyNameAtomic);
                    if (type == null) {
                        return null;
                    }

                    // handle map-in-map case
                    if (type is TypeBeanOrUnderlying[] beanOrUnderlyings) {
                        var innerType = beanOrUnderlyings[0].EventType;
                        if (!(innerType is BaseNestableEventType)) {
                            return null;
                        }

                        return innerType.GetFragmentType(propertyNested);
                    }

                    if (type is EventType[] innerEventTypeArray) {
                        // handle EventType[] in map
                        var innerType = innerEventTypeArray[0];
                        return innerType.GetFragmentType(propertyNested);
                    }

                    // handle array class in map case
                    if (!(type is Type)) {
                        return null;
                    }

                    if (!((Type) type).IsArray) {
                        return null;
                    }

                    var fragmentParent = EventBeanUtility.CreateNativeFragmentType(
                        (Type) type,
                        null,
                        _beanEventTypeFactory,
                        _publicFields);

                    return fragmentParent?.FragmentType.GetFragmentType(propertyNested);
                }

                if (property is MappedProperty) {
                    // No type information available for the property's map value
                    return null;
                }

                return null;
            }

            // If there is a map value in the map, return the Object value if this is a dynamic property
            if (ReferenceEquals(nestedType, typeof(IDictionary<string, object>))) {
                return null;
            }

            if (nestedType is IDictionary<string, object>) {
                return null;
            }

            if (nestedType is Type simpleClass) {
                if (!simpleClass.IsFragmentableType()) {
                    return null;
                }

                EventType nestedEventType = _beanEventTypeFactory.GetCreateBeanType(simpleClass, _publicFields);
                return nestedEventType.GetFragmentType(propertyNested);
            }

            if (nestedType is EventType innerEventType) {
                return innerEventType.GetFragmentType(propertyNested);
            }

            if (nestedType is EventType[] eventTypeArray) {
                return eventTypeArray[0].GetFragmentType(propertyNested);
            }

            if (nestedType is TypeBeanOrUnderlying typeBeanOrUnderlying) {
                var innerType = typeBeanOrUnderlying.EventType;
                if (!(innerType is BaseNestableEventType)) {
                    return null;
                }

                return innerType.GetFragmentType(propertyNested);
            }

            if (nestedType is TypeBeanOrUnderlying[] typeBeanOrUnderlyings) {
                var innerType = typeBeanOrUnderlyings[0].EventType;
                if (!(innerType is BaseNestableEventType)) {
                    return null;
                }

                return innerType.GetFragmentType(propertyNested);
            }

            var message = "Nestable map type configuration encountered an unexpected value type of '" +
                          nestedType.GetType() +
                          " for property '" +
                          propertyName +
                          "', expected Class, Map.class or Map<String, Object> as value type";
            throw new PropertyAccessException(message);
        }