svn path=/branches/mono-1-1-9/mcs/; revision=50438
[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;
34 using System.Collections;
35 using System.Reflection;
36 using System.Globalization;
37 using System.ComponentModel.Design;
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
50         private TypeDescriptor ()
51         {
52         }
53
54         [MonoTODO]
55         public static void AddEditorTable (Type editorBaseType, Hashtable table)
56         {
57                 throw new NotImplementedException ();
58         }
59
60         public static IDesigner CreateDesigner(IComponent component, Type designerBaseType)
61         {
62                 string tn = designerBaseType.AssemblyQualifiedName;
63                 AttributeCollection col = GetAttributes (component);
64                 
65                 foreach (Attribute at in col) {
66                         DesignerAttribute dat = at as DesignerAttribute;
67                         if (dat != null && tn == dat.DesignerBaseTypeName) {
68                                 return (IDesigner) Activator.CreateInstance (GetTypeFromName (component, dat.DesignerTypeName));
69                         }
70                 }
71                                 
72                 return null;
73         }
74
75         public static EventDescriptor CreateEvent (Type componentType,
76                                                    string name,
77                                                    Type type,
78                                                    Attribute [] attributes)
79         {
80                 return new ReflectionEventDescriptor (componentType, name, type, attributes);
81         }
82
83         public static EventDescriptor CreateEvent (Type componentType,
84                                                    EventDescriptor oldEventDescriptor,
85                                                    Attribute [] attributes)
86         {
87                 return new ReflectionEventDescriptor (componentType, oldEventDescriptor, attributes);
88         }
89
90         public static PropertyDescriptor CreateProperty (Type componentType,
91                                                          string name,
92                                                          Type type,
93                                                          Attribute [] attributes)
94         {
95                 return new ReflectionPropertyDescriptor (componentType, name, type, attributes);
96         }
97
98         public static PropertyDescriptor CreateProperty (Type componentType,
99                                                          PropertyDescriptor oldPropertyDescriptor,
100                                                          Attribute [] attributes)
101         {
102                 return new ReflectionPropertyDescriptor (componentType, oldPropertyDescriptor, attributes);
103         }
104
105         public static AttributeCollection GetAttributes (Type componentType)
106         {
107                 if (componentType == null)
108                         return AttributeCollection.Empty;
109
110                 return GetTypeInfo (componentType).GetAttributes ();
111         }
112
113         public static AttributeCollection GetAttributes (object component)
114         {
115                 return GetAttributes (component, false);
116         }
117
118         public static AttributeCollection GetAttributes (object component, bool noCustomTypeDesc)
119         {
120                 if (component == null)
121                     return AttributeCollection.Empty;
122
123                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
124                     return ((ICustomTypeDescriptor) component).GetAttributes ();
125                 } else {
126                         IComponent com = component as IComponent;
127                         if (com != null)
128                                 return GetComponentInfo (com).GetAttributes ();
129                         else
130                                 return GetTypeInfo (component.GetType()).GetAttributes ();
131                 }
132         }
133
134         public static string GetClassName (object component)
135         {
136                 return GetClassName (component, false);
137         }
138
139         public static string GetClassName (object component, bool noCustomTypeDesc)
140         {
141                 if (component == null)
142                     throw new ArgumentNullException ("component", "component cannot be null");
143
144                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
145                     return ((ICustomTypeDescriptor) component).GetClassName ();
146                 } else {
147                     return component.GetType ().FullName;
148                 }
149         }
150
151         public static string GetComponentName (object component)
152         {
153                 return GetComponentName (component, false);
154         }
155
156         public static string GetComponentName (object component, bool noCustomTypeDesc)
157         {
158                 if (component == null)
159                     throw new ArgumentNullException ("component", "component cannot be null");
160
161                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
162                     return ((ICustomTypeDescriptor) component).GetComponentName ();
163                 } else {
164                         IComponent c = component as IComponent;
165                         if (c != null && c.Site != null)
166                                 return c.Site.Name;
167 #if NET_2_0
168                         return null;
169 #else
170
171 #endif
172                         return component.GetType().Name;
173                 }
174         }
175
176         public static TypeConverter GetConverter (object component)
177         {
178                 return GetConverter (component.GetType ());
179         }
180
181         public static TypeConverter GetConverter (object component, bool noCustomTypeDesc)
182         {
183                 if (component == null)
184                         throw new ArgumentNullException ("component", "component cannot be null");
185
186                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
187                         return ((ICustomTypeDescriptor) component).GetConverter ();
188                 } 
189                 else {
190                         Type t = null;
191                         AttributeCollection atts = GetAttributes (component, false);
192                         TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)];
193                         if (tca != null && tca.ConverterTypeName.Length > 0) {
194                                 t = GetTypeFromName (component as IComponent, tca.ConverterTypeName);
195                         }
196                         
197                         if (t != null) {
198                                 ConstructorInfo ci = t.GetConstructor (new Type[] { typeof(Type) });
199                                 if (ci != null)
200                                         return (TypeConverter) ci.Invoke (new object[] { component.GetType () });
201                                 else
202                                         return (TypeConverter) Activator.CreateInstance (t);
203                         }
204                         else
205                                 return GetConverter (component.GetType ());
206                 }
207         }
208
209         private static Hashtable DefaultConverters
210         {
211                 get {
212                         lock (creatingDefaultConverters) {
213                                 if (defaultConverters != null)
214                                         return defaultConverters;
215                                 
216                                 defaultConverters = new Hashtable ();
217                                 defaultConverters.Add (typeof (bool), typeof (BooleanConverter));
218                                 defaultConverters.Add (typeof (byte), typeof (ByteConverter));
219                                 defaultConverters.Add (typeof (sbyte), typeof (SByteConverter));
220                                 defaultConverters.Add (typeof (string), typeof (StringConverter));
221                                 defaultConverters.Add (typeof (char), typeof (CharConverter));
222                                 defaultConverters.Add (typeof (short), typeof (Int16Converter));
223                                 defaultConverters.Add (typeof (int), typeof (Int32Converter));
224                                 defaultConverters.Add (typeof (long), typeof (Int64Converter));
225                                 defaultConverters.Add (typeof (ushort), typeof (UInt16Converter));
226                                 defaultConverters.Add (typeof (uint), typeof (UInt32Converter));
227                                 defaultConverters.Add (typeof (ulong), typeof (UInt64Converter));
228                                 defaultConverters.Add (typeof (float), typeof (SingleConverter));
229                                 defaultConverters.Add (typeof (double), typeof (DoubleConverter));
230                                 defaultConverters.Add (typeof (decimal), typeof (DecimalConverter));
231                                 defaultConverters.Add (typeof (object), typeof (TypeConverter));
232                                 defaultConverters.Add (typeof (void), typeof (TypeConverter));
233                                 defaultConverters.Add (typeof (Array), typeof (ArrayConverter));
234                                 defaultConverters.Add (typeof (CultureInfo), typeof (CultureInfoConverter));
235                                 defaultConverters.Add (typeof (DateTime), typeof (DateTimeConverter));
236                                 defaultConverters.Add (typeof (Guid), typeof (GuidConverter));
237                                 defaultConverters.Add (typeof (TimeSpan), typeof (TimeSpanConverter));
238                                 defaultConverters.Add (typeof (ICollection), typeof (CollectionConverter));
239                         }
240                         return defaultConverters;
241                 }
242         }
243         
244         public static TypeConverter GetConverter (Type type)
245         {
246                 TypeConverterAttribute tca = null;
247                 Type t = null;
248                 object [] atts = type.GetCustomAttributes (typeof(TypeConverterAttribute), true);
249                 
250                 if (atts.Length > 0)
251                         tca = (TypeConverterAttribute)atts[0];
252                 
253                 if (tca != null) {
254                         t = GetTypeFromName (null, tca.ConverterTypeName);
255                 }
256                 
257                 if (t == null) {
258                         if (type.IsEnum) {
259                                 // EnumConverter needs to know the enum type
260                                 return new EnumConverter(type);
261                         } else if (type.IsArray) {
262                                 return new ArrayConverter ();
263                         }
264                 }
265                 
266                 if (t == null)
267                         t = FindConverterType (type);
268
269                 if (t != null) {
270                         Exception exc = null;
271                         try {
272                                 return (TypeConverter) Activator.CreateInstance (t);
273                         } catch (MissingMethodException e) {
274                                 exc = e;
275                         }
276
277                         try {
278                                 return (TypeConverter) Activator.CreateInstance (t, new object [] {type});
279                         } catch (MissingMethodException e) {
280                                 throw exc;
281                         }
282                 }
283
284                 return new ReferenceConverter (type);    // Default?
285         }
286
287         private static Type FindConverterType (Type type)
288         {
289                 Type t = null;
290                 
291                 // Is there a default converter
292                 t = (Type) DefaultConverters [type];
293                 if (t != null)
294                         return t;
295                 
296                 // Find default converter with a type this type is assignable to
297                 foreach (Type defType in DefaultConverters.Keys) {
298                         if (defType.IsInterface && defType.IsAssignableFrom (type)) {
299                                 return (Type) DefaultConverters [defType];
300                         }
301                 }
302                 
303                 // Nothing found, try the same with our base type
304                 if (type.BaseType != null)
305                         return FindConverterType (type.BaseType);
306                 else
307                         return null;
308         }
309
310         public static EventDescriptor GetDefaultEvent (Type componentType)
311         {
312                 return GetTypeInfo (componentType).GetDefaultEvent ();
313         }
314
315         public static EventDescriptor GetDefaultEvent (object component)
316         {
317                 return GetDefaultEvent (component, false);
318         }
319
320         public static EventDescriptor GetDefaultEvent (object component, bool noCustomTypeDesc)
321         {
322                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
323                         return ((ICustomTypeDescriptor) component).GetDefaultEvent ();
324                 else {
325                         IComponent com = component as IComponent;
326                         if (com != null)
327                                 return GetComponentInfo (com).GetDefaultEvent ();
328                         else
329                                 return GetTypeInfo (component.GetType()).GetDefaultEvent ();
330                 }
331         }
332
333         public static PropertyDescriptor GetDefaultProperty (Type componentType)
334         {
335                 return GetTypeInfo (componentType).GetDefaultProperty ();
336         }
337
338         public static PropertyDescriptor GetDefaultProperty (object component)
339         {
340                 return GetDefaultProperty (component, false);
341         }
342
343         public static PropertyDescriptor GetDefaultProperty (object component, bool noCustomTypeDesc)
344         {
345                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
346                         return ((ICustomTypeDescriptor) component).GetDefaultProperty ();
347                 else {
348                         IComponent com = component as IComponent;
349                         if (com != null)
350                                 return GetComponentInfo (com).GetDefaultProperty ();
351                         else
352                                 return GetTypeInfo (component.GetType()).GetDefaultProperty ();
353                 }
354         }
355
356         public static object GetEditor (Type componentType, Type editorBaseType)
357         {
358                 Type t = null;
359                 object [] atts = componentType.GetCustomAttributes (typeof(EditorAttribute), true);
360                 if (atts == null || atts.Length == 0)
361                         return null;
362                 
363                 
364                 foreach (EditorAttribute ea in atts)
365                 {
366                         t = GetTypeFromName (null, ea.EditorTypeName);
367                         if (t.IsSubclassOf(editorBaseType))
368                                 break;
369                 }
370
371                 if (t != null) {
372                         Exception exc = null;
373                         try {
374                                 return Activator.CreateInstance (t);
375                         } catch (MissingMethodException e) {
376                                 exc = e;
377                         }
378
379                         try {
380                                 return Activator.CreateInstance (t, new object [] {componentType});
381                         } catch (MissingMethodException e) {
382                                 throw exc;
383                         }
384                 }
385
386                 return null;    // No editor specified
387         }
388
389         public static object GetEditor (object component, Type editorBaseType)
390         {
391                 return GetEditor (component, editorBaseType, false);
392         }
393
394         [MonoTODO]
395         public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
396         {
397                 throw new NotImplementedException ();
398         }
399
400         public static EventDescriptorCollection GetEvents (object component)
401         {
402                 return GetEvents (component, false);
403         }
404
405         public static EventDescriptorCollection GetEvents (Type componentType)
406         {
407                 return GetEvents (componentType, null);
408         }
409
410         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes)
411         {
412                 return GetEvents (component, attributes, false);
413         }
414
415         public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
416         {
417                 return GetEvents (component, null, noCustomTypeDesc);
418         }
419
420         public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
421         {
422                 return GetTypeInfo (componentType).GetEvents (attributes);
423         }
424
425         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc)
426         {
427                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
428                         return ((ICustomTypeDescriptor) component).GetEvents (attributes);
429                 else {
430                         IComponent com = component as IComponent;
431                         if (com != null)
432                                 return GetComponentInfo (com).GetEvents (attributes);
433                         else
434                                 return GetTypeInfo (component.GetType()).GetEvents (attributes);
435                 }
436         }
437
438         public static PropertyDescriptorCollection GetProperties (object component)
439         {
440                 return GetProperties (component, false);
441         }
442
443         public static PropertyDescriptorCollection GetProperties (Type componentType)
444         {
445                 return GetProperties (componentType, null);
446         }
447
448         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes)
449         {
450                 return GetProperties (component, attributes, false);
451         }
452
453         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
454         {
455                 if (component == null)
456                         throw new ArgumentNullException ("component");
457
458                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
459                         return ((ICustomTypeDescriptor) component).GetProperties (attributes);
460                 else {
461                         IComponent com = component as IComponent;
462                         if (com != null)
463                                 return GetComponentInfo (com).GetProperties (attributes);
464                         else
465                                 return GetTypeInfo (component.GetType()).GetProperties (attributes);
466                 }
467         }
468
469         public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
470         {
471                 return GetProperties (component, null, noCustomTypeDesc);
472         }
473
474         public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
475         {
476                 return GetTypeInfo (componentType).GetProperties (attributes);
477         }
478
479         public static void SortDescriptorArray (IList infos)
480         {
481                 string[] names = new string [infos.Count];
482                 object[] values = new object [infos.Count];
483                 for (int n=0; n<names.Length; n++) {
484                         names[n] = ((MemberDescriptor)infos[n]).Name;
485                         values[n] = infos[n];
486                 }
487                 Array.Sort (names, values);
488                 infos.Clear();
489                 foreach (object ob in values)
490                         infos.Add (ob);
491         }
492
493         public static IComNativeDescriptorHandler ComNativeDescriptorHandler {
494                 get { return descriptorHandler; }
495                 set { descriptorHandler = value; }
496         }
497
498         public static void Refresh (Assembly assembly)
499         {
500                 foreach (Type type in assembly.GetTypes())
501                         Refresh (type);
502         }
503
504         public static void Refresh (Module module)
505         {
506                 foreach (Type type in module.GetTypes())
507                         Refresh (type);
508         }
509
510         public static void Refresh (object component)
511         {
512                 lock (componentTable)
513                 {
514                         componentTable.Remove (component);
515                 }
516                 if (Refreshed != null) Refreshed (new RefreshEventArgs (component));
517         }
518
519         public static void Refresh (Type type)
520         {
521                 lock (typeTable)
522                 {
523                         typeTable.Remove (type);
524                 }
525                 if (Refreshed != null) Refreshed (new RefreshEventArgs (type));
526         }
527
528         static EventHandler onDispose;
529
530         static void OnComponentDisposed (object sender, EventArgs args)
531         {
532                 lock (componentTable) {
533                         componentTable.Remove (sender);
534                 }
535         }
536
537         public static event RefreshEventHandler Refreshed;
538         
539         internal static ComponentInfo GetComponentInfo (IComponent com)
540         {
541                 lock (componentTable)
542                 {
543                         ComponentInfo ci = (ComponentInfo) componentTable [com];
544                         if (ci == null) {
545                                 if (onDispose == null)
546                                         onDispose = new EventHandler (OnComponentDisposed);
547
548                                 com.Disposed += onDispose;
549                                 ci = new ComponentInfo (com);
550                                 componentTable [com] = ci;
551                         }
552                         return ci;
553                 }
554         }
555         
556         internal static TypeInfo GetTypeInfo (Type type)
557         {
558                 lock (typeTable)
559                 {
560                         TypeInfo ci = (TypeInfo) typeTable [type];
561                         if (ci == null) {
562                                 ci = new TypeInfo (type);
563                                 typeTable [type] = ci;
564                         }
565                         return ci;
566                 }
567         }
568         
569         static Type GetTypeFromName (IComponent component, string typeName)
570         {
571                 if (component != null && component.Site != null) {
572                         ITypeResolutionService resver = (ITypeResolutionService) component.Site.GetService (typeof(ITypeResolutionService));
573                         if (resver != null) return resver.GetType (typeName, true, false);
574                 }
575                 
576                 Type t = Type.GetType (typeName);
577                 if (t == null) throw new ArgumentException ("Type '" + typeName + "' not found");
578                 return t;
579         }
580 }
581
582         internal abstract class Info
583         {
584                 Type _infoType;
585                 EventDescriptor _defaultEvent;
586                 bool _gotDefaultEvent;
587                 PropertyDescriptor _defaultProperty;
588                 bool _gotDefaultProperty;
589                 AttributeCollection _attributes;
590                 
591                 public Info (Type infoType)
592                 {
593                         _infoType = infoType;
594                 }
595                 
596                 public abstract AttributeCollection GetAttributes ();
597                 public abstract EventDescriptorCollection GetEvents ();
598                 public abstract PropertyDescriptorCollection GetProperties ();
599                 
600                 public Type InfoType
601                 {
602                         get { return _infoType; }
603                 }
604                 
605                 public EventDescriptorCollection GetEvents (Attribute[] attributes)
606                 {
607                         EventDescriptorCollection evs = GetEvents ();
608                         if (attributes == null) return evs;
609                         else return evs.Filter (attributes);
610                 }
611                 
612                 public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
613                 {
614                         PropertyDescriptorCollection props = GetProperties ();
615                         if (attributes == null) return props;
616                         else return props.Filter (attributes);
617                 }
618                 
619                 public EventDescriptor GetDefaultEvent ()
620                 {
621                         if (_gotDefaultEvent) return _defaultEvent;
622                         
623                         DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
624                         if (attr == null || attr.Name == null) 
625                                 _defaultEvent = null;
626                         else {
627                                 EventDescriptorCollection events = GetEvents ();
628                                 _defaultEvent = events [attr.Name];
629 #if !NET_2_0
630                                 // In our test case (TypeDescriptorTest.TestGetDefaultEvent), we have
631                                 // a scenario where a custom filter adds the DefaultEventAttribute,
632                                 // but its FilterEvents method removes the event the
633                                 // DefaultEventAttribute applied to.  .NET 1.x accepts this and returns
634                                 // the *other* event defined in the class.
635                                 //
636                                 // Consequently, we know we have a DefaultEvent, but we need to check
637                                 // and ensure that the requested event is unfiltered.  If it is, just
638                                 // grab the first element in the collection.
639                                 if (_defaultEvent == null && events.Count > 0)
640                                         _defaultEvent = events [0];
641 #endif
642                         }
643                         _gotDefaultEvent = true;
644                         return _defaultEvent;
645                 }
646                 
647                 public PropertyDescriptor GetDefaultProperty ()
648                 {
649                         if (_gotDefaultProperty) return _defaultProperty;
650                         
651                         DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
652                         if (attr == null || attr.Name == null) 
653                                 _defaultProperty = null;
654                         else {
655                                 PropertyDescriptorCollection properties = GetProperties ();
656                                 _defaultProperty = properties[attr.Name];
657                         }
658                         _gotDefaultProperty = true;
659                         return _defaultProperty;
660                 }
661                 
662                 protected AttributeCollection GetAttributes (IComponent comp)
663                 {
664                         if (_attributes != null) return _attributes;
665                         
666                         bool cache = true;
667                         object[] ats = _infoType.GetCustomAttributes (true);
668                         Hashtable t = new Hashtable ();
669                         foreach (Attribute at in ats)
670                                 t [at.TypeId] = at;
671                                         
672                         if (comp != null && comp.Site != null) 
673                         {
674                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) comp.Site.GetService (typeof(ITypeDescriptorFilterService));
675                                 cache = filter.FilterAttributes (comp, t);
676                         }
677                         
678                         ArrayList atts = new ArrayList ();
679                         atts.AddRange (t.Values);
680                         AttributeCollection attCol = new AttributeCollection (atts);
681                         if (cache) _attributes = attCol;
682                         return attCol;
683                 }
684         }
685
686         internal class ComponentInfo : Info
687         {
688                 IComponent _component;
689                 EventDescriptorCollection _events;
690                 PropertyDescriptorCollection _properties;
691                 
692                 public ComponentInfo (IComponent component): base (component.GetType())
693                 {
694                         _component = component;
695                 }
696                 
697                 public override AttributeCollection GetAttributes ()
698                 {
699                         return base.GetAttributes (_component);
700                 }
701                 
702                 public override EventDescriptorCollection GetEvents ()
703                 {
704                         if (_events != null) return _events;
705                         
706                         bool cache = true;
707                         EventInfo[] events = _component.GetType().GetEvents ();
708                         Hashtable t = new Hashtable ();
709                         foreach (EventInfo ev in events)
710                                 t [ev.Name] = new ReflectionEventDescriptor (ev);
711                                         
712                         if (_component.Site != null) 
713                         {
714                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
715                                 cache = filter.FilterEvents (_component, t);
716                         }
717                         
718                         ArrayList atts = new ArrayList ();
719                         atts.AddRange (t.Values);
720                         EventDescriptorCollection attCol = new EventDescriptorCollection (atts);
721                         if (cache) _events = attCol;
722                         return attCol;
723                 }
724                 
725                 public override PropertyDescriptorCollection GetProperties ()
726                 {
727                         if (_properties != null) return _properties;
728                         
729                         bool cache = true;
730                         PropertyInfo[] props = _component.GetType().GetProperties ();
731                         Hashtable t = new Hashtable ();
732                         foreach (PropertyInfo pr in props)
733                                 t [pr.Name] = new ReflectionPropertyDescriptor (pr);
734                                         
735                         if (_component.Site != null) 
736                         {
737                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
738                                 cache = filter.FilterProperties (_component, t);
739                         }
740                         
741                         ArrayList atts = new ArrayList ();
742                         atts.AddRange (t.Values);
743                         PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (atts);
744                         if (cache) _properties = attCol;
745                         return attCol;
746                 }
747         }
748         
749         internal class TypeInfo : Info
750         {
751                 EventDescriptorCollection _events;
752                 PropertyDescriptorCollection _properties;
753                 
754                 public TypeInfo (Type t): base (t)
755                 {
756                 }
757                 
758                 public override AttributeCollection GetAttributes ()
759                 {
760                         return base.GetAttributes (null);
761                 }
762                 
763                 public override EventDescriptorCollection GetEvents ()
764                 {
765                         if (_events != null) return _events;
766                         
767                         EventInfo[] events = InfoType.GetEvents ();
768                         EventDescriptor[] descs = new EventDescriptor [events.Length];
769                         for (int n=0; n<events.Length; n++)
770                                 descs [n] = new ReflectionEventDescriptor (events[n]);
771
772                         _events = new EventDescriptorCollection (descs);
773                         return _events;
774                 }
775                 
776                 public override PropertyDescriptorCollection GetProperties ()
777                 {
778                         if (_properties != null) return _properties;
779                         
780                         PropertyInfo[] props = InfoType.GetProperties ();
781                         PropertyDescriptor[] descs = new PropertyDescriptor [props.Length];
782                         for (int n=0; n<props.Length; n++)
783                                 descs [n] = new ReflectionPropertyDescriptor (props[n]);
784
785                         _properties = new PropertyDescriptorCollection (descs);
786                         return _properties;
787                 }
788         }
789 }