2 // Copyright (C) 2010 Novell Inc. http://novell.com
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 using System.Collections.Generic;
26 using System.ComponentModel;
29 using System.Reflection;
31 using System.Windows.Markup;
33 using System.Xaml.Schema;
38 internal class ValueSerializerContext : IValueSerializerContext, IXamlSchemaContextProvider
40 XamlNameResolver name_resolver = new XamlNameResolver ();
41 XamlTypeResolver type_resolver;
42 NamespaceResolver namespace_resolver;
43 PrefixLookup prefix_lookup;
44 XamlSchemaContext sctx;
45 IAmbientProvider ambient_provider;
47 public ValueSerializerContext (PrefixLookup prefixLookup, XamlSchemaContext schemaContext, IAmbientProvider ambientProvider)
49 if (prefixLookup == null)
50 throw new ArgumentNullException ("prefixLookup");
51 if (schemaContext == null)
52 throw new ArgumentNullException ("schemaContext");
53 prefix_lookup = prefixLookup;
54 namespace_resolver = new NamespaceResolver (prefix_lookup.Namespaces);
55 type_resolver = new XamlTypeResolver (namespace_resolver, schemaContext);
57 ambient_provider = ambientProvider;
60 public object GetService (Type serviceType)
62 if (serviceType == typeof (INamespacePrefixLookup))
64 if (serviceType == typeof (IXamlNamespaceResolver))
65 return namespace_resolver;
66 if (serviceType == typeof (IXamlNameResolver))
68 if (serviceType == typeof (IXamlNameProvider))
70 if (serviceType == typeof (IXamlTypeResolver))
72 if (serviceType == typeof (IAmbientProvider))
73 return ambient_provider;
74 if (serviceType == typeof (IXamlSchemaContextProvider))
79 XamlSchemaContext IXamlSchemaContextProvider.SchemaContext {
83 public IContainer Container {
84 get { throw new NotImplementedException (); }
86 public object Instance {
87 get { throw new NotImplementedException (); }
89 public PropertyDescriptor PropertyDescriptor {
90 get { throw new NotImplementedException (); }
92 public void OnComponentChanged ()
94 throw new NotImplementedException ();
96 public bool OnComponentChanging ()
98 throw new NotImplementedException ();
100 public ValueSerializer GetValueSerializerFor (PropertyDescriptor descriptor)
102 throw new NotImplementedException ();
104 public ValueSerializer GetValueSerializerFor (Type type)
106 throw new NotImplementedException ();
110 internal class XamlTypeResolver : IXamlTypeResolver
112 NamespaceResolver ns_resolver;
113 XamlSchemaContext schema_context;
115 public XamlTypeResolver (NamespaceResolver namespaceResolver, XamlSchemaContext schemaContext)
117 ns_resolver = namespaceResolver;
118 schema_context = schemaContext;
121 public Type Resolve (string typeName)
123 var tn = XamlTypeName.Parse (typeName, ns_resolver);
124 var xt = schema_context.GetXamlType (tn);
125 return xt != null ? xt.UnderlyingType : null;
129 internal class NamespaceResolver : IXamlNamespaceResolver
131 public NamespaceResolver (IList<NamespaceDeclaration> source)
133 this.source = source;
136 IList<NamespaceDeclaration> source;
138 public string GetNamespace (string prefix)
140 foreach (var nsd in source)
141 if (nsd.Prefix == prefix)
142 return nsd.Namespace;
146 public IEnumerable<NamespaceDeclaration> GetNamespacePrefixes ()
152 internal class AmbientProvider : IAmbientProvider
154 List<AmbientPropertyValue> values = new List<AmbientPropertyValue> ();
155 Stack<AmbientPropertyValue> live_stack = new Stack<AmbientPropertyValue> ();
157 public void Push (AmbientPropertyValue v)
168 public IEnumerable<object> GetAllAmbientValues (params XamlType [] types)
170 return GetAllAmbientValues (null, false, types);
173 public IEnumerable<AmbientPropertyValue> GetAllAmbientValues (IEnumerable<XamlType> ceilingTypes, params XamlMember [] properties)
175 return GetAllAmbientValues (ceilingTypes, false, null, properties);
178 public IEnumerable<AmbientPropertyValue> GetAllAmbientValues (IEnumerable<XamlType> ceilingTypes, bool searchLiveStackOnly, IEnumerable<XamlType> types, params XamlMember [] properties)
180 return DoGetAllAmbientValues (ceilingTypes, searchLiveStackOnly, types, properties).ToList ();
183 IEnumerable<AmbientPropertyValue> DoGetAllAmbientValues (IEnumerable<XamlType> ceilingTypes, bool searchLiveStackOnly, IEnumerable<XamlType> types, params XamlMember [] properties)
185 if (searchLiveStackOnly) {
186 if (live_stack.Count > 0) {
187 // pop, call recursively, then push back.
188 var p = live_stack.Pop ();
189 if (p.RetrievedProperty != null && ceilingTypes != null && ceilingTypes.Contains (p.RetrievedProperty.Type))
191 if (DoesAmbientPropertyApply (p, types, properties))
194 foreach (var i in GetAllAmbientValues (ceilingTypes, searchLiveStackOnly, types, properties))
200 // FIXME: does ceilingTypes matter?
201 foreach (var p in values)
202 if (DoesAmbientPropertyApply (p, types, properties))
207 bool DoesAmbientPropertyApply (AmbientPropertyValue p, IEnumerable<XamlType> types, params XamlMember [] properties)
209 if (types == null || !types.Any () || types.Any (xt => xt.UnderlyingType != null && xt.UnderlyingType.IsInstanceOfType (p.Value)))
210 if (properties == null || !properties.Any () || properties.Contains (p.RetrievedProperty))
215 public object GetFirstAmbientValue (params XamlType [] types)
217 foreach (var obj in GetAllAmbientValues (types))
222 public AmbientPropertyValue GetFirstAmbientValue (IEnumerable<XamlType> ceilingTypes, params XamlMember [] properties)
224 foreach (var obj in GetAllAmbientValues (ceilingTypes, properties))