Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / MIT / System / Web / UI / MobileControls / IndividualDeviceConfig.cs / 1305376 / IndividualDeviceConfig.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- // Comment this out to get a version that doesn't need synchronized // access. This can be used for profiling, to compare whether the lock // or the late writing is more useful. using System; using System.Web.Configuration; using System.Configuration; using System.Xml; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Web; using System.Web.Util; using System.Threading; using System.Web.Mobile; namespace System.Web.UI.MobileControls { // Data structure for an individual device configuration. // Included predicates, page adapter type, and a list of // control/controlAdapter pairs. [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.")] internal class IndividualDeviceConfig { internal delegate bool DeviceQualifiesDelegate(HttpContext context); private String _name; private readonly ControlsConfig _controlsConfig; private DeviceQualifiesDelegate _deviceQualifiesPredicate; private Type _pageAdapterType; private IWebObjectFactory _pageAdapterFactory; // Parent device configuration. private IndividualDeviceConfig _parentConfig; private String _parentConfigName; // ControlType --> ControlAdapterType mapping (one of these // per individual device config) private readonly Hashtable _controlAdapterTypes = new Hashtable(); // ControlType --> ControlAdapterType mapping cache, used to // store mappings that are derived from a complex lookup (one of these // per individual device config) private readonly Hashtable _controlAdapterLookupCache = new Hashtable(); // Provide synchronized access to the hashtable, allowing // multiple readers but just one writer. Here we have one per // device config. private readonly ReaderWriterLock _controlAdapterTypesLock = new ReaderWriterLock(); // The highest level to check. private static readonly Type _baseControlType = typeof(System.Web.UI.Control); // This constructor takes both a delegate that chooses this // device, and a Type to instantiate the appropriate page // adapter with. internal IndividualDeviceConfig(ControlsConfig controlsConfig, String name, DeviceQualifiesDelegate deviceQualifiesDelegate, Type pageAdapterType, String parentConfigName) { _controlsConfig = controlsConfig; _name = name; _deviceQualifiesPredicate = deviceQualifiesDelegate; _parentConfigName = parentConfigName; _parentConfig = null; PageAdapterType = pageAdapterType; } // This constructor takes just a page adapter for situations // where device selection isn't necessary (e.g., the designer). internal IndividualDeviceConfig(Type pageAdapterType) : this(null, null, null, pageAdapterType, null) { } // Given a context, see if this device config should handle // the given device. If there is no predicate, return true. internal /*public*/ bool DeviceQualifies(HttpContext context) { return _deviceQualifiesPredicate == null ? true : _deviceQualifiesPredicate(context); } // Register an adapter with the given control. internal /*public*/ void AddControl(Type controlType, Type adapterType) { // Don't need to synchronize, as this is only being called // from one thread -- the configuration section handler. _controlAdapterTypes[controlType] = FactoryGenerator.StaticFactoryGenerator.GetFactory(adapterType); } private Type PageAdapterType { get { return _pageAdapterType; } set { _pageAdapterType = value; if (value != null) { Debug.Assert(typeof(IPageAdapter).IsAssignableFrom(value)); _pageAdapterFactory = (IWebObjectFactory)FactoryGenerator.StaticFactoryGenerator.GetFactory(_pageAdapterType); } } } internal DeviceQualifiesDelegate DeviceQualifiesPredicate { get { return _deviceQualifiesPredicate; } set { _deviceQualifiesPredicate = value; } } protected IWebObjectFactory LookupControl(Type controlType) { return LookupControl(controlType, false); } private IWebObjectFactory LookupControl(Type controlType, bool lookInTypeCache) { IWebObjectFactory factory; factory = (IWebObjectFactory)_controlAdapterTypes[controlType]; if (factory == null && lookInTypeCache) { // Grab reader lock... using (new ReaderWriterLockResource(_controlAdapterTypesLock, false)) { factory = (IWebObjectFactory)_controlAdapterLookupCache[controlType]; } } return factory; } // Create a new page adapter for the device. internal /*public*/ IPageAdapter NewPageAdapter() { IPageAdapter a = _pageAdapterFactory.CreateInstance() as IPageAdapter; if (a == null) { throw new Exception( SR.GetString(SR.IndividualDeviceConfig_TypeMustSupportInterface, _pageAdapterType.FullName, "IPageAdapter")); } return a; } // Given a control's type, create a control adapter for it. internal virtual IControlAdapter NewControlAdapter(Type originalControlType) { IWebObjectFactory factory = GetAdapterFactory(originalControlType); // Should return non-null, or throw an exception. Debug.Assert(factory != null); IControlAdapter a = (IControlAdapter) factory.CreateInstance(); return a; } // Given a control's type, returns the adapter type to be used. // Note that it's legal to not register an adapter type for each // control type. // // This lookup uses the following steps: // // (1) Look up the control type directly, to see if an adapter type // has been registered for it. // (2) Walk up the control inheritance chain, to see if an adapter type // has been registered for the class. For example, if the passed // control type is a validator, check BaseValidator, Label, // TextControl, and finally MobileControl. // (3) If no adapter type has still been found, call the parent configuration, // if any, to look up the adapter type. For example, the CHTML device // configuration would call the HTML device configuration. // (4) If an adapter type is found, but is not explicitly registered for // the passed control type, add an entry to the table, so that // subsequent requests do not need to walk the hierarchy. protected IWebObjectFactory GetAdapterFactory(Type originalControlType) { Debug.Assert(_parentConfigName == null); Type controlType = originalControlType; IWebObjectFactory factory = LookupControl(controlType, true); // Look in type cache // Walk up hierarchy looking for registered adapters. // Stop when we get to the base control. while (factory == null && controlType != _baseControlType) { factory = LookupControl(controlType); if (factory == null) { controlType = controlType.BaseType; } } // Could not find one in the current hierarchy. So, look it up in // the parent config if there is one. if (factory == null && _parentConfig != null) { factory = _parentConfig.GetAdapterFactory(originalControlType); } if (factory == null) { throw new Exception( SR.GetString(SR.IndividualDeviceConfig_ControlWithIncorrectPageAdapter, controlType.FullName, _pageAdapterType.FullName)); } if (controlType != originalControlType) { // Add to lookup cache, so the next lookup won't require // traversing the hierarchy. // Grab writer lock... using (new ReaderWriterLockResource(_controlAdapterTypesLock, true)) { _controlAdapterLookupCache[originalControlType] = factory; } } return factory; } internal /*public*/ String Name { get { return _name; } } internal /*public*/ String ParentConfigName { get { return _parentConfigName; } set { _parentConfigName = null; } } internal /*public*/ IndividualDeviceConfig ParentConfig { get { return _parentConfig; } set { _parentConfig = value; } } private enum FixupState { NotFixedUp, FixingUp, FixedUp }; private FixupState _fixup = FixupState.NotFixedUp; internal /*public*/ void FixupInheritance(IndividualDeviceConfig referrer, XmlNode configNode) { if (_fixup == FixupState.FixedUp) { return; } if (_fixup == FixupState.FixingUp) { Debug.Assert(referrer != null); // Circular reference throw new Exception(SR.GetString(SR.MobileControlsSectionHandler_CircularReference, referrer.Name)); } _fixup = FixupState.FixingUp; if (ParentConfigName != null) { Debug.Assert(ParentConfigName.Length != 0 && ParentConfig == null); ParentConfig = _controlsConfig.GetDeviceConfig(ParentConfigName); if (ParentConfig == null) { throw new ConfigurationErrorsException( SR.GetString(SR.MobileControlsSectionHandler_DeviceConfigNotFound, ParentConfigName), configNode); } // Make sure parent is fixed up. ParentConfig.FixupInheritance(this, configNode); if (PageAdapterType == null) { PageAdapterType = ParentConfig.PageAdapterType; } if (DeviceQualifiesPredicate == null) { DeviceQualifiesPredicate = ParentConfig.DeviceQualifiesPredicate; } Debug.Assert(PageAdapterType != null); Debug.Assert(DeviceQualifiesPredicate != null); // Reset this since we don't need it any longer. ParentConfigName = null; } _fixup = FixupState.FixedUp; } } [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.")] internal class ReaderWriterLockResource : IDisposable { private ReaderWriterLock _lock; private bool _writerLock; internal /*public*/ ReaderWriterLockResource(ReaderWriterLock theLock, bool writerLock) { _lock = theLock; _writerLock = writerLock; if (_writerLock) { _lock.AcquireWriterLock(Timeout.Infinite); } else { _lock.AcquireReaderLock(Timeout.Infinite); } } /*public*/ void IDisposable.Dispose() { if (_writerLock) { _lock.ReleaseWriterLock(); } else { _lock.ReleaseReaderLock(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProcessHostFactoryHelper.cs
- MemoryPressure.cs
- TableRow.cs
- TextLine.cs
- _BufferOffsetSize.cs
- BinaryUtilClasses.cs
- ProviderConnectionPoint.cs
- WebFaultException.cs
- ParameterInfo.cs
- Annotation.cs
- CommandTreeTypeHelper.cs
- ObjectItemLoadingSessionData.cs
- NetPeerTcpBindingCollectionElement.cs
- RuntimeEnvironment.cs
- XPathQilFactory.cs
- SmtpTransport.cs
- HeaderUtility.cs
- SafeSecurityHandles.cs
- InternalBufferOverflowException.cs
- QueryCacheManager.cs
- SQLByte.cs
- _ListenerAsyncResult.cs
- DataGridViewLinkColumn.cs
- PingOptions.cs
- AssemblyCache.cs
- WebBrowserNavigatingEventHandler.cs
- SafeRegistryKey.cs
- BCLDebug.cs
- SqlMetaData.cs
- CurrentChangingEventManager.cs
- WebResourceUtil.cs
- DoubleConverter.cs
- PtsPage.cs
- VisualStyleElement.cs
- Receive.cs
- HtmlInputButton.cs
- Region.cs
- PathTooLongException.cs
- RSAPKCS1SignatureDeformatter.cs
- TabControlCancelEvent.cs
- Restrictions.cs
- UIntPtr.cs
- DataStorage.cs
- IriParsingElement.cs
- NetSectionGroup.cs
- ObjectSet.cs
- XmlHierarchicalDataSourceView.cs
- Connector.cs
- QuadraticBezierSegment.cs
- DesignerActionGlyph.cs
- PropertyGeneratedEventArgs.cs
- XmlILStorageConverter.cs
- ChannelBinding.cs
- TypeElementCollection.cs
- ObjectDataSourceStatusEventArgs.cs
- diagnosticsswitches.cs
- TransactionsSectionGroup.cs
- HostingMessageProperty.cs
- Image.cs
- NavigatorInput.cs
- SecurityCapabilities.cs
- GuidelineSet.cs
- PerformanceCounter.cs
- EntityDataSourceViewSchema.cs
- TextPenaltyModule.cs
- GridItem.cs
- GeneralTransform3DTo2D.cs
- DiscoveryInnerClientAdhocCD1.cs
- TableLayoutSettingsTypeConverter.cs
- TreeNodeClickEventArgs.cs
- RegionIterator.cs
- OdbcCommandBuilder.cs
- TextTreePropertyUndoUnit.cs
- _TransmitFileOverlappedAsyncResult.cs
- JsonServiceDocumentSerializer.cs
- RequiredAttributeAttribute.cs
- AnimationClockResource.cs
- ColumnMapVisitor.cs
- CustomLineCap.cs
- TailCallAnalyzer.cs
- AgileSafeNativeMemoryHandle.cs
- Repeater.cs
- Int32.cs
- xmlglyphRunInfo.cs
- CachedCompositeFamily.cs
- ViewUtilities.cs
- CacheEntry.cs
- GlyphRun.cs
- XmlSerializer.cs
- DBDataPermissionAttribute.cs
- ListenerConnectionDemuxer.cs
- brushes.cs
- CngUIPolicy.cs
- OleDbCommandBuilder.cs
- _ConnectOverlappedAsyncResult.cs
- InternalCompensate.cs
- BatchStream.cs
- ContractAdapter.cs
- httpserverutility.cs
- BindingValueChangedEventArgs.cs