|
From: <fab...@us...> - 2008-07-21 04:50:01
|
Revision: 3642
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3642&view=rev
Author: fabiomaulo
Date: 2008-07-21 04:49:58 +0000 (Mon, 21 Jul 2008)
Log Message:
-----------
- Enabled <tuplizer> (NH-1397)
- Fix NH-1395
- Fix NH-1396
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs
trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs
trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs
trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs
trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/Customer.hbm.xml
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/EntityNameInterceptor.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityInstantiator.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityTuplizer.cs
trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/TuplizerDynamicEntity.cs
Modified: trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Cfg/HbmConstants.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -48,5 +48,6 @@
public const string nsResultset = nsPrefix + ":resultset";
public const string nsUnionSubclass = nsPrefix + ":union-subclass";
+ public const string nsTuplizer = nsPrefix + ":tuplizer";
}
}
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/ClassBinder.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -106,36 +106,32 @@
protected void BindClass(XmlNode node, PersistentClass model)
{
- string className = node.Attributes["name"] == null ? null : FullClassName(node.Attributes["name"].Value, mappings);
+ // transfer an explicitly defined entity name
+ // handle the lazy attribute
+ 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;
- // CLASS
- model.ClassName = ClassForFullNameChecked(className, "persistent class {0} not found").AssemblyQualifiedName;
-
- string entityName = node.Attributes["entity-name"] == null ? null : node.Attributes["name"].Value;
+ string entityName = (node.Attributes["entity-name"] != null ? node.Attributes["entity-name"].Value : null)
+ ??
+ ClassForNameChecked(node.Attributes["name"].Value, mappings, "persistent class {0} not found").
+ FullName;
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);
+ BindPocoRepresentation(node, model);
+ BindXmlRepresentation(node, model);
+ BindMapRepresentation(node, model);
- // go ahead and set the lazy here, since pojo.proxy can override it.
- model.IsLazy = lazy;
+ BindPersistentClassCommonValues(node, model);
+ }
- 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;
-
+ private void BindPersistentClassCommonValues(XmlNode node, PersistentClass model)
+ {
// DISCRIMINATOR
XmlAttribute discriminatorNode = node.Attributes["discriminator-value"];
model.DiscriminatorValue = (discriminatorNode == null) ? model.EntityName : discriminatorNode.Value;
@@ -179,8 +175,8 @@
//persister = typeof( EntityPersister );
}
else
- model.EntityPersisterClass =
- ClassForNameChecked(persisterNode.Value, mappings, "could not instantiate persister class: {0}");
+ model.EntityPersisterClass = ClassForNameChecked(persisterNode.Value, mappings,
+ "could not instantiate persister class: {0}");
// CUSTOM SQL
HandleCustomSQL(node, model);
@@ -200,6 +196,71 @@
model.IsAbstract = isAbstract;
}
+ private void BindMapRepresentation(XmlNode node, PersistentClass entity)
+ {
+ XmlNode tuplizer = LocateTuplizerDefinition(node, EntityMode.Map);
+ if (tuplizer != null)
+ {
+ string tupClassName = FullClassName(tuplizer.Attributes["class"].Value, mappings);
+ entity.AddTuplizer(EntityMode.Map, tupClassName);
+ }
+ }
+
+ private void BindXmlRepresentation(XmlNode node, PersistentClass entity)
+ {
+ string nodeName = null;
+ XmlAttribute nodeAtt = node.Attributes["node"];
+ if(nodeAtt != null)
+ nodeName = nodeAtt.Value;
+ if (nodeName == null)
+ nodeName = StringHelper.Unqualify(entity.EntityName);
+ entity.NodeName = nodeName;
+
+ XmlNode tuplizer = LocateTuplizerDefinition(node, EntityMode.Xml);
+ if (tuplizer != null)
+ {
+ string tupClassName = FullClassName(tuplizer.Attributes["class"].Value, mappings);
+ entity.AddTuplizer(EntityMode.Xml, tupClassName);
+ }
+ }
+
+ private void BindPocoRepresentation(XmlNode node, PersistentClass entity)
+ {
+ string className = node.Attributes["name"] == null
+ ? null
+ : ClassForNameChecked(node.Attributes["name"].Value, mappings, "persistent class {0} not found").
+ AssemblyQualifiedName;
+
+ entity.ClassName = className;
+
+ XmlAttribute proxyNode = node.Attributes["proxy"];
+ if (proxyNode != null)
+ {
+ entity.ProxyInterfaceName = ClassForNameChecked(proxyNode.Value, mappings, "proxy class not found: {0}").AssemblyQualifiedName;
+ entity.IsLazy = true;
+ }
+ else if (entity.IsLazy)
+ entity.ProxyInterfaceName = className;
+
+ XmlNode tuplizer = LocateTuplizerDefinition(node, EntityMode.Poco);
+ if (tuplizer != null)
+ {
+ string tupClassName = FullClassName(tuplizer.Attributes["class"].Value, mappings);
+ entity.AddTuplizer(EntityMode.Poco, tupClassName);
+ }
+ }
+
+ private XmlNode LocateTuplizerDefinition(XmlNode container, EntityMode mode)
+ {
+ string modeToFind = EntityModeHelper.ToString(mode);
+ foreach (XmlNode node in container.SelectNodes(HbmConstants.nsTuplizer, namespaceManager))
+ {
+ if (modeToFind.Equals(node.Attributes["entity-mode"].Value))
+ return node;
+ }
+ return null;
+ }
+
private void BindJoin(XmlNode node, Join join)
{
PersistentClass persistentClass = join.PersistentClass;
@@ -1116,27 +1177,20 @@
private static string GetEntityName(XmlNode elem, Mappings model)
{
- // TODO: H3.2 Implement real entityName (look at IEntityPersister for feature)
- //string entityName = XmlHelper.GetAttributeValue(elem, "entity-name");
- //return entityName == null ? GetClassName( elem.Attributes[ "class" ], model ) : entityName;
- XmlAttribute att = elem.Attributes["class"];
+ string entityName = XmlHelper.GetAttributeValue(elem, "entity-name");
+ if (entityName == null)
+ {
+ XmlAttribute att = elem.Attributes["class"];
- if (att == null)
- return null;
+ return att == null ? null : GetClassName(att.Value, model);
+ }
+ else
+ {
+ return entityName;
+ }
- return GetClassName(att.Value, model);
}
- private static string GetQualifiedClassName(XmlNode elem, Mappings model)
- {
- XmlAttribute att = elem.Attributes["class"];
-
- if (att == null)
- return null;
-
- return GetQualifiedClassName(att.Value, model);
- }
-
protected XmlNodeList SelectNodes(XmlNode node, string xpath)
{
return node.SelectNodes(xpath, namespaceManager);
Modified: trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/EmptyInterceptor.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -58,7 +58,7 @@
return null;
}
- public string GetEntityName(object entity)
+ public virtual string GetEntityName(object entity)
{
return null;
}
Modified: trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Engine/UnsavedValueFactory.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -45,14 +45,11 @@
object defaultValue = identifierGetter.Get(Instantiate(constructor));
return new IdentifierValue(defaultValue);
}
- // TODO: NH - the branch below is actually never visited, so it's commented out
- /*
- else if( identifierGetter != null && ( identifierType is ValueTypeType ) )
+ else if (identifierGetter != null && (identifierType is PrimitiveType))
{
- object defaultValue = ( ( ValueTypeType ) identifierType ).DefaultValue;
- return new Cascades.IdentifierValue( defaultValue );
+ object defaultValue = ((PrimitiveType) identifierType).DefaultValue;
+ return new IdentifierValue(defaultValue);
}
- */
else
{
return IdentifierValue.SaveNull;
Modified: trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -730,6 +730,7 @@
/// <returns></returns>
public object Instantiate(IEntityPersister persister, object id)
{
+ ErrorIfClosed();
object result = interceptor.Instantiate(persister.EntityName, entityMode, id);
if (result == null)
{
Modified: trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Mapping/PersistentClass.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -59,7 +59,7 @@
private string temporaryIdTableName;
private string temporaryIdTableDDL;
- private IDictionary<EntityMode, System.Type> tuplizerImpls;
+ private IDictionary<EntityMode, string> tuplizerImpls;
private Versioning.OptimisticLock optimisticLockMode;
@@ -571,14 +571,11 @@
get { return temporaryIdTableDDL; }
}
- public virtual IDictionary<EntityMode, System.Type> TuplizerMap
+ public virtual IDictionary<EntityMode, string> TuplizerMap
{
get
{
- if (tuplizerImpls == null)
- return null;
-
- return new Dictionary<EntityMode, System.Type>(tuplizerImpls);
+ return tuplizerImpls == null ? null : new UnmodifiableDictionary<EntityMode, string>(tuplizerImpls);
}
}
@@ -1157,11 +1154,11 @@
get { return identifierMapper != null; }
}
- public void AddTuplizer(EntityMode entityMode, System.Type implClass)
+ public void AddTuplizer(EntityMode entityMode, string implClass)
{
if (tuplizerImpls == null)
{
- tuplizerImpls = new Dictionary<EntityMode, System.Type>();
+ tuplizerImpls = new Dictionary<EntityMode, string>();
}
tuplizerImpls[entityMode] = implClass;
}
@@ -1170,7 +1167,9 @@
{
if (tuplizerImpls == null)
return null;
- return tuplizerImpls[mode].AssemblyQualifiedName;
+ string result;
+ tuplizerImpls.TryGetValue(mode, out result);
+ return result;
}
public bool HasNaturalId()
Modified: trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Mapping/Subclass.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -161,19 +161,19 @@
get { return Superclass.FilterMap; }
}
- public override IDictionary<EntityMode, System.Type> TuplizerMap
+ public override IDictionary<EntityMode, string> TuplizerMap
{
get
{
- IDictionary<EntityMode, System.Type> specificTuplizerDefs = base.TuplizerMap;
- IDictionary<EntityMode, System.Type> superclassTuplizerDefs = Superclass.TuplizerMap;
+ IDictionary<EntityMode, string> specificTuplizerDefs = base.TuplizerMap;
+ IDictionary<EntityMode, string> superclassTuplizerDefs = Superclass.TuplizerMap;
if (specificTuplizerDefs == null && superclassTuplizerDefs == null)
{
return null;
}
else
{
- IDictionary<EntityMode, System.Type> combined = new Dictionary<EntityMode, System.Type>();
+ IDictionary<EntityMode, string> combined = new Dictionary<EntityMode, string>();
if (superclassTuplizerDefs != null)
{
ArrayHelper.AddAll(combined, superclassTuplizerDefs);
@@ -182,7 +182,7 @@
{
ArrayHelper.AddAll(combined, specificTuplizerDefs);
}
- return combined;
+ return new UnmodifiableDictionary<EntityMode, string>(combined);
}
}
}
Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityEntityModeToTuplizerMapping.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using NHibernate.Mapping;
+using NHibernate.Util;
namespace NHibernate.Tuple.Entity
{
@@ -25,19 +26,14 @@
public EntityEntityModeToTuplizerMapping(PersistentClass mappedEntity, EntityMetamodel em)
{
// create our own copy of the user-supplied tuplizer impl map
- Dictionary<EntityMode, System.Type> userSuppliedTuplizerImpls;
- if (mappedEntity.TuplizerMap != null)
- {
- userSuppliedTuplizerImpls = new Dictionary<EntityMode, System.Type>(mappedEntity.TuplizerMap);
- }
- else
- {
- userSuppliedTuplizerImpls = new Dictionary<EntityMode, System.Type>();
- }
+ Dictionary<EntityMode, string> userSuppliedTuplizerImpls = mappedEntity.TuplizerMap != null
+ ? new Dictionary<EntityMode, string>(
+ mappedEntity.TuplizerMap)
+ : new Dictionary<EntityMode, string>();
// Build the dynamic-map tuplizer...
ITuplizer dynamicMapTuplizer;
- System.Type tuplizerImpl;
+ string tuplizerImpl;
if (!userSuppliedTuplizerImpls.TryGetValue(EntityMode.Map, out tuplizerImpl))
{
dynamicMapTuplizer = new DynamicMapEntityTuplizer(em, mappedEntity);
@@ -51,7 +47,7 @@
// then the pojo tuplizer, using the dynamic-map tuplizer if no pojo representation is available
ITuplizer pojoTuplizer;
- System.Type tempObject2;
+ string tempObject2;
userSuppliedTuplizerImpls.TryGetValue(EntityMode.Poco, out tempObject2);
userSuppliedTuplizerImpls.Remove(EntityMode.Poco);
tuplizerImpl = tempObject2;
@@ -82,22 +78,23 @@
}
// then handle any user-defined entity modes...
- foreach (KeyValuePair<EntityMode, System.Type> pair in userSuppliedTuplizerImpls)
+ foreach (KeyValuePair<EntityMode, string> pair in userSuppliedTuplizerImpls)
{
IEntityTuplizer tuplizer = BuildEntityTuplizer(pair.Value, mappedEntity, em);
AddTuplizer(pair.Key, tuplizer);
}
}
- private static IEntityTuplizer BuildEntityTuplizer(System.Type implClass, PersistentClass pc, EntityMetamodel em)
+ private static IEntityTuplizer BuildEntityTuplizer(string className, PersistentClass pc, EntityMetamodel em)
{
try
{
+ System.Type implClass = ReflectHelper.ClassForName(className);
return (IEntityTuplizer)implClass.GetConstructor(entityTuplizerCTORSignature).Invoke(new object[] { em, pc });
}
catch (Exception t)
{
- throw new HibernateException("Could not build tuplizer [" + implClass.FullName + "]", t);
+ throw new HibernateException("Could not build tuplizer [" + className + "]", t);
}
}
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Address.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,10 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Address
+ {
+ long Id { get; set;}
+ string Street { get; set;}
+ string City { get; set;}
+ string PostalCode { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Company.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,8 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Company
+ {
+ long Id { get; set;}
+ string Name { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Customer.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,7 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Customer:Person
+ {
+ Company Company { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/DataProxyHandler.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,59 @@
+using System.Collections;
+using Castle.Core.Interceptor;
+
+namespace NHibernate.Test.DynamicEntity
+{
+ public sealed class DataProxyHandler : Castle.Core.Interceptor.IInterceptor
+ {
+ private readonly Hashtable data = new Hashtable();
+ private readonly string entityName;
+
+ public DataProxyHandler(string entityName, object id)
+ {
+ this.entityName = entityName;
+ data["Id"] = id;
+ }
+
+ public string EntityName
+ {
+ get { return entityName; }
+ }
+
+ public Hashtable Data
+ {
+ get { return data; }
+ }
+
+ #region IInterceptor Members
+
+ public void Intercept(IInvocation invocation)
+ {
+ invocation.ReturnValue = null;
+ string methodName = invocation.Method.Name;
+ if ("get_DataHandler".Equals(methodName))
+ {
+ invocation.ReturnValue = this;
+ }
+ else if (methodName.StartsWith("set_"))
+ {
+ string propertyName = methodName.Substring(4);
+ data[propertyName] = invocation.Arguments[0];
+ }
+ else if (methodName.StartsWith("get_"))
+ {
+ string propertyName = methodName.Substring(4);
+ invocation.ReturnValue = data[propertyName];
+ }
+ else if ("ToString".Equals(methodName))
+ {
+ invocation.ReturnValue = entityName + "#" + data["Id"];
+ }
+ else if ("GetHashCode".Equals(methodName))
+ {
+ invocation.ReturnValue = GetHashCode();
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/IProxyMarker.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,7 @@
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface IProxyMarker
+ {
+ DataProxyHandler DataHandler { get;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/Customer.hbm.xml 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.DynamicEntity">
+
+ <!--
+ Mapping the Customer and Company interfaces. Our custom Interceptor
+ will be responsible for:
+ a) creating instances representing these interfaces;
+ b) determining the appropriate entity-name (i.e., which entity mapping to use) given an instance of one of these proxies.
+ -->
+ <class name="Person" table="t_person" abstract="false">
+ <!-- <class name="Person" table="t_person" discriminator-value="person"> -->
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <discriminator force="false"/>
+ <property name="Name"/>
+
+ <many-to-one name="Address" cascade="all" column="addr_id"/>
+
+ <set name="Family" lazy="true" cascade="all">
+ <key column="pers_id"/>
+ <one-to-many class="Person"/>
+ </set>
+
+ <subclass name="Customer" discriminator-value="customer" abstract="false">
+ <many-to-one name="Company" cascade="none" column="comp_id"/>
+ </subclass>
+ </class>
+
+ <!-- Company interface mapping -->
+ <class name="Company" table="t_company" abstract="false">
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <property name="Name"/>
+ </class>
+
+ <class name="Address" table="t_address" abstract="false">
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <property name="Street"/>
+ <property name="City"/>
+ <property name="PostalCode"/>
+ </class>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/InterceptorDynamicEntity.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,92 @@
+using System.Collections;
+using NHibernate.Cfg;
+using NUnit.Framework;
+
+namespace NHibernate.Test.DynamicEntity.Interceptor
+{
+ [TestFixture]
+ public class InterceptorDynamicEntity : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override IList Mappings
+ {
+ get { return new string[] {"DynamicEntity.Interceptor.Customer.hbm.xml"}; }
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ configuration.SetInterceptor(new ProxyInterceptor());
+ }
+
+ [Test]
+ public void It()
+ {
+ // Test saving these dyna-proxies
+ ISession session = OpenSession();
+ session.BeginTransaction();
+ Company company = ProxyHelper.NewCompanyProxy();
+ company.Name = "acme";
+ session.Save(company);
+ Customer customer = ProxyHelper.NewCustomerProxy();
+ customer.Name = "Steve";
+ customer.Company = company;
+ session.Save(customer);
+ session.Transaction.Commit();
+ session.Close();
+
+ Assert.IsNotNull(company.Id, "company id not assigned");
+ Assert.IsNotNull(customer.Id, "customer id not assigned");
+
+ // Test loading these dyna-proxies, along with flush processing
+ session = OpenSession();
+ session.BeginTransaction();
+ customer = session.Load<Customer>(customer.Id);
+ Assert.IsFalse(NHibernateUtil.IsInitialized(customer), "should-be-proxy was initialized");
+
+ customer.Name = "other";
+ session.Flush();
+ Assert.IsFalse(NHibernateUtil.IsInitialized(customer.Company), "should-be-proxy was initialized");
+
+ session.Refresh(customer);
+ Assert.AreEqual("other", customer.Name, "name not updated");
+ Assert.AreEqual("acme", customer.Company.Name, "company association not correct");
+
+ session.Transaction.Commit();
+ session.Close();
+
+ // Test detached entity re-attachment with these dyna-proxies
+ customer.Name = "Steve";
+ session = OpenSession();
+ session.BeginTransaction();
+ session.Update(customer);
+ session.Flush();
+ session.Refresh(customer);
+ Assert.AreEqual("Steve", customer.Name, "name not updated");
+ session.Transaction.Commit();
+ session.Close();
+
+ // Test querying
+ session = OpenSession();
+ session.BeginTransaction();
+ int count = session.CreateQuery("from Customer").List().Count;
+ Assert.AreEqual(1, count, "querying dynamic entity");
+ session.Clear();
+ count = session.CreateQuery("from Person").List().Count;
+ Assert.AreEqual(1, count, "querying dynamic entity");
+ session.Transaction.Commit();
+ session.Close();
+
+ // test deleteing
+ session = OpenSession();
+ session.BeginTransaction();
+ session.Delete(company);
+ session.Delete(customer);
+ session.Transaction.Commit();
+ session.Close();
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Interceptor/ProxyInterceptor.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,27 @@
+namespace NHibernate.Test.DynamicEntity.Interceptor
+{
+ public class ProxyInterceptor : EmptyInterceptor
+ {
+ public override string GetEntityName(object entity)
+ {
+ string entityName = ProxyHelper.ExtractEntityName(entity) ?? base.GetEntityName(entity);
+ return entityName;
+ }
+
+ public override object Instantiate(string entityName, EntityMode entityMode, object id)
+ {
+ if (entityMode == EntityMode.Poco)
+ {
+ if (typeof(Customer).FullName.Equals(entityName))
+ {
+ return ProxyHelper.NewCustomerProxy(id);
+ }
+ else if (typeof(Company).FullName.Equals(entityName))
+ {
+ return ProxyHelper.NewCompanyProxy(id);
+ }
+ }
+ return base.Instantiate(entityName, entityMode, id);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Person.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,12 @@
+using Iesi.Collections.Generic;
+
+namespace NHibernate.Test.DynamicEntity
+{
+ public interface Person
+ {
+ long Id { get; set;}
+ string Name { get; set;}
+ Address Address { get;set;}
+ ISet<Person> Family { get; set;}
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/ProxyHelper.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,79 @@
+using Castle.DynamicProxy;
+
+namespace NHibernate.Test.DynamicEntity
+{
+ public class ProxyHelper
+ {
+ private static readonly ProxyGenerator proxyGenerator = new ProxyGenerator();
+
+ public static Person NewPersonProxy()
+ {
+ return NewPersonProxy(0L);
+ }
+
+ public static Person NewPersonProxy(object id)
+ {
+ return
+ (Person)
+ proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof (Person),
+ new System.Type[] {typeof (IProxyMarker), typeof (Person)},
+ new DataProxyHandler(typeof (Person).FullName, id));
+ }
+
+ public static Customer NewCustomerProxy()
+ {
+ return NewCustomerProxy(0L);
+ }
+
+ public static Customer NewCustomerProxy(object id)
+ {
+ return
+ (Customer)
+ proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof (Customer),
+ new System.Type[] {typeof (IProxyMarker), typeof (Customer)},
+ new DataProxyHandler(typeof (Customer).FullName, id));
+ }
+
+ public static Company NewCompanyProxy()
+ {
+ return NewCompanyProxy(0L);
+ }
+
+ public static Company NewCompanyProxy(object id)
+ {
+ return
+ (Company)
+ proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof (Company),
+ new System.Type[] {typeof (IProxyMarker), typeof (Company)},
+ new DataProxyHandler(typeof (Company).FullName, id));
+ }
+
+ public static Address NewAddressProxy()
+ {
+ return NewAddressProxy(0L);
+ }
+
+ public static Address NewAddressProxy(object id)
+ {
+ return
+ (Address)
+ proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof (Address),
+ new System.Type[] {typeof (IProxyMarker), typeof (Address)},
+ new DataProxyHandler(typeof (Address).FullName, id));
+ }
+
+ public static string ExtractEntityName(object obj)
+ {
+ // Our custom Proxy instances actually bundle
+ // their appropriate entity name, so we simply extract it from there
+ // if this represents one of our proxies; otherwise, we return null
+ IProxyMarker pm = obj as IProxyMarker;
+ if (pm != null)
+ {
+ DataProxyHandler myHandler = pm.DataHandler;
+ return myHandler.EntityName;
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/Customer.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/Customer.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/Customer.hbm.xml 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.DynamicEntity">
+
+ <!--
+ Mapping the Customer and Company interfaces. Our custom Interceptor
+ will be responsible for:
+ a) creating instances representing these interfaces;
+ b) determining the appropriate entity-name (i.e., which entity mapping to use) given an instance of one of these proxies.
+ -->
+ <class name="Person" table="t_person" discriminator-value="person" abstract="false">
+ <tuplizer class="NHibernate.Test.DynamicEntity.Tuplizer.MyEntityTuplizer, NHibernate.Test" entity-mode="poco"/>
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <discriminator force="false"/>
+ <property name="Name"/>
+
+ <many-to-one name="Address" cascade="all" column="addr_id"/>
+
+ <set name="Family" lazy="true" cascade="all" generic="true">
+ <key column="pers_id"/>
+ <one-to-many class="Person"/>
+ </set>
+
+ <subclass name="Customer" discriminator-value="customer" abstract="false">
+ <tuplizer class="NHibernate.Test.DynamicEntity.Tuplizer.MyEntityTuplizer, NHibernate.Test" entity-mode="poco"/>
+ <many-to-one name="Company" cascade="none" column="comp_id"/>
+ </subclass>
+ </class>
+
+ <!-- Company interface mapping -->
+ <class name="Company" table="t_company" abstract="false">
+ <tuplizer class="NHibernate.Test.DynamicEntity.Tuplizer.MyEntityTuplizer, NHibernate.Test" entity-mode="poco"/>
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <property name="Name"/>
+ </class>
+
+ <class name="Address" table="t_address" abstract="false">
+ <tuplizer class="NHibernate.Test.DynamicEntity.Tuplizer.MyEntityTuplizer, NHibernate.Test" entity-mode="poco"/>
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <property name="Street"/>
+ <property name="City"/>
+ <property name="PostalCode"/>
+ </class>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/EntityNameInterceptor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/EntityNameInterceptor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/EntityNameInterceptor.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,11 @@
+namespace NHibernate.Test.DynamicEntity.Tuplizer
+{
+ public class EntityNameInterceptor : EmptyInterceptor
+ {
+ public override string GetEntityName(object entity)
+ {
+ string entityName = ProxyHelper.ExtractEntityName(entity) ?? base.GetEntityName(entity);
+ return entityName;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityInstantiator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityInstantiator.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityInstantiator.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,56 @@
+using System;
+using NHibernate.Tuple;
+
+namespace NHibernate.Test.DynamicEntity.Tuplizer
+{
+ public class MyEntityInstantiator : IInstantiator
+ {
+ private readonly System.Type entityType;
+
+ public MyEntityInstantiator(System.Type entityType)
+ {
+ this.entityType = entityType;
+ }
+
+ public object Instantiate(object id)
+ {
+ if (typeof(Person).Equals(entityType))
+ {
+ return ProxyHelper.NewPersonProxy(id);
+ }
+ if (typeof(Customer).Equals(entityType))
+ {
+ return ProxyHelper.NewCustomerProxy(id);
+ }
+ else if (typeof(Company).Equals(entityType))
+ {
+ return ProxyHelper.NewCompanyProxy(id);
+ }
+ else if (typeof(Address).Equals(entityType))
+ {
+ return ProxyHelper.NewAddressProxy(id);
+ }
+ else
+ {
+ throw new ArgumentException("unknown entity for instantiation [" + entityType.FullName + "]");
+ }
+ }
+
+ public object Instantiate()
+ {
+ return Instantiate(null);
+ }
+
+ public bool IsInstance(object obj)
+ {
+ try
+ {
+ return entityType.IsInstanceOfType(obj);
+ }
+ catch (Exception e)
+ {
+ throw new HibernateException("could not get handle to entity-name as interface : " + e);
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityTuplizer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityTuplizer.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/MyEntityTuplizer.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,24 @@
+using NHibernate.Mapping;
+using NHibernate.Tuple.Entity;
+
+namespace NHibernate.Test.DynamicEntity.Tuplizer
+{
+ public class MyEntityTuplizer : PocoEntityTuplizer
+ {
+ public MyEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) : base(entityMetamodel, mappedEntity) {}
+
+ protected override Tuple.IInstantiator BuildInstantiator(PersistentClass persistentClass)
+ {
+ return new MyEntityInstantiator(persistentClass.MappedClass);
+ }
+
+ protected override Proxy.IProxyFactory BuildProxyFactory(PersistentClass persistentClass, NHibernate.Properties.IGetter idGetter, NHibernate.Properties.ISetter idSetter)
+ {
+ // allows defining a custom proxy factory, which is responsible for
+ // generating lazy proxies for a given entity.
+ //
+ // Here we simply use the default...
+ return base.BuildProxyFactory(persistentClass, idGetter, idSetter);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/TuplizerDynamicEntity.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/TuplizerDynamicEntity.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/DynamicEntity/Tuplizer/TuplizerDynamicEntity.cs 2008-07-21 04:49:58 UTC (rev 3642)
@@ -0,0 +1,108 @@
+using System.Collections;
+using Iesi.Collections.Generic;
+using NHibernate.Cfg;
+using NUnit.Framework;
+
+namespace NHibernate.Test.DynamicEntity.Tuplizer
+{
+ [TestFixture]
+ public class TuplizerDynamicEntity : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override IList Mappings
+ {
+ get { return new string[] {"DynamicEntity.Tuplizer.Customer.hbm.xml"}; }
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ configuration.SetInterceptor(new EntityNameInterceptor());
+ }
+
+ [Test]
+ public void It()
+ {
+ // Test saving these dyna-proxies
+ ISession session = OpenSession();
+ session.BeginTransaction();
+ Company company = ProxyHelper.NewCompanyProxy();
+ company.Name = "acme";
+ session.Save(company);
+ Customer customer = ProxyHelper.NewCustomerProxy();
+ customer.Name = "Steve";
+ customer.Company = company;
+ Address address = ProxyHelper.NewAddressProxy();
+ address.Street = "somewhere over the rainbow";
+ address.City = "lawerence, kansas";
+ address.PostalCode = "toto";
+ customer.Address = address;
+ customer.Family = new HashedSet<Person>();
+ Person son = ProxyHelper.NewPersonProxy();
+ son.Name = "son";
+ customer.Family.Add(son);
+ Person wife = ProxyHelper.NewPersonProxy();
+ wife.Name = "wife";
+ customer.Family.Add(wife);
+ session.Save(customer);
+ session.Transaction.Commit();
+ session.Close();
+
+ Assert.IsNotNull(company.Id, "company id not assigned");
+ Assert.IsNotNull(customer.Id, "customer id not assigned");
+ Assert.IsNotNull(address.Id, "address id not assigned");
+ Assert.IsNotNull(son.Id, "son:Person id not assigned");
+ Assert.IsNotNull(wife.Id, "wife:Person id not assigned");
+
+ // Test loading these dyna-proxies, along with flush processing
+ session = OpenSession();
+ session.BeginTransaction();
+ customer = session.Load<Customer>(customer.Id);
+ Assert.IsFalse(NHibernateUtil.IsInitialized(customer), "should-be-proxy was initialized");
+
+ customer.Name = "other";
+ session.Flush();
+ Assert.IsFalse(NHibernateUtil.IsInitialized(customer.Company), "should-be-proxy was initialized");
+
+ session.Refresh(customer);
+ Assert.AreEqual("other", customer.Name, "name not updated");
+ Assert.AreEqual("acme", customer.Company.Name, "company association not correct");
+
+ session.Transaction.Commit();
+ session.Close();
+
+ // Test detached entity re-attachment with these dyna-proxies
+ customer.Name = "Steve";
+ session = OpenSession();
+ session.BeginTransaction();
+ session.Update(customer);
+ session.Flush();
+ session.Refresh(customer);
+ Assert.AreEqual("Steve", customer.Name, "name not updated");
+ session.Transaction.Commit();
+ session.Close();
+
+ // Test querying
+ session = OpenSession();
+ session.BeginTransaction();
+ int count = session.CreateQuery("from Customer").List().Count;
+ Assert.AreEqual(1, count, "querying dynamic entity");
+ session.Clear();
+ count = session.CreateQuery("from Person").List().Count;
+ Assert.AreEqual(3, count, "querying dynamic entity");
+ session.Transaction.Commit();
+ session.Close();
+
+ // test deleteing
+ session = OpenSession();
+ session.BeginTransaction();
+ session.Delete(company);
+ session.Delete(customer);
+ session.Transaction.Commit();
+ session.Close();
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-19 14:07:03 UTC (rev 3641)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-21 04:49:58 UTC (rev 3642)
@@ -120,6 +120,19 @@
<Compile Include="DriverTest\NullReferenceFixture.cs" />
<Compile Include="DriverTest\OracleClientDriverFixture.cs" />
<Compile Include="DriverTest\OracleDataClientDriverFixture.cs" />
+ <Compile Include="DynamicEntity\Address.cs" />
+ <Compile Include="DynamicEntity\Company.cs" />
+ <Compile Include="DynamicEntity\Customer.cs" />
+ <Compile Include="DynamicEntity\DataProxyHandler.cs" />
+ <Compile Include="DynamicEntity\Interceptor\InterceptorDynamicEntity.cs" />
+ <Compile Include="DynamicEntity\Interceptor\ProxyInterceptor.cs" />
+ <Compile Include="DynamicEntity\IProxyMarker.cs" />
+ <Compile Include="DynamicEntity\Person.cs" />
+ <Compile Include="DynamicEntity\ProxyHelper.cs" />
+ <Compile Include="DynamicEntity\Tuplizer\EntityNameInterceptor.cs" />
+ <Compile Include="DynamicEntity\Tuplizer\MyEntityInstantiator.cs" />
+ <Compile Include="DynamicEntity\Tuplizer\MyEntityTuplizer.cs" />
+ <Compile Include="DynamicEntity\Tuplizer\TuplizerDynamicEntity.cs" />
<Compile Include="EngineTest\TypedValueFixture.cs" />
<Compile Include="ExceptionsTest\Group.cs" />
<Compile Include="ExceptionsTest\MSSQLExceptionConverterExample.cs" />
@@ -1345,6 +1358,11 @@
<EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="DynamicEntity\Interceptor\Customer.hbm.xml" />
+ <Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" />
+ </ItemGroup>
+ <ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|