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