public EventPropertyGetter GetGetter(String propertyName) { EventPropertyGetter cachedGetter = _propertyGetterCache.Get(propertyName); if (cachedGetter != null) { return(cachedGetter); } SimplePropertyInfo simpleProp = GetSimplePropertyInfo(propertyName); if ((simpleProp != null) && (simpleProp.Getter != null)) { EventPropertyGetter propertyGetter = simpleProp.Getter; _propertyGetterCache.Put(propertyName, propertyGetter); return(propertyGetter); } Property prop = PropertyParser.ParseAndWalk(propertyName, false); if (prop is SimpleProperty) { // there is no such property since it wasn't in simplePropertyGetters return(null); } EventPropertyGetter getter = prop.GetGetter(this, _eventAdapterService); _propertyGetterCache.Put(propertyName, getter); return(getter); }
private static Pair<int?, string> GetStreamIndex(string resolvedPropertyName) { var property = PropertyParser.ParseAndWalk(resolvedPropertyName); if (!(property is NestedProperty)) { throw new IllegalStateException( string.Format("Expected a nested property providing an index for array match '{0}'", resolvedPropertyName)); } var nested = ((NestedProperty) property); if (nested.Properties.Count < 2) { throw new IllegalStateException( string.Format("Expected a nested property name for array match '{0}', none found", resolvedPropertyName)); } if (!(nested.Properties[0] is IndexedProperty)) { throw new IllegalStateException( string.Format("Expected an indexed property for array match '{0}', please provide an index", resolvedPropertyName)); } var index = ((IndexedProperty) nested.Properties[0]).Index; nested.Properties.RemoveAt(0); var writer = new StringWriter(); nested.ToPropertyEPL(writer); return new Pair<int?, string>(index, writer.ToString()); }
public FragmentEventType GetFragmentType(String propertyExpression) { SimplePropertyInfo simpleProp = GetSimplePropertyInfo(propertyExpression); if ((simpleProp != null) && (simpleProp.PropertyType != null)) { GenericPropertyDesc genericProp = simpleProp.Descriptor.GetReturnTypeGeneric(); return(EventBeanUtility.CreateNativeFragmentType(genericProp.PropertyType, genericProp.GenericType, _eventAdapterService)); } Property prop = PropertyParser.ParseAndWalk(propertyExpression, false); if (prop is SimpleProperty) { // there is no such property since it wasn't in simplePropertyTypes return(null); } GenericPropertyDesc genericPropertyDesc = prop.GetPropertyTypeGeneric(this, _eventAdapterService); if (genericPropertyDesc == null) { return(null); } return(EventBeanUtility.CreateNativeFragmentType(genericPropertyDesc.PropertyType, genericPropertyDesc.GenericType, _eventAdapterService)); }
public override EventPropertyWriter GetWriter(String propertyName) { if (WritablePropertyDescriptors == null) { InitializeWriters(); } var pair = PropertyWriters.Get(propertyName); if (pair != null) { return(pair.Second); } var property = PropertyParser.ParseAndWalk(propertyName, false); if (property is MappedProperty) { var mapProp = (MappedProperty)property; return(new MapEventBeanPropertyWriterMapProp(mapProp.PropertyNameAtomic, mapProp.Key)); } if (property is IndexedProperty) { var indexedProp = (IndexedProperty)property; return(new MapEventBeanPropertyWriterIndexedProp(indexedProp.PropertyNameAtomic, indexedProp.Index)); } return(null); }
protected override EventPropertyGetter DoResolvePropertyGetter(String propertyExpression) { var getter = _propertyGetterCache.Get(propertyExpression); if (getter != null) { return(getter); } if (!ConfigurationEventTypeXMLDOM.IsXPathPropertyExpr) { Property prop = PropertyParser.ParseAndWalk(propertyExpression); getter = prop.GetGetterDOM(); if (!prop.IsDynamic) { getter = new DOMConvertingGetter(propertyExpression, (DOMPropertyGetter)getter, typeof(string)); } } else { try { var ast = PropertyParser.Parse(propertyExpression); var isDynamic = PropertyParser.IsPropertyDynamic(ast); var xPathExpr = SimpleXMLPropertyParser.Walk( ast, propertyExpression, RootElementName, _defaultNamespacePrefix, _isResolvePropertiesAbsolute); if (Log.IsInfoEnabled) { Log.Info("Compiling XPath expression for property '" + propertyExpression + "' as '" + xPathExpr + "'"); } var xPathExpression = XPathExpression.Compile(xPathExpr, NamespaceContext); var xPathReturnType = isDynamic ? XPathResultType.Any : XPathResultType.String; getter = new XPathPropertyGetter( propertyExpression, xPathExpr, xPathExpression, xPathReturnType, null, null); } catch (XPathException e) { throw new EPException( "Error constructing XPath expression from property name '" + propertyExpression + '\'', e); } } // no fragment factory, fragments not allowed _propertyGetterCache.Put(propertyExpression, getter); return(getter); }
private string TryKey(string key) { string propertyName = "m(\"" + key + "\")"; log.Debug(".tryKey propertyName=" + propertyName + " key=" + key); Property property = PropertyParser.ParseAndWalk(propertyName, false); return(((MappedProperty)property).Key); }
/// <summary> /// Return a writer for writing a single property value. /// </summary> /// <param name="propertyName">to write to</param> /// <returns> /// null or writer if writable /// </returns> public EventPropertyWriter GetWriter(String propertyName) { if (_writeablePropertyDescriptors == null) { InitializeWriters(); } var pair = _writerMap.Get(propertyName); if (pair != null) { return(pair.Second); } var property = PropertyParser.ParseAndWalk(propertyName, false); if (property is MappedProperty) { var mapProp = (MappedProperty)property; var methodName = string.Format("Set{0}", mapProp.PropertyNameAtomic); var methodInfo = UnderlyingType.GetMethod( methodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(object) }, null); if (methodInfo == null) { Log.Info("Failed to find mapped property '" + mapProp.PropertyNameAtomic + "' for writing to property '" + propertyName + "'"); return(null); } var fastMethod = FastClass.GetMethod(methodInfo); return(new BeanEventPropertyWriterMapProp(UnderlyingType, fastMethod, mapProp.Key)); } if (property is IndexedProperty) { var indexedProp = (IndexedProperty)property; var methodName = string.Format("Set{0}", indexedProp.PropertyNameAtomic); var methodInfo = UnderlyingType.GetMethod( methodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(int), typeof(object) }, null); if (methodInfo == null) { Log.Info("Failed to find mapped property '" + indexedProp.PropertyNameAtomic + "' for writing to property '" + propertyName + "'"); return(null); } var fastMethod = FastClass.GetMethod(methodInfo); return(new BeanEventPropertyWriterIndexedProp(UnderlyingType, fastMethod, indexedProp.Index)); } return(null); }
public void TestParse() { Property property; IList <Property> nested; property = PropertyParser.ParseAndWalk("a", false); Assert.AreEqual("a", ((SimpleProperty)property).PropertyNameAtomic); property = PropertyParser.ParseAndWalk("i[1]", false); Assert.AreEqual("i", ((IndexedProperty)property).PropertyNameAtomic); Assert.AreEqual(1, ((IndexedProperty)property).Index); property = PropertyParser.ParseAndWalk("m('key')", false); Assert.AreEqual("m", ((MappedProperty)property).PropertyNameAtomic); Assert.AreEqual("key", ((MappedProperty)property).Key); property = PropertyParser.ParseAndWalk("a.b[2].c('m')", false); nested = ((NestedProperty)property).Properties; Assert.AreEqual(3, nested.Count); Assert.AreEqual("a", ((SimpleProperty)nested[0]).PropertyNameAtomic); Assert.AreEqual("b", ((IndexedProperty)nested[1]).PropertyNameAtomic); Assert.AreEqual(2, ((IndexedProperty)nested[1]).Index); Assert.AreEqual("c", ((MappedProperty)nested[2]).PropertyNameAtomic); Assert.AreEqual("m", ((MappedProperty)nested[2]).Key); property = PropertyParser.ParseAndWalk("a", true); Assert.AreEqual("a", ((DynamicSimpleProperty)property).PropertyNameAtomic); property = PropertyParser.ParseAndWalk("`order`.p0", false); nested = ((NestedProperty)property).Properties; Assert.AreEqual(2, nested.Count); Assert.AreEqual("order", ((SimpleProperty)nested[0]).PropertyNameAtomic); Assert.AreEqual("p0", ((SimpleProperty)nested[1]).PropertyNameAtomic); property = PropertyParser.ParseAndWalk("`jim's strings`.p0", false); nested = ((NestedProperty)property).Properties; Assert.AreEqual(2, nested.Count); Assert.AreEqual("jim's strings", ((SimpleProperty)nested[0]).PropertyNameAtomic); Assert.AreEqual("p0", ((SimpleProperty)nested[1]).PropertyNameAtomic); property = PropertyParser.ParseAndWalk("`children's books`[0]", false); IndexedProperty indexed = (IndexedProperty)property; Assert.AreEqual(0, indexed.Index); Assert.AreEqual("children's books", indexed.PropertyNameAtomic); property = PropertyParser.ParseAndWalk("x\\.y", false); Assert.AreEqual("x.y", ((SimpleProperty)property).PropertyNameAtomic); property = PropertyParser.ParseAndWalk("x\\.\\.y", false); Assert.AreEqual("x..y", ((SimpleProperty)property).PropertyNameAtomic); }
public Type GetPropertyType(String propertyName) { var simpleProp = GetSimplePropertyInfo(propertyName); if ((simpleProp != null) && (simpleProp.PropertyType != null)) { return(simpleProp.PropertyType); } var prop = PropertyParser.ParseAndWalk(propertyName, false); if (prop is SimpleProperty) { // there is no such property since it wasn't in simplePropertyTypes return(null); } return(prop.GetPropertyType(this, _eventAdapterService)); }
public override EventPropertyWriter GetWriter(String propertyName) { if (_writablePropertyDescriptors == null) { InitializeWriters(); } Pair <EventPropertyDescriptor, ObjectArrayEventBeanPropertyWriter> pair = _propertyWriters.Get(propertyName); if (pair != null) { return(pair.Second); } Property property = PropertyParser.ParseAndWalk(propertyName, false); if (property is MappedProperty) { var mapProp = (MappedProperty)property; int index; if (!PropertiesIndexes.TryGetValue(mapProp.PropertyNameAtomic, out index)) { return(null); } return(new ObjectArrayEventBeanPropertyWriterMapProp(index, mapProp.Key)); } if (property is IndexedProperty) { var indexedProp = (IndexedProperty)property; int index; if (!PropertiesIndexes.TryGetValue(indexedProp.PropertyNameAtomic, out index)) { return(null); } return(new ObjectArrayEventBeanPropertyWriterIndexedProp(index, indexedProp.Index)); } return(null); }
private Type DoResolvePropertyType(String propertyExpression, bool allowSimpleProperties) { // see if this is an indexed property int index = ASTUtil.UnescapedIndexOfDot(propertyExpression); if ((!allowSimpleProperties) && (index == -1)) { // parse, can be an indexed property Property property = PropertyParser.ParseAndWalk(propertyExpression); if (!property.IsDynamic) { if (!(property is IndexedProperty)) { return(null); } var indexedProp = (IndexedProperty)property; EventPropertyDescriptor descriptor = PropertyDescriptorMap.Get(indexedProp.PropertyNameAtomic); if (descriptor == null) { return(null); } return(descriptor.PropertyType); } } Property prop = PropertyParser.ParseAndWalk(propertyExpression); if (prop.IsDynamic) { return(typeof(XmlNode)); } SchemaItem item = prop.GetPropertyTypeSchema(_schemaModelRoot, EventAdapterService); if (item == null) { return(null); } return(SchemaUtil.ToReturnType(item)); }
public static MapIndexedPropPair GetIndexedAndMappedProps(String[] properties) { ICollection <String> mapPropertiesToCopy = new HashSet <String>(); ICollection <String> arrayPropertiesToCopy = new HashSet <String>(); for (var i = 0; i < properties.Length; i++) { var prop = PropertyParser.ParseAndWalk(properties[i]); if (prop is MappedProperty) { var mappedProperty = (MappedProperty)prop; mapPropertiesToCopy.Add(mappedProperty.PropertyNameAtomic); } if (prop is IndexedProperty) { var indexedProperty = (IndexedProperty)prop; arrayPropertiesToCopy.Add(indexedProperty.PropertyNameAtomic); } } return(new MapIndexedPropPair(mapPropertiesToCopy, arrayPropertiesToCopy)); }
public EventPropertyDescriptor GetWritableProperty(String propertyName) { if (_writeablePropertyDescriptors == null) { InitializeWriters(); } var pair = _writerMap.Get(propertyName); if (pair != null) { return(pair.First); } var property = PropertyParser.ParseAndWalk(propertyName, false); if (property is MappedProperty) { var writer = GetWriter(propertyName); if (writer == null) { return(null); } var mapProp = (MappedProperty)property; return(new EventPropertyDescriptor(mapProp.PropertyNameAtomic, typeof(Object), null, false, true, false, true, false)); } if (property is IndexedProperty) { var writer = GetWriter(propertyName); if (writer == null) { return(null); } var indexedProp = (IndexedProperty)property; return(new EventPropertyDescriptor(indexedProp.PropertyNameAtomic, typeof(Object), null, true, false, true, false, false)); } return(null); }
public EventPropertyGetter GetGetter(String propertyName) { RevisionPropertyTypeDesc desc = _propertyDesc.Get(propertyName); if (desc != null) { return(desc.RevisionGetter); } // dynamic property names note allowed if (propertyName.IndexOf('?') != -1) { return(null); } // see if this is a nested property int index = ASTUtil.UnescapedIndexOfDot(propertyName); if (index == -1) { Property prop = PropertyParser.ParseAndWalk(propertyName); if (prop is SimpleProperty) { // there is no such property since it wasn't found earlier return(null); } String atomic = null; if (prop is IndexedProperty) { var indexedprop = (IndexedProperty)prop; atomic = indexedprop.PropertyNameAtomic; } if (prop is MappedProperty) { var indexedprop = (MappedProperty)prop; atomic = indexedprop.PropertyNameAtomic; } desc = _propertyDesc.Get(atomic); if (desc == null) { return(null); } if (!(desc.PropertyType is Type)) { return(null); } var nestedClass = (Type)desc.PropertyType; var complexProperty = (BeanEventType)_eventAdapterService.AddBeanType(nestedClass.Name, nestedClass, false, false, false); return(prop.GetGetter(complexProperty, _eventAdapterService)); } // Map event types allow 2 types of properties inside: // - a property that is a Java object is interrogated via bean property getters and BeanEventType // - a property that is a Map itself is interrogated via map property getters // Take apart the nested property into a map key and a nested value class property name String propertyMap = ASTUtil.UnescapeDot(propertyName.Substring(0, index)); String propertyNested = propertyName.Substring(index + 1); desc = _propertyDesc.Get(propertyMap); if (desc == null) { return(null); // prefix not a known property } // only nested classes supported for revision event types since deep property information not currently exposed by EventType if (desc.PropertyType is Type) { // ask the nested class to resolve the property Type simpleClass = (Type)desc.PropertyType; EventType nestedEventType = _eventAdapterService.AddBeanType(simpleClass.FullName, simpleClass, false, false, false); EventPropertyGetter nestedGetter = nestedEventType.GetGetter(propertyNested); if (nestedGetter == null) { return(null); } // construct getter for nested property return(new RevisionNestedPropertyGetter(desc.RevisionGetter, nestedGetter, _eventAdapterService)); } else { return(null); } }
protected override FragmentEventType DoResolveFragmentType(String property) { if ((!ConfigurationEventTypeXMLDOM.IsAutoFragment) || (ConfigurationEventTypeXMLDOM.IsXPathPropertyExpr)) { return(null); } Property prop = PropertyParser.ParseAndWalk(property); SchemaItem item = prop.GetPropertyTypeSchema(_schemaModelRoot, EventAdapterService); if ((item == null) || (!CanFragment(item))) { return(null); } var complex = (SchemaElementComplex)item; // build name of event type String[] atomicProps = prop.ToPropertyArray(); String delimiterDot = "."; var eventTypeNameBuilder = new StringBuilder(Name); foreach (String atomic in atomicProps) { eventTypeNameBuilder.Append(delimiterDot); eventTypeNameBuilder.Append(atomic); } String eventTypeName = eventTypeNameBuilder.ToString(); // check if the type exists, use the existing type if found EventType existingType = EventAdapterService.GetEventTypeByName(eventTypeName); if (existingType != null) { return(new FragmentEventType(existingType, complex.IsArray, false)); } // add a new type var xmlDom = new ConfigurationEventTypeXMLDOM(); xmlDom.RootElementName = "//" + complex.Name; // such the reload of the type can resolve it xmlDom.RootElementNamespace = complex.Namespace; xmlDom.IsAutoFragment = ConfigurationEventTypeXMLDOM.IsAutoFragment; xmlDom.IsEventSenderValidatesRoot = ConfigurationEventTypeXMLDOM.IsEventSenderValidatesRoot; xmlDom.IsXPathPropertyExpr = ConfigurationEventTypeXMLDOM.IsXPathPropertyExpr; xmlDom.IsXPathResolvePropertiesAbsolute = ConfigurationEventTypeXMLDOM.IsXPathResolvePropertiesAbsolute; xmlDom.SchemaResource = ConfigurationEventTypeXMLDOM.SchemaResource; xmlDom.SchemaText = ConfigurationEventTypeXMLDOM.SchemaText; xmlDom.XPathFunctionResolver = ConfigurationEventTypeXMLDOM.XPathFunctionResolver; xmlDom.XPathVariableResolver = ConfigurationEventTypeXMLDOM.XPathVariableResolver; xmlDom.DefaultNamespace = ConfigurationEventTypeXMLDOM.DefaultNamespace; xmlDom.AddNamespacePrefixes(ConfigurationEventTypeXMLDOM.NamespacePrefixes); EventType newType; try { newType = EventAdapterService.AddXMLDOMType(eventTypeName, xmlDom, _schemaModel, true); } catch (Exception ex) { Log.Error( "Failed to add dynamic event type for fragment of XML schema for property '" + property + "' :" + ex.Message, ex); return(null); } return(new FragmentEventType(newType, complex.IsArray, false)); }
/// <summary> /// Return the xPath corresponding to the given property. The PropertyName String /// may be simple, nested, indexed or mapped. /// </summary> /// <param name="propertyName">is the event property name</param> /// <param name="namespace">is the default namespace</param> /// <param name="schemaModel">is the schema model</param> /// <param name="xPathContext">is the xpath factory instance to use</param> /// <param name="rootElementName">is the name of the root element</param> /// <param name="eventAdapterService">for type lookup and creation</param> /// <param name="xmlEventType">the resolving type</param> /// <param name="isAllowFragment">whether fragmenting is allowed</param> /// <param name="defaultNamespace">default namespace</param> /// <returns> /// xpath expression /// </returns> /// <throws>EPException is there are XPath errors</throws> public static EventPropertyGetter GetXPathResolution(String propertyName, XPathNamespaceContext xPathContext, String rootElementName, String @namespace, SchemaModel schemaModel, EventAdapterService eventAdapterService, BaseXMLEventType xmlEventType, bool isAllowFragment, String defaultNamespace) { if (Log.IsDebugEnabled) { Log.Debug("Determining XPath expression for property '" + propertyName + "'"); } var ctx = new XPathNamespaceContext(); var namespaces = schemaModel.Namespaces; string defaultNamespacePrefix = null; for (int i = 0; i < namespaces.Count; i++) { var namespacePrefix = "n" + i; ctx.AddNamespace(namespacePrefix, namespaces[i]); if ((defaultNamespace != null) && (defaultNamespace == namespaces[i])) { defaultNamespacePrefix = namespacePrefix; } } Property property = PropertyParser.ParseAndWalk(propertyName); var isDynamic = property.IsDynamic; var rootComplexElement = SchemaUtil.FindRootElement(schemaModel, @namespace, rootElementName); string prefix = ctx.LookupPrefix(rootComplexElement.Namespace); if (prefix == null) { prefix = ""; } else { prefix += ':'; } var xPathBuf = new StringBuilder(); xPathBuf.Append('/'); xPathBuf.Append(prefix); if (rootElementName.StartsWith("//")) { xPathBuf.Append(rootElementName.Substring(2)); } else { xPathBuf.Append(rootElementName); } var parentComplexElement = rootComplexElement; Pair <String, XPathResultType> pair = null; if (!(property is NestedProperty)) { pair = MakeProperty(rootComplexElement, property, ctx, true, isDynamic, defaultNamespacePrefix); if (pair == null) { throw new PropertyAccessException("Failed to locate property '" + propertyName + "' in schema"); } xPathBuf.Append(pair.First); } else { NestedProperty nestedProperty = (NestedProperty)property; int indexLast = nestedProperty.Properties.Count - 1; for (int i = 0; i < indexLast + 1; i++) { var isLast = i == indexLast; var propertyNested = nestedProperty.Properties[i]; pair = MakeProperty(parentComplexElement, propertyNested, ctx, isLast, isDynamic, defaultNamespacePrefix); if (pair == null) { throw new PropertyAccessException("Failed to locate property '" + propertyName + "' nested property part '" + property.PropertyNameAtomic + "' in schema"); } var text = propertyNested.PropertyNameAtomic; var obj = SchemaUtil.FindPropertyMapping(parentComplexElement, text); if (obj is SchemaElementComplex) { parentComplexElement = (SchemaElementComplex)obj; } xPathBuf.Append(pair.First); } } var xPath = xPathBuf.ToString(); if ((ExecutionPathDebugLog.IsEnabled) && (Log.IsDebugEnabled)) { Log.Debug(".parse XPath for property '" + propertyName + "' is expression=" + xPath); } // Compile assembled XPath expression if (Log.IsDebugEnabled) { Log.Debug("Compiling XPath expression '" + xPath + "' for property '" + propertyName + "' using namespace context :" + ctx); } XPathExpression expr; try { expr = XPathExpression.Compile(xPath, ctx); } catch (XPathException e) { String detail = "Error constructing XPath expression from property expression '" + propertyName + "' expression '" + xPath + "'"; if (e.Message != null) { throw new EPException(detail + " :" + e.Message, e); } throw new EPException(detail, e); } // get type var item = property.GetPropertyTypeSchema(rootComplexElement, eventAdapterService); if ((item == null) && (!isDynamic)) { return(null); } var resultType = isDynamic ? typeof(XmlNode) : SchemaUtil.ToReturnType(item); FragmentFactory fragmentFactory = null; if (isAllowFragment) { fragmentFactory = new FragmentFactoryDOMGetter(eventAdapterService, xmlEventType, propertyName); } return(new XPathPropertyGetter(propertyName, xPath, expr, pair.Second, resultType, fragmentFactory)); }
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; }
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); }
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 Object CoerceProperty(String propertyName, Type containingType, Object value, Type type, EngineImportService engineImportService, bool forceNumeric, bool includeClassNameInEx) { if (value is ExprNode && type != typeof(ExprNode)) { if (value is ExprIdentNode) { var identNode = (ExprIdentNode)value; Property prop; try { prop = PropertyParser.ParseAndWalk(identNode.FullUnresolvedName); } catch (Exception ex) { throw new ExprValidationException("Failed to parse property '" + identNode.FullUnresolvedName + "'"); } if (!(prop is MappedProperty)) { throw new ExprValidationException("Unrecognized property '" + identNode.FullUnresolvedName + "'"); } var mappedProperty = (MappedProperty)prop; if (mappedProperty.PropertyNameAtomic.ToLower() == ENVIRONMENT_PROPERTIES_NAME) { return(Environment.GetEnvironmentVariable(mappedProperty.Key)); } } else { var exprNode = (ExprNode)value; var evaluator = exprNode.ExprEvaluator; if (evaluator == null) { throw new ExprValidationException("Failed to evaluate expression '" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(exprNode) + "'"); } value = evaluator.Evaluate(new EvaluateParams(null, true, null)); } } if (value == null) { return(null); } if (value.GetType() == type) { return(value); } if (value.GetType().IsAssignmentCompatible(type)) { if (forceNumeric && value.GetBoxedType() != type.GetBoxedType() && type.IsNumeric() && value.GetType().IsNumeric()) { value = CoercerFactory.CoerceBoxed(value, type.GetBoxedType()); } return(value); } if (TypeHelper.IsSubclassOrImplementsInterface(value.GetType(), type)) { return(value); } if (type.IsArray) { if (!(value.GetType().IsGenericCollection())) { string detail = "expects an array but receives a value of type " + value.GetType().FullName; throw new ExprValidationException(GetExceptionText(propertyName, containingType, includeClassNameInEx, detail)); } var items = value.UnwrapIntoArray <object>(); var coercedArray = Array.CreateInstance(type.GetElementType(), items.Length); for (var i = 0; i < items.Length; i++) { var coercedValue = CoerceProperty(propertyName + " (array element)", type, items[i], type.GetElementType(), engineImportService, false, includeClassNameInEx); coercedArray.SetValue(coercedValue, i); } return(coercedArray); } if (!(value is Map)) { string detail = "expects an " + TypeHelper.GetTypeNameFullyQualPretty(type) + " but receives a value of type " + value.GetType().FullName; throw new ExprValidationException(GetExceptionText(propertyName, containingType, includeClassNameInEx, detail)); } var props = (IDictionary <String, Object>)value; return(InstantiatePopulateObject(props, type, engineImportService)); }
private EventPropertyGetter DoResolvePropertyGetter(String propertyExpression, bool allowSimpleProperties) { EventPropertyGetter getter = _propertyGetterCache.Get(propertyExpression); if (getter != null) { return(getter); } if (!allowSimpleProperties) { // see if this is an indexed property int index = ASTUtil.UnescapedIndexOfDot(propertyExpression); if (index == -1) { // parse, can be an indexed property Property property = PropertyParser.ParseAndWalk(propertyExpression); if (!property.IsDynamic) { if (!(property is IndexedProperty)) { return(null); } var indexedProp = (IndexedProperty)property; getter = PropertyGetters.Get(indexedProp.PropertyNameAtomic); if (null == getter) { return(null); } EventPropertyDescriptor descriptor = PropertyDescriptorMap.Get(indexedProp.PropertyNameAtomic); if (descriptor == null) { return(null); } if (!descriptor.IsIndexed) { return(null); } if (descriptor.PropertyType == typeof(XmlNodeList)) { FragmentFactory fragmentFactory = new FragmentFactoryDOMGetter( EventAdapterService, this, indexedProp.PropertyNameAtomic); return(new XPathPropertyArrayItemGetter(getter, indexedProp.Index, fragmentFactory)); } if (descriptor.PropertyType == typeof(string)) { FragmentFactory fragmentFactory = new FragmentFactoryDOMGetter( EventAdapterService, this, indexedProp.PropertyNameAtomic); return(new XPathPropertyArrayItemGetter(getter, indexedProp.Index, fragmentFactory)); } } } } if (!_isPropertyExpressionXPath) { Property prop = PropertyParser.ParseAndWalk(propertyExpression); bool isDynamic = prop.IsDynamic; if (!isDynamic) { SchemaItem item = prop.GetPropertyTypeSchema(_schemaModelRoot, EventAdapterService); if (item == null) { return(null); } getter = prop.GetGetterDOM(_schemaModelRoot, EventAdapterService, this, propertyExpression); if (getter == null) { return(null); } Type returnType = SchemaUtil.ToReturnType(item); if ((returnType != typeof(XmlNode)) && (returnType != typeof(XmlNodeList))) { if (!returnType.IsArray) { getter = new DOMConvertingGetter(propertyExpression, (DOMPropertyGetter)getter, returnType); } else { getter = new DOMConvertingArrayGetter((DOMPropertyGetter)getter, returnType.GetElementType()); } } } else { return(prop.GetGetterDOM()); } } else { bool allowFragments = !ConfigurationEventTypeXMLDOM.IsXPathPropertyExpr; getter = SchemaXMLPropertyParser.GetXPathResolution( propertyExpression, NamespaceContext, RootElementName, _rootElementNamespace, _schemaModel, EventAdapterService, this, allowFragments, ConfigurationEventTypeXMLDOM.DefaultNamespace); } _propertyGetterCache.Put(propertyExpression, getter); return(getter); }