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
- VectorAnimation.cs
- RandomNumberGenerator.cs
- TransformerTypeCollection.cs
- ProfilePropertyMetadata.cs
- TargetFrameworkUtil.cs
- BindingManagerDataErrorEventArgs.cs
- TraceRecord.cs
- HuffmanTree.cs
- PenThreadPool.cs
- VersionConverter.cs
- ValidatingReaderNodeData.cs
- InheritablePropertyChangeInfo.cs
- FormatterConverter.cs
- TextTreeDeleteContentUndoUnit.cs
- UnsafeNativeMethods.cs
- WebBrowserNavigatingEventHandler.cs
- FramingEncoders.cs
- CountdownEvent.cs
- ToolStrip.cs
- ConfigurationPropertyCollection.cs
- DataSourceCollectionBase.cs
- XmlElementAttributes.cs
- FormViewPagerRow.cs
- TreeNodeBinding.cs
- CellRelation.cs
- ReadOnlyPropertyMetadata.cs
- Guid.cs
- grammarelement.cs
- RedistVersionInfo.cs
- sqlmetadatafactory.cs
- X509CertificateClaimSet.cs
- TableItemPattern.cs
- WebPartAddingEventArgs.cs
- DocumentViewer.cs
- PointHitTestParameters.cs
- GlyphCache.cs
- PeerCollaboration.cs
- InfoCardBaseException.cs
- SafeEventLogWriteHandle.cs
- Root.cs
- WebResponse.cs
- ControlTemplate.cs
- BitmapFrameEncode.cs
- StatusBarPanelClickEvent.cs
- dsa.cs
- RecipientInfo.cs
- Int64AnimationUsingKeyFrames.cs
- SchemaTableColumn.cs
- CodeTypeMember.cs
- CodeStatementCollection.cs
- CreatingCookieEventArgs.cs
- DWriteFactory.cs
- OdbcHandle.cs
- PageAction.cs
- TextAction.cs
- ToolboxDataAttribute.cs
- XamlGridLengthSerializer.cs
- DateTime.cs
- PrefixHandle.cs
- COMException.cs
- XmlSchemaAttributeGroupRef.cs
- PrintPreviewDialog.cs
- Variant.cs
- HtmlInputPassword.cs
- TextBoxDesigner.cs
- DoubleAnimation.cs
- SettingsPropertyValue.cs
- ConnectorMovedEventArgs.cs
- UnsafeCollabNativeMethods.cs
- XPathNavigatorException.cs
- WebPartAddingEventArgs.cs
- WeakHashtable.cs
- MessagePropertyVariants.cs
- CircleHotSpot.cs
- SpotLight.cs
- XsdBuildProvider.cs
- Blend.cs
- AppDomainProtocolHandler.cs
- MarshalByRefObject.cs
- MemberAccessException.cs
- UInt16Converter.cs
- Util.cs
- MetadataItemEmitter.cs
- HttpStreamXmlDictionaryReader.cs
- SiteMapNodeItemEventArgs.cs
- Environment.cs
- AccessControlList.cs
- ParagraphVisual.cs
- BinaryWriter.cs
- LogWriteRestartAreaAsyncResult.cs
- WhitespaceRuleReader.cs
- DataGridViewColumnCollection.cs
- AsyncOperationContext.cs
- EventManager.cs
- Splitter.cs
- RichTextBoxContextMenu.cs
- RemoteArgument.cs
- EntitySqlQueryCacheKey.cs
- ExpressionBindingCollection.cs
- DrawingAttributes.cs