⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classbinder.cs

📁 NHibernate NET开发者所需的
💻 CS
📖 第 1 页 / 共 3 页
字号:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using NHibernate.Cfg.MappingSchema;
using NHibernate.Engine;
using NHibernate.Mapping;
using NHibernate.Type;
using NHibernate.Util;

namespace NHibernate.Cfg.XmlHbmBinding
{
	public abstract class ClassBinder : Binder
	{
		protected readonly Dialect.Dialect dialect;
		protected readonly XmlNamespaceManager namespaceManager;

		public ClassBinder(Binder parent, XmlNamespaceManager namespaceManager, Dialect.Dialect dialect)
			: base(parent)
		{
			this.dialect = dialect;
			this.namespaceManager = namespaceManager;
		}

		public ClassBinder(ClassBinder parent)
			: base(parent)
		{
			dialect = parent.dialect;
			namespaceManager = parent.namespaceManager;
		}

		protected void PropertiesFromXML(XmlNode node, PersistentClass model)
		{
			Table table = model.Table;

			foreach (XmlNode subnode in node.ChildNodes)
			{
				//I am only concerned with elements that are from the nhibernate namespace
				if (subnode.NamespaceURI != Configuration.MappingSchemaXMLNS)
					continue;

				string name = subnode.LocalName; //.Name;
				string propertyName = GetPropertyName(subnode);

				IValue value = null;
				CollectionBinder collectionBinder = new CollectionBinder(this);
				if (collectionBinder.CanCreate(name))
				{
					Mapping.Collection collection = collectionBinder.Create(name, subnode, model.EntityName,
						propertyName, model, model.MappedClass);

					mappings.AddCollection(collection);
					value = collection;
				}
				else if ("many-to-one".Equals(name))
				{
					value = new ManyToOne(table);
					BindManyToOne(subnode, (ManyToOne) value, propertyName, true);
				}
				else if ("any".Equals(name))
				{
					value = new Any(table);
					BindAny(subnode, (Any) value, true);
				}
				else if ("one-to-one".Equals(name))
				{
					value = new OneToOne(table, model);
					BindOneToOne(subnode, (OneToOne) value);
				}
				else if ("property".Equals(name))
				{
					value = new SimpleValue(table);
					BindSimpleValue(subnode, (SimpleValue) value, true, propertyName);
				}
				else if ("component".Equals(name) || "dynamic-component".Equals(name))
				{
					// NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
					System.Type reflectedClass = GetPropertyType(subnode, model.MappedClass, propertyName);
					value = new Component(model);
					BindComponent(subnode, (Component) value, reflectedClass, model.EntityName, propertyName, true);
				}
				else if ("join".Equals(name))
				{
					Join join = new Join();
					join.PersistentClass = model;
					BindJoin(subnode, join);
					model.AddJoin(join);
				}
				else if ("subclass".Equals(name))
					new SubclassBinder(this).HandleSubclass(model, subnode);

				else if ("joined-subclass".Equals(name))
					new JoinedSubclassBinder(this).HandleJoinedSubclass(model, subnode);

				else if ("union-subclass".Equals(name))
					new UnionSubclassBinder(this).HandleUnionSubclass(model, subnode);

				else if ("filter".Equals(name))
					ParseFilter(subnode, model);

				if (value != null)
					model.AddProperty(CreateProperty(value, propertyName, model.MappedClass, subnode));
			}
		}

		protected void BindClass(XmlNode node, PersistentClass model)
		{
			string className = node.Attributes["name"] == null ? null : FullClassName(node.Attributes["name"].Value, mappings);

			// CLASS
			model.ClassName = ClassForFullNameChecked(className, "persistent class {0} not found").AssemblyQualifiedName;

			string entityName = node.Attributes["entity-name"] == null ? null : node.Attributes["name"].Value;
			if (entityName == null)
				entityName = model.MappedClass.FullName;
			if (entityName == null)
			{
				throw new MappingException("Unable to determine entity name");
			}
			model.EntityName = entityName;

			// PROXY INTERFACE
			XmlAttribute proxyNode = node.Attributes["proxy"];
			XmlAttribute lazyNode = node.Attributes["lazy"];
			bool lazy = lazyNode == null ? mappings.DefaultLazy : "true".Equals(lazyNode.Value);

			// go ahead and set the lazy here, since pojo.proxy can override it.
			model.IsLazy = lazy;

			if (proxyNode != null)
			{
				model.ProxyInterfaceName = ClassForNameChecked(proxyNode.Value, mappings, "proxy class not found: {0}").AssemblyQualifiedName;
				model.IsLazy = true;
			}
			else if (model.IsLazy)
				model.ProxyInterfaceName = model.MappedClass.AssemblyQualifiedName;

			// DISCRIMINATOR
			XmlAttribute discriminatorNode = node.Attributes["discriminator-value"];
			model.DiscriminatorValue = (discriminatorNode == null) ? model.EntityName : discriminatorNode.Value;

			// DYNAMIC UPDATE
			XmlAttribute dynamicNode = node.Attributes["dynamic-update"];
			model.DynamicUpdate = (dynamicNode == null) ? false : "true".Equals(dynamicNode.Value);

			// DYNAMIC INSERT
			XmlAttribute insertNode = node.Attributes["dynamic-insert"];
			model.DynamicInsert = (insertNode == null) ? false : "true".Equals(insertNode.Value);

			// IMPORT

			// we automatically want to add an import of the Assembly Qualified Name (includes version, 
			// culture, public-key) to the className supplied in the hbm.xml file.  The most common use-case
			// will have it contain the "FullClassname, AssemblyName", it might contain version, culture, 
			// public key, etc...) but should not assume it does.
			mappings.AddImport(model.MappedClass.AssemblyQualifiedName, StringHelper.GetFullClassname(className));

			// if we are supposed to auto-import the Class then add an import to get from the Classname
			// to the Assembly Qualified Class Name
			if (mappings.IsAutoImport)
				mappings.AddImport(model.MappedClass.AssemblyQualifiedName, StringHelper.GetClassname(className));

			// BATCH SIZE
			XmlAttribute batchNode = node.Attributes["batch-size"];
			if (batchNode != null)
				model.BatchSize = int.Parse(batchNode.Value);

			// SELECT BEFORE UPDATE
			XmlAttribute sbuNode = node.Attributes["select-before-update"];
			if (sbuNode != null)
				model.SelectBeforeUpdate = "true".Equals(sbuNode.Value);

			// OPTIMISTIC LOCK MODE
			XmlAttribute olNode = node.Attributes["optimistic-lock"];
			model.OptimisticLockMode = GetOptimisticLockMode(olNode);

			// META ATTRIBUTES
			model.MetaAttributes = GetMetas(node);

			// PERSISTER
			XmlAttribute persisterNode = node.Attributes["persister"];
			if (persisterNode == null)
			{
				//persister = typeof( EntityPersister );
			}
			else
				model.EntityPersisterClass =
					ClassForNameChecked(persisterNode.Value, mappings, "could not instantiate persister class: {0}");

			// CUSTOM SQL
			HandleCustomSQL(node, model);

			foreach (XmlNode syncNode in node.SelectNodes(HbmConstants.nsSynchronize, namespaceManager))
				model.AddSynchronizedTable(XmlHelper.GetAttributeValue(syncNode, "table"));

			bool? isAbstract = null;
			XmlAttribute abstractNode = node.Attributes["abstract"];
			if (abstractNode != null)
			{
				if ("true".Equals(abstractNode.Value) || "1".Equals(abstractNode.Value))
					isAbstract = true;
				else if ("false".Equals(abstractNode.Value) || "0".Equals(abstractNode.Value))
					isAbstract = false;
			}
			model.IsAbstract = isAbstract;
		}

		private void BindJoin(XmlNode node, Join join)
		{
			PersistentClass persistentClass = join.PersistentClass;
			String path = persistentClass.EntityName;

			// TABLENAME

			XmlAttribute schemaNode = node.Attributes["schema"];
			string schema = schemaNode == null ? mappings.SchemaName : schemaNode.Value;
			XmlAttribute catalogNode = node.Attributes["catalog"];
			string catalog = catalogNode == null ? mappings.CatalogName : catalogNode.Value;

			Table table = mappings.AddTable(schema, catalog, GetClassTableName(persistentClass, node), null, false);
			join.Table = table;

			XmlAttribute fetchNode = node.Attributes["fetch"];
			if (fetchNode != null)
				join.IsSequentialSelect = "select".Equals(fetchNode.Value);

			XmlAttribute invNode = node.Attributes["inverse"];
			if (invNode != null)
				join.IsInverse = "true".Equals(invNode.Value);

			XmlAttribute nullNode = node.Attributes["optional"];
			if (nullNode != null)
				join.IsOptional = "true".Equals(nullNode.Value);

			log.InfoFormat("Mapping class join: {0} -> {1}", persistentClass.EntityName, join.Table.Name);

			// KEY
			XmlNode keyNode = node.SelectSingleNode(HbmConstants.nsKey, namespaceManager);
			SimpleValue key = new DependantValue(table, persistentClass.Identifier);
			join.Key = key;
			if (keyNode.Attributes["on-delete"] != null)
				key.IsCascadeDeleteEnabled = "cascade".Equals(keyNode.Attributes["on-delete"].Value);
			BindSimpleValue(keyNode, key, false, persistentClass.EntityName);

			join.CreatePrimaryKey(dialect);
			join.CreateForeignKey();

			// PROPERTIES
			//PropertiesFromXML(node, persistentClass, mappings);
			foreach (XmlNode subnode in node.ChildNodes)
			{
				string name = subnode.Name;
				XmlAttribute nameAttribute = subnode.Attributes["name"];
				string propertyName = nameAttribute == null ? null : nameAttribute.Value;

				IValue value = null;
				switch (name)
				{
					case "many-to-one":
						value = new ManyToOne(table);
						BindManyToOne(subnode, (ManyToOne) value, propertyName, true);
						break;
					case "any":
						value = new Any(table);
						BindAny(subnode, (Any) value, true);
						break;
					case "property":
						value = new SimpleValue(table);
						BindSimpleValue(subnode, (SimpleValue) value, true, propertyName);
						break;
					case "component":
					case "dynamic-component":
						string subpath = StringHelper.Qualify(path, propertyName);
						value = new Component(join);
						BindComponent(
							subnode,
							(Component) value,
							join.PersistentClass.MappedClass,
							propertyName,
							subpath,
							true);
						break;
				}

				if (value != null)
				{
					Mapping.Property prop = CreateProperty(value, propertyName, persistentClass.MappedClass, subnode);
					prop.IsOptional = join.IsOptional;
					join.AddProperty(prop);
				}
			}

			// CUSTOM SQL
			HandleCustomSQL(node, join);
		}

		private void HandleCustomSQL(XmlNode node, PersistentClass model)
		{
			XmlNode element = node.SelectSingleNode(HbmConstants.nsSqlInsert, namespaceManager);

			if (element != null)
			{
				bool callable = IsCallable(element);
				model.SetCustomSQLInsert(element.InnerText.Trim(), callable, GetResultCheckStyle(element, callable));
			}

			element = node.SelectSingleNode(HbmConstants.nsSqlDelete, namespaceManager);
			if (element != null)
			{
				bool callable = IsCallable(element);
				model.SetCustomSQLDelete(element.InnerText.Trim(), callable, GetResultCheckStyle(element, callable));
			}

			element = node.SelectSingleNode(HbmConstants.nsSqlUpdate, namespaceManager);
			if (element != null)
			{
				bool callable = IsCallable(element);
				model.SetCustomSQLUpdate(element.InnerText.Trim(), callable, GetResultCheckStyle(element, callable));
			}

			element = node.SelectSingleNode(HbmConstants.nsLoader, namespaceManager);
			if (element != null)
				model.LoaderName = XmlHelper.GetAttributeValue(element, "query-ref");
		}

		private void HandleCustomSQL(XmlNode node, Join model)
		{
			XmlNode element = node.SelectSingleNode(HbmConstants.nsSqlInsert, namespaceManager);
			if (element != null)
			{
				bool callable = IsCallable(element);
				model.SetCustomSQLInsert(element.InnerText.Trim(), callable, GetResultCheckStyle(element, callable));
			}

			element = node.SelectSingleNode(HbmConstants.nsSqlDelete, namespaceManager);
			if (element != null)
			{
				bool callable = IsCallable(element);
				model.SetCustomSQLDelete(element.InnerText.Trim(), callable, GetResultCheckStyle(element, callable));
			}

			element = node.SelectSingleNode(HbmConstants.nsSqlUpdate, namespaceManager);
			if (element != null)
			{
				bool callable = IsCallable(element);
				model.SetCustomSQLUpdate(element.InnerText.Trim(), callable, GetResultCheckStyle(element, callable));
			}
		}

		private static Versioning.OptimisticLock GetOptimisticLockMode(XmlAttribute olAtt)
		{
			if (olAtt == null)
				return Versioning.OptimisticLock.Version;

			string olMode = olAtt.Value;

			if (olMode == null || "version".Equals(olMode))
				return Versioning.OptimisticLock.Version;
			else if ("dirty".Equals(olMode))
				return Versioning.OptimisticLock.Dirty;
			else if ("all".Equals(olMode))
				return Versioning.OptimisticLock.All;
			else if ("none".Equals(olMode))
				return Versioning.OptimisticLock.None;
			else
				throw new MappingException("Unsupported optimistic-lock style: " + olMode);
		}

		protected PersistentClass GetSuperclass(XmlNode subnode)
		{
			XmlAttribute extendsAttr = subnode.Attributes["extends"];
			if (extendsAttr == null)
				throw new MappingException("'extends' attribute is not found.");
			String extendsValue = FullClassName(extendsAttr.Value, mappings);
			System.Type superclass = ClassForFullNameChecked(extendsValue,
				"extended class not found: {0}");
			PersistentClass superModel = mappings.GetClass(superclass);

			if (superModel == null)
				throw new MappingException("Cannot extend unmapped class: " + extendsValue);
			return superModel;
		}

		protected string GetClassTableName(PersistentClass model, XmlNode node)
		{
			XmlAttribute tableNameNode = node.Attributes["table"];
			if (tableNameNode == null)
				return mappings.NamingStrategy.ClassToTableName(model.EntityName);
			else
				return mappings.NamingStrategy.TableName(tableNameNode.Value);
		}

		protected void MakeIdentifier(XmlNode node, SimpleValue model)
		{
			//GENERATOR

			XmlNode subnode = node.SelectSingleNode(HbmConstants.nsGenerator, namespaceManager);
			if (subnode != null)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -