1 //------------------------------------------------------------------------------
2 // <copyright file="MobileControlsSection.cs" company="Microsoft Corporation">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 
7 using System.Collections;
8 using System.ComponentModel;
9 using System.Configuration;
10 using System.Diagnostics;
11 using System.Globalization;
12 
13 namespace System.Web.UI.MobileControls
14 {
15     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
16     public sealed class MobileControlsSection : ConfigurationSection
17     {
18         private ControlsConfig _controlConfig;
19         private object _lock = new object();
20         internal static readonly TypeConverter              StdTypeNameConverter        = new MobileTypeNameConverter();
21         internal static readonly ConfigurationValidatorBase NonEmptyStringValidator     = new StringValidator( 1 );
22 
23         private static ConfigurationPropertyCollection _properties;
24 
25         #region Property Declarations
26         private static readonly ConfigurationProperty   _propHistorySize =
27             new ConfigurationProperty(  "sessionStateHistorySize",
28                                         typeof( int ),
29                                         Constants.DefaultSessionsStateHistorySize,
30                                         null,
31                                         new IntegerValidator( 0 ,int.MaxValue),
32                                         ConfigurationPropertyOptions.None );
33         private static readonly ConfigurationProperty   _propDictType =
34             new ConfigurationProperty(  "cookielessDataDictionaryType",
35                                         typeof( Type ),
36                                         typeof( System.Web.Mobile.CookielessData ),
37                                         MobileControlsSection.StdTypeNameConverter,
38                                         new SubclassTypeValidator( typeof( IDictionary ) ),
39                                         ConfigurationPropertyOptions.None );
40         private static readonly ConfigurationProperty   _propAllowCustomAttributes =
41             new ConfigurationProperty(  "allowCustomAttributes",
42                                         typeof( bool ),
43                                         false,
44                                         ConfigurationPropertyOptions.None );
45         private static readonly ConfigurationProperty   _propDevices =
46             new ConfigurationProperty( null,
47                                        typeof( DeviceElementCollection ),
48                                        null,
49                                        ConfigurationPropertyOptions.IsDefaultCollection );
50         #endregion
51 
MobileControlsSection()52         static MobileControlsSection()
53         {
54             // Property initialization
55             _properties = new ConfigurationPropertyCollection();
56             _properties.Add( _propHistorySize );
57             _properties.Add( _propDevices );
58             _properties.Add( _propDictType );
59             _properties.Add( _propAllowCustomAttributes );
60         }
61 
MobileControlsSection()62         public MobileControlsSection()
63         {
64         }
65 
66         // VSWhidbey 450801. Only create one ControlsConfig per MobileControlsSection instance.
GetControlsConfig()67         internal ControlsConfig GetControlsConfig() {
68             if (_controlConfig == null) {
69                 lock (_lock) {
70                     if (_controlConfig == null) {
71                         _controlConfig = MobileControlsSectionHelper.CreateControlsConfig(this);
72                     }
73                 }
74             }
75             return _controlConfig;
76         }
77 
78         protected override ConfigurationPropertyCollection Properties
79         {
80             get
81             {
82                 return _properties;
83             }
84         }
85 
86         [ConfigurationProperty("sessionStateHistorySize", DefaultValue = 6)]
87         [IntegerValidator(MinValue = 0)]
88         public int SessionStateHistorySize
89         {
90             get
91             {
92                 return (int)base[ _propHistorySize ];
93             }
94             set
95             {
96                 base[ _propHistorySize ] = value;
97             }
98         }
99 
100         [ConfigurationProperty("cookielessDataDictionaryType", DefaultValue = typeof(System.Web.Mobile.CookielessData))]
101         [TypeConverter(typeof(MobileTypeNameConverter))]
102         [SubclassTypeValidator(typeof(IDictionary))]
103         public Type CookielessDataDictionaryType
104         {
105             get
106             {
107                 return (Type)base[ _propDictType ];
108             }
109             set
110             {
111                 base[ _propDictType ] = value;
112             }
113         }
114 
115         [ConfigurationProperty("allowCustomAttributes", DefaultValue = false)]
116         public bool AllowCustomAttributes
117         {
118             get
119             {
120                 return (bool)base[ _propAllowCustomAttributes ];
121             }
122             set
123             {
124                 base[ _propAllowCustomAttributes ] = value;
125             }
126         }
127 
128         [ConfigurationProperty("", IsDefaultCollection = true)]
129         public DeviceElementCollection Devices
130         {
131             get
132             {
133                 return (DeviceElementCollection)base[ _propDevices ];
134             }
135         }
136     }
137 
138 
139     [ConfigurationCollection(typeof(DeviceElement), AddItemName="device")]
140     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
141     public sealed class DeviceElementCollection : ConfigurationElementCollection
142     {
143         private static readonly ConfigurationPropertyCollection _properties;
144 
DeviceElementCollection()145         static DeviceElementCollection()
146         {
147             _properties = new ConfigurationPropertyCollection();
148         }
DeviceElementCollection()149         public DeviceElementCollection()
150         {
151         }
152 
153         protected override ConfigurationPropertyCollection Properties
154         {
155             get
156             {
157                 return _properties;
158             }
159         }
160 
161         public object[] AllKeys
162         {
163             get
164             {
165                 return BaseGetAllKeys();
166             }
167         }
168 
Add( DeviceElement deviceElement )169         public void Add( DeviceElement deviceElement )
170         {
171             BaseAdd( deviceElement );
172         }
173 
Remove( string name )174         public void Remove( string name )
175         {
176             BaseRemove( name );
177         }
Remove( DeviceElement deviceElement )178         public void Remove( DeviceElement deviceElement )
179         {
180             BaseRemove( GetElementKey( deviceElement ) );
181         }
RemoveAt( int index )182         public void RemoveAt( int index )
183         {
184             BaseRemoveAt( index );
185         }
186         public new DeviceElement this[ string name ]
187         {
188             get
189             {
190                 return (DeviceElement)BaseGet( name );
191             }
192         }
193         public DeviceElement this[ int index ]
194         {
195             get
196             {
197                 return (DeviceElement)BaseGet( index );
198             }
199             set
200             {
201                 if ( BaseGet( index ) != null)
202                 {
203                     BaseRemoveAt( index );
204                 }
205 
206                 BaseAdd( index, value );
207             }
208         }
Clear()209         public void Clear()
210         {
211             BaseClear();
212         }
213 
CreateNewElement()214         protected override ConfigurationElement CreateNewElement()
215         {
216             return new DeviceElement();
217         }
218 
GetElementKey( ConfigurationElement element )219         protected override Object GetElementKey( ConfigurationElement element )
220         {
221             return ( (DeviceElement)element ).Name;
222         }
223 
224         protected override string ElementName
225         {
226             get
227             {
228                 return "device";
229             }
230         }
231 
232         protected override bool ThrowOnDuplicate
233         {
234             get
235             {
236                 return true;
237             }
238         }
239 
240         public override ConfigurationElementCollectionType CollectionType
241         {
242             get
243             {
244                 return ConfigurationElementCollectionType.BasicMapAlternate;
245             }
246         }
247     }
248 
249 
250     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
251     public sealed class DeviceElement : ConfigurationElement
252     {
253         private static readonly ConfigurationElementProperty s_elemProperty = new ConfigurationElementProperty( new CallbackValidator( typeof( DeviceElement ), ValidateElement ) );
254         private static ConfigurationPropertyCollection _properties;
255 
256         #region Property Declarations
257         private static readonly ConfigurationProperty   _propName =
258             new ConfigurationProperty(  "name",
259                                         typeof( string ),
260                                         null,
261                                         null,
262                                         MobileControlsSection.NonEmptyStringValidator,
263                                         ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey );
264         private static readonly ConfigurationProperty   _propInheritsFrom =
265             new ConfigurationProperty(  "inheritsFrom",
266                                         typeof( string ),
267                                         null,
268                                         null,
269                                         MobileControlsSection.NonEmptyStringValidator,
270                                         ConfigurationPropertyOptions.None );
271         private static readonly ConfigurationProperty   _propPredicateClass =
272             new ConfigurationProperty(  "predicateClass",
273                                         typeof( Type ),
274                                         null,
275                                         MobileControlsSection.StdTypeNameConverter,
276                                         null,
277                                         ConfigurationPropertyOptions.None );
278         private static readonly ConfigurationProperty   _propPredicateMethod =
279             new ConfigurationProperty(  "predicateMethod",
280                                         typeof( string ),
281                                         null,
282                                         null,
283                                         MobileControlsSection.NonEmptyStringValidator,
284                                         ConfigurationPropertyOptions.None );
285         private static readonly ConfigurationProperty   _propPageAdapter =
286             new ConfigurationProperty(  "pageAdapter",
287                                         typeof( Type ),
288                                         null,
289                                         MobileControlsSection.StdTypeNameConverter,
290                                         new SubclassTypeValidator( typeof( IPageAdapter ) ),
291                                         ConfigurationPropertyOptions.None );
292         private static readonly ConfigurationProperty _propControls =
293             new ConfigurationProperty(  null,
294                                         typeof(ControlElementCollection),
295                                         null,
296                                         ConfigurationPropertyOptions.IsDefaultCollection );
297         #endregion
298 
DeviceElement()299         static DeviceElement()
300         {
301             // Property initialization
302             _properties = new ConfigurationPropertyCollection();
303             _properties.Add( _propName );
304             _properties.Add( _propInheritsFrom );
305             _properties.Add( _propPredicateClass );
306             _properties.Add( _propPredicateMethod );
307             _properties.Add( _propPageAdapter );
308             _properties.Add( _propControls );
309         }
DeviceElement()310         internal DeviceElement()
311         {
312         }
DeviceElement( string name, string inheritsFrom )313         public DeviceElement( string name, string inheritsFrom )
314         {
315             base[ _propName ]           = name;
316             base[ _propInheritsFrom ]   = inheritsFrom;
317         }
318 
DeviceElement( string name, Type predicateClass, string predicateMethod, Type pageAdapter )319         public DeviceElement( string name, Type predicateClass, string predicateMethod, Type pageAdapter )
320         {
321             base[ _propName] = name;
322             base[ _propPredicateClass] = predicateClass;
323             base[ _propPredicateMethod] = predicateMethod;
324             base[ _propPageAdapter ] = pageAdapter;
325         }
326 
DeviceElement(string name, string inheritsFrom, Type predicateClass, string predicateMethod, Type pageAdapter)327         public DeviceElement(string name, string inheritsFrom, Type predicateClass,
328                              string predicateMethod, Type pageAdapter)
329         {
330             base[ _propName] = name;
331             base[ _propInheritsFrom ] = inheritsFrom;
332             base[ _propPredicateClass] = predicateClass;
333             base[ _propPredicateMethod] = predicateMethod;
334             base[ _propPageAdapter ] = pageAdapter;
335         }
336 
337         protected override ConfigurationPropertyCollection Properties
338         {
339             get
340             {
341                 return _properties;
342             }
343         }
344 
345         [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
346         [StringValidator(MinLength = 1)]
347         public string Name
348         {
349             get
350             {
351                 return (string)base[ _propName ];
352             }
353             set
354             {
355                 base[ _propName ] = value;
356             }
357         }
358 
359         [ConfigurationProperty("inheritsFrom")]
360         [StringValidator(MinLength = 1)]
361         public string InheritsFrom
362         {
363             get
364             {
365                 return (string)base[ _propInheritsFrom ];
366             }
367             set
368             {
369                 base[ _propInheritsFrom ] = value;
370             }
371         }
372 
373         [ConfigurationProperty("predicateClass")]
374         [TypeConverter(typeof(MobileTypeNameConverter))]
375         public Type PredicateClass
376         {
377             get
378             {
379                 return (Type)base[ _propPredicateClass ];
380             }
381             set
382             {
383                 base[ _propPredicateClass ] = value;
384             }
385         }
386 
387         [ConfigurationProperty("predicateMethod")]
388         [StringValidator(MinLength = 1)]
389         public string PredicateMethod
390         {
391             get
392             {
393                 return (string)base[ _propPredicateMethod ];
394             }
395             set
396             {
397                 base[ _propPredicateMethod ] = value;
398             }
399         }
400 
401         [ConfigurationProperty("pageAdapter")]
402         [TypeConverter(typeof(MobileTypeNameConverter))]
403         [SubclassTypeValidator(typeof(IPageAdapter))]
404         public Type PageAdapter
405         {
406             get
407             {
408                 return (Type)base[_propPageAdapter];
409             }
410             set
411             {
412                 base[_propPageAdapter] = value;
413             }
414         }
415 
416         [ConfigurationProperty("", IsDefaultCollection = true)]
417         public ControlElementCollection Controls
418         {
419             get
420             {
421                 return (ControlElementCollection)base[ _propControls ];
422             }
423         }
424 
425         protected override ConfigurationElementProperty ElementProperty
426         {
427             get
428             {
429                 return s_elemProperty;
430             }
431         }
432 
GetDelegate()433         internal IndividualDeviceConfig.DeviceQualifiesDelegate GetDelegate()
434         {
435             try
436             {
437                 return (IndividualDeviceConfig.DeviceQualifiesDelegate)IndividualDeviceConfig.DeviceQualifiesDelegate.CreateDelegate(
438                         typeof(IndividualDeviceConfig.DeviceQualifiesDelegate),
439                         PredicateClass,
440                         PredicateMethod );
441             }
442             catch
443             {
444                 throw new ConfigurationErrorsException(
445                     SR.GetString(SR.MobileControlsSectionHandler_CantCreateMethodOnClass, PredicateMethod, PredicateClass.FullName),
446                                  ElementInformation.Source, ElementInformation.LineNumber);
447             }
448         }
449 
ValidateElement( object value )450         static private void ValidateElement( object value )
451         {
452             Debug.Assert( ( value != null ) && ( value is DeviceElement ) );
453 
454             DeviceElement elem = (DeviceElement)value;
455 
456             // If there is no inheritance the properties must exists and be valid
457             if ( string.IsNullOrEmpty(elem.InheritsFrom) )
458             {
459                 if ( elem.PredicateClass == null )
460                 {
461                     throw new ConfigurationErrorsException( SR.GetString(SR.ConfigSect_MissingValue, "predicateClass"),
462                                                             elem.ElementInformation.Source,
463                                                             elem.ElementInformation.LineNumber );
464                 }
465 
466                 if ( elem.PageAdapter == null )
467                 {
468                     throw new ConfigurationErrorsException( SR.GetString(SR.ConfigSect_MissingValue, "pageAdapter"),
469                                                             elem.ElementInformation.Source,
470                                                             elem.ElementInformation.LineNumber );
471                 }
472 
473                 // Resolve the method
474                 elem.GetDelegate();
475             }
476         }
477     }
478 
479     [ConfigurationCollection(typeof(ControlElement), AddItemName = "control")]
480     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
481     public sealed class ControlElementCollection : ConfigurationElementCollection
482     {
483         private static readonly ConfigurationPropertyCollection _properties;
484 
ControlElementCollection()485         static ControlElementCollection()
486         {
487             _properties = new ConfigurationPropertyCollection();
488         }
ControlElementCollection()489         public ControlElementCollection()
490         {
491         }
492 
493         protected override ConfigurationPropertyCollection Properties
494         {
495             get
496             {
497                 return _properties;
498             }
499         }
500 
501         public object[] AllKeys
502         {
503             get
504             {
505                 return BaseGetAllKeys();
506             }
507         }
508 
Add( ControlElement controlElement )509         public void Add( ControlElement controlElement )
510         {
511             BaseAdd( controlElement );
512         }
Remove( string name )513         public void Remove( string name )
514         {
515             BaseRemove( name );
516         }
Remove( ControlElement controlElement )517         public void Remove( ControlElement controlElement )
518         {
519             BaseRemove( GetElementKey( controlElement ) );
520         }
RemoveAt( int index )521         public void RemoveAt( int index )
522         {
523             BaseRemoveAt( index );
524         }
525         public new ControlElement this[ string name ]
526         {
527             get
528             {
529                 return (ControlElement)BaseGet( name );
530             }
531         }
532         public ControlElement this[ int index ]
533         {
534             get
535             {
536                 return (ControlElement)BaseGet( index );
537             }
538             set
539             {
540                 if ( BaseGet( index ) != null)
541                 {
542                     BaseRemoveAt( index );
543                 }
544 
545                 BaseAdd( index, value );
546             }
547         }
Clear()548         public void Clear()
549         {
550             BaseClear();
551         }
552 
CreateNewElement()553         protected override ConfigurationElement CreateNewElement()
554         {
555             return new ControlElement();
556         }
557 
GetElementKey( ConfigurationElement element )558         protected override Object GetElementKey( ConfigurationElement element )
559         {
560             return ( (ControlElement)element ).Name;
561         }
562 
563         protected override string ElementName
564         {
565             get
566             {
567                 return "control";
568             }
569         }
570 
571         protected override bool ThrowOnDuplicate
572         {
573             get
574             {
575                 return true;
576             }
577         }
578 
579         public override ConfigurationElementCollectionType CollectionType
580         {
581             get
582             {
583                 return ConfigurationElementCollectionType.BasicMap;
584             }
585         }
586     }
587 
588 
589     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
590     public sealed class ControlElement : ConfigurationElement
591     {
592         private static readonly ConfigurationElementProperty    s_elemProperty      = new ConfigurationElementProperty( new CallbackValidator( typeof( ControlElement ), ValidateElement ) );
593         private static readonly ConfigurationValidatorBase      s_SubclassTypeValidator = new SubclassTypeValidator( typeof( MobileControl ) );
594         private static ConfigurationPropertyCollection _properties;
595 
596 
597         #region Property Declarations
598         private static readonly ConfigurationProperty   _propName =
599             new ConfigurationProperty(  "name",
600                                         typeof( string ),
601                                         null,
602                                         null,
603                                         MobileControlsSection.NonEmptyStringValidator,
604                                         ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey );
605         private static readonly ConfigurationProperty   _propAdapter =
606             new ConfigurationProperty(  "adapter",
607                                         typeof( Type ),
608                                         null,
609                                         MobileControlsSection.StdTypeNameConverter,
610                                         new SubclassTypeValidator( typeof( IControlAdapter ) ),
611                                         ConfigurationPropertyOptions.IsRequired );
612         #endregion
613 
ControlElement()614         static ControlElement()
615         {
616             // Property initialization
617             _properties = new ConfigurationPropertyCollection();
618             _properties.Add( _propName );
619             _properties.Add( _propAdapter );
620         }
ControlElement()621         internal ControlElement()
622         {
623         }
ControlElement( string name, Type adapter )624         public ControlElement( string name, Type adapter )
625         {
626             base[ _propName]        = name;
627             base[ _propAdapter ]    = adapter;
628         }
629         protected override ConfigurationPropertyCollection Properties
630         {
631             get
632             {
633                 return _properties;
634             }
635         }
636 
637         [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
638         [StringValidator(MinLength = 1)]
639         public string Name
640         {
641             get
642             {
643                 return (string)base[ _propName ];
644             }
645             set
646             {
647                 base[ _propName ] = value;
648             }
649         }
650 
651         public Type Control
652         {
653             get
654             {
655                 return Type.GetType( Name );
656             }
657             set
658             {
659                 if ( value == null )
660                 {
661                     throw new ArgumentNullException( "value" );
662                 }
663 
664                 s_SubclassTypeValidator.Validate( value );
665                 Name = value.FullName;
666             }
667         }
668 
669         [ConfigurationProperty("adapter", IsRequired = true)]
670         [TypeConverter(typeof(MobileTypeNameConverter))]
671         [SubclassTypeValidator(typeof(IControlAdapter))]
672         public Type Adapter
673         {
674             get
675             {
676                 return (Type)base[ _propAdapter ];
677             }
678             set
679             {
680                 base[ _propAdapter ] = value;
681             }
682         }
683 
684         protected override ConfigurationElementProperty ElementProperty
685         {
686             get
687             {
688                 return s_elemProperty;
689             }
690         }
691 
ValidateElement( object value )692         static private void ValidateElement( object value )
693         {
694             Debug.Assert( ( value != null ) && ( value is ControlElement ) );
695 
696             ControlElement elem = (ControlElement)value;
697 
698             // Make sure Name is a valid type
699 
700             // This will throw if the type cannot be resolved
701             Type tp = MobileControlsSection.StdTypeNameConverter.ConvertFromInvariantString( elem.Name ) as Type;
702 
703             // Validate that tp inherits from MobileControl
704             s_SubclassTypeValidator.Validate( tp );
705         }
706     }
707 
708     // From old versions the default type names specified in mobile control config
709     // section do not associate with assembly names.  So we cannot use
710     // System.Configuration.TypeNameConverter as it wouldn't look up the type
711     // names in the mobile assembly.  To workaround it, we create the same
712     // converter here to be used in the mobile assembly.
713     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
714     public sealed class MobileTypeNameConverter : ConfigurationConverterBase {
715 
ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type targetType)716         public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci,
717                                          object value, Type targetType) {
718             Debug.Assert(targetType != null);
719             Type valueType = value as Type;
720             if (valueType == null) {
721                 throw new ArgumentException(SR.GetString(SR.MobileTypeNameConverter_UnsupportedValueType,
722                                                           ((value == null) ? String.Empty : value.ToString()),
723                                                           targetType.FullName));
724             }
725 
726             return valueType.FullName;
727         }
728 
ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)729         public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data) {
730             Debug.Assert(data is string);
731             Type result = Type.GetType((string)data);
732             if (result == null) {
733                 throw new ConfigurationErrorsException(
734                     SR.GetString(SR.MobileTypeNameConverter_TypeNotResolved, (string)data));
735             }
736 
737             return result;
738         }
739     }
740 }
741 
742 
743 
744