You've already forked linux-packaging-mono
297 lines
8.7 KiB
C#
297 lines
8.7 KiB
C#
//
|
|
// MetaModel.cs
|
|
//
|
|
// Authors:
|
|
// Atsushi Enomoto <atsushi@ximian.com>
|
|
// Marek Habersack <mhabersack@novell.com>
|
|
//
|
|
// Copyright (C) 2008 Novell Inc. http://novell.com
|
|
//
|
|
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.Security.Permissions;
|
|
using System.Security.Principal;
|
|
using System.Web.Caching;
|
|
using System.Web.DynamicData.ModelProviders;
|
|
|
|
namespace System.Web.DynamicData
|
|
{
|
|
[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
|
[AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
|
public class MetaModel
|
|
{
|
|
const string DEFAULT_DYNAMIC_DATA_VIRTUAL_FOLDER_PATH = "~/DynamicData/";
|
|
|
|
static object registered_models_lock = new object ();
|
|
|
|
static MetaModel default_model;
|
|
static Exception registration_exception;
|
|
static Dictionary<Type, MetaModel> registered_models;
|
|
|
|
string dynamicDataFolderVirtualPath;
|
|
|
|
public static MetaModel Default {
|
|
get { return default_model; }
|
|
internal set { default_model = value; }
|
|
}
|
|
|
|
public static MetaModel GetModel (Type contextType)
|
|
{
|
|
if (contextType == null)
|
|
throw new ArgumentNullException ("contextType");
|
|
|
|
MetaModel m;
|
|
if (!TryGetModel (contextType, out m))
|
|
throw new InvalidOperationException (String.Format ("Type '{0}' is not registered as a MetaModel", contextType));
|
|
|
|
return m;
|
|
}
|
|
|
|
public static void ResetRegistrationException ()
|
|
{
|
|
registration_exception = null;
|
|
}
|
|
|
|
public MetaModel ()
|
|
{
|
|
if (default_model == null)
|
|
default_model = this;
|
|
|
|
FieldTemplateFactory ftf = new FieldTemplateFactory ();
|
|
ftf.Initialize (this);
|
|
FieldTemplateFactory = ftf;
|
|
|
|
Tables = new ReadOnlyCollection<MetaTable> (new MetaTable [0]);
|
|
VisibleTables = new List<MetaTable> ();
|
|
}
|
|
|
|
public string DynamicDataFolderVirtualPath {
|
|
get {
|
|
if (dynamicDataFolderVirtualPath == null)
|
|
return DEFAULT_DYNAMIC_DATA_VIRTUAL_FOLDER_PATH;
|
|
|
|
return dynamicDataFolderVirtualPath;
|
|
}
|
|
|
|
set {
|
|
if (!String.IsNullOrEmpty (value))
|
|
dynamicDataFolderVirtualPath = VirtualPathUtility.AppendTrailingSlash (value);
|
|
else
|
|
dynamicDataFolderVirtualPath = value;
|
|
}
|
|
}
|
|
|
|
public IFieldTemplateFactory FieldTemplateFactory { get; set; }
|
|
|
|
public ReadOnlyCollection<MetaTable> Tables { get; private set; }
|
|
|
|
public List<MetaTable> VisibleTables { get; private set; }
|
|
|
|
void CheckRegistrationError ()
|
|
{
|
|
if (registration_exception != null)
|
|
throw new InvalidOperationException ("An error occured during context model registration", registration_exception);
|
|
}
|
|
|
|
public string GetActionPath (string tableName, string action, object row)
|
|
{
|
|
return GetTable (tableName).GetActionPath (action, row);
|
|
}
|
|
|
|
internal static void GetDataFieldAttribute <T> (AttributeCollection attributes, ref T backingField) where T: Attribute
|
|
{
|
|
if (backingField != null)
|
|
return;
|
|
|
|
foreach (Attribute attr in attributes) {
|
|
if (attr == null || !typeof (T).IsAssignableFrom (attr.GetType ()))
|
|
continue;
|
|
|
|
backingField = attr as T;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public MetaTable GetTable (string uniqueTableName)
|
|
{
|
|
MetaTable mt;
|
|
if (TryGetTable (uniqueTableName, out mt))
|
|
return mt;
|
|
throw new ArgumentException (String.Format ("Table '{0}' does not exist in registered context", uniqueTableName));
|
|
}
|
|
|
|
public MetaTable GetTable (Type entityType)
|
|
{
|
|
if (entityType == null)
|
|
throw new ArgumentNullException ("entityType");
|
|
|
|
foreach (var t in Tables) {
|
|
if (t.EntityType == entityType)
|
|
return t;
|
|
}
|
|
|
|
throw new ArgumentException (String.Format ("Entity type '{0}' does not exist in registered context", entityType));
|
|
}
|
|
|
|
public MetaTable GetTable (string tableName, Type contextType)
|
|
{
|
|
if (tableName == null)
|
|
throw new ArgumentNullException ("tableName");
|
|
|
|
MetaModel model;
|
|
if (contextType != null && !TryGetModel (contextType, out model))
|
|
throw new ArgumentException ("Unknown context type '" + contextType + "'. This context type has not been registered.");
|
|
|
|
return GetModel (contextType).GetTable (tableName);
|
|
}
|
|
|
|
internal static ICustomTypeDescriptor GetTypeDescriptor (Type type)
|
|
{
|
|
return TypeDescriptor.GetProvider (type).GetTypeDescriptor (type);
|
|
}
|
|
|
|
public void RegisterContext (Func<object> contextFactory)
|
|
{
|
|
RegisterContext (contextFactory, null);
|
|
}
|
|
|
|
public void RegisterContext (Type contextType)
|
|
{
|
|
RegisterContext (contextType, null);
|
|
}
|
|
|
|
public void RegisterContext (DataModelProvider dataModelProvider)
|
|
{
|
|
RegisterContext (dataModelProvider, null);
|
|
}
|
|
|
|
public void RegisterContext (Type contextType, ContextConfiguration configuration)
|
|
{
|
|
if (contextType == null)
|
|
throw new ArgumentNullException ("contextType");
|
|
CheckRegistrationError ();
|
|
RegisterContext (() => Activator.CreateInstance (contextType), configuration);
|
|
RegisterModel (contextType, this, configuration);
|
|
}
|
|
|
|
public void RegisterContext (Func<object> contextFactory, ContextConfiguration configuration)
|
|
{
|
|
if (contextFactory == null)
|
|
throw new ArgumentNullException ("contextFactory");
|
|
CheckRegistrationError ();
|
|
try {
|
|
// FIXME: entity framework support is not done.
|
|
RegisterContextCore (new DLinqDataModelProvider (contextFactory), configuration);
|
|
} catch (Exception ex) {
|
|
registration_exception = ex;
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public void RegisterContext (DataModelProvider dataModelProvider, ContextConfiguration configuration)
|
|
{
|
|
if (dataModelProvider == null)
|
|
throw new ArgumentNullException ("dataModelProvider");
|
|
CheckRegistrationError ();
|
|
try {
|
|
RegisterContextCore (dataModelProvider, configuration);
|
|
} catch (Exception ex) {
|
|
registration_exception = ex;
|
|
throw;
|
|
}
|
|
}
|
|
|
|
void RegisterContextCore (DataModelProvider dataModelProvider, ContextConfiguration configuration)
|
|
{
|
|
RegisterModel (dataModelProvider.ContextType, this, configuration);
|
|
|
|
var l = new List<MetaTable> (Tables);
|
|
foreach (var t in dataModelProvider.Tables)
|
|
l.Add (new MetaTable (this, t, configuration));
|
|
|
|
Tables = new ReadOnlyCollection<MetaTable> (l);
|
|
|
|
foreach (MetaTable t in l)
|
|
t.Init ();
|
|
|
|
VisibleTables = l;
|
|
}
|
|
|
|
static void RegisterModel (Type contextType, MetaModel model, ContextConfiguration configuration)
|
|
{
|
|
lock (registered_models_lock) {
|
|
if (registered_models == null)
|
|
registered_models = new Dictionary <Type, MetaModel> ();
|
|
|
|
if (registered_models.ContainsKey (contextType))
|
|
return;
|
|
|
|
registered_models.Add (contextType, model);
|
|
}
|
|
RegisterTypeDescriptionProvider (contextType, configuration);
|
|
}
|
|
|
|
static void RegisterTypeDescriptionProvider (Type type, ContextConfiguration config)
|
|
{
|
|
Func <Type, TypeDescriptionProvider> factory = config == null ? null : config.MetadataProviderFactory;
|
|
if (config == null || factory == null)
|
|
return;
|
|
|
|
TypeDescriptionProvider provider = factory (type);
|
|
if (provider == null)
|
|
return;
|
|
|
|
TypeDescriptor.AddProvider (provider, type);
|
|
}
|
|
|
|
public bool TryGetTable (string uniqueTableName, out MetaTable table)
|
|
{
|
|
if (uniqueTableName == null)
|
|
throw new ArgumentNullException ("uniqueTableName");
|
|
foreach (var t in Tables)
|
|
if (t.Name == uniqueTableName) {
|
|
table = t;
|
|
return true;
|
|
}
|
|
table = null;
|
|
return false;
|
|
}
|
|
|
|
static bool TryGetModel (Type contextType, out MetaModel model)
|
|
{
|
|
model = null;
|
|
if (registered_models != null && registered_models.TryGetValue (contextType, out model))
|
|
return model != null;
|
|
|
|
return false;
|
|
}
|
|
|
|
}
|
|
}
|