2007-08-19 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / System / System.ComponentModel / TypeDescriptor.cs
1 //
2 // System.ComponentModel.TypeDescriptor.cs
3 //
4 // Authors:
5 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8 // (C) 2002 Ximian, Inc (http://www.ximian.com)
9 // (C) 2003 Andreas Nahr
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System.Collections;
34 using System.Reflection;
35 using System.Globalization;
36 using System.ComponentModel.Design;
37 using System.Security.Permissions;
38
39 namespace System.ComponentModel
40 {
41
42 public sealed class TypeDescriptor
43 {
44         private static readonly object creatingDefaultConverters = new object ();
45         private static Hashtable defaultConverters;
46         private static IComNativeDescriptorHandler descriptorHandler;
47         private static Hashtable componentTable = new Hashtable ();
48         private static Hashtable typeTable = new Hashtable ();
49         private static Hashtable editors;
50
51         private TypeDescriptor ()
52         {
53         }
54
55 #if NET_2_0
56         [MonoNotSupported ("")]
57         [EditorBrowsable (EditorBrowsableState.Advanced)]
58         public static Type ComObjectType {
59                 get { throw new NotImplementedException (); }
60         }
61
62         [MonoNotSupported("")]
63         [EditorBrowsable (EditorBrowsableState.Advanced)]
64         public static TypeDescriptionProvider AddAttributes (object instance, params Attribute [] attributes)
65         {
66                 throw new NotImplementedException ();
67         }
68
69         [MonoNotSupported("")]
70         [EditorBrowsable (EditorBrowsableState.Advanced)]
71         public static TypeDescriptionProvider AddAttributes (Type type, params Attribute [] attributes)
72         {
73                 throw new NotImplementedException ();
74         }
75
76         [MonoNotSupported("")]
77         [EditorBrowsable (EditorBrowsableState.Advanced)]
78         public static void AddProvider (TypeDescriptionProvider provider, object instance)
79         {
80                 throw new NotImplementedException ();
81         }
82
83         [MonoNotSupported("")]
84         [EditorBrowsable (EditorBrowsableState.Advanced)]
85         public static void AddProvider (TypeDescriptionProvider provider, Type type)
86         {
87                 throw new NotImplementedException ();
88         }
89
90         [MonoNotSupported("")]
91         public static object CreateInstance (IServiceProvider provider, Type objectType, Type [] argTypes, object [] args)
92         {
93                 throw new NotImplementedException ();
94         }
95 #endif
96
97 #if NET_2_0
98         [EditorBrowsable (EditorBrowsableState.Advanced)]
99 #endif
100         public static void AddEditorTable (Type editorBaseType, Hashtable table)
101         {
102                 if (editors == null)
103                         editors = new Hashtable ();
104                         
105                 editors [editorBaseType] = table;
106         }
107
108         public static IDesigner CreateDesigner(IComponent component, Type designerBaseType)
109         {
110                 string tn = designerBaseType.AssemblyQualifiedName;
111                 AttributeCollection col = GetAttributes (component);
112                 
113                 foreach (Attribute at in col) {
114                         DesignerAttribute dat = at as DesignerAttribute;
115                         if (dat != null && tn == dat.DesignerBaseTypeName) {
116                                 return (IDesigner) Activator.CreateInstance (GetTypeFromName (component, dat.DesignerTypeName));
117                         }
118                 }
119                                 
120                 return null;
121         }
122
123         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
124         public static EventDescriptor CreateEvent (Type componentType,
125                                                    string name,
126                                                    Type type,
127                                                    params Attribute [] attributes)
128         {
129                 return new ReflectionEventDescriptor (componentType, name, type, attributes);
130         }
131
132         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
133         public static EventDescriptor CreateEvent (Type componentType,
134                                                    EventDescriptor oldEventDescriptor,
135                                                    params Attribute [] attributes)
136         {
137                 return new ReflectionEventDescriptor (componentType, oldEventDescriptor, attributes);
138         }
139
140         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
141         public static PropertyDescriptor CreateProperty (Type componentType,
142                                                          string name,
143                                                          Type type,
144                                                          params Attribute [] attributes)
145         {
146                 return new ReflectionPropertyDescriptor (componentType, name, type, attributes);
147         }
148
149         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
150         public static PropertyDescriptor CreateProperty (Type componentType,
151                                                          PropertyDescriptor oldPropertyDescriptor,
152                                                          params Attribute [] attributes)
153         {
154                 return new ReflectionPropertyDescriptor (componentType, oldPropertyDescriptor, attributes);
155         }
156
157         public static AttributeCollection GetAttributes (Type componentType)
158         {
159                 if (componentType == null)
160                         return AttributeCollection.Empty;
161
162                 return GetTypeInfo (componentType).GetAttributes ();
163         }
164
165         public static AttributeCollection GetAttributes (object component)
166         {
167                 return GetAttributes (component, false);
168         }
169
170 #if NET_2_0
171         [EditorBrowsable (EditorBrowsableState.Advanced)]
172 #endif
173         public static AttributeCollection GetAttributes (object component, bool noCustomTypeDesc)
174         {
175                 if (component == null)
176                         return AttributeCollection.Empty;
177
178                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
179                         return ((ICustomTypeDescriptor) component).GetAttributes ();
180                 } else {
181                         IComponent com = component as IComponent;
182                         if (com != null && com.Site != null)
183                                 return GetComponentInfo (com).GetAttributes ();
184                         else
185                                 return GetTypeInfo (component.GetType()).GetAttributes ();
186                 }
187         }
188
189         public static string GetClassName (object component)
190         {
191                 return GetClassName (component, false);
192         }
193
194 #if NET_2_0
195         [EditorBrowsable (EditorBrowsableState.Advanced)]
196 #endif
197         public static string GetClassName (object component, bool noCustomTypeDesc)
198         {
199                 if (component == null)
200                         throw new ArgumentNullException ("component", "component cannot be null");
201
202                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
203                         String res = ((ICustomTypeDescriptor) component).GetClassName ();
204                         if (res == null)
205                                 res = ((ICustomTypeDescriptor) component).GetComponentName ();
206                         if (res == null)
207                                 res = component.GetType ().FullName;
208                         return res;
209                 } else {
210                         return component.GetType ().FullName;
211                 }
212         }
213
214         public static string GetComponentName (object component)
215         {
216                 return GetComponentName (component, false);
217         }
218
219 #if NET_2_0
220         [EditorBrowsable (EditorBrowsableState.Advanced)]
221 #endif
222         public static string GetComponentName (object component, bool noCustomTypeDesc)
223         {
224                 if (component == null)
225                         throw new ArgumentNullException ("component", "component cannot be null");
226
227                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
228                         return ((ICustomTypeDescriptor) component).GetComponentName ();
229                 } else {
230                         IComponent c = component as IComponent;
231                         if (c != null && c.Site != null)
232                                 return c.Site.Name;
233 #if NET_2_0
234                         return null;
235 #else
236                         return component.GetType().Name;
237 #endif
238                 }
239         }
240
241 #if NET_2_0
242         [MonoNotSupported("")]
243         public static string GetFullComponentName (object component)
244         {
245                 throw new NotImplementedException ();
246         }
247
248         [MonoNotSupported("")]
249         public static string GetClassName (Type componentType)
250         {
251                 throw new NotImplementedException ();
252         }
253 #endif
254
255         public static TypeConverter GetConverter (object component)
256         {
257                 return GetConverter (component, false);
258         }
259
260 #if NET_2_0
261         [EditorBrowsable (EditorBrowsableState.Advanced)]
262 #endif
263         public static TypeConverter GetConverter (object component, bool noCustomTypeDesc)
264         {
265                 if (component == null)
266                         throw new ArgumentNullException ("component", "component cannot be null");
267
268                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
269                         return ((ICustomTypeDescriptor) component).GetConverter ();
270                 } 
271                 else {
272                         Type t = null;
273                         AttributeCollection atts = GetAttributes (component, false);
274                         TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)];
275                         if (tca != null && tca.ConverterTypeName.Length > 0) {
276                                 t = GetTypeFromName (component as IComponent, tca.ConverterTypeName);
277                         }
278                         
279                         if (t != null) {
280                                 ConstructorInfo ci = t.GetConstructor (new Type[] { typeof(Type) });
281                                 if (ci != null)
282                                         return (TypeConverter) ci.Invoke (new object[] { component.GetType () });
283                                 else
284                                         return (TypeConverter) Activator.CreateInstance (t);
285                         }
286                         else
287                                 return GetConverter (component.GetType ());
288                 }
289         }
290
291         private static Hashtable DefaultConverters
292         {
293                 get {
294                         lock (creatingDefaultConverters) {
295                                 if (defaultConverters != null)
296                                         return defaultConverters;
297                                 
298                                 defaultConverters = new Hashtable ();
299                                 defaultConverters.Add (typeof (bool), typeof (BooleanConverter));
300                                 defaultConverters.Add (typeof (byte), typeof (ByteConverter));
301                                 defaultConverters.Add (typeof (sbyte), typeof (SByteConverter));
302                                 defaultConverters.Add (typeof (string), typeof (StringConverter));
303                                 defaultConverters.Add (typeof (char), typeof (CharConverter));
304                                 defaultConverters.Add (typeof (short), typeof (Int16Converter));
305                                 defaultConverters.Add (typeof (int), typeof (Int32Converter));
306                                 defaultConverters.Add (typeof (long), typeof (Int64Converter));
307                                 defaultConverters.Add (typeof (ushort), typeof (UInt16Converter));
308                                 defaultConverters.Add (typeof (uint), typeof (UInt32Converter));
309                                 defaultConverters.Add (typeof (ulong), typeof (UInt64Converter));
310                                 defaultConverters.Add (typeof (float), typeof (SingleConverter));
311                                 defaultConverters.Add (typeof (double), typeof (DoubleConverter));
312                                 defaultConverters.Add (typeof (decimal), typeof (DecimalConverter));
313                                 defaultConverters.Add (typeof (object), typeof (TypeConverter));
314                                 defaultConverters.Add (typeof (void), typeof (TypeConverter));
315                                 defaultConverters.Add (typeof (Array), typeof (ArrayConverter));
316                                 defaultConverters.Add (typeof (CultureInfo), typeof (CultureInfoConverter));
317                                 defaultConverters.Add (typeof (DateTime), typeof (DateTimeConverter));
318                                 defaultConverters.Add (typeof (Guid), typeof (GuidConverter));
319                                 defaultConverters.Add (typeof (TimeSpan), typeof (TimeSpanConverter));
320                                 defaultConverters.Add (typeof (ICollection), typeof (CollectionConverter));
321                         }
322                         return defaultConverters;
323                 }
324         }
325         
326         public static TypeConverter GetConverter (Type type)
327         {
328                 TypeConverterAttribute tca = null;
329                 Type t = null;
330                 object [] atts = type.GetCustomAttributes (typeof(TypeConverterAttribute), true);
331                 
332                 if (atts.Length > 0)
333                         tca = (TypeConverterAttribute)atts[0];
334                 
335                 if (tca != null) {
336                         t = GetTypeFromName (null, tca.ConverterTypeName);
337                 }
338                 
339                 if (t == null) {
340                         if (type.IsEnum) {
341                                 // EnumConverter needs to know the enum type
342                                 return new EnumConverter(type);
343                         } else if (type.IsArray) {
344                                 return new ArrayConverter ();
345                         }
346                 }
347                 
348                 if (t == null)
349                         t = FindConverterType (type);
350
351                 if (t != null) {
352                         Exception exc = null;
353                         try {
354                                 return (TypeConverter) Activator.CreateInstance (t);
355                         } catch (MissingMethodException e) {
356                                 exc = e;
357                         }
358
359                         try {
360                                 return (TypeConverter) Activator.CreateInstance (t, new object [] {type});
361                         } catch (MissingMethodException e) {
362                                 throw exc;
363                         }
364                 }
365
366                 return new ReferenceConverter (type);    // Default?
367         }
368
369         private static Type FindConverterType (Type type)
370         {
371                 Type t = null;
372                 
373                 // Is there a default converter
374                 t = (Type) DefaultConverters [type];
375                 if (t != null)
376                         return t;
377                 
378                 // Find default converter with a type this type is assignable to
379                 foreach (Type defType in DefaultConverters.Keys) {
380                         if (defType.IsInterface && defType.IsAssignableFrom (type)) {
381                                 return (Type) DefaultConverters [defType];
382                         }
383                 }
384                 
385                 // Nothing found, try the same with our base type
386                 if (type.BaseType != null)
387                         return FindConverterType (type.BaseType);
388                 else
389                         return null;
390         }
391
392         public static EventDescriptor GetDefaultEvent (Type componentType)
393         {
394                 return GetTypeInfo (componentType).GetDefaultEvent ();
395         }
396
397         public static EventDescriptor GetDefaultEvent (object component)
398         {
399                 return GetDefaultEvent (component, false);
400         }
401
402 #if NET_2_0
403         [EditorBrowsable (EditorBrowsableState.Advanced)]
404 #endif
405         public static EventDescriptor GetDefaultEvent (object component, bool noCustomTypeDesc)
406         {
407                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
408                         return ((ICustomTypeDescriptor) component).GetDefaultEvent ();
409                 else {
410                         IComponent com = component as IComponent;
411                         if (com != null && com.Site != null)
412                                 return GetComponentInfo (com).GetDefaultEvent ();
413                         else
414                                 return GetTypeInfo (component.GetType()).GetDefaultEvent ();
415                 }
416         }
417
418         public static PropertyDescriptor GetDefaultProperty (Type componentType)
419         {
420                 return GetTypeInfo (componentType).GetDefaultProperty ();
421         }
422
423         public static PropertyDescriptor GetDefaultProperty (object component)
424         {
425                 return GetDefaultProperty (component, false);
426         }
427
428 #if NET_2_0
429         [EditorBrowsable (EditorBrowsableState.Advanced)]
430 #endif
431         public static PropertyDescriptor GetDefaultProperty (object component, bool noCustomTypeDesc)
432         {
433                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
434                         return ((ICustomTypeDescriptor) component).GetDefaultProperty ();
435                 else {
436                         IComponent com = component as IComponent;
437                         if (com != null && com.Site != null)
438                                 return GetComponentInfo (com).GetDefaultProperty ();
439                         else
440                                 return GetTypeInfo (component.GetType()).GetDefaultProperty ();
441                 }
442         }
443                 
444         internal static object CreateEditor (Type t, Type componentType)
445         {
446                 if (t == null) 
447                         return null;
448
449                 Exception exc = null;
450                 try {
451                         return Activator.CreateInstance (t);
452                 } catch (MissingMethodException e) {
453                         exc = e;
454                 }
455
456                 try {
457                         return Activator.CreateInstance (t, new object [] {componentType});
458                 } catch (MissingMethodException e) {
459                         throw exc;
460                 }
461         }
462                 
463         private static object FindEditorInTable (Type componentType, Type editorBaseType, Hashtable table)
464         {
465                 object value = null;
466                 object editor = null;
467                 Type ct = componentType;
468                 
469                 if (componentType == null || editorBaseType == null || table == null)
470                                 return null;
471                         
472                 while (ct != null) {                                            
473                         value = table [ct];
474                         if (value != null)
475                                 break;                  
476                         ct = ct.BaseType;
477                 }
478                 
479                 if (value == null) {
480                         foreach (Type iface in componentType.GetInterfaces ()) {
481                                 value = table [iface];
482                                 if (value != null) 
483                                                 break;
484                         }
485                 }
486                                 
487                 if (value == null)
488                                 return null;
489                                 
490                 if (value is string) {
491                         editor = CreateEditor (Type.GetType ((string) value), componentType);
492                 } else if (value is Type) {
493                         editor = CreateEditor ((Type) value, componentType);
494                 } else if (value.GetType ().IsSubclassOf (editorBaseType)) {
495                         editor = value;
496                 }
497                 
498                 if (editor != null) 
499                         table [componentType] = editor;
500                 
501                 return editor;
502         }
503
504         public static object GetEditor (Type componentType, Type editorBaseType)
505         {
506                 Type t = null;
507                 object [] atts = componentType.GetCustomAttributes (typeof(EditorAttribute), true);
508                 
509                 if (atts != null && atts.Length != 0) {
510                         foreach (EditorAttribute ea in atts)
511                         {
512                                 t = GetTypeFromName (null, ea.EditorTypeName);
513                                 if (t.IsSubclassOf(editorBaseType))
514                                         break;
515                         }
516                 }
517                 
518                 if (t != null)
519                         return CreateEditor (t, componentType);
520                         
521                 if (t == null) {
522 #if !TARGET_JVM
523                         // Make sure the editorBaseType's static constructor has been called,
524                         // since that's where we're putting the initialization of its editor table.
525                         
526                         System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (editorBaseType.TypeHandle);
527 #endif                          
528                         if (editors != null) {
529                                 return FindEditorInTable (componentType, editorBaseType, editors [editorBaseType] as Hashtable);
530                         }
531                 }
532
533                 return null;    // No editor specified
534         }
535
536         public static object GetEditor (object component, Type editorBaseType)
537         {
538                 return GetEditor (component, editorBaseType, false);
539         }
540
541 #if NET_2_0
542         [EditorBrowsable (EditorBrowsableState.Advanced)]
543 #endif
544         public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
545         {
546                 if (component == null)
547                         throw new ArgumentNullException ("component");
548                 if (editorBaseType == null)
549                         throw new ArgumentNullException ("editorBaseType");
550                 
551                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
552                         return ((ICustomTypeDescriptor) component).GetEditor (editorBaseType);
553
554                 object [] atts = component.GetType ().GetCustomAttributes (typeof (EditorAttribute), true);
555                 if (atts.Length == 0)
556                         return null;
557                 string target = editorBaseType.AssemblyQualifiedName;
558                 
559                 foreach (EditorAttribute ea in atts){
560                         if (ea.EditorBaseTypeName == target){
561                                 Type t = Type.GetType (ea.EditorTypeName, true);
562
563                                 return Activator.CreateInstance (t);
564                         }
565                 }
566                 return null;
567         }
568
569         public static EventDescriptorCollection GetEvents (object component)
570         {
571                 return GetEvents (component, false);
572         }
573
574         public static EventDescriptorCollection GetEvents (Type componentType)
575         {
576                 return GetEvents (componentType, null);
577         }
578
579         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes)
580         {
581                 return GetEvents (component, attributes, false);
582         }
583
584 #if NET_2_0
585         [EditorBrowsable (EditorBrowsableState.Advanced)]
586 #endif
587         public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
588         {
589                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
590                         return ((ICustomTypeDescriptor) component).GetEvents ();
591                 else {
592                         IComponent com = component as IComponent;
593                         if (com != null && com.Site != null)
594                                 return GetComponentInfo (com).GetEvents ();
595                         else
596                                 return GetTypeInfo (component.GetType()).GetEvents ();
597                 }
598         }
599
600         public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
601         {
602                 return GetTypeInfo (componentType).GetEvents (attributes);
603         }
604
605 #if NET_2_0
606         [EditorBrowsable (EditorBrowsableState.Advanced)]
607 #endif
608         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc)
609         {
610                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
611                         return ((ICustomTypeDescriptor) component).GetEvents (attributes);
612                 else {
613                         IComponent com = component as IComponent;
614                         if (com != null && com.Site != null)
615                                 return GetComponentInfo (com).GetEvents (attributes);
616                         else
617                                 return GetTypeInfo (component.GetType()).GetEvents (attributes);
618                 }
619         }
620
621         public static PropertyDescriptorCollection GetProperties (object component)
622         {
623                 return GetProperties (component, false);
624         }
625
626         public static PropertyDescriptorCollection GetProperties (Type componentType)
627         {
628                 return GetProperties (componentType, null);
629         }
630
631         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes)
632         {
633                 return GetProperties (component, attributes, false);
634         }
635
636         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
637         {
638                 if (component == null)
639                         return PropertyDescriptorCollection.Empty;
640
641                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
642                         return ((ICustomTypeDescriptor) component).GetProperties (attributes);
643                 else {
644                         IComponent com = component as IComponent;
645                         if (com != null && com.Site != null)
646                                 return GetComponentInfo (com).GetProperties (attributes);
647                         else
648                                 return GetTypeInfo (component.GetType()).GetProperties (attributes);
649                 }
650         }
651
652 #if NET_2_0
653         [EditorBrowsable (EditorBrowsableState.Advanced)]
654 #endif
655         public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
656         {
657                 if (component == null)
658                         return PropertyDescriptorCollection.Empty;
659
660                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
661                         return ((ICustomTypeDescriptor) component).GetProperties ();
662                 else {
663                         IComponent com = component as IComponent;
664                         if (com != null && com.Site != null)
665                                 return GetComponentInfo (com).GetProperties ();
666                         else
667                                 return GetTypeInfo (component.GetType()).GetProperties ();
668                 }
669         }
670
671         public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
672         {
673                 return GetTypeInfo (componentType).GetProperties (attributes);
674         }
675
676 #if NET_2_0
677         [MonoNotSupported ("")]
678         [EditorBrowsable (EditorBrowsableState.Advanced)]
679         public static TypeDescriptionProvider GetProvider (object instance)
680         {
681                 throw new NotImplementedException ();
682         }
683
684         [MonoNotSupported ("")]
685         [EditorBrowsable (EditorBrowsableState.Advanced)]
686         public static TypeDescriptionProvider GetProvider (Type type)
687         {
688                 throw new NotImplementedException ();
689         }
690
691         [MonoNotSupported ("")]
692         [EditorBrowsable (EditorBrowsableState.Advanced)]
693         public static Type GetReflectionType (object instance)
694         {
695                 throw new NotImplementedException ();
696         }
697
698         [MonoNotSupported ("")]
699         [EditorBrowsable (EditorBrowsableState.Advanced)]
700         public static Type GetReflectionType (Type type)
701         {
702                 throw new NotImplementedException ();
703         }
704
705         [MonoNotSupported("Associations not supported")]
706         [EditorBrowsable (EditorBrowsableState.Advanced)]
707         public static void CreateAssociation (object primary, object secondary)
708         {
709                 throw new NotImplementedException ();
710         }
711
712         [MonoNotSupported ("Associations not supported")]
713         [EditorBrowsable (EditorBrowsableState.Advanced)]
714         public static object GetAssociation (Type type, object primary)
715         {
716                 throw new NotImplementedException ();
717         }
718
719         [MonoNotSupported ("Associations not supported")]
720         [EditorBrowsable (EditorBrowsableState.Advanced)]
721         public static void RemoveAssociation (object primary, object secondary)
722         {
723                 throw new NotImplementedException ();
724         }
725
726         [MonoNotSupported ("Associations not supported")]
727         [EditorBrowsable (EditorBrowsableState.Advanced)]
728         public static void RemoveAssociations (object primary)
729         {
730                 throw new NotImplementedException ();
731         }
732
733         [MonoNotSupported ("")]
734         [EditorBrowsable (EditorBrowsableState.Advanced)]
735         public static void RemoveProvider (TypeDescriptionProvider provider, object instance)
736         {
737                 throw new NotImplementedException ();
738         }
739
740         [MonoNotSupported ("")]
741         [EditorBrowsable (EditorBrowsableState.Advanced)]
742         public static void RemoveProvider (TypeDescriptionProvider provider, Type type)
743         {
744                 throw new NotImplementedException ();
745         }
746 #endif
747
748         public static void SortDescriptorArray (IList infos)
749         {
750                 string[] names = new string [infos.Count];
751                 object[] values = new object [infos.Count];
752                 for (int n=0; n<names.Length; n++) {
753                         names[n] = ((MemberDescriptor)infos[n]).Name;
754                         values[n] = infos[n];
755                 }
756                 Array.Sort (names, values);
757                 infos.Clear();
758                 foreach (object ob in values)
759                         infos.Add (ob);
760         }
761
762         public static IComNativeDescriptorHandler ComNativeDescriptorHandler {
763                 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
764                 get { return descriptorHandler; }
765                 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
766                 set { descriptorHandler = value; }
767         }
768
769         public static void Refresh (Assembly assembly)
770         {
771                 foreach (Type type in assembly.GetTypes())
772                         Refresh (type);
773         }
774
775         public static void Refresh (Module module)
776         {
777                 foreach (Type type in module.GetTypes())
778                         Refresh (type);
779         }
780
781         public static void Refresh (object component)
782         {
783                 lock (componentTable)
784                 {
785                         componentTable.Remove (component);
786                 }
787                 if (Refreshed != null) Refreshed (new RefreshEventArgs (component));
788         }
789
790         public static void Refresh (Type type)
791         {
792                 lock (typeTable)
793                 {
794                         typeTable.Remove (type);
795                 }
796                 if (Refreshed != null) Refreshed (new RefreshEventArgs (type));
797         }
798
799         static EventHandler onDispose;
800
801         static void OnComponentDisposed (object sender, EventArgs args)
802         {
803                 lock (componentTable) {
804                         componentTable.Remove (sender);
805                 }
806         }
807
808         public static event RefreshEventHandler Refreshed;
809         
810         internal static ComponentInfo GetComponentInfo (IComponent com)
811         {
812                 lock (componentTable)
813                 {
814                         ComponentInfo ci = (ComponentInfo) componentTable [com];
815                         if (ci == null) {
816                                 if (onDispose == null)
817                                         onDispose = new EventHandler (OnComponentDisposed);
818
819                                 com.Disposed += onDispose;
820                                 ci = new ComponentInfo (com);
821                                 componentTable [com] = ci;
822                         }
823                         return ci;
824                 }
825         }
826         
827         internal static TypeInfo GetTypeInfo (Type type)
828         {
829                 lock (typeTable)
830                 {
831                         TypeInfo ci = (TypeInfo) typeTable [type];
832                         if (ci == null) {
833                                 ci = new TypeInfo (type);
834                                 typeTable [type] = ci;
835                         }
836                         return ci;
837                 }
838         }
839         
840         internal static Type GetTypeFromName (IComponent component, string typeName)
841         {
842                 if (component != null && component.Site != null) {
843                         ITypeResolutionService resver = (ITypeResolutionService) component.Site.GetService (typeof(ITypeResolutionService));
844                         if (resver != null)
845                                 return resver.GetType (typeName, true, false);
846                 }
847                 
848                 Type t = Type.GetType (typeName);
849                 if (t == null) throw new ArgumentException ("Type '" + typeName + "' not found");
850                 return t;
851         }
852 }
853
854         internal abstract class Info
855         {
856                 Type _infoType;
857                 EventDescriptor _defaultEvent;
858                 bool _gotDefaultEvent;
859                 PropertyDescriptor _defaultProperty;
860                 bool _gotDefaultProperty;
861                 AttributeCollection _attributes;
862                 
863                 public Info (Type infoType)
864                 {
865                         _infoType = infoType;
866                 }
867                 
868                 public abstract AttributeCollection GetAttributes ();
869                 public abstract EventDescriptorCollection GetEvents ();
870                 public abstract PropertyDescriptorCollection GetProperties ();
871                 
872                 public Type InfoType
873                 {
874                         get { return _infoType; }
875                 }
876                 
877                 public EventDescriptorCollection GetEvents (Attribute[] attributes)
878                 {
879                         EventDescriptorCollection evs = GetEvents ();
880                         if (attributes == null)
881                                 return evs;
882                         else
883                                 return evs.Filter (attributes);
884                 }
885                 
886                 public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
887                 {
888                         PropertyDescriptorCollection props = GetProperties ();
889                         if (attributes == null)
890                                 return props;
891                         else
892                                 return props.Filter (attributes);
893                 }
894                 
895                 public EventDescriptor GetDefaultEvent ()
896                 {
897                         if (_gotDefaultEvent)
898                                 return _defaultEvent;
899                         
900                         DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
901                         if (attr == null || attr.Name == null) 
902                                 _defaultEvent = null;
903                         else {
904                                 EventDescriptorCollection events = GetEvents ();
905                                 _defaultEvent = events [attr.Name];
906 #if !NET_2_0
907                                 // In our test case (TypeDescriptorTest.TestGetDefaultEvent), we have
908                                 // a scenario where a custom filter adds the DefaultEventAttribute,
909                                 // but its FilterEvents method removes the event the
910                                 // DefaultEventAttribute applied to.  .NET 1.x accepts this and returns
911                                 // the *other* event defined in the class.
912                                 //
913                                 // Consequently, we know we have a DefaultEvent, but we need to check
914                                 // and ensure that the requested event is unfiltered.  If it is, just
915                                 // grab the first element in the collection.
916                                 if (_defaultEvent == null && events.Count > 0)
917                                         _defaultEvent = events [0];
918 #endif
919                         }
920                         _gotDefaultEvent = true;
921                         return _defaultEvent;
922                 }
923                 
924                 public PropertyDescriptor GetDefaultProperty ()
925                 {
926                         if (_gotDefaultProperty)
927                                 return _defaultProperty;
928                         
929                         DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
930                         if (attr == null || attr.Name == null) 
931                                 _defaultProperty = null;
932                         else {
933                                 PropertyDescriptorCollection properties = GetProperties ();
934                                 _defaultProperty = properties[attr.Name];
935                         }
936                         _gotDefaultProperty = true;
937                         return _defaultProperty;
938                 }
939                 
940                 protected AttributeCollection GetAttributes (IComponent comp)
941                 {
942                         if (_attributes != null)
943                                 return _attributes;
944                         
945                         bool cache = true;
946                         object[] ats = _infoType.GetCustomAttributes (true);
947                         Hashtable t = new Hashtable ();
948
949                         // Filter the custom attributes, so that only the top
950                         // level of the same type are left.
951                         //
952                         for (int i = ats.Length -1; i >= 0; i--) {
953                                 t [((Attribute) ats[i]).TypeId] = ats[i];
954                         }
955                                         
956                         if (comp != null && comp.Site != null) 
957                         {
958                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) comp.Site.GetService (typeof(ITypeDescriptorFilterService));
959                                 if (filter != null)
960                                         cache = filter.FilterAttributes (comp, t);
961                         }
962                         
963                         ArrayList atts = new ArrayList ();
964                         atts.AddRange (t.Values);
965                         AttributeCollection attCol = new AttributeCollection (atts);
966                         if (cache)
967                                 _attributes = attCol;
968                         return attCol;
969                 }
970         }
971
972         internal class ComponentInfo : Info
973         {
974                 IComponent _component;
975                 EventDescriptorCollection _events;
976                 PropertyDescriptorCollection _properties;
977                 
978                 public ComponentInfo (IComponent component): base (component.GetType())
979                 {
980                         _component = component;
981                 }
982                 
983                 public override AttributeCollection GetAttributes ()
984                 {
985                         return base.GetAttributes (_component);
986                 }
987                 
988                 public override EventDescriptorCollection GetEvents ()
989                 {
990                         if (_events != null)
991                                 return _events;
992                         
993                         bool cache = true;
994                         EventInfo[] events = _component.GetType().GetEvents ();
995                         Hashtable t = new Hashtable ();
996                         foreach (EventInfo ev in events)
997                                 t [ev.Name] = new ReflectionEventDescriptor (ev);
998                                         
999                         if (_component.Site != null) 
1000                         {
1001                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1002                                 if (filter != null)
1003                                         cache = filter.FilterEvents (_component, t);
1004                         }
1005                         
1006                         ArrayList atts = new ArrayList ();
1007                         atts.AddRange (t.Values);
1008                         EventDescriptorCollection attCol = new EventDescriptorCollection (atts);
1009                         if (cache) _events = attCol;
1010                         return attCol;
1011                 }
1012                 
1013                 public override PropertyDescriptorCollection GetProperties ()
1014                 {
1015                         if (_properties != null)
1016                                 return _properties;
1017                         
1018                         bool cache = true;
1019                         PropertyInfo[] props = _component.GetType().GetProperties (BindingFlags.Instance | BindingFlags.Public);
1020                         Hashtable t = new Hashtable ();
1021                         for (int i = props.Length-1; i >= 0; i--)
1022                                 t [props[i].Name] = new ReflectionPropertyDescriptor (props[i]);
1023                                         
1024                         if (_component.Site != null) 
1025                         {
1026                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1027                                 if (filter != null)
1028                                         cache = filter.FilterProperties (_component, t);
1029                         }
1030
1031                         PropertyDescriptor[] descriptors = new PropertyDescriptor[t.Values.Count];
1032                         t.Values.CopyTo (descriptors, 0);
1033                         PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (descriptors, true);
1034                         if (cache)
1035                                 _properties = attCol;
1036                         return attCol;
1037                 }
1038         }
1039         
1040         internal class TypeInfo : Info
1041         {
1042                 EventDescriptorCollection _events;
1043                 PropertyDescriptorCollection _properties;
1044                 
1045                 public TypeInfo (Type t): base (t)
1046                 {
1047                 }
1048                 
1049                 public override AttributeCollection GetAttributes ()
1050                 {
1051                         return base.GetAttributes (null);
1052                 }
1053                 
1054                 public override EventDescriptorCollection GetEvents ()
1055                 {
1056                         if (_events != null)
1057                                 return _events;
1058                         
1059                         EventInfo[] events = InfoType.GetEvents ();
1060                         EventDescriptor[] descs = new EventDescriptor [events.Length];
1061                         for (int n=0; n<events.Length; n++)
1062                                 descs [n] = new ReflectionEventDescriptor (events[n]);
1063
1064                         _events = new EventDescriptorCollection (descs);
1065                         return _events;
1066                 }
1067                 
1068                 public override PropertyDescriptorCollection GetProperties ()
1069                 {
1070                         if (_properties != null)
1071                                 return _properties;
1072                         
1073                         PropertyInfo[] props = InfoType.GetProperties (BindingFlags.Instance | BindingFlags.Public);
1074                         Hashtable descs = new Hashtable ();
1075                         for (int n= props.Length-1; n >= 0; n--)
1076                                 if (props [n].GetIndexParameters ().Length == 0)
1077                                         descs[props[n].Name] = new ReflectionPropertyDescriptor (props[n]);
1078
1079                         PropertyDescriptor[] descriptors = new PropertyDescriptor[descs.Values.Count];
1080                         descs.Values.CopyTo (descriptors, 0);
1081                         _properties = new PropertyDescriptorCollection (descriptors, true);
1082                         return _properties;
1083                 }
1084         }
1085 }