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.
24 using System
.Collections
.Generic
;
27 namespace System
.Xaml
.Schema
29 public class XamlTypeName
31 public static XamlTypeName
Parse (string typeName
, IXamlNamespaceResolver namespaceResolver
)
34 if (!TryParse (typeName
, namespaceResolver
, out n
))
35 throw new FormatException (String
.Format ("Invalid typeName: '{0}'", typeName
));
39 public static bool TryParse (string typeName
, IXamlNamespaceResolver namespaceResolver
, out XamlTypeName result
)
42 throw new ArgumentNullException ("typeName");
43 if (namespaceResolver
== null)
44 throw new ArgumentNullException ("namespaceResolver");
47 IList
<XamlTypeName
> args
= null;
49 int idx
= typeName
.IndexOf ('(');
51 if (typeName
[typeName
.Length
- 1] != ')')
53 if (!TryParseList (typeName
.Substring (idx
+ 1, typeName
.Length
- idx
- 2), namespaceResolver
, out args
))
55 typeName
= typeName
.Substring (0, idx
);
58 idx
= typeName
.IndexOf (':');
61 prefix
= String
.Empty
;
64 prefix
= typeName
.Substring (0, idx
);
65 local
= typeName
.Substring (idx
+ 1);
66 if (!XamlLanguage
.IsValidXamlName (prefix
))
69 if (!XamlLanguage
.IsValidXamlName (local
))
71 string ns
= namespaceResolver
.GetNamespace (prefix
);
75 result
= new XamlTypeName (ns
, local
, args
);
79 static readonly char [] commas
= {','}
;
81 public static IList
<XamlTypeName
> ParseList (string typeNameList
, IXamlNamespaceResolver namespaceResolver
)
83 IList
<XamlTypeName
> list
;
84 if (!TryParseList (typeNameList
, namespaceResolver
, out list
))
85 throw new FormatException (String
.Format ("Invalid type name list: '{0}'", typeNameList
));
89 public static bool TryParseList (string typeNameList
, IXamlNamespaceResolver namespaceResolver
, out IList
<XamlTypeName
> list
)
91 if (typeNameList
== null)
92 throw new ArgumentNullException ("typeNameList");
93 if (namespaceResolver
== null)
94 throw new ArgumentNullException ("namespaceResolver");
97 var split
= typeNameList
.Split (commas
);
98 if (split
.Length
== 0)
101 var arr
= new XamlTypeName
[split
.Length
];
103 for (int i
= 0; i
< split
.Length
; i
++) {
104 var s
= split
[i
].Trim ();
106 if (!TryParse (s
, namespaceResolver
, out tn
))
115 public static string ToString (IList
<XamlTypeName
> typeNameList
, INamespacePrefixLookup prefixLookup
)
117 if (typeNameList
== null)
118 throw new ArgumentNullException ("typeNameList");
119 if (prefixLookup
== null)
120 throw new ArgumentNullException ("prefixLookup");
122 return DoToString (typeNameList
, prefixLookup
);
125 static string DoToString (IList
<XamlTypeName
> typeNameList
, INamespacePrefixLookup prefixLookup
)
129 foreach (var ta
in typeNameList
) {
134 ret
+= ta
.ToString (prefixLookup
);
141 public XamlTypeName ()
143 TypeArguments
= empty_type_args
;
146 static readonly XamlTypeName
[] empty_type_args
= new XamlTypeName
[0];
148 public XamlTypeName (XamlType xamlType
)
151 if (xamlType
== null)
152 throw new ArgumentNullException ("xamlType");
153 Namespace
= xamlType
.PreferredXamlNamespace
;
154 Name
= xamlType
.Name
;
155 if (xamlType
.TypeArguments
!= null && xamlType
.TypeArguments
.Count
> 0) {
156 var l
= new List
<XamlTypeName
> ();
157 l
.AddRange (from x
in xamlType
.TypeArguments
.AsQueryable () select new XamlTypeName (x
));
162 public XamlTypeName (string xamlNamespace
, string name
)
163 : this (xamlNamespace
, name
, null)
167 public XamlTypeName (string xamlNamespace
, string name
, IEnumerable
<XamlTypeName
> typeArguments
)
170 Namespace
= xamlNamespace
;
172 if (typeArguments
!= null) {
173 if (typeArguments
.Any (t
=> t
== null))
174 throw new ArgumentNullException ("typeArguments", "typeArguments array contains one or more null XamlTypeName");
175 var l
= new List
<XamlTypeName
> ();
176 l
.AddRange (typeArguments
);
181 public string Name { get; set; }
182 public string Namespace { get; set; }
183 public IList
<XamlTypeName
> TypeArguments { get; private set; }
185 public override string ToString ()
187 return ToString (null);
190 public string ToString (INamespacePrefixLookup prefixLookup
)
192 if (Namespace
== null)
193 throw new InvalidOperationException ("Namespace must be set before calling ToString method.");
195 throw new InvalidOperationException ("Name must be set before calling ToString method.");
198 if (prefixLookup
== null)
199 ret
= String
.Concat ("{", Namespace, "}", Name
);
201 string p
= prefixLookup
.LookupPrefix (Namespace
);
203 throw new InvalidOperationException (String
.Format ("Could not lookup prefix for namespace '{0}'", Namespace
));
204 ret
= p
.Length
== 0 ? Name
: p
+ ":" + Name
;
207 if (TypeArguments
.Count
> 0)
208 ret
+= String
.Concat ("(", DoToString (TypeArguments
, prefixLookup
), ")");