Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
namespace System.Xaml.Schema
{
[FlagsAttribute]
public enum AllowedMemberLocations
{
None = 0,
Attribute = 1,
MemberElement = 2,
Any = 3
}
}

View File

@@ -0,0 +1,48 @@
2010-04-22 Atsushi Enomoto <atsushi@ximian.com>
* XamlMemberInvoker.cs : make sure GetValue() is not supported
on directives.
2010-04-14 Atsushi Enomoto <atsushi@ximian.com>
* XamlTypeTypeConverter.cs : this prefers UnderlyingType.ToString()
unlike XamlType.ToString().
2010-04-14 Atsushi Enomoto <atsushi@ximian.com>
* XamlTypeName.cs : corcompare shows I was missing useful two.
2010-04-14 Atsushi Enomoto <atsushi@ximian.com>
* XamlTypeName.cs : implemented.
2010-04-13 Atsushi Enomoto <atsushi@ximian.com>
* XamlTypeInvoker.cs : implement AddToCollection and AddToDictionary.
2010-04-13 Atsushi Enomoto <atsushi@ximian.com>
* XamlTypeInvoker.cs : implement CreateInstance() for object writer.
2010-04-12 Atsushi Enomoto <atsushi@ximian.com>
* XamlTypeName.cs : methods were missing.
2010-04-09 Atsushi Enomoto <atsushi@ximian.com>
* XamlTypeTypeConverter.cs, XamlValueConverter.cs : implemented.
2010-04-08 Atsushi Enomoto <atsushi@ximian.com>
* XamlMemberInvoker.cs : implement most of it.
2010-04-08 Atsushi Enomoto <atsushi@ximian.com>
* AllowedMemberLocations.cs
ShouldSerializeResult.cs
XamlCollectionKind.cs
XamlMemberInvoker.cs
XamlTypeInvoker.cs
XamlTypeName.cs
XamlTypeTypeConverter.cs
XamlValueConverter.cs : initial checkin.

View File

@@ -0,0 +1,34 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
namespace System.Xaml.Schema
{
public enum ShouldSerializeResult
{
Default,
True,
False
}
}

View File

@@ -0,0 +1,35 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
namespace System.Xaml.Schema
{
public enum XamlCollectionKind
{
None,
Collection,
Dictionary,
Array,
}
}

View File

@@ -0,0 +1,94 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Reflection;
namespace System.Xaml.Schema
{
public class XamlMemberInvoker
{
static readonly XamlMemberInvoker unknown = new XamlMemberInvoker ();
public static XamlMemberInvoker UnknownInvoker {
get { return unknown; }
}
protected XamlMemberInvoker ()
{
}
public XamlMemberInvoker (XamlMember member)
{
if (member == null)
throw new ArgumentNullException ("member");
this.member = member;
}
XamlMember member;
public MethodInfo UnderlyingGetter {
get { return member != null ? member.UnderlyingGetter : null; }
}
public MethodInfo UnderlyingSetter {
get { return member != null ? member.UnderlyingSetter : null; }
}
void ThrowIfUnknown ()
{
if (member == null)
throw new NotSupportedException ("Current operation is invalid for unknown member.");
}
public virtual object GetValue (object instance)
{
ThrowIfUnknown ();
if (instance == null)
throw new ArgumentNullException ("instance");
if (member is XamlDirective)
throw new NotSupportedException (String.Format ("not supported operation on directive member {0}", member));
if (UnderlyingGetter == null)
throw new NotSupportedException (String.Format ("Attempt to get value from write-only property or event {0}", member));
return UnderlyingGetter.Invoke (instance, new object [0]);
}
public virtual void SetValue (object instance, object value)
{
ThrowIfUnknown ();
if (instance == null)
throw new ArgumentNullException ("instance");
if (member is XamlDirective)
throw new NotSupportedException (String.Format ("not supported operation on directive member {0}", member));
if (UnderlyingSetter == null)
throw new NotSupportedException (String.Format ("Attempt to set value from read-only property {0}", member));
if (member.IsAttachable)
UnderlyingSetter.Invoke (null, new object [] {instance, value});
else
UnderlyingSetter.Invoke (instance, new object [] {value});
}
public virtual ShouldSerializeResult ShouldSerializeValue (object instance)
{
throw new NotImplementedException ();
}
}
}

View File

@@ -0,0 +1,156 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
// Copyright (C) 2012 Xamarin Inc. http://xamarin.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Markup;
namespace System.Xaml.Schema
{
public class XamlTypeInvoker
{
static readonly XamlTypeInvoker unknown = new XamlTypeInvoker ();
public static XamlTypeInvoker UnknownInvoker {
get { return unknown; }
}
protected XamlTypeInvoker ()
{
}
public XamlTypeInvoker (XamlType type)
{
if (type == null)
throw new ArgumentNullException ("type");
this.type = type;
}
XamlType type;
void ThrowIfUnknown ()
{
if (type == null || type.UnderlyingType == null)
throw new NotSupportedException (String.Format ("Current operation is valid only when the underlying type on a XamlType is known, but it is unknown for '{0}'", type));
}
public EventHandler<XamlSetMarkupExtensionEventArgs> SetMarkupExtensionHandler {
get { return type == null ? null : type.SetMarkupExtensionHandler; }
}
public EventHandler<XamlSetTypeConverterEventArgs> SetTypeConverterHandler {
get { return type == null ? null : type.SetTypeConverterHandler; }
}
public virtual void AddToCollection (object instance, object item)
{
if (instance == null)
throw new ArgumentNullException ("instance");
if (item == null)
throw new ArgumentNullException ("item");
var ct = instance.GetType ();
var xct = type == null ? null : type.SchemaContext.GetXamlType (ct);
MethodInfo mi = null;
// FIXME: this method lookup should be mostly based on GetAddMethod(). At least iface method lookup must be done there.
if (type != null && type.UnderlyingType != null) {
if (!xct.IsCollection) // not sure why this check is done only when UnderlyingType exists...
throw new NotSupportedException (String.Format ("Non-collection type '{0}' does not support this operation", xct));
if (ct.IsAssignableFrom (type.UnderlyingType))
mi = GetAddMethod (type.SchemaContext.GetXamlType (item.GetType ()));
}
if (mi == null) {
if (ct.IsGenericType) {
mi = ct.GetMethod ("Add", ct.GetGenericArguments ());
if (mi == null)
mi = LookupAddMethod (ct, typeof (ICollection<>).MakeGenericType (ct.GetGenericArguments ()));
} else {
mi = ct.GetMethod ("Add", new Type [] {typeof (object)});
if (mi == null)
mi = LookupAddMethod (ct, typeof (IList));
}
}
if (mi == null)
throw new InvalidOperationException (String.Format ("The collection type '{0}' does not have 'Add' method", ct));
mi.Invoke (instance, new object [] {item});
}
public virtual void AddToDictionary (object instance, object key, object item)
{
if (instance == null)
throw new ArgumentNullException ("instance");
var t = instance.GetType ();
// FIXME: this likely needs similar method lookup to AddToCollection().
MethodInfo mi = null;
if (t.IsGenericType) {
mi = instance.GetType ().GetMethod ("Add", t.GetGenericArguments ());
if (mi == null)
mi = LookupAddMethod (t, typeof (IDictionary<,>).MakeGenericType (t.GetGenericArguments ()));
} else {
mi = instance.GetType ().GetMethod ("Add", new Type [] {typeof (object), typeof (object)});
if (mi == null)
mi = LookupAddMethod (t, typeof (IDictionary));
}
mi.Invoke (instance, new object [] {key, item});
}
MethodInfo LookupAddMethod (Type ct, Type iface)
{
var map = ct.GetInterfaceMap (iface);
for (int i = 0; i < map.TargetMethods.Length; i++)
if (map.InterfaceMethods [i].Name == "Add")
return map.TargetMethods [i];
return null;
}
public virtual object CreateInstance (object [] arguments)
{
ThrowIfUnknown ();
return Activator.CreateInstance (type.UnderlyingType, arguments);
}
public virtual MethodInfo GetAddMethod (XamlType contentType)
{
return type == null || type.UnderlyingType == null || type.ItemType == null || type.LookupCollectionKind () == XamlCollectionKind.None ? null : type.UnderlyingType.GetMethod ("Add", new Type [] {contentType.UnderlyingType});
}
public virtual MethodInfo GetEnumeratorMethod ()
{
return type.UnderlyingType == null || type.LookupCollectionKind () == XamlCollectionKind.None ? null : type.UnderlyingType.GetMethod ("GetEnumerator");
}
public virtual IEnumerator GetItems (object instance)
{
if (instance == null)
throw new ArgumentNullException ("instance");
return ((IEnumerable) instance).GetEnumerator ();
}
}
}

View File

@@ -0,0 +1,264 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
namespace System.Xaml.Schema
{
public class XamlTypeName
{
public static XamlTypeName Parse (string typeName, IXamlNamespaceResolver namespaceResolver)
{
XamlTypeName n;
if (!TryParse (typeName, namespaceResolver, out n))
throw new FormatException (String.Format ("Invalid typeName: '{0}'", typeName));
return n;
}
public static bool TryParse (string typeName, IXamlNamespaceResolver namespaceResolver, out XamlTypeName result)
{
if (typeName == null)
throw new ArgumentNullException ("typeName");
if (namespaceResolver == null)
throw new ArgumentNullException ("namespaceResolver");
result = null;
IList<XamlTypeName> args = null;
int nArray = 0;
int idx;
if (typeName.Length > 2 && typeName [typeName.Length - 1] == ']') {
idx = typeName.LastIndexOf ('[');
if (idx < 0)
return false; // mismatch brace
nArray = 1;
for (int i = idx + 1; i < typeName.Length - 1; i++) {
if (typeName [i] != ',')
return false; // only ',' is expected
nArray++;
}
if (!TryParse (typeName.Substring (0, idx), namespaceResolver, out result))
return false;
// Weird result, but Name ends with '[]'
result = new XamlTypeName (result.Namespace, result.Name + '[' + new string (',', nArray - 1) + ']', result.TypeArguments);
return true;
}
idx = typeName.IndexOf ('(');
if (idx >= 0) {
if (typeName [typeName.Length - 1] != ')')
return false;
if (!TryParseList (typeName.Substring (idx + 1, typeName.Length - idx - 2), namespaceResolver, out args))
return false;
typeName = typeName.Substring (0, idx);
}
idx = typeName.IndexOf (':');
string prefix, local;
if (idx < 0) {
prefix = String.Empty;
local = typeName;
} else {
prefix = typeName.Substring (0, idx);
local = typeName.Substring (idx + 1);
if (!XamlLanguage.IsValidXamlName (prefix))
return false;
}
if (!XamlLanguage.IsValidXamlName (local))
return false;
string ns = namespaceResolver.GetNamespace (prefix);
if (ns == null)
return false;
result = new XamlTypeName (ns, local, args);
return true;
}
public static IList<XamlTypeName> ParseList (string typeNameList, IXamlNamespaceResolver namespaceResolver)
{
IList<XamlTypeName> list;
if (!TryParseList (typeNameList, namespaceResolver, out list))
throw new FormatException (String.Format ("Invalid type name list: '{0}'", typeNameList));
return list;
}
static readonly char [] comma_or_parens = new char [] {',', '(', ')'};
public static bool TryParseList (string typeNameList, IXamlNamespaceResolver namespaceResolver, out IList<XamlTypeName> list)
{
if (typeNameList == null)
throw new ArgumentNullException ("typeNameList");
if (namespaceResolver == null)
throw new ArgumentNullException ("namespaceResolver");
list = null;
int idx = 0;
int parens = 0;
XamlTypeName tn;
List<string> l = new List<string> ();
int lastToken = 0;
while (true) {
int i = typeNameList.IndexOfAny (comma_or_parens, idx);
if (i < 0) {
l.Add (typeNameList.Substring (lastToken));
break;
}
switch (typeNameList [i]) {
case ',':
if (parens != 0)
break;
l.Add (typeNameList.Substring (idx, i - idx));
break;
case '(':
parens++;
break;
case ')':
parens--;
break;
}
idx = i + 1;
while (idx < typeNameList.Length && typeNameList [idx] == ' ')
idx++;
if (parens == 0 && typeNameList [i] == ',')
lastToken = idx;
}
var ret = new List<XamlTypeName> ();
foreach (var s in l) {
if (!TryParse (s, namespaceResolver, out tn))
return false;
ret.Add (tn);
}
list = ret;
return true;
}
public static string ToString (IList<XamlTypeName> typeNameList, INamespacePrefixLookup prefixLookup)
{
if (typeNameList == null)
throw new ArgumentNullException ("typeNameList");
if (prefixLookup == null)
throw new ArgumentNullException ("prefixLookup");
return DoToString (typeNameList, prefixLookup);
}
static string DoToString (IList<XamlTypeName> typeNameList, INamespacePrefixLookup prefixLookup)
{
bool comma = false;
string ret = "";
foreach (var ta in typeNameList) {
if (comma)
ret += ", ";
else
comma = true;
ret += ta.ToString (prefixLookup);
}
return ret;
}
// instance members
public XamlTypeName ()
{
TypeArguments = empty_type_args;
}
static readonly XamlTypeName [] empty_type_args = new XamlTypeName [0];
public XamlTypeName (XamlType xamlType)
: this ()
{
if (xamlType == null)
throw new ArgumentNullException ("xamlType");
Namespace = xamlType.PreferredXamlNamespace;
Name = xamlType.Name;
if (xamlType.TypeArguments != null && xamlType.TypeArguments.Count > 0) {
var l = new List<XamlTypeName> ();
l.AddRange (from x in xamlType.TypeArguments.AsQueryable () select new XamlTypeName (x));
TypeArguments = l;
}
}
public XamlTypeName (string xamlNamespace, string name)
: this (xamlNamespace, name, null)
{
}
public XamlTypeName (string xamlNamespace, string name, IEnumerable<XamlTypeName> typeArguments)
: this ()
{
Namespace = xamlNamespace;
Name = name;
if (typeArguments != null) {
if (typeArguments.Any (t => t == null))
throw new ArgumentNullException ("typeArguments", "typeArguments array contains one or more null XamlTypeName");
var l = new List<XamlTypeName> ();
l.AddRange (typeArguments);
TypeArguments = l;
}
}
public string Name { get; set; }
public string Namespace { get; set; }
public IList<XamlTypeName> TypeArguments { get; private set; }
public override string ToString ()
{
return ToString (null);
}
public string ToString (INamespacePrefixLookup prefixLookup)
{
if (Namespace == null)
throw new InvalidOperationException ("Namespace must be set before calling ToString method.");
if (Name == null)
throw new InvalidOperationException ("Name must be set before calling ToString method.");
string ret;
if (prefixLookup == null)
ret = String.Concat ("{", Namespace, "}", Name);
else {
string p = prefixLookup.LookupPrefix (Namespace);
if (p == null)
throw new InvalidOperationException (String.Format ("Could not lookup prefix for namespace '{0}'", Namespace));
ret = p.Length == 0 ? Name : p + ":" + Name;
}
string arr = null;
if (ret [ret.Length - 1] == ']') {
int idx = ret.LastIndexOf ('[');
arr = ret.Substring (idx);
ret = ret.Substring (0, idx);
}
if (TypeArguments.Count > 0)
ret += String.Concat ("(", DoToString (TypeArguments, prefixLookup), ")");
return ret + arr;
}
}
}

View File

@@ -0,0 +1,67 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Markup;
using System.Xaml;
namespace System.Xaml.Schema
{
public class XamlTypeTypeConverter : TypeConverter
{
public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof (string);
}
public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof (string);
}
public override Object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, Object value)
{
throw new NotSupportedException (String.Format ("Conversion from type {0} is not supported", value != null ? value.GetType () : null));
}
public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (!CanConvertTo (context, destinationType))
throw new NotSupportedException (String.Format ("Conversion to type {0} is not supported", destinationType));
var vctx = (IValueSerializerContext) context;
var lookup = vctx != null ? (INamespacePrefixLookup) vctx.GetService (typeof (INamespacePrefixLookup)) : null;
var xt = value as XamlType;
if (xt != null && destinationType == typeof (string)) {
if (lookup != null)
return new XamlTypeName (xt).ToString (lookup);
else
return xt.UnderlyingType != null ? xt.UnderlyingType.ToString () : xt.ToString ();
}
else
return base.ConvertTo (context, culture, value, destinationType); // it seems it still handles not-supported types (such as int).
}
}
}

View File

@@ -0,0 +1,132 @@
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace System.Xaml.Schema
{
public class XamlValueConverter<TConverterBase> : IEquatable<XamlValueConverter<TConverterBase>>
where TConverterBase : class
{
public XamlValueConverter (Type converterType, XamlType targetType)
: this (converterType, targetType, null)
{
}
public XamlValueConverter (Type converterType, XamlType targetType, string name)
{
if (converterType == null && targetType == null && name == null)
throw new ArgumentException ("Either of converterType, targetType or name must be non-null");
ConverterType = converterType;
TargetType = targetType;
Name = name;
}
TConverterBase converter_instance;
public TConverterBase ConverterInstance {
get {
if (converter_instance == null)
converter_instance = CreateInstance ();
return converter_instance;
}
}
public Type ConverterType { get; private set; }
public string Name { get; private set; }
public XamlType TargetType { get; private set; }
public static bool operator == (XamlValueConverter<TConverterBase> left, XamlValueConverter<TConverterBase> right)
{
return IsNull (left) ? IsNull (right) : left.Equals (right);
}
static bool IsNull (XamlValueConverter<TConverterBase> a)
{
return Object.ReferenceEquals (a, null);
}
public static bool operator != (XamlValueConverter<TConverterBase> left, XamlValueConverter<TConverterBase> right)
{
return IsNull (left) ? !IsNull (right) : IsNull (right) || left.ConverterType != right.ConverterType || left.TargetType != right.TargetType || left.Name != right.Name;
}
public bool Equals (XamlValueConverter<TConverterBase> other)
{
return !IsNull (other) && ConverterType == other.ConverterType && TargetType == other.TargetType && Name == other.Name;
}
public override bool Equals (object obj)
{
var a = obj as XamlValueConverter<TConverterBase>;
return Equals (a);
}
protected virtual TConverterBase CreateInstance ()
{
if (ConverterType == null)
return null;
if (!typeof (TConverterBase).IsAssignableFrom (ConverterType))
throw new XamlSchemaException (String.Format ("ConverterType '{0}' is not derived from '{1}' type", ConverterType, typeof (TConverterBase)));
if (TargetType != null && TargetType.UnderlyingType != null) {
// special case: Enum
if (TargetType.UnderlyingType.IsEnum)
return (TConverterBase) (object) new EnumConverter (TargetType.UnderlyingType);
// special case: Nullable<T>
if (TargetType.IsNullable && TargetType.UnderlyingType.IsValueType)
return (TConverterBase) (object) new NullableConverter (TargetType.UnderlyingType);
}
if (ConverterType.GetConstructor (Type.EmptyTypes) == null)
return null;
return (TConverterBase) Activator.CreateInstance (ConverterType, true);
}
public override int GetHashCode ()
{
var ret = ConverterType != null ? ConverterType.GetHashCode () : 0;
ret <<= 5;
if (TargetType != null)
ret += TargetType.GetHashCode ();
ret <<= 5;
if (Name != null)
ret += Name.GetHashCode ();
return ret;
}
public override string ToString ()
{
if (Name != null)
return Name;
if (ConverterType != null && TargetType != null)
return String.Concat (ConverterType.Name, "(", TargetType.Name, ")");
else if (ConverterType != null)
return ConverterType.Name;
else
return TargetType.Name;
}
}
}