예제 #1
0
 public ContextControllerKeyedFactoryForge(
     ContextControllerFactoryEnv ctx,
     ContextSpecKeyed detail)
     : base(ctx)
 {
     this.detail = detail;
 }
예제 #2
0
        protected internal static Type[] ValidateContextDesc(
            string contextName,
            ContextSpecKeyed partitionSpec)
        {
            if (partitionSpec.Items.IsEmpty()) {
                throw new ExprValidationException("Empty list of partition items");
            }

            // verify properties exist
            foreach (var item in partitionSpec.Items) {
                var type = item.FilterSpecCompiled.FilterForEventType;
                foreach (var property in item.PropertyNames) {
                    var getter = type.GetGetter(property);
                    if (getter == null) {
                        throw new ExprValidationException(
                            "For context '" +
                            contextName +
                            "' property name '" +
                            property +
                            "' not found on type " +
                            type.Name);
                    }
                }
            }

            // verify property number and types compatible
            var firstItem = partitionSpec.Items[0];
            if (partitionSpec.Items.Count > 1) {
                // verify the same filter event type is only listed once

                for (var i = 0; i < partitionSpec.Items.Count; i++) {
                    var compareTo = partitionSpec.Items[i].FilterSpecCompiled.FilterForEventType;

                    for (var j = 0; j < partitionSpec.Items.Count; j++) {
                        if (i == j) {
                            continue;
                        }

                        EventType compareFrom = partitionSpec.Items[j].FilterSpecCompiled.FilterForEventType;
                        if (compareFrom == compareTo) {
                            throw new ExprValidationException(
                                "For context '" +
                                contextName +
                                "' the event type '" +
                                compareFrom.Name +
                                "' is listed twice");
                        }

                        if (EventTypeUtility.IsTypeOrSubTypeOf(compareFrom, compareTo) ||
                            EventTypeUtility.IsTypeOrSubTypeOf(compareTo, compareFrom)) {
                            throw new ExprValidationException(
                                "For context '" +
                                contextName +
                                "' the event type '" +
                                compareFrom.Name +
                                "' is listed twice: Event type '" +
                                compareFrom.Name +
                                "' is a subtype or supertype of event type '" +
                                compareTo.Name +
                                "'");
                        }
                    }
                }

                // build property type information
                var names = new string[firstItem.PropertyNames.Count];
                var types = new Type[firstItem.PropertyNames.Count];
                var typesBoxed = new Type[firstItem.PropertyNames.Count];
                for (var i = 0; i < firstItem.PropertyNames.Count; i++) {
                    var property = firstItem.PropertyNames[i];
                    names[i] = property;
                    types[i] = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property);
                    typesBoxed[i] = types[i].GetBoxedType();
                }

                // compare property types and numbers
                for (var item = 1; item < partitionSpec.Items.Count; item++) {
                    ContextSpecKeyedItem nextItem = partitionSpec.Items[item];

                    // compare number of properties
                    if (nextItem.PropertyNames.Count != types.Length) {
                        throw new ExprValidationException(
                            "For context '" +
                            contextName +
                            "' expected the same number of property names for each event type, found " +
                            types.Length +
                            " properties for event type '" +
                            firstItem.FilterSpecCompiled.FilterForEventType.Name +
                            "' and " +
                            nextItem.PropertyNames.Count +
                            " properties for event type '" +
                            nextItem.FilterSpecCompiled.FilterForEventType.Name +
                            "'");
                    }

                    // compare property types
                    for (var i = 0; i < nextItem.PropertyNames.Count; i++) {
                        var property = nextItem.PropertyNames[i];
                        var type = nextItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property)
                            .GetBoxedType();
                        var typeBoxed = type.GetBoxedType();
                        var left = TypeHelper.IsSubclassOrImplementsInterface(typeBoxed, typesBoxed[i]);
                        var right = TypeHelper.IsSubclassOrImplementsInterface(typesBoxed[i], typeBoxed);
                        if (typeBoxed != typesBoxed[i] && !left && !right) {
                            throw new ExprValidationException(
                                "For context '" +
                                contextName +
                                "' for context '" +
                                contextName +
                                "' found mismatch of property types, property '" +
                                names[i] +
                                "' of type '" +
                                types[i].CleanName() +
                                "' compared to property '" +
                                property +
                                "' of type '" +
                                typeBoxed.CleanName() +
                                "'");
                        }
                    }
                }
            }

            var propertyTypes = new Type[firstItem.PropertyNames.Count];
            for (var i = 0; i < firstItem.PropertyNames.Count; i++) {
                var property = firstItem.PropertyNames[i];
                propertyTypes[i] = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property);
            }

            return propertyTypes;
        }