public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                Predicate <PropertyTreeNavigator> predicate = ImplicitDirective(target, "source");

                var node = children.FindAndRemove(predicate).FirstOrDefault();

                if (node != null)
                {
                    IServiceProvider serviceProvider = parent.GetBasicServices(node);
                    var uriContext = node as IUriContext;
                    TargetSourceDirective ss;
                    ss = parent.DirectiveFactory.CreateTargetSource(node, uriContext);

                    if (ss != null)
                    {
                        try {
                            target = target.BindStreamingSource(ss, serviceProvider);
                        } catch (PropertyTreeException) {
                            throw;
                        } catch (Exception ex) {
                            if (ex.IsCriticalException())
                            {
                                throw;
                            }

                            parent._errors.FailedToLoadFromSource(ss.Uri, ex, node.FileLocation);
                        }
                    }
                }

                return(target);
            }
Example #2
0
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                Type             type            = target.ComponentType ?? typeof(object);
                Type             concreteClass   = type.GetConcreteClass();
                QualifiedName    name            = self.QualifiedName;
                IServiceProvider serviceProvider = parent;

                if (concreteClass != null && type != concreteClass)
                {
                    target.BindTargetType(TypeReference.FromType(concreteClass), serviceProvider);
                }
                else if (type.IsComposable())
                {
                    target.BindTargetProvider(name, null, serviceProvider);
                }

                if (target.Component == null && !target.ComponentType.GetTypeInfo().IsSealed)
                {
                    // TODO This predicate is probably too loose
                    Predicate <PropertyTreeNavigator> predicate = t => t.Name == "type";
                    var node = children.FindAndRemove(predicate).FirstOrDefault();
                    ApplyType(parent, target, node);
                }
                return(PickBuilderTypeIfAvailable(target));
            }
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                target.ApplyUriContextToProperties(self.BaseUri);

                children.FindAndRemove(t => Apply(parent, target, t)).All();
                return(target);
            }
Example #4
0
        public override PropertyTreeMetaObject BindInitializer(Expression expression, IExpressionContext context, IServiceProvider serviceProvider)
        {
            var values = expression.Evaluate(context);

            if (values == null)
            {
                return(this);
            }
            if (!(values is IEnumerable))
            {
                values = new [] { values };
            }

            var myValues = ReflectionMetaObject.GetAddonElements((IEnumerable)values);
            var addon    = ReflectionMetaObject.FindAddonMethod(ComponentType, myValues);

            if (addon == null)
            {
                var errors = serviceProvider.GetServiceOrDefault(PropertyTreeBinderErrors.Default);
                errors.NoAddMethodSupported(component.GetType(), PropertyTreeBinderImpl.FindFileLocation(serviceProvider));
                return(this);
            }
            foreach (var item in myValues)
            {
                addon.Invoke(Component, new object[] {
                    item
                });
            }
            return(this);
        }
            private PropertyTreeMetaObject DoOperatorBind(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator navigator, OperatorDefinition op)
            {
                OperatorDefinition addon = op;

                if (addon.DefaultParameter != null) {
                    Type itemType = ((PropertyTreeFactoryDefinition) addon).OutputType;
                    // TODO Use service activation (we have the output type)

                    var item = target.CreateChild(itemType);
                    var model = parent.Bind(item, navigator, null);
                    var args = new Dictionary<string, PropertyTreeMetaObject>
                    {
                        { addon.DefaultParameter.Name, model }
                    };

                    try {
                        target.BindAddChild(op, args);

                    } catch (Exception ex) {
                        if (ex.IsCriticalException())
                            throw;

                        parent.errors.BadAddChild(target.ComponentType, ex, navigator.FileLocation);
                    }

                } else {
                    // TODO The number and kinds of arguments are constrained.  This should probably
                    // be enforced within schema operator reflection (spec)

                    Action<IReadOnlyDictionary<string, PropertyTreeMetaObject>> func;
                    var children = NodeList.Create(SelectChildren(navigator));

                    switch (addon.OperatorType) {
                        case OperatorType.Add:
                            func = args => {
                                var child = target.BindAddChild(addon, args);

                                if (child.ShouldBindChildren) {
                                    parent.BindChildNodes(child, navigator, children);
                                }
                            };
                            break;

                        case OperatorType.Remove:
                            func = args => target.BindRemoveChild(addon, args);
                            break;

                        case OperatorType.Clear:
                        default:
                            func = args => target.BindClearChildren(addon, args);
                            break;
                    }

                    var services = parent.GetBasicServices(navigator);
                    var args2 = parent.ExtractParameterDictionary(op, target, services, children);
                    func(args2);
                }

                return target;
            }
            private void DoPropertyBind(PropertyTreeBinderImpl parent,
                                        PropertyTreeMetaObject target,
                                        PropertyTreeNavigator navigator,
                                        PropertyDefinition property)
            {
                object ancestor = null;
                PropertyTreeMetaObject ancestorMeta = null;

                if (property.IsExtender) {
                    var ancestorType = property.DeclaringTreeDefinition.SourceClrType;
                    ancestorMeta = target.GetAncestors().Cast<PropertyTreeMetaObject>().FirstOrDefault(
                        t => ancestorType.IsAssignableFrom(t.ComponentType));

                    if (ancestorMeta != null)
                        ancestor = ancestorMeta.Component;
                }

                var component = target.Component;
                PropertyTreeMetaObject propertyTarget = target.CreateChild(property, navigator.QualifiedName, ancestorMeta);

                var services = new PropertyBindContext(
                    component,
                    property,
                    ServiceProvider.Compose(ServiceProvider.FromValue(navigator), parent))
                {
                    LineNumber = navigator.LineNumber,
                    LinePosition = navigator.LinePosition,
                };

                propertyTarget = parent.Bind(propertyTarget, navigator, services);
                target.BindSetMember(property, navigator.QualifiedName, propertyTarget, ancestorMeta, services);
            }
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent,
                                                           PropertyTreeMetaObject target,
                                                           PropertyTreeNavigator self,
                                                           NodeList children)
            {
                Type type = target.ComponentType ?? typeof(object);

                // Select providers
                if (type.IsProviderType())
                {
                    var node = children.FindAndRemove(ImplicitDirective(target, "provider")).FirstOrDefault();

                    if (node != null)
                    {
                        var serviceProvider = parent.GetBasicServices(node);
                        var pro             = parent.DirectiveFactory.CreateTargetProvider(type, node);
                        if (pro != null)
                        {
                            target = target.BindTargetProvider(pro, serviceProvider);
                            return(target);
                        }
                    }
                }

                return(target);
            }
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                IServiceProvider serviceProvider = parent.GetBasicServices(self);
                int lineNumber   = self.LineNumber;
                int linePosition = self.LinePosition;

                return(target.BindFileLocation(lineNumber, linePosition, serviceProvider));
            }
            bool IApplyMemberStep.Apply(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator node)
            {
                var member = target.SelectOperator(ImpliedName(node, target));

                if (member != null) {
                    DoOperatorBind(parent, target, node, member);
                    return true;
                }

                return false;
            }
            bool IApplyMemberStep.Apply(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator node)
            {
                var member = target.SelectOperator(ImpliedName(node, target));

                if (member != null)
                {
                    DoOperatorBind(parent, target, node, member);
                    return(true);
                }

                return(false);
            }
Example #11
0
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                if (target.ShouldConstruct)
                {
                    var ctor = target.GetDefinition().Constructor;

                    if (ctor != null)
                    {
                        return(target.BindConstructor(ctor, Empty <string, PropertyTreeMetaObject> .ReadOnlyDictionary));
                    }
                }
                return(target);
            }
Example #12
0
            private void ApplyType(PropertyTreeBinderImpl parent,
                                   PropertyTreeMetaObject target,
                                   PropertyTreeNavigator node)
            {
                if (node == null)
                {
                    return;
                }

                var serviceProvider = parent.GetBasicServices(node);

                target.BindTargetType(parent.DirectiveFactory.CreateTargetType(node), serviceProvider);
            }
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                QualifiedName name = self.QualifiedName;
                var           ctor = PropertyTreeDefinition.FromType(target.ComponentType).Constructor;

                if (target.ShouldConstruct && ctor != null)
                {
                    OperatorDefinition op = ctor;
                    var args = parent.ExtractParameterDictionary(op, target, parent.GetBasicServices(self), children);

                    target = target.BindConstructor(ctor, args);
                }

                return(target);
            }
Example #14
0
        public override PropertyTreeMetaObject BindStreamingSource(StreamContext input, IServiceProvider serviceProvider)
        {
            var binder = serviceProvider.GetRequiredService <PropertyTreeMetaObjectBinder>();
            var ss     = binder.CreateStreamingSource(this, input, serviceProvider);

            if (ss == null)
            {
                var errors = serviceProvider.GetServiceOrDefault(PropertyTreeBinderErrors.Default);
                errors.CouldNotBindStreamingSource(this.ComponentType, PropertyTreeBinderImpl.FindFileLocation(serviceProvider));
                return(this);
            }

            // Hydrate the existing instance
            ss.Load(input, this.Component);
            return(this);
        }
            bool IApplyMemberStep.Apply(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator node)
            {
                PropertyDefinition prop;
                if (_allowDefault) {
                    prop = target.GetDefinition().DefaultProperty;
                    if (prop == null)
                        return false;

                } else {
                    var im = ImpliedName(node, target);
                    prop = target.SelectProperty(im);
                    if (prop == null || prop.IsIndexer)
                        return false;
                }

                DoPropertyBind(parent, target, node, prop);
                return true;
            }
Example #16
0
        private bool TryAggregation(PropertyTreeMetaObject value,
                                    QualifiedName name,
                                    PropertyDefinition property,
                                    IServiceProvider serviceProvider)
        {
            object current;

            if (!property.TryGetValue(component, null, name, out current))
            {
                return(false);
            }

            var enumerable = value.Component as IEnumerable;

            if (current != null && enumerable != null)
            {
                var items = enumerable;
                if (!ReferenceEquals(current, items) && enumerable.GetEnumerator().MoveNext())
                {
                    MethodInfo mi = FindAddonMethod(current.GetType(), enumerable);

                    if (mi == null)
                    {
                        // Error because aggregation will be needed on read-only properties
                        if (property.IsReadOnly)
                        {
                            var errors = serviceProvider.GetServiceOrDefault(PropertyTreeBinderErrors.Default);
                            errors.NoAddMethodSupported(component.GetType(), PropertyTreeBinderImpl.FindFileLocation(serviceProvider));
                        }
                        return(false);
                    }

                    foreach (var item in items)
                    {
                        mi.Invoke(current, new object[] { item });
                    }
                    // Success because aggregation was applied
                    return(true);
                }
            }
            return(false);
        }
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                Predicate <PropertyTreeNavigator> predicate = ImplicitDirective(target, "base");

                var node = children.FindAndRemove(predicate).FirstOrDefault();

                Uri baseUri;
                IServiceProvider serviceProvider;

                if (node == null)
                {
                    baseUri         = self.BaseUri;
                    serviceProvider = parent;
                }
                else
                {
                    baseUri         = Utility.NewUri(Convert.ToString(node.Value));
                    serviceProvider = parent.GetBasicServices(node);
                }
                return(target.BindBaseUri(baseUri, serviceProvider));
            }
Example #18
0
            public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
            {
                Predicate <PropertyTreeNavigator> predicate = ImplicitDirective(target, "id");

                var node = children.FindAndRemove(predicate).FirstOrDefault();

                if (node == null)
                {
                    node = children.FindAndRemove("name").FirstOrDefault();
                }
                if (node != null)
                {
                    // TODO Handle when a name is duplicated or contains whitespace
                    var    ns = parent.FindNameScope(target);
                    string id = Convert.ToString(node.Value);

                    if (string.IsNullOrEmpty(id))
                    {
                        parent._errors.IdCannotBeBlank(node.FileLocation);
                    }
                    else if (ns.FindName(id) == null)
                    {
                        ns.RegisterName(id, target.Component);
                    }
                    else
                    {
                        parent._errors.IdAlreadyRegistered(id, node.FileLocation);
                    }

                    var nameProperty = target.SelectProperty(NamespaceUri.Default + "name");
                    if (nameProperty != null)
                    {
                        parent.DoPropertyBind(target, node, nameProperty);
                    }
                }

                return(target);
            }
            public override PropertyTreeMetaObject Process(
                PropertyTreeBinderImpl parent,
                PropertyTreeMetaObject target,
                PropertyTreeNavigator self,
                NodeList children)
            {
                if (!(target is UntypedToTypedMetaObject))
                {
                    return(target);
                }

                if (!children.Any())
                {
                    return(target);
                }

                try {
                    // TODO Only supports one child (lame spec)
                    var rootType = target.Root.ComponentType;
                    var types    = children.Select(t => ConvertToType(t, rootType)).ToArray();

                    target = target.BindGenericParameters(types);
                } catch (PropertyTreeException) {
                    throw;
                } catch (Exception ex) {
                    if (ex.IsCriticalException())
                    {
                        throw;
                    }

                    parent._errors.CouldNotBindGenericParameters(target.ComponentType, ex, self.FileLocation);
                }

                parent.Bind(target, children.First(), null);
                children.Clear();
                return(target);
            }
            bool IApplyMemberStep.Apply(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator node)
            {
                PropertyDefinition prop = null;

                if (_allowDefault)
                {
                    var defaultProperties = target.GetDefinition().DefaultProperties;

                    if (defaultProperties.Skip(1).Any())
                    {
                        prop = defaultProperties.FirstOrDefault(p => p.TryGetValue(target.Component, node.QualifiedName));
                    }

                    if (prop == null)
                    {
                        prop = defaultProperties.FirstOrDefault();
                    }

                    if (prop == null)
                    {
                        return(false);
                    }
                }
                else
                {
                    var im = ImpliedName(node, target);
                    prop = target.SelectProperty(im);
                    if (prop == null || prop.IsIndexer)
                    {
                        return(false);
                    }
                }

                parent.DoPropertyBind(target, node, prop);
                return(true);
            }
 public SerializerDirectiveFactory(PropertyTreeBinderImpl parent)
 {
     this.parent = parent;
 }
 public SerializerDirectiveFactory(PropertyTreeBinderImpl parent)
 {
     this.parent = parent;
 }
Example #23
0
        public Dictionary <string, PropertyTreeMetaObject> ExtractParameterDictionary(
            OperatorDefinition op,
            PropertyTreeMetaObject target,
            IServiceProvider serviceProvider,
            NodeList children)
        {
            // Named constructor arguments
            var duplicates = new HashSet <QualifiedName>();
            var mapped     = new Dictionary <QualifiedName, PropertyTreeNavigator>();

            foreach (var child in children)
            {
                // Implicitly map default NS to real
                var impliedName = ImpliedName(child, target);

                if (duplicates.Contains(impliedName))
                {
                    // Duplicates can't bind to parameters (only to param arrays)
                }
                else if (mapped.ContainsKey(impliedName))
                {
                    // Detected a duplicate
                    duplicates.Add(impliedName);
                    mapped.Remove(impliedName);
                }
                else
                {
                    mapped.Add(impliedName, child);
                }
            }

            var args = new Dictionary <string, PropertyTreeMetaObject>(op.Parameters.Count);

            PropertyDefinition myParam         = null;
            List <string>      requiredMissing = new List <string>();

            foreach (PropertyDefinition p in op.Parameters)
            {
                // Fallback to empty ns
                PropertyTreeNavigator nav;
                QualifiedName         impliedName = p.QualifiedName;
                if (p.QualifiedName.Namespace.IsDefault)
                {
                    impliedName = impliedName.ChangeNamespace(op.Namespace);
                }

                if (mapped.TryGetValue(impliedName, out nav))
                {
                    // Binds a parameter required for activating an instance
                    // TODO Should we supply/use attributes from the parameter
                    // and/or corresponding property descriptor?

                    var childContext = target.CreateChild(p.PropertyType);
                    args[p.Name] = Bind(childContext, nav, serviceProvider);
                    children.Remove(nav);
                }
                else if (p.IsOptional)
                {
                    PropertyTreeMetaObject defaultValue;
                    if (p.DefaultValue == null)
                    {
                        defaultValue = PropertyTreeMetaObject.Create(p.PropertyType);
                    }
                    else
                    {
                        defaultValue = PropertyTreeMetaObject.Create(p.DefaultValue);
                    }
                    args[p.Name] = defaultValue;
                }
                else if (p.IsParamArray)
                {
                    myParam = p;
                }

                else if (TypeHelper.IsParameterRequired(p.PropertyType))
                {
                    requiredMissing.Add(Utility.DisplayName(p.QualifiedName));
                }
            }

            if (requiredMissing.Count > 0)
            {
                _errors.RequiredPropertiesMissing(requiredMissing, op, FindFileLocation(serviceProvider));
            }

            if (myParam == null && !target.GetDefinition().DefaultProperties.Any() && duplicates.Any(t => target.SelectProperty(t) != null))
            {
                _errors.DuplicatePropertyName(duplicates, FindFileLocation(serviceProvider));
            }

            // Try param array
            if (myParam != null)
            {
                var all         = new List <object>();
                var elementType = myParam.PropertyType.GetElementType();
                foreach (var kvp in children)
                {
                    // Bind child nodes so tha latebound applies
                    var childrenList = NodeList.Create(PropertyTreeBinderImpl.SelectChildren(kvp));
                    var inline       = BindChildNodes(PropertyTreeMetaObject.Create(elementType), kvp, childrenList);
                    var inlineVal    = inline.Component;
                    all.Add(inlineVal);
                }

                children.Clear();
                var array = Array.CreateInstance(elementType, all.Count);
                ((System.Collections.ICollection)all).CopyTo(array, 0);
                args[myParam.Name] = PropertyTreeMetaObject.Create(array);
            }

            return(args);
        }
Example #24
0
 public abstract PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent,
                                                PropertyTreeMetaObject target,
                                                PropertyTreeNavigator self,
                                                NodeList children);
 public override PropertyTreeMetaObject Process(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator self, NodeList children)
 {
     return(target.BindEndObject(parent));
 }
 // TODO Implement property ordering based on [DependsOn]
 private bool Apply(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator node)
 {
     return(_items.Any(t => t.Apply(parent, target, node)));
 }
            private PropertyTreeMetaObject DoOperatorBind(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator navigator, OperatorDefinition op)
            {
                OperatorDefinition addon = op;

                if (addon.DefaultParameter != null)
                {
                    Type itemType = addon.OutputType;
                    // TODO Use service activation (we have the output type)

                    var item  = target.CreateChild(itemType);
                    var model = parent.Bind(item, navigator, null);
                    var args  = new Dictionary <string, PropertyTreeMetaObject>
                    {
                        { addon.DefaultParameter.Name, model }
                    };

                    try {
                        target.BindAddChild(op, args);
                    } catch (PropertyTreeException) {
                        throw;
                    } catch (Exception ex) {
                        if (ex.IsCriticalException())
                        {
                            throw;
                        }

                        parent._errors.BadAddChild(target.ComponentType, ex, navigator.FileLocation);
                    }
                }
                else
                {
                    // TODO The number and kinds of arguments are constrained.  This should probably
                    // be enforced within schema operator reflection (spec)

                    Action <IReadOnlyDictionary <string, PropertyTreeMetaObject> > func;
                    var children = NodeList.Create(SelectChildren(navigator));

                    switch (addon.OperatorType)
                    {
                    case OperatorType.Add:
                        func = args => {
                            var child = target.BindAddChild(addon, args);

                            if (child.ShouldBindChildren)
                            {
                                parent.BindChildNodes(child, navigator, children);
                            }
                        };
                        break;

                    case OperatorType.Remove:
                        func = args => target.BindRemoveChild(addon, args);
                        break;

                    case OperatorType.Clear:
                    default:
                        func = args => target.BindClearChildren(addon, args);
                        break;
                    }

                    var services = parent.GetBasicServices(navigator);
                    var args2    = parent.ExtractParameterDictionary(op, target, services, children);
                    func(args2);
                }

                return(target);
            }