e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
184 lines
7.1 KiB
C#
184 lines
7.1 KiB
C#
namespace System.Web.DynamicData.Util {
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Web.Resources;
|
|
using System.Web.UI;
|
|
using System.ComponentModel;
|
|
using IDataBoundControlInterface = System.Web.UI.WebControls.IDataBoundControl;
|
|
|
|
internal static class MetaTableHelper {
|
|
|
|
private static object s_mappingKey = new object();
|
|
|
|
internal static Dictionary<object, MappingInfo> GetMapping(HttpContextBase httpContext) {
|
|
Dictionary<object, MappingInfo> mapping = httpContext.Items[s_mappingKey] as Dictionary<object, MappingInfo>;
|
|
if (mapping == null) {
|
|
mapping = new Dictionary<object, MappingInfo>();
|
|
httpContext.Items[s_mappingKey] = mapping;
|
|
}
|
|
return mapping;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a table from the mapping. Does not throw.
|
|
/// </summary>
|
|
internal static MetaTable GetTableFromMapping(HttpContextBase httpContext, object control) {
|
|
IDictionary<object, MappingInfo> mapping = GetMapping(httpContext);
|
|
// don't throw if no mapping found
|
|
MappingInfo mappingInfo;
|
|
if (mapping.TryGetValue(control, out mappingInfo)) {
|
|
return mappingInfo.Table;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static MappingInfo GetMappingInfo(object control, HttpContextBase httpContext) {
|
|
IDictionary<object, MappingInfo> mapping = GetMapping(httpContext);
|
|
MappingInfo mappingInfo;
|
|
if (!mapping.TryGetValue(control, out mappingInfo)) {
|
|
mappingInfo = new MappingInfo();
|
|
mapping[control] = mappingInfo;
|
|
}
|
|
return mappingInfo;
|
|
}
|
|
|
|
internal static void SetTableInMapping(HttpContextBase httpContext, object control, MetaTable table, IDictionary<string, object> defaultValues) {
|
|
MappingInfo mappingInfo = GetMappingInfo(control, httpContext);
|
|
mappingInfo.Table = table;
|
|
if (defaultValues != null) {
|
|
mappingInfo.DefaultValueMapping = new DefaultValueMapping(defaultValues);
|
|
}
|
|
}
|
|
|
|
internal static MetaTable GetTableWithFullFallback(IDataSource dataSource, HttpContextBase context) {
|
|
MetaTable table = GetTableFromMapping(context, dataSource);
|
|
if (table != null) {
|
|
return table;
|
|
}
|
|
|
|
IDynamicDataSource dynamicDataSource = dataSource as IDynamicDataSource;
|
|
if (dynamicDataSource != null) {
|
|
table = GetTableFromDynamicDataSource(dynamicDataSource);
|
|
if (table != null) {
|
|
return table;
|
|
}
|
|
}
|
|
|
|
table = DynamicDataRouteHandler.GetRequestMetaTable(context);
|
|
if (table != null) {
|
|
return table;
|
|
}
|
|
|
|
Control c = dataSource as Control;
|
|
string id = (c != null ? c.ID : String.Empty);
|
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
|
DynamicDataResources.MetaTableHelper_CantFindTable,
|
|
id));
|
|
}
|
|
|
|
internal static MetaTable GetMetaTableFromObject(object dataSource) {
|
|
IEnumerable enumerable = dataSource as IEnumerable;
|
|
if (enumerable == null) {
|
|
return null;
|
|
}
|
|
|
|
// Use the first item to determine the type
|
|
//
|
|
foreach (object o in enumerable) {
|
|
if (o != null) {
|
|
return MetaTable.GetTable(o.GetType());
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// Gets a table from an IDynamicDataSource's ContextType and EntitySetName.
|
|
/// Does not throw, returns null on failure.
|
|
internal static MetaTable GetTableFromDynamicDataSource(IDynamicDataSource dynamicDataSource) {
|
|
string tableName = dynamicDataSource.EntitySetName;
|
|
Type contextType = dynamicDataSource.ContextType;
|
|
if (contextType == null || String.IsNullOrEmpty(tableName)) {
|
|
return null;
|
|
}
|
|
|
|
|
|
MetaModel model;
|
|
if (MetaModel.MetaModelManager.TryGetModel(contextType, out model)) {
|
|
Debug.Assert(model != null);
|
|
MetaTable table;
|
|
if (model.TryGetTable(tableName, out table)) {
|
|
return table;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
internal static MetaTable FindMetaTable(Control current) {
|
|
return FindMetaTable(current, HttpContext.Current.ToWrapper());
|
|
}
|
|
|
|
internal static DefaultValueMapping GetDefaultValueMapping(Control current, HttpContextBase context) {
|
|
IDictionary<object, MappingInfo> mapping = GetMapping(context);
|
|
if (!(current is INamingContainer)) {
|
|
current = current.NamingContainer;
|
|
}
|
|
|
|
for (; current != null; current = current.NamingContainer) {
|
|
MappingInfo mappingInfo;
|
|
// If we find a mapping then return that value
|
|
if (mapping.TryGetValue(current, out mappingInfo)) {
|
|
return mappingInfo.DefaultValueMapping;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
internal static MetaTable FindMetaTable(Control current, HttpContextBase context) {
|
|
MetaTable table = null;
|
|
// Start from the first naming container
|
|
if (!(current is INamingContainer)) {
|
|
current = current.NamingContainer;
|
|
}
|
|
for (; current != null; current = current.NamingContainer) {
|
|
// Find the first table mapped to a control
|
|
table = GetTableFromMapping(context, current);
|
|
if (table != null) {
|
|
return table;
|
|
}
|
|
|
|
IDataBoundControlInterface dataBoundControl = DataControlHelper.GetDataBoundControl(current, false /*failIfNotFound*/);
|
|
|
|
// Not a data control: continue searching
|
|
if (dataBoundControl == null) {
|
|
continue;
|
|
}
|
|
|
|
IDataSource dataSourceControl = dataBoundControl.DataSourceObject;
|
|
// Check if it's associated with a DataSource or can be retrieved from the current route
|
|
if (dataSourceControl != null) {
|
|
return GetTableWithFullFallback(dataSourceControl, context);
|
|
}
|
|
|
|
// Check if it has a datasource (i.e. not a control, but directly some data)
|
|
object dataSource = dataBoundControl.DataSource;
|
|
if (dataSource != null) {
|
|
// Try to get a MetaTable from it. If so, we're done
|
|
table = GetMetaTableFromObject(dataSource);
|
|
if (table != null) {
|
|
return table;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|