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