Beispiel #1
0
        /// <summary>
        ///     NOTE: Code-generation-invoked method, method name and parameter order matters
        ///     Returns the fragment for dynamic properties.
        /// </summary>
        /// <param name="object">to inspect</param>
        /// <param name="eventBeanTypedEventFactory">factory for event beans and event types</param>
        /// <param name="beanEventTypeFactory">bean factory</param>
        /// <returns>fragment</returns>
        public static object GetFragmentDynamic(
            object @object,
            EventBeanTypedEventFactory eventBeanTypedEventFactory,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            if (@object == null) {
                return null;
            }

            BeanEventType fragmentEventType = null;
            var isArray = false;
            var objectType = @object.GetType();
            if (objectType.IsArray) {
                if (objectType.GetElementType().IsFragmentableType()) {
                    isArray = true;
                    fragmentEventType = beanEventTypeFactory.GetCreateBeanType(objectType.GetElementType(), false);
                }
            }
            else {
                if (objectType.IsFragmentableType()) {
                    fragmentEventType = beanEventTypeFactory.GetCreateBeanType(objectType, false);
                }
            }

            if (fragmentEventType == null) {
                return null;
            }

            if (isArray) {
                var objectArray = (Array) @object;
                var len = objectArray.Length;
                var events = new EventBean[len];
                var countFilled = 0;

                for (var i = 0; i < len; i++) {
                    var element = objectArray.GetValue(i);
                    if (element == null) {
                        continue;
                    }

                    events[countFilled] = eventBeanTypedEventFactory.AdapterForTypedObject(element, fragmentEventType);
                    countFilled++;
                }

                if (countFilled == len) {
                    return events;
                }

                if (countFilled == 0) {
                    return new EventBean[0];
                }

                var returnVal = new EventBean[countFilled];
                Array.Copy(events, 0, returnVal, 0, countFilled);
                return returnVal;
            }

            return eventBeanTypedEventFactory.AdapterForTypedObject(@object, fragmentEventType);
        }
Beispiel #2
0
        public GenericPropertyDesc GetPropertyTypeGeneric(
            BeanEventType eventType,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            GenericPropertyDesc result = null;

            bool publicFields = eventType.Stem.IsPublicFields;

            var properties = Properties;
            var propertiesCount = properties.Count;
            for (var ii = 0; ii < propertiesCount; ii++) {
                var property = properties[ii];
                result = property.GetPropertyTypeGeneric(eventType, beanEventTypeFactory);

                if (result == null) {
                    // property not found, return null
                    return null;
                }

                if (ii < (propertiesCount - 1)) {
                    // Map cannot be used to further nest as the type cannot be determined
                    if (result.GenericType.IsGenericStringDictionary()) {
                        return null;
                    }

                    if (result.GenericType.IsArray) {
                        return null;
                    }

                    eventType = beanEventTypeFactory.GetCreateBeanType(result.GenericType, publicFields);
                }
            }

            return result;
        }
Beispiel #3
0
        public EventPropertyGetterSPI GetGetter(
            BeanEventType eventType,
            EventBeanTypedEventFactory eventBeanTypedEventFactory,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            IList<EventPropertyGetter> getters = new List<EventPropertyGetter>();

            Property lastProperty = null;
            bool publicFields = eventType.Stem.IsPublicFields;

            var properties = Properties;
            var propertiesCount = properties.Count;

            for (var ii = 0; ii < propertiesCount; ii++) {
                var property = properties[ii];
                lastProperty = property;
                EventPropertyGetter getter = property.GetGetter(
                    eventType,
                    eventBeanTypedEventFactory,
                    beanEventTypeFactory);
                if (getter == null) {
                    return null;
                }

                if (ii < (propertiesCount - 1)) {
                    var clazz = property.GetPropertyType(eventType, beanEventTypeFactory);
                    if (clazz == null) {
                        // if the property is not valid, return null
                        return null;
                    }

                    // Map cannot be used to further nest as the type cannot be determined
                    if (clazz.IsGenericDictionary()) {
                        return null;
                    }

                    if (clazz.IsArray) {
                        return null;
                    }

                    eventType = beanEventTypeFactory.GetCreateBeanType(clazz, publicFields);
                }

                getters.Add(getter);
            }

            var finalPropertyType = lastProperty.GetPropertyTypeGeneric(eventType, beanEventTypeFactory);
            return new NestedPropertyGetter(
                getters,
                eventBeanTypedEventFactory,
                finalPropertyType.GenericType,
                finalPropertyType.Generic,
                beanEventTypeFactory);
        }
Beispiel #4
0
 private void DetermineFragmentable()
 {
     if (_fragmentEventType == null) {
         if (_fragmentClassType.IsFragmentableType()) {
             _fragmentEventType = _beanEventTypeFactory.GetCreateBeanType(_fragmentClassType, false);
         }
         else {
             _isFragmentable = false;
         }
     }
 }
Beispiel #5
0
        public Type GetPropertyType(
            BeanEventType eventType,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            Type result = null;
            var boxed = false;

            var properties = Properties;
            var propertiesCount = properties.Count;
            for (var ii = 0; ii < propertiesCount; ii++) {
                var property = properties[ii];
                boxed |= !(property is SimpleProperty);
                result = property.GetPropertyType(eventType, beanEventTypeFactory);

                if (result == null) {
                    // property not found, return null
                    return null;
                }

                if (ii < (propertiesCount - 1)) {
                    // Map cannot be used to further nest as the type cannot be determined
                    if (result.IsGenericDictionary()) {
                        return null;
                    }

#if IRRELEVANT
                    if (result.IsArray || result.IsValueType || result.IsBuiltinDataType()) {
                        return null;
                    }
#endif

                    var publicFields = eventType.Stem.IsPublicFields;
                    eventType = beanEventTypeFactory.GetCreateBeanType(result, publicFields);
                }
            }

            return !boxed ? result : result.GetBoxedType();
        }
Beispiel #6
0
        /// <summary>
        ///     Create a fragment event type.
        /// </summary>
        /// <param name="propertyType">property return type</param>
        /// <param name="genericType">property generic type parameter, or null if none</param>
        /// <param name="beanEventTypeFactory">for event types</param>
        /// <param name="publicFields">indicator whether classes are public-field-property-accessible</param>
        /// <returns>fragment type</returns>
        public static FragmentEventType CreateNativeFragmentType(
            Type propertyType,
            Type genericType,
            BeanEventTypeFactory beanEventTypeFactory,
            bool publicFields)
        {
            var isIndexed = false;

            if (propertyType.IsArray) {
                isIndexed = true;
                propertyType = propertyType.GetElementType();
            }
            else if (propertyType.IsGenericDictionary()) {
                // Ignore this - technically enumerable
            }
            else if (propertyType.IsGenericEnumerable()) {
                propertyType = GenericExtensions
                    .FindGenericEnumerationInterface(propertyType)
                    .GetGenericArguments()[0];
                isIndexed = true;

#if false
                if (genericType == null) {
                    return null;
                }

                propertyType = genericType;
#endif
            }

            if (!propertyType.IsFragmentableType()) {
                return null;
            }

            EventType type = beanEventTypeFactory.GetCreateBeanType(propertyType, publicFields);
            return new FragmentEventType(type, isIndexed, true);
        }
Beispiel #7
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);
        }
Beispiel #8
0
        public virtual MapEventPropertyGetter GetGetterMap(
            IDictionary<string, object> optionalMapPropTypes,
            EventBeanTypedEventFactory eventBeanTypedEventFactory,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            IList<EventPropertyGetterSPI> getters = new List<EventPropertyGetterSPI>();
            var currentDictionary = optionalMapPropTypes;

            var count = 0;
            var properties = Properties;
            var propertiesCount = properties.Count;

            for (var ii = 0; ii < propertiesCount; ii++) {
                count++;
                var property = properties[ii];

                // manufacture a getter for getting the item out of the map
                EventPropertyGetterSPI getter = property.GetGetterMap(
                    currentDictionary,
                    eventBeanTypedEventFactory,
                    beanEventTypeFactory);
                if (getter == null) {
                    return null;
                }

                getters.Add(getter);

                var theBase = (PropertyBase) property;
                var propertyName = theBase.PropertyNameAtomic;

                // For the next property if there is one, check how to property type is defined
                if (ii >= (propertiesCount - 1)) {
                    continue;
                }

                if (currentDictionary != null) {
                    // check the type that this property will return
                    var propertyReturnType = currentDictionary.Get(propertyName);

                    if (propertyReturnType == null) {
                        currentDictionary = null;
                    }

                    if (propertyReturnType != null) {
                        if (propertyReturnType is IDictionary<string, object> mapReturnType) {
                            currentDictionary = mapReturnType;
                        }
                        else if (propertyReturnType.Equals(typeof(IDictionary<string, object>))) {
                            currentDictionary = null;
                        }
                        else if (propertyReturnType is TypeBeanOrUnderlying) {
                            var innerType = ((TypeBeanOrUnderlying) propertyReturnType).EventType;
                            if (innerType == null) {
                                return null;
                            }

                            var remainingProps = ToPropertyEPL(Properties, count);
                            var getterInner = ((EventTypeSPI) innerType).GetGetterSPI(remainingProps);
                            if (getterInner == null) {
                                return null;
                            }

                            getters.Add(getterInner);
                            break; // the single getter handles the rest
                        }
                        else if (propertyReturnType is TypeBeanOrUnderlying[]) {
                            var innerType = ((TypeBeanOrUnderlying[]) propertyReturnType)[0].EventType;
                            if (innerType == null) {
                                return null;
                            }

                            var remainingProps = ToPropertyEPL(Properties, count);
                            var getterInner = ((EventTypeSPI) innerType).GetGetterSPI(remainingProps);
                            if (getterInner == null) {
                                return null;
                            }

                            getters.Add(getterInner);
                            break; // the single getter handles the rest
                        }
                        else if (propertyReturnType is EventType) {
                            var innerType = (EventType) propertyReturnType;
                            var remainingProps = ToPropertyEPL(Properties, count);
                            var getterInner = ((EventTypeSPI) innerType).GetGetterSPI(remainingProps);
                            if (getterInner == null) {
                                return null;
                            }

                            getters.Add(getterInner);
                            break; // the single getter handles the rest
                        }
                        else {
                            // treat the return type of the map property as an object
                            var ponoType = (Type) propertyReturnType;
                            if (!ponoType.IsArray) {
                                var beanType = beanEventTypeFactory.GetCreateBeanType(ponoType, false);
                                var remainingProps = ToPropertyEPL(Properties, count);
                                var getterInner = beanType.GetGetterSPI(remainingProps);
                                if (getterInner == null) {
                                    return null;
                                }

                                getters.Add(getterInner);
                                break; // the single getter handles the rest
                            }
                            else {
                                var componentType = ponoType.GetElementType();
                                var beanType = beanEventTypeFactory.GetCreateBeanType(componentType, false);
                                var remainingProps = ToPropertyEPL(Properties, count);
                                var getterInner = beanType.GetGetterSPI(remainingProps);
                                if (getterInner == null) {
                                    return null;
                                }

                                getters.Add(getterInner);
                                break; // the single getter handles the rest
                            }
                        }
                    }
                }
            }

            var hasNonmapGetters = false;
            for (var i = 0; i < getters.Count; i++) {
                if (!(getters[i] is MapEventPropertyGetter)) {
                    hasNonmapGetters = true;
                }
            }

            if (!hasNonmapGetters) {
                return new MapNestedPropertyGetterMapOnly(getters, eventBeanTypedEventFactory);
            }

            return new MapNestedPropertyGetterMixedType(getters);
        }
Beispiel #9
0
        public virtual Type GetPropertyTypeMap(
            IDictionary<string, object> optionalMapPropTypes,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            var currentDictionary = optionalMapPropTypes;

            var count = 0;
            var properties = Properties;
            var propertiesCount = properties.Count;

            for (var ii = 0; ii < propertiesCount; ii++) {
                count++;
                var property = properties[ii];
                var theBase = (PropertyBase) property;
                var propertyName = theBase.PropertyNameAtomic;

                object nestedType = null;
                if (currentDictionary != null) {
                    nestedType = currentDictionary.Get(propertyName);
                }

                if (nestedType == null) {
                    if (property is DynamicProperty) {
                        return typeof(object);
                    }

                    return null;
                }

                if (ii >= (propertiesCount - 1)) {
                    if (nestedType is Type) {
                        return (Type) nestedType;
                    }

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

                if (Equals(nestedType, typeof(IDictionary<string, object>))) {
                    return typeof(object);
                }

                if (nestedType is Type ponoType) {
                    if (!ponoType.IsArray) {
                        var beanType = beanEventTypeFactory.GetCreateBeanType(ponoType, false);
                        var remainingProps = ToPropertyEPL(Properties, count);
                        return beanType.GetPropertyType(remainingProps);
                    }

                    if (property is IndexedProperty) {
                        var componentType = ponoType.GetElementType();
                        var beanType = beanEventTypeFactory.GetCreateBeanType(componentType, false);
                        var remainingProps = ToPropertyEPL(Properties, count);
                        return beanType.GetPropertyType(remainingProps);
                    }
                }

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

                    var remainingProps = ToPropertyEPL(Properties, count);
                    return innerType.GetPropertyType(remainingProps);
                }

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

                    var remainingProps = ToPropertyEPL(Properties, count);
                    return innerType.GetPropertyType(remainingProps);
                }

                if (nestedType is EventType) {
                    // property type is the name of a map event type
                    var innerType = (EventType) nestedType;
                    var remainingProps = ToPropertyEPL(Properties, count);
                    return innerType.GetPropertyType(remainingProps);
                }

                if (!(nestedType is IDictionary<string, object>)) {
                    var message = "Nestable map type configuration encountered an unexpected value type of '" +
                                  nestedType.GetType() +
                                  "' for property '" +
                                  propertyName +
                                  "', expected Type or Map<string, object> as value type";
                    throw new PropertyAccessException(message);
                }

                currentDictionary = (IDictionary<string, object>) nestedType;
            }

            throw new IllegalStateException("Unexpected end of nested property");
        }
Beispiel #10
0
        private static VariableMetaData GetTypeInfo(
            string variableName,
            string variableModuleName,
            NameAccessModifier variableVisibility,
            string optionalContextName,
            NameAccessModifier? optionalContextVisibility,
            string optionalContextModule,
            ClassIdentifierWArray variableTypeWArray,
            bool preconfigured,
            bool constant,
            bool compileTimeConstant,
            object valueAsProvided,
            ImportService importService,
            ExtensionClass extensionClass,
            EventBeanTypedEventFactory eventBeanTypedEventFactory,
            EventTypeRepositoryImpl eventTypeRepositoryPreconfigured,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            // Determine the variable type
            var primitiveType = TypeHelper.GetPrimitiveTypeForName(variableTypeWArray.ClassIdentifier);
            var type = TypeHelper.GetTypeForSimpleName(variableTypeWArray.ClassIdentifier).GetBoxedType();
            Type arrayType = null;
            EventType eventType = null;
            if (type == null) {
                if (variableTypeWArray.ClassIdentifier.Equals("object", StringComparison.InvariantCultureIgnoreCase)) {
                    type = TypeHelper.GetArrayType(typeof(object), variableTypeWArray.ArrayDimensions);
                }

                if (type == null) {
                    eventType = eventTypeRepositoryPreconfigured.GetTypeByName(variableTypeWArray.ClassIdentifier);
                    if (eventType != null) {
                        type = eventType.UnderlyingType;
                    }
                }

                ImportException lastException = null;
                if (type == null) {
                    try {
                        type = importService.ResolveClass(variableTypeWArray.ClassIdentifier, false, extensionClass);
                        type = TypeHelper.GetArrayType(type, variableTypeWArray.ArrayDimensions);
                    }
                    catch (ImportException e) {
                        Log.Debug("Not found '" + type + "': " + e.Message, e);
                        lastException = e;
                        // expected
                    }
                }

                if (type == null) {
                    throw new VariableTypeException(
                        "Cannot create variable '" +
                        variableName +
                        "', type '" +
                        variableTypeWArray.ClassIdentifier +
                        "' is not a recognized type",
                        lastException);
                }

                if (variableTypeWArray.ArrayDimensions > 0 && eventType != null) {
                    throw new VariableTypeException(
                        "Cannot create variable '" +
                        variableName +
                        "', type '" +
                        variableTypeWArray.ClassIdentifier +
                        "' cannot be declared as an array type as it is an event type",
                        lastException);
                }
            }
            else {
                if (variableTypeWArray.ArrayDimensions > 0) {
                    if (variableTypeWArray.IsArrayOfPrimitive) {
                        if (primitiveType == null) {
                            throw new VariableTypeException(
                                "Cannot create variable '" +
                                variableName +
                                "', type '" +
                                variableTypeWArray.ClassIdentifier +
                                "' is not a primitive type");
                        }

                        arrayType = TypeHelper.GetArrayType(primitiveType, variableTypeWArray.ArrayDimensions);
                    }
                    else {
                        arrayType = TypeHelper.GetArrayType(type, variableTypeWArray.ArrayDimensions);
                    }
                }
            }

            if (eventType == null &&
                !type.IsBuiltinDataType() &&
                type != typeof(object) &&
                !type.IsArray &&
                !type.IsEnum) {
                if (variableTypeWArray.ArrayDimensions > 0) {
                    throw new VariableTypeException(
                        "Cannot create variable '" +
                        variableName +
                        "', type '" +
                        variableTypeWArray.ClassIdentifier +
                        "' cannot be declared as an array, only scalar types can be array");
                }

                eventType = beanEventTypeFactory.GetCreateBeanType(type, false);
            }

            if (arrayType != null) {
                type = arrayType;
            }

            var coerced = GetCoercedValue(valueAsProvided, eventType, variableName, type, eventBeanTypedEventFactory);
            return new VariableMetaData(
                variableName,
                variableModuleName,
                variableVisibility,
                optionalContextName,
                optionalContextVisibility,
                optionalContextModule,
                type,
                eventType,
                preconfigured,
                constant,
                compileTimeConstant,
                coerced,
                true);
        }