From: <fab...@us...> - 2008-10-16 03:32:27
|
Revision: 3862 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3862&view=rev Author: fabiomaulo Date: 2008-10-16 03:32:17 +0000 (Thu, 16 Oct 2008) Log Message: ----------- - Generic entities support trough entity-name - Improve of TypeNameParser Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Util/SessionFactoryHelper.cs trunk/nhibernate/src/NHibernate/Util/TypeNameParser.cs trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/A.cs trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Fixture.cs trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/UtilityTest/TypeNameParserFixture.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Util/SessionFactoryHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Util/SessionFactoryHelper.cs 2008-10-15 21:43:03 UTC (rev 3861) +++ trunk/nhibernate/src/NHibernate/Hql/Util/SessionFactoryHelper.cs 2008-10-16 03:32:17 UTC (rev 3862) @@ -11,6 +11,14 @@ { public static IQueryable FindQueryableUsingImports(ISessionFactoryImplementor sfi, string className) { + // NH : this method prevent unrecognized class when entityName != class.FullName + // this is a patch for the TODO below + var possibleResult = sfi.TryGetEntityPersister(GetEntityName(className)) as IQueryable; + if(possibleResult != null) + { + return possibleResult; + } + string importedClassName = sfi.GetImportedClassName(className); if (importedClassName == null) Modified: trunk/nhibernate/src/NHibernate/Util/TypeNameParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Util/TypeNameParser.cs 2008-10-15 21:43:03 UTC (rev 3861) +++ trunk/nhibernate/src/NHibernate/Util/TypeNameParser.cs 2008-10-16 03:32:17 UTC (rev 3862) @@ -7,10 +7,7 @@ { public class ParserException : ApplicationException { - public ParserException(string message) - : base(message) - { - } + public ParserException(string message) : base(message) {} } public class TypeNameParser @@ -27,7 +24,7 @@ private char[] Characters(int count) { - char[] chars = new char[count]; + var chars = new char[count]; if (input.ReadBlock(chars, 0, count) < count) { throw new ParserException(count + " characters expected"); @@ -50,13 +47,13 @@ private string AssemblyName() { - StringBuilder result = new StringBuilder(); + var result = new StringBuilder(); SkipSpaces(); int code; while ((code = input.Peek()) != -1) { - char ch = (char) code; + var ch = (char) code; if (ch == ']') { @@ -69,27 +66,47 @@ return result.ToString(); } - private string BracketedPart() + private string BracketedPart(string defaultNamespace, string defaultAssembly) { Debug.Assert(input.Peek() == '['); - StringBuilder result = new StringBuilder(); + var result = new StringBuilder(); + var genericTypeName = new StringBuilder(200); int depth = 0; do { - if (input.Peek() == '[') + int c = input.Peek(); + if (c == '[') { depth++; + result.Append(PossiblyEscapedCharacter()); } - else if (input.Peek() == ']') + else if (c == ']') { depth--; + if (genericTypeName.Length > 0) + { + var r = Parse(genericTypeName.ToString(), defaultNamespace, defaultAssembly); + result.Append(r.ToString()); + genericTypeName.Remove(0, genericTypeName.Length); + } + result.Append(PossiblyEscapedCharacter()); } + else if (c == ',' || c == ' ') + { + if (genericTypeName.Length > 0) + genericTypeName.Append(PossiblyEscapedCharacter()); + else + result.Append(PossiblyEscapedCharacter()); + } + else + { + genericTypeName.Append(PossiblyEscapedCharacter()); + } + } + while (depth > 0 && input.Peek() != -1); - result.Append(PossiblyEscapedCharacter()); - } while (depth > 0 && input.Peek() != -1); - if (depth > 0 && input.Peek() == -1) { throw new ParserException("Unmatched left bracket ('[')"); @@ -101,51 +118,54 @@ public AssemblyQualifiedTypeName ParseTypeName(string text, string defaultNamespace, string defaultAssembly) { text = text.Trim(); - - StringBuilder type = new StringBuilder(text.Length); + if (IsSystemType(text)) + { + defaultNamespace = null; + defaultAssembly = null; + } + var type = new StringBuilder(text.Length); string assembly = StringHelper.IsEmpty(defaultAssembly) ? null : defaultAssembly; try { bool seenNamespace = false; - input = new StringReader(text); - - int code; - while ((code = input.Peek()) != -1) + using (input = new StringReader(text)) { - char ch = (char) code; - - if (ch == '.') + int code; + while ((code = input.Peek()) != -1) { - seenNamespace = true; - } + var ch = (char) code; - if (ch == ',') - { - input.Read(); - assembly = AssemblyName(); - if (input.Peek() != -1) + if (ch == '.') { - throw new ParserException("Extra characters found at the end of the type name"); + seenNamespace = true; } + + if (ch == ',') + { + input.Read(); + assembly = AssemblyName(); + if (input.Peek() != -1) + { + throw new ParserException("Extra characters found at the end of the type name"); + } + } + else if (ch == '[') + { + type.Append(BracketedPart(defaultNamespace, defaultAssembly)); + } + else + { + type.Append(PossiblyEscapedCharacter()); + } } - else if (ch == '[') - { - type.Append(BracketedPart()); - } - else - { - type.Append(PossiblyEscapedCharacter()); - } + + input.Close(); } - - input.Close(); - if (!seenNamespace && StringHelper.IsNotEmpty(defaultNamespace)) { - type.Insert(0, '.') - .Insert(0, defaultNamespace); + type.Insert(0, '.').Insert(0, defaultNamespace); } return new AssemblyQualifiedTypeName(type.ToString(), assembly); } @@ -155,6 +175,11 @@ } } + private bool IsSystemType(string tyname) + { + return tyname.StartsWith("System"); // ugly + } + public static AssemblyQualifiedTypeName Parse(string text) { return Parse(text, null, null); Modified: trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/A.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/A.cs 2008-10-15 21:43:03 UTC (rev 3861) +++ trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/A.cs 2008-10-16 03:32:17 UTC (rev 3862) @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace NHibernate.Test.GenericTest.Overall @@ -9,26 +8,10 @@ /// </summary> public class A<T> { - private int? id; - private IList<T> collection; - private T property; + public virtual int? Id { get; set; } - public virtual int? Id - { - get { return id; } - set { id = value; } - } + public virtual T Property { get; set; } - public virtual T Property - { - get { return property; } - set { property = value; } - } - - public virtual IList<T> Collection - { - get { return collection; } - set { collection = value; } - } + public virtual IList<T> Collection { get; set; } } } Modified: trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Fixture.cs 2008-10-15 21:43:03 UTC (rev 3861) +++ trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Fixture.cs 2008-10-16 03:32:17 UTC (rev 3862) @@ -1,4 +1,3 @@ -using System; using System.Collections; using System.Collections.Generic; @@ -7,12 +6,11 @@ namespace NHibernate.Test.GenericTest.Overall { [TestFixture] - [Ignore( "Generic entities not supported" )] public class Fixture : TestCase { protected override IList Mappings { - get { return new string[] { "GenericTest.Overall.Mappings.hbm.xml" }; } + get { return new[] { "GenericTest.Overall.Mappings.hbm.xml" }; } } protected override string MappingsAssembly @@ -23,22 +21,19 @@ [Test] public void CRUD() { - A<int> entity = new A<int>(); - entity.Property = 10; - entity.Collection = new List<int>(); - entity.Collection.Add( 20 ); + var entity = new A<int> {Property = 10, Collection = new List<int> {20}}; using( ISession session = OpenSession() ) using( ITransaction transaction = session.BeginTransaction() ) { - session.Save( entity ); + session.Save("AInt", entity); transaction.Commit(); } using( ISession session = OpenSession() ) using( ITransaction transaction = session.BeginTransaction() ) { - session.Delete( entity ); + session.Delete("AInt", entity); transaction.Commit(); } } Modified: trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Mappings.hbm.xml 2008-10-15 21:43:03 UTC (rev 3861) +++ trunk/nhibernate/src/NHibernate.Test/GenericTest/Overall/Mappings.hbm.xml 2008-10-16 03:32:17 UTC (rev 3862) @@ -4,7 +4,7 @@ assembly="NHibernate.Test" namespace="NHibernate.Test.GenericTest.Overall"> - <class name="A`1[System.Int32]" table="A"> + <class name="A`1[System.Int32]" table="AInt" entity-name="AInt"> <id name="Id"> <generator class="native" /> Modified: trunk/nhibernate/src/NHibernate.Test/UtilityTest/TypeNameParserFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/UtilityTest/TypeNameParserFixture.cs 2008-10-15 21:43:03 UTC (rev 3861) +++ trunk/nhibernate/src/NHibernate.Test/UtilityTest/TypeNameParserFixture.cs 2008-10-16 03:32:17 UTC (rev 3862) @@ -127,5 +127,74 @@ { TypeNameParser.Parse("\\"); } + + [Test] + public void ParseGenericTypeNameWithDefaults() + { + string fullSpec = "TName`1[PartialName]"; + string defaultassembly = "SomeAssembly"; + string defaultNamespace = "SomeAssembly.MyNS"; + string expectedType = "SomeAssembly.MyNS.TName`1[SomeAssembly.MyNS.PartialName, SomeAssembly]"; + string expectedAssembly = "SomeAssembly"; + + AssemblyQualifiedTypeName tn = TypeNameParser.Parse(fullSpec, defaultNamespace, defaultassembly); + Assert.AreEqual(expectedType, tn.Type, "Type name should match"); + Assert.AreEqual(expectedAssembly, tn.Assembly, "Assembly name should match"); + + fullSpec = "TName`1[[PartialName]]"; + defaultassembly = "SomeAssembly"; + defaultNamespace = "SomeAssembly.MyNS"; + expectedType = "SomeAssembly.MyNS.TName`1[[SomeAssembly.MyNS.PartialName, SomeAssembly]]"; + expectedAssembly = "SomeAssembly"; + + tn = TypeNameParser.Parse(fullSpec, defaultNamespace, defaultassembly); + Assert.AreEqual(expectedType, tn.Type, "Type name should match"); + Assert.AreEqual(expectedAssembly, tn.Assembly, "Assembly name should match"); + + fullSpec = "TName`2[[PartialName],[OtherPartialName]]"; + defaultassembly = "SomeAssembly"; + defaultNamespace = "SomeAssembly.MyNS"; + expectedType = "SomeAssembly.MyNS.TName`2[[SomeAssembly.MyNS.PartialName, SomeAssembly],[SomeAssembly.MyNS.OtherPartialName, SomeAssembly]]"; + expectedAssembly = "SomeAssembly"; + tn = TypeNameParser.Parse(fullSpec, defaultNamespace, defaultassembly); + Assert.AreEqual(expectedType, tn.Type, "Type name should match"); + Assert.AreEqual(expectedAssembly, tn.Assembly, "Assembly name should match"); + } + + [Test] + public void ParseGenericTypeNameWithDefaultNamespaceUnused() + { + string fullSpec = "TName`1[SomeAssembly.MyOtherNS.PartialName]"; + string defaultassembly = "SomeAssembly"; + string defaultNamespace = "SomeAssembly.MyNS"; + string expectedType = "SomeAssembly.MyNS.TName`1[SomeAssembly.MyOtherNS.PartialName, SomeAssembly]"; + string expectedAssembly = "SomeAssembly"; + + AssemblyQualifiedTypeName tn = TypeNameParser.Parse(fullSpec, defaultNamespace, defaultassembly); + Assert.AreEqual(expectedType, tn.Type, "Type name should match"); + Assert.AreEqual(expectedAssembly, tn.Assembly, "Assembly name should match"); + + fullSpec = "SomeType`1[System.Int32]"; + defaultassembly = "SomeAssembly"; + defaultNamespace = null; + expectedType = "SomeType`1[System.Int32]"; + expectedAssembly = "SomeAssembly"; + + tn = TypeNameParser.Parse(fullSpec, defaultNamespace, defaultassembly); + Assert.AreEqual(expectedType, tn.Type, "Type name should match"); + Assert.AreEqual(expectedAssembly, tn.Assembly, "Assembly name should match"); + + fullSpec = typeof(MyGClass<int>).AssemblyQualifiedName; + defaultassembly = "SomeAssembly"; + defaultNamespace = "SomeAssembly.MyNS"; + expectedType = typeof(MyGClass<int>).AssemblyQualifiedName; + tn = TypeNameParser.Parse(fullSpec, defaultNamespace, defaultassembly); + Assert.AreEqual(expectedType, tn.Type + ", " + tn.Assembly, "Type name should match"); + } + + public class MyGClass<T> + { + + } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |